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:
@@ -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>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user