import React, { useState, useEffect } from 'react'; import { Navigate, useLocation } from 'react-router-dom'; import { Terminal, Radar, Zap, RefreshCw, Box } from 'lucide-react'; import { useCTF } from './CTFContext'; export const formatDuration = (ms: number) => { if (ms < 0) return "00:00:00"; const seconds = Math.floor((ms / 1000) % 60); const minutes = Math.floor((ms / (1000 * 60)) % 60); const hours = Math.floor(ms / (1000 * 60 * 60)); return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`; }; export const ProtectedRoute: React.FC<{ children: React.ReactNode }> = ({ children }) => { const { currentUser } = useCTF(); const location = useLocation(); if (!currentUser) return ; return <>{children}; }; export const Countdown: React.FC<{ target: number; onEnd?: () => void; label?: string }> = ({ target, onEnd, label }) => { const [timeLeft, setTimeLeft] = useState(target - Date.now()); useEffect(() => { const timer = setInterval(() => { const remaining = target - Date.now(); setTimeLeft(remaining); if (remaining <= 0) { clearInterval(timer); onEnd?.(); } }, 1000); return () => clearInterval(timer); }, [target, onEnd]); if (timeLeft <= 0) return null; return (
{label && {label}} {formatDuration(timeLeft)}
); }; export const CategoryIcon: React.FC<{ category: string; size?: number; color?: string }> = ({ category, size = 32, color = "currentColor" }) => { switch (category) { case 'WEB': return ; case 'PWN': return ; case 'REV': return ; case 'CRY': return ; default: return ; } }; export const Button: React.FC & { variant?: 'primary' | 'secondary' }> = ({ children, variant = 'primary', className = "", ...props }) => { const styles = variant === 'primary' ? "bg-[#ff0000] text-black border-2 border-[#ff0000] hover:bg-black hover:text-[#ff0000] disabled:opacity-50" : "bg-black text-[#bf00ff] border-2 border-[#bf00ff] hover:bg-[#bf00ff] hover:text-black disabled:opacity-50"; return ( ); };