feat(web): billing loading skeleton shape + show-more pagination

Make the payments loading state mirror the table card (header + rows)
instead of generic bars, and paginate the list client-side (10 at a time
with a "Show more" button) so long payment histories don't render all at
once.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-27 00:07:50 +03:00
parent 94d04d5339
commit 0e61a2fcc7
3 changed files with 22 additions and 6 deletions

View File

@@ -69,6 +69,7 @@ function BillingPage() {
const { t, locale } = useTranslation();
const [statusFilter, setStatusFilter] = useState<string>("all");
const [methodFilter, setMethodFilter] = useState<string>("all");
const [visibleCount, setVisibleCount] = useState(10);
const hasActiveFilter = statusFilter !== "all" || methodFilter !== "all";
function clearFilters() {
@@ -198,11 +199,17 @@ function BillingPage() {
{/* Loading State */}
{isLoading ? (
<div className="space-y-4">
{["s1", "s2", "s3", "s4", "s5"].map((id) => (
<Skeleton key={id} className="h-16 w-full" />
))}
</div>
<Card>
<CardHeader>
<Skeleton className="h-5 w-32" />
</CardHeader>
<CardContent className="space-y-3">
<Skeleton className="h-4 w-full" />
{["s1", "s2", "s3", "s4", "s5"].map((id) => (
<Skeleton key={id} className="h-10 w-full" />
))}
</CardContent>
</Card>
) : !filteredPayments || filteredPayments.length === 0 ? (
<Card>
<CardContent className="flex flex-col items-center gap-3 py-12 text-center text-muted-foreground">
@@ -245,7 +252,7 @@ function BillingPage() {
</tr>
</thead>
<tbody className="divide-y">
{filteredPayments.map((payment) => (
{filteredPayments.slice(0, visibleCount).map((payment) => (
<tr key={payment.id}>
<td className="py-4 tabular-nums">
{new Date(payment.createdAt).toLocaleDateString(
@@ -287,6 +294,13 @@ function BillingPage() {
</tbody>
</table>
</div>
{filteredPayments.length > visibleCount && (
<div className="mt-4 text-center">
<Button variant="outline" size="sm" onClick={() => setVisibleCount((c) => c + 10)}>
{t("billing.showMore")}
</Button>
</div>
)}
</CardContent>
</Card>
)}