- Updated various components to use consistent color tokens, improving visual coherence. - Refactored layout components to utilize the new PublicShell for better structure. - Enhanced error and status messaging styles for improved user feedback. - Standardized button usage across forms and modals for a unified interaction experience. - Introduced new UI design tokens and guidelines in documentation to support future development.
97 lines
3.1 KiB
TypeScript
97 lines
3.1 KiB
TypeScript
import { cn } from "@/lib/utils";
|
|
|
|
interface SkeletonProps {
|
|
className?: string;
|
|
animate?: boolean;
|
|
}
|
|
|
|
export function Skeleton({ className, animate = true }: SkeletonProps) {
|
|
return (
|
|
<div
|
|
className={cn(
|
|
"bg-[var(--cp-skeleton-base)] rounded-md",
|
|
animate && "animate-pulse",
|
|
className
|
|
)}
|
|
/>
|
|
);
|
|
}
|
|
|
|
export function LoadingCard({ className }: { className?: string }) {
|
|
return (
|
|
<div
|
|
className={cn(
|
|
"bg-card text-card-foreground border border-border rounded-[var(--cp-card-radius)] p-[var(--cp-card-padding)] shadow-[var(--cp-card-shadow)]",
|
|
className
|
|
)}
|
|
>
|
|
<div className="space-y-4">
|
|
<div className="flex items-center space-x-3">
|
|
<Skeleton className="h-8 w-8 rounded-full" />
|
|
<div className="space-y-2 flex-1">
|
|
<Skeleton className="h-4 w-1/3" />
|
|
<Skeleton className="h-3 w-1/2" />
|
|
</div>
|
|
</div>
|
|
<div className="space-y-2">
|
|
<Skeleton className="h-3 w-full" />
|
|
<Skeleton className="h-3 w-4/5" />
|
|
<Skeleton className="h-3 w-3/5" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function LoadingTable({ rows = 5, columns = 4 }: { rows?: number; columns?: number }) {
|
|
return (
|
|
<div className="bg-card text-card-foreground border border-border rounded-[var(--cp-card-radius)] overflow-hidden">
|
|
{/* Header */}
|
|
<div className="border-b border-border p-4">
|
|
<div className="grid gap-4" style={{ gridTemplateColumns: `repeat(${columns}, 1fr)` }}>
|
|
{Array.from({ length: columns }).map((_, i) => (
|
|
<Skeleton key={i} className="h-4 w-20" />
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
{/* Rows */}
|
|
<div className="divide-y divide-border">
|
|
{Array.from({ length: rows }).map((_, rowIndex) => (
|
|
<div key={rowIndex} className="p-4">
|
|
<div className="grid gap-4" style={{ gridTemplateColumns: `repeat(${columns}, 1fr)` }}>
|
|
{Array.from({ length: columns }).map((_, colIndex) => (
|
|
<Skeleton key={colIndex} className="h-4 w-full" />
|
|
))}
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function LoadingStats({ count = 4 }: { count?: number }) {
|
|
return (
|
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
|
|
{Array.from({ length: count }).map((_, i) => (
|
|
<div
|
|
key={i}
|
|
className="bg-card text-card-foreground border border-border rounded-[var(--cp-card-radius)] p-[var(--cp-card-padding)] shadow-[var(--cp-card-shadow)]"
|
|
>
|
|
<div className="flex items-center">
|
|
<Skeleton className="h-8 w-8 rounded-full" />
|
|
<div className="ml-4 space-y-2 flex-1">
|
|
<Skeleton className="h-4 w-16" />
|
|
<Skeleton className="h-6 w-12" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// Note: PageLoadingState is now handled by PageLayout component with proper skeleton loading
|
|
// FullPageLoadingState removed - use skeleton loading instead
|