- Frontend React (SKEEN Brand) con Vite, TypeScript, Tailwind - Frontend Homenest (versión alternativa) - Módulos Odoo 17 custom (citas, pacientes, monedero, pagos, ventas, inventario, whatsapp) - WACRM fork (Next.js 16 + Supabase) - Hermes + Bridge + Skills (Qwen3.6 via Nan Builders) - Scripts de migración y operación - Documentación extensiva en docs/
53 lines
1.4 KiB
TypeScript
53 lines
1.4 KiB
TypeScript
import type { FC } from 'react';
|
|
import { cn } from '../../lib/utils';
|
|
|
|
interface SkeletonProps {
|
|
className?: string;
|
|
count?: number;
|
|
}
|
|
|
|
export const Skeleton: FC<SkeletonProps> = ({ className, count = 1 }) => {
|
|
return (
|
|
<div className="space-y-2 animate-pulse">
|
|
{Array.from({ length: count }).map((_, i) => (
|
|
<div
|
|
key={i}
|
|
className={cn('rounded-xl bg-theme-border-strong', className)}
|
|
/>
|
|
))}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export const SkeletonCard: FC<{ lines?: number; className?: string }> = ({
|
|
lines = 3,
|
|
className,
|
|
}) => {
|
|
return (
|
|
<div className={cn('bg-theme-surface rounded-2xl p-4 sm:p-6 border border-theme-border shadow-sm', className)}>
|
|
<div className="flex items-center justify-between mb-4">
|
|
<Skeleton className="h-5 w-1/3" />
|
|
<Skeleton className="h-4 w-16" />
|
|
</div>
|
|
<div className="space-y-3">
|
|
{Array.from({ length: lines }).map((_, i) => (
|
|
<Skeleton key={i} className="h-12 w-full" />
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export const SkeletonStat: FC = () => (
|
|
<div className="bg-theme-surface rounded-2xl p-5 border border-theme-border shadow-sm">
|
|
<div className="flex items-center justify-between mb-4">
|
|
<Skeleton className="h-9 w-9 rounded-full" />
|
|
<Skeleton className="h-4 w-12" />
|
|
</div>
|
|
<Skeleton className="h-3 w-20 mb-2" />
|
|
<Skeleton className="h-7 w-24" />
|
|
</div>
|
|
);
|
|
|
|
export default Skeleton;
|