'use client'; import { useState } from 'react'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; import { ScrollArea } from '@/components/ui/scroll-area'; import { Progress } from '@/components/ui/progress'; import { Trophy, Lock, CheckCircle, ChevronDown, ChevronUp } from 'lucide-react'; import type { AchievementState } from '@/lib/game/types'; import { ACHIEVEMENTS, ACHIEVEMENT_CATEGORY_COLORS, getAchievementsByCategory, isAchievementRevealed } from '@/lib/game/data/achievements'; import { GameState } from '@/lib/game/types'; interface AchievementsProps { achievements: AchievementState; gameState: Pick; } export function AchievementsDisplay({ achievements, gameState }: AchievementsProps) { const [expandedCategory, setExpandedCategory] = useState('combat'); const categories = getAchievementsByCategory(); const unlockedCount = achievements.unlocked.length; const totalCount = Object.keys(ACHIEVEMENTS).length; // Calculate progress for each achievement const getProgress = (achievementId: string): number => { const achievement = ACHIEVEMENTS[achievementId]; if (!achievement) return 0; if (achievements.unlocked.includes(achievementId)) return achievement.requirement.value; const { type, subType } = achievement.requirement; switch (type) { case 'floor': if (subType === 'noPacts') { return gameState.maxFloorReached >= achievement.requirement.value && gameState.signedPacts.length === 0 ? achievement.requirement.value : gameState.maxFloorReached; } return gameState.maxFloorReached; case 'spells': return gameState.totalSpellsCast || 0; case 'damage': return gameState.totalDamageDealt || 0; case 'mana': return gameState.totalManaGathered || 0; case 'pact': return gameState.signedPacts.length; case 'craft': return gameState.totalCraftsCompleted || 0; default: return achievements.progress[achievementId] || 0; } }; return ( Achievements {unlockedCount} / {totalCount}
{Object.entries(categories).map(([category, categoryAchievements]) => (
{expandedCategory === category && (
{categoryAchievements.map((achievement) => { const isUnlocked = achievements.unlocked.includes(achievement.id); const progress = getProgress(achievement.id); const isRevealed = isAchievementRevealed(achievement, progress); const progressPercent = Math.min(100, (progress / achievement.requirement.value) * 100); if (!isRevealed && !isUnlocked) { return (
???
); } return (
{isUnlocked ? ( ) : ( )} {achievement.name}
{achievement.reward.title && isUnlocked && ( Title )}
{achievement.desc}
{!isUnlocked && (
{progress.toLocaleString()} / {achievement.requirement.value.toLocaleString()} {progressPercent.toFixed(0)}%
)} {isUnlocked && achievement.reward && (
Reward: {achievement.reward.insight && ` +${achievement.reward.insight} Insight`} {achievement.reward.manaBonus && ` +${achievement.reward.manaBonus} Max Mana`} {achievement.reward.damageBonus && ` +${(achievement.reward.damageBonus * 100).toFixed(0)}% Damage`} {achievement.reward.title && ` "${achievement.reward.title}"`}
)}
); })}
)}
))}
); }