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 { Badge } from "@/components/ui/badge"; import { Trophy, Lock, Unlock, Target, Calendar, Recycle, Trees, Leaf, Timer, Binary, Trash2, Scale, Network, BarChart, Flame, Zap, Share2, Activity, Star } 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 getAchievementIcon = (achievement) => { // First check for tier-specific trophies if (achievement.tier) { const baseSize = "w-8 h-8"; switch (achievement.tier) { case 'bronze': return <Trophy className={`${baseSize} text-amber-600`} />; case 'silver': return <Trophy className={`${baseSize} text-gray-400`} />; case 'gold': return <Trophy className={`${baseSize} text-yellow-400`} />; } } // Then check for achievement-specific icons based on name or description keywords const name = achievement.name.toLowerCase(); const description = achievement.description.toLowerCase(); const baseSize = "w-8 h-8 text-primary"; if (name.includes('recycle') || description.includes('recycle')) { return <Recycle className={baseSize} />; } else if (name.includes('tree') || description.includes('tree')) { return <Trees className={baseSize} />; } else if (name.includes('streak') || description.includes('streak')) { return <Flame className={baseSize} />; } else if (name.includes('speed') || name.includes('fast')) { return <Zap className={baseSize} />; } else if (name.includes('accurate') || name.includes('precision')) { return <Target className={baseSize} />; } else if (name.includes('share') || description.includes('share')) { return <Share2 className={baseSize} />; } else if (name.includes('time') || description.includes('time')) { return <Timer className={baseSize} />; } else if (name.includes('ai') || description.includes('ai')) { return <Binary className={baseSize} />; } else if (name.includes('waste') || description.includes('waste')) { return <Trash2 className={baseSize} />; } else if (name.includes('balance') || description.includes('balance')) { return <Scale className={baseSize} />; } else if (name.includes('network') || description.includes('network')) { return <Network className={baseSize} />; } else if (name.includes('stats') || description.includes('statistics')) { return <BarChart className={baseSize} />; } else if (name.includes('activity') || description.includes('activity')) { return <Activity className={baseSize} />; } else if (name.includes('eco') || description.includes('environment')) { return <Leaf className={baseSize} />; } // Default icon if no specific matches return <Star className={baseSize} />; }; 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" /> Achievement Progress </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]) => ( <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)} <span>{achievement.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"> {achievement.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' ? achievement.target : achievement.progress}/{achievement.target} </span> </div> {achievement.unlock_date && ( <div className="flex items-center gap-2 text-sm text-muted-foreground"> <Calendar className="w-4 h-4" /> <span>Unlocked: {formatDate(achievement.unlock_date)}</span> </div> )} {achievement.tier && ( <Badge variant={ achievement.tier === 'gold' ? 'default' : achievement.tier === 'silver' ? 'secondary' : 'outline' }> {achievement.tier.charAt(0).toUpperCase() + achievement.tier.slice(1)} Tier </Badge> )} </div> </CardContent> </Card> ))} </div> </main> </SidebarInset> </SidebarProvider> ); }; export default AchievementsPage;
Leave a Comment