mirror of
https://github.com/stack-auth/stack.git
synced 2026-07-20 21:29:36 +08:00
refactor: shared skeleton for table
This commit is contained in:
parent
be619368fc
commit
970abc0f03
@ -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' ? (
|
||||
<Suspense fallback={<CustomerAvatarSkeleton />}>
|
||||
<Suspense fallback={<AvatarCellSkeleton />}>
|
||||
<UserCell userId={row.customerId} />
|
||||
</Suspense>
|
||||
) : row.customerType === 'team' ? (
|
||||
<Suspense fallback={<CustomerAvatarSkeleton />}>
|
||||
<Suspense fallback={<AvatarCellSkeleton />}>
|
||||
<TeamCell teamId={row.customerId} />
|
||||
</Suspense>
|
||||
) : (
|
||||
@ -1643,15 +1644,6 @@ function ProductCustomersSection({ productId, product }: ProductCustomersSection
|
||||
);
|
||||
}
|
||||
|
||||
function CustomerAvatarSkeleton() {
|
||||
return (
|
||||
<div className="flex items-center gap-2">
|
||||
<Skeleton className="h-6 w-6 shrink-0 rounded-full" />
|
||||
<Skeleton className="h-4 w-24" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function CustomerRowActions({ customerType, customerId }: { customerType: string, customerId: string }) {
|
||||
const adminApp = useAdminApp();
|
||||
return (
|
||||
|
||||
@ -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 (
|
||||
<div className="flex items-center gap-2 max-w-40">
|
||||
<Skeleton className="h-6 w-6 shrink-0 rounded-full" />
|
||||
<Skeleton className="h-4 w-24" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
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 (
|
||||
<Suspense fallback={<CustomerAvatarSkeleton />}>
|
||||
<Suspense fallback={<AvatarCellSkeleton className="max-w-40" />}>
|
||||
<UserAvatarCell userId={summary.customerId} />
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
if (summary?.customerType === 'team' && summary.customerId) {
|
||||
return (
|
||||
<Suspense fallback={<CustomerAvatarSkeleton />}>
|
||||
<Suspense fallback={<AvatarCellSkeleton className="max-w-40" />}>
|
||||
<TeamAvatarCell teamId={summary.customerId} />
|
||||
</Suspense>
|
||||
);
|
||||
|
||||
@ -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 (
|
||||
<div className={cn("flex items-center gap-2", props.className)}>
|
||||
<Skeleton className="h-6 w-6 shrink-0 rounded-full" />
|
||||
<Skeleton className="h-4 w-24" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
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' });
|
||||
|
||||
Loading…
Reference in New Issue
Block a user