import { useState, type CSSProperties } from 'react'; import type { Achievement } from '../network/api'; interface AchievementsPanelProps { achievements: Achievement[]; } const buttonStyle: CSSProperties = { position: 'fixed', top: 12, right: 240, zIndex: 50, display: 'flex', alignItems: 'center', gap: 4, padding: '5px 10px', borderRadius: 8, border: '1px solid rgba(255, 215, 0, 0.2)', backgroundColor: 'rgba(0,0,0,0.55)', color: '#daa520', fontSize: 11, fontWeight: 600, cursor: 'pointer', pointerEvents: 'auto', userSelect: 'none', }; const panelStyle: CSSProperties = { position: 'fixed', top: 12, right: 240, zIndex: 50, width: 260, maxHeight: 340, borderRadius: 10, border: '1px solid rgba(255, 215, 0, 0.15)', backgroundColor: 'rgba(10, 10, 20, 0.88)', backdropFilter: 'blur(6px)', overflow: 'hidden', pointerEvents: 'auto', display: 'flex', flexDirection: 'column', }; const panelHeaderStyle: CSSProperties = { display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '7px 10px', borderBottom: '1px solid rgba(255,255,255,0.08)', fontSize: 12, fontWeight: 700, color: '#daa520', flexShrink: 0, }; const closeButtonStyle: CSSProperties = { background: 'none', border: 'none', color: '#888', fontSize: 14, cursor: 'pointer', padding: '0 4px', lineHeight: 1, }; const listStyle: CSSProperties = { padding: '6px 10px 8px', overflowY: 'auto', flex: 1, }; function achievementRowStyle(unlocked: boolean): CSSProperties { return { marginBottom: 8, padding: '6px 8px', borderRadius: 6, border: unlocked ? '1px solid rgba(255, 215, 0, 0.5)' : '1px solid rgba(255, 255, 255, 0.08)', backgroundColor: unlocked ? 'rgba(255, 215, 0, 0.06)' : 'rgba(255, 255, 255, 0.02)', }; } const titleRowStyle: CSSProperties = { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 3, }; const progressBarBgStyle: CSSProperties = { width: '100%', height: 5, borderRadius: 3, backgroundColor: 'rgba(255,255,255,0.08)', overflow: 'hidden', marginTop: 4, }; function progressBarFillStyle(pct: number, unlocked: boolean): CSSProperties { return { width: `${Math.min(100, pct)}%`, height: '100%', borderRadius: 3, backgroundColor: unlocked ? '#ffd700' : '#daa520', transition: 'width 300ms ease', }; } function formatDate(iso: string): string { try { const d = new Date(iso); return d.toLocaleDateString(undefined, { month: 'short', day: 'numeric' }); } catch { return ''; } } export function AchievementsPanel({ achievements }: AchievementsPanelProps) { const [expanded, setExpanded] = useState(false); const unlockedCount = achievements.filter((a) => a.unlocked).length; if (!expanded) { return ( ); } return (
🏆 Achievements
{achievements.map((ach) => { const pct = ach.conditionValue > 0 ? (Math.min(ach.conditionValue, ach.conditionValue) / ach.conditionValue) * 100 : 0; return (
{ach.unlocked ? '\u2714 ' : ''}{ach.title} {ach.unlocked && ach.unlockedAt && ( {formatDate(ach.unlockedAt)} )}
{ach.description}
{!ach.unlocked && (
)} {ach.unlocked && (
+{ach.rewardAmount} {ach.rewardType}
)}
); })} {achievements.length === 0 && (
No achievements yet
)}
); }