From 970abc0f036e0ef0488ff7848d196096be82c8aa Mon Sep 17 00:00:00 2001 From: nams1570 Date: Tue, 14 Jul 2026 10:35:36 -0700 Subject: [PATCH] refactor: shared skeleton for table --- .../payments/products/[productId]/page-client.tsx | 14 +++----------- .../components/data-table/transaction-table.tsx | 15 +++------------ .../src/components/ui/data-table/cells.tsx | 11 +++++++++++ 3 files changed, 17 insertions(+), 23 deletions(-) diff --git a/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/products/[productId]/page-client.tsx b/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/products/[productId]/page-client.tsx index 81cfcdc21..71efa7ddb 100644 --- a/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/products/[productId]/page-client.tsx +++ b/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/products/[productId]/page-client.tsx @@ -9,6 +9,7 @@ import { ActionCell, Alert, AvatarCell, + AvatarCellSkeleton, Badge, Button, Checkbox, @@ -1552,11 +1553,11 @@ function ProductCustomersSection({ productId, product }: ProductCustomersSection width: 200, renderCell: ({ row }) => ( row.customerType === 'user' ? ( - }> + }> ) : row.customerType === 'team' ? ( - }> + }> ) : ( @@ -1643,15 +1644,6 @@ function ProductCustomersSection({ productId, product }: ProductCustomersSection ); } -function CustomerAvatarSkeleton() { - return ( -
- - -
- ); -} - function CustomerRowActions({ customerType, customerId }: { customerType: string, customerId: string }) { const adminApp = useAdminApp(); return ( diff --git a/apps/dashboard/src/components/data-table/transaction-table.tsx b/apps/dashboard/src/components/data-table/transaction-table.tsx index 5c1dd5d3c..0936d54eb 100644 --- a/apps/dashboard/src/components/data-table/transaction-table.tsx +++ b/apps/dashboard/src/components/data-table/transaction-table.tsx @@ -5,7 +5,7 @@ 'use client'; import { useAdminApp } from '@/app/(main)/(protected)/projects/[projectId]/use-admin-app'; -import { ActionCell, ActionDialog, Alert, AlertDescription, AvatarCell, Badge, Input, Label, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, SimpleTooltip, Skeleton } from '@/components/ui'; +import { ActionCell, ActionDialog, Alert, AlertDescription, AvatarCell, AvatarCellSkeleton, Badge, Input, Label, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, SimpleTooltip } from '@/components/ui'; import type { Icon as PhosphorIcon } from '@phosphor-icons/react'; import { ArrowClockwiseIcon, ArrowCounterClockwiseIcon, GearIcon, ProhibitIcon, QuestionIcon, ReceiptXIcon, ShoppingCartIcon, ShuffleIcon } from '@phosphor-icons/react'; import { DataGrid, DataGridToolbar, useDataGridUrlState, useDataSource, type DataGridColumnDef, type DataGridDataSource, type DataGridExportField, type DataGridExportScope } from '@hexclave/dashboard-ui-components'; @@ -153,15 +153,6 @@ function TeamAvatarCell({ teamId }: { teamId: string }) { ); } -function CustomerAvatarSkeleton() { - return ( -
- - -
- ); -} - function pickChargedAmountDisplay(entry: MoneyTransferEntry | undefined): string { if (!entry) { return '—'; @@ -521,14 +512,14 @@ function TransactionTableBody(props: { const summary = summaryByIdRef.current.get(row.id); if (summary?.customerType === 'user' && summary.customerId) { return ( - }> + }> ); } if (summary?.customerType === 'team' && summary.customerId) { return ( - }> + }> ); diff --git a/apps/dashboard/src/components/ui/data-table/cells.tsx b/apps/dashboard/src/components/ui/data-table/cells.tsx index 1a77b99a1..ac71e596d 100644 --- a/apps/dashboard/src/components/ui/data-table/cells.tsx +++ b/apps/dashboard/src/components/ui/data-table/cells.tsx @@ -6,6 +6,7 @@ import { Badge } from "../badge"; import { Button } from "../button"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger } from "../dropdown-menu"; import { SimpleTooltip } from "../simple-tooltip"; +import { Skeleton } from "../skeleton"; import { cn } from "@/lib/utils"; export function TextCell(props: { children: React.ReactNode, size?: number, icon?: React.ReactNode }) { @@ -55,6 +56,16 @@ export function AvatarCell(props: { src?: string, fallback?: string }) { ); } +/** Loading placeholder matching AvatarCell + adjacent label layout. */ +export function AvatarCellSkeleton(props: { className?: string }) { + return ( +
+ + +
+ ); +} + export function DateCell(props: { date: Date, ignoreAfterYears?: number }) { const ignore = !!props.ignoreAfterYears && new Date(new Date().setFullYear(new Date().getFullYear() + props.ignoreAfterYears)) < props.date; const timeString = props.date.toLocaleTimeString([], { year: 'numeric', month: 'numeric', day: 'numeric', hour: '2-digit', minute: '2-digit' });