AeThex-OS/client/src/os/components/UI.tsx

63 lines
1.8 KiB
TypeScript

import { motion } from 'framer-motion';
export function Skeleton({ className = "", animate = true }: { className?: string; animate?: boolean }) {
return (
<div className={`bg-white/10 rounded ${animate ? 'animate-pulse' : ''} ${className}`} />
);
}
export function LoadingSkeleton() {
return (
<div className="p-4 space-y-4">
<Skeleton className="h-8 w-3/4" />
<Skeleton className="h-4 w-full" />
<Skeleton className="h-4 w-5/6" />
<div className="flex gap-4 mt-6">
<Skeleton className="h-24 w-24 rounded-lg" />
<div className="flex-1 space-y-2">
<Skeleton className="h-4 w-full" />
<Skeleton className="h-4 w-4/5" />
<Skeleton className="h-4 w-3/4" />
</div>
</div>
<div className="grid grid-cols-3 gap-4 mt-4">
<Skeleton className="h-20 rounded-lg" />
<Skeleton className="h-20 rounded-lg" />
<Skeleton className="h-20 rounded-lg" />
</div>
</div>
);
}
export function ParticleField() {
const particles = Array.from({ length: 30 }, (_, i) => ({
id: i,
x: Math.random() * 100,
y: Math.random() * 100,
size: Math.random() * 2 + 1,
duration: Math.random() * 20 + 10,
delay: Math.random() * 5,
}));
return (
<div className="fixed inset-0 pointer-events-none overflow-hidden" style={{ zIndex: 0 }}>
{particles.map(p => (
<motion.div
key={p.id}
className="absolute rounded-full bg-cyan-400/20"
style={{ left: `${p.x}%`, top: `${p.y}%`, width: p.size, height: p.size }}
animate={{
y: [0, -30, 0],
opacity: [0.2, 0.5, 0.2],
}}
transition={{
duration: p.duration,
repeat: Infinity,
delay: p.delay,
ease: "easeInOut",
}}
/>
))}
</div>
);
}