import { useEffect, useState } from 'react' import { Check, HelpCircle, Target } from 'lucide-react' import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card' import { Badge } from '@/components/ui/badge' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import { getChallenges, getProgress, submitFlag, getHints, type Challenge, type Progress } from '@/lib/api' import { useI18n } from '@/contexts/I18nContext' export default function Challenges() { const { t } = useI18n() const [challenges, setChallenges] = useState([]) const [progress, setProgress] = useState(null) const [loading, setLoading] = useState(true) const [submitting, setSubmitting] = useState(null) const [flags, setFlags] = useState>({}) const [hints, setHints] = useState>({}) const [showHints, setShowHints] = useState>({}) const [message, setMessage] = useState<{ type: 'success' | 'error'; text: string } | null>(null) const loadData = async () => { try { const [challengesData, progressData] = await Promise.all([ getChallenges(), getProgress(), ]) setChallenges(challengesData) setProgress(progressData) } catch (error) { console.error('Failed to load data:', error) } finally { setLoading(false) } } useEffect(() => { loadData() }, []) const handleSubmit = async (challengeId: number) => { const flag = flags[challengeId]?.trim() if (!flag) { setMessage({ type: 'error', text: 'Please enter a flag' }) return } setSubmitting(challengeId) setMessage(null) try { const result = await submitFlag(challengeId, flag) if (result.correct) { setMessage({ type: 'success', text: result.already_solved ? 'Already solved!' : `Correct! +${result.points_earned} points`, }) setFlags({ ...flags, [challengeId]: '' }) await loadData() } else { setMessage({ type: 'error', text: 'Incorrect flag. Try again!' }) } } catch (error) { setMessage({ type: 'error', text: 'Submission failed' }) } finally { setSubmitting(null) setTimeout(() => setMessage(null), 3000) } } const handleShowHints = async (challengeId: number) => { if (!hints[challengeId]) { const challengeHints = await getHints(challengeId) setHints({ ...hints, [challengeId]: challengeHints }) } setShowHints({ ...showHints, [challengeId]: !showHints[challengeId] }) } const getDifficultyColor = (difficulty: string) => { switch (difficulty) { case 'Easy': return 'bg-green-500' case 'Medium': return 'bg-yellow-500' case 'Hard': return 'bg-orange-500' case 'Expert': return 'bg-red-500' default: return 'bg-gray-500' } } const getNetworkColor = (network: string) => { switch (network) { case 'dmz': return 'bg-blue-500/10 text-blue-500 border-blue-500/20' case 'office': return 'bg-purple-500/10 text-purple-500 border-purple-500/20' case 'production': return 'bg-orange-500/10 text-orange-500 border-orange-500/20' case 'core': return 'bg-red-500/10 text-red-500 border-red-500/20' default: return 'bg-gray-500/10 text-gray-500 border-gray-500/20' } } if (loading) { return (
{t('dashboard.loading')}
) } return (

{t('challenges.title')}

{t('challenges.desc')}

{message && (
{message.text}
)}
{challenges.sort((a, b) => (a.order || 0) - (b.order || 0)).map((challenge) => { const isCompleted = progress?.completed_challenges.includes(challenge.id) || false const flagValue = flags[challenge.id] || '' return (
{t(`challenge.${challenge.id}.name` as any)} {isCompleted && ( )}
{t(`challenge.${challenge.id}.desc` as any)}
{t(`difficulty.${challenge.difficulty}` as any)}
{t('challenges.points')} {challenge.points}
{t('challenges.network')} {t(`network.${challenge.network}` as any)}
{t('challenges.targets')} {challenge.targets.join(', ')}
{!isCompleted && (
setFlags({ ...flags, [challenge.id]: e.target.value }) } onKeyDown={(e) => { if (e.key === 'Enter') handleSubmit(challenge.id) }} />
{showHints[challenge.id] && hints[challenge.id] && (
{hints[challenge.id].map((hint, idx) => (
{hint}
))}
)}
)}
{isCompleted && (
{t('challenges.completed')}
)}
) })}
) }