- Add comprehensive analytics components with export functionality - Implement territory management with manager performance tracking - Add seatmap components for venue layout management - Create customer management features with modal interface - Add advanced hooks for dashboard flags and territory data - Implement seat selection and venue management utilities - Add type definitions for ticketing and seatmap systems 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
108 lines
3.6 KiB
TypeScript
108 lines
3.6 KiB
TypeScript
import React from 'react';
|
|
import { clsx } from 'clsx';
|
|
|
|
import { Card } from '@/components/ui/Card';
|
|
import { Skeleton } from '@/components/loading/Skeleton';
|
|
|
|
interface TableSkeletonProps {
|
|
rows?: number;
|
|
columns?: number;
|
|
hasHeader?: boolean;
|
|
hasActions?: boolean;
|
|
hasAvatar?: boolean;
|
|
className?: string;
|
|
}
|
|
|
|
/**
|
|
* Loading skeleton for data tables
|
|
* Provides flexible column and row configuration with realistic table structure
|
|
*/
|
|
export const TableSkeleton: React.FC<TableSkeletonProps> = ({
|
|
rows = 8,
|
|
columns = 5,
|
|
hasHeader = true,
|
|
hasActions = true,
|
|
hasAvatar = false,
|
|
className = ''
|
|
}) => {
|
|
// Adjust effective columns based on avatar and actions
|
|
const effectiveColumns = hasActions ? columns : columns;
|
|
|
|
return (
|
|
<Card className={clsx('overflow-hidden', className)}>
|
|
{/* Table header */}
|
|
{hasHeader && (
|
|
<div className="bg-glass-bg border-b border-glass-border px-6 py-4">
|
|
<div className={clsx(
|
|
'grid gap-4 items-center',
|
|
`grid-cols-${Math.min(effectiveColumns, 6)}`
|
|
)}>
|
|
{Array.from({ length: effectiveColumns }).map((_, index) => (
|
|
<Skeleton.Base key={`header-${index}`} className="h-4 w-3/4" />
|
|
))}
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Table rows */}
|
|
<div className="divide-y divide-glass-border">
|
|
{Array.from({ length: rows }).map((_, rowIndex) => (
|
|
<div key={`row-${rowIndex}`} className="px-6 py-4">
|
|
<div className={clsx(
|
|
'grid gap-4 items-center',
|
|
`grid-cols-${Math.min(effectiveColumns, 6)}`
|
|
)}>
|
|
{Array.from({ length: effectiveColumns }).map((_, colIndex) => {
|
|
// First column with optional avatar
|
|
if (colIndex === 0) {
|
|
return (
|
|
<div key={`col-${colIndex}`} className="flex items-center space-x-3">
|
|
{hasAvatar && <Skeleton.Avatar size="sm" />}
|
|
<Skeleton.Base className="h-4 w-20" />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// Last column with actions (if enabled)
|
|
if (colIndex === effectiveColumns - 1 && hasActions) {
|
|
return (
|
|
<div key={`col-${colIndex}`} className="flex space-x-2 justify-end">
|
|
<Skeleton.Button size="sm" className="w-16" />
|
|
<Skeleton.Button size="sm" className="w-16" />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// Regular data columns with varied widths for realism
|
|
const widths = ['w-16', 'w-20', 'w-24', 'w-32', 'w-28'];
|
|
const widthClass = widths[colIndex % widths.length];
|
|
|
|
return (
|
|
<Skeleton.Base
|
|
key={`col-${colIndex}`}
|
|
className={`h-4 ${widthClass}`}
|
|
/>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
{/* Table footer (pagination area) */}
|
|
<div className="bg-glass-bg border-t border-glass-border px-6 py-4">
|
|
<div className="flex items-center justify-between">
|
|
<Skeleton.Base className="h-4 w-32" />
|
|
<div className="flex space-x-2">
|
|
<Skeleton.Button size="sm" className="w-16" />
|
|
<Skeleton.Button size="sm" className="w-8" />
|
|
<Skeleton.Button size="sm" className="w-8" />
|
|
<Skeleton.Button size="sm" className="w-16" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</Card>
|
|
);
|
|
};
|
|
|
|
export default TableSkeleton; |