Untitled
"use client"; import React from 'react'; import { useMetrics } from '@/hooks/useMetrics'; import { AppSidebar } from "@/components/app-sidebar"; import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbSeparator, } from "@/components/ui/breadcrumb"; import { Separator } from "@/components/ui/separator"; import { SidebarInset, SidebarProvider, SidebarTrigger, } from "@/components/ui/sidebar"; import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card"; import { Progress } from "@/components/ui/progress"; import { Trophy, Lock, Unlock, Target, Calendar, CalendarRange, Recycle, Trees, Leaf, Timer, Binary, Trash2, Scale, Network, BarChart, Flame, Zap, Share2, Activity, Star, SunDim, Snowflake, Bird, Moon, Sun, StickyNote, Footprints } from 'lucide-react'; import { useTranslation, type SupportedLanguages } from "@/utils/translations"; import { useSettings } from "@/hooks/useSettings"; const AchievementsPage = () => { const { metrics, loading, error } = useMetrics(); const { settings } = useSettings(); const { t } = useTranslation(settings?.language as SupportedLanguages || 'EN'); if (loading) return <div className="p-4">Loading achievements...</div>; if (error) return <div className="p-4 text-red-500">Error loading achievements</div>; if (!metrics) return null; const achievements = Object.entries(metrics.achievements); const unlockedCount = achievements.filter(([_, a]) => a.status === 'completed').length; const totalCount = achievements.length; const formatDate = (dateString: string) => { const date = new Date(dateString); return date.toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' }); }; const getAchievementTranslation = (id: string) => { return { name: t(`achievements.${id}.name`), description: t(`achievements.${id}.description`) }; }; const formatProgressValue = (id: string, value: number) => { if (id.includes('eco_warrior') || id.includes('tree')) { return Number(value.toFixed(3)); } return value; }; const getAchievementIcon = (achievement, id: string) => { const getTierColor = (tier) => { switch (tier) { case 'bronze': return 'text-amber-600'; case 'silver': return 'text-gray-400'; case 'gold': return 'text-yellow-400'; default: return 'text-primary'; } }; const baseSize = "w-8 h-8"; const color = achievement.tier ? getTierColor(achievement.tier) : 'text-primary'; switch (id) { case 'first_sort': return <Footprints className={`${baseSize} ${color}`} />; case 'seasonal_master': return <SunDim className={`${baseSize} ${color}`} />; case 'winter_sorter': return <Snowflake className={`${baseSize} ${color}`} />; case 'monthly_master': return <Calendar className={`${baseSize} ${color}`} />; case 'paper_specialist': return <StickyNote className={`${baseSize} ${color}`} />; case 'early_bird': return <Bird className={`${baseSize} ${color}`} />; case 'night_owl': return <Moon className={`${baseSize} ${color}`} />; case 'weekend_warrior': return <CalendarRange className={`${baseSize} ${color}`} />; case 'summer_sorter': return <Sun className={`${baseSize} ${color}`} />; case 'recycling_specialist': return <Recycle className={`${baseSize} ${color}`} />; case 'quick_draw': return <Timer className={`${baseSize} ${color}`} />; case 'organic_specialist': return <Leaf className={`${baseSize} ${color}`} />; case 'residual_specialist': return <Trash2 className={`${baseSize} ${color}`} />; case 'tree_hero': return <Trees className={`${baseSize} ${color}`} />; case 'time_lord': return <Timer className={`${baseSize} ${color}`} />; case 'perfect_balance': return <Scale className={`${baseSize} ${color}`} />; case 'efficient_manager': return <BarChart className={`${baseSize} ${color}`} />; default: return <Trophy className={`${baseSize} ${color}`} />; } }; return ( <SidebarProvider> <AppSidebar /> <SidebarInset> <header className="flex shrink-0 items-center gap-2 border-b px-4 py-6"> <SidebarTrigger className="-ml-1" /> <Separator orientation="vertical" className="mr-2 h-4" /> <Breadcrumb> <BreadcrumbList> <BreadcrumbItem> <BreadcrumbLink href="/">{t('navigation.home')}</BreadcrumbLink> </BreadcrumbItem> <BreadcrumbSeparator /> <BreadcrumbItem> <BreadcrumbLink href="/achievements">{t('navigation.achievements')}</BreadcrumbLink> </BreadcrumbItem> </BreadcrumbList> </Breadcrumb> </header> <main className="p-4"> <Card className="mb-6"> <CardHeader> <CardTitle className="flex items-center gap-2"> <Trophy className="w-6 h-6 text-primary" /> {t('navigation.achievements')} </CardTitle> </CardHeader> <CardContent> <div className="flex items-center gap-4"> <Progress value={(unlockedCount / totalCount) * 100} className="w-full" /> <span className="text-sm font-medium"> {unlockedCount}/{totalCount} </span> </div> </CardContent> </Card> <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4"> {achievements.sort(([, a], [, b]) => { if (a.status === 'completed' && b.status !== 'completed') return -1; if (a.status !== 'completed' && b.status === 'completed') return 1; return (b.progress / b.target) - (a.progress / a.target); }).map(([id, achievement]) => { const translation = getAchievementTranslation(id); return ( <Card key={id} className={`relative overflow-hidden transition-all duration-200 ${ achievement.status === 'completed' ? 'dark:bg-gradient-to-br dark:from-primary/10 dark:to-primary/5 ' + 'bg-gradient-to-br from-primary/20 to-background border-primary/50 ' + 'shadow-lg shadow-primary/5' : 'opacity-75' }`} > <CardHeader> <CardTitle className="flex items-center justify-between"> <div className="flex items-center gap-2"> {getAchievementIcon(achievement, id)} <span>{translation.name}</span> </div> {achievement.status === 'completed' ? ( <Unlock className="w-5 h-5 text-primary" /> ) : ( <Lock className="w-5 h-5" /> )} </CardTitle> </CardHeader> <CardContent> <p className="mb-4 text-sm text-muted-foreground"> {translation.description} </p> <div className="space-y-4"> <div className="flex items-center gap-2"> <Target className="w-4 h-4" /> <Progress value={achievement.status === 'completed' ? 100 : (achievement.progress / achievement.target) * 100} className="flex-1" /> <span className="text-sm font-medium"> {achievement.status === 'completed' ? formatProgressValue(id, achievement.target) : formatProgressValue(id, achievement.progress)} /{formatProgressValue(id, achievement.target)} </span> </div> {(achievement.unlock_date || achievement.status === 'completed') && ( <div className="flex items-center gap-2 text-sm text-muted-foreground"> <Calendar className="w-4 h-4" /> <span> {t('navigation.unlocked')}: { achievement.unlock_date ? formatDate(achievement.unlock_date) : formatDate(new Date().toISOString()) } </span> </div> )} </div> </CardContent> </Card> ); })} </div> </main> </SidebarInset> </SidebarProvider> ); }; export default AchievementsPage;
Leave a Comment