'use client'; import { useMemo } from 'react'; import { useAttunementStore } from '@/lib/game/stores'; import { ATTUNEMENTS_DEF } from '@/lib/game/data/attunements'; import { Separator } from '@/components/ui/separator'; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'; const SLOT_LABELS: Record = { rightHand: 'R. Hand', leftHand: 'L. Hand', head: 'Head', back: 'Back', chest: 'Chest', leftLeg: 'L. Leg', rightLeg: 'R. Leg', }; export function AttunementStatus() { const attunements = useAttunementStore((s) => s.attunements); const attunementOrder = useMemo(() => { const map = new Map(); Object.values(ATTUNEMENTS_DEF).forEach((d, i) => map.set(d.id, i)); return map; }, []); const activeAttunements = useMemo(() => { return Object.entries(attunements) .filter(([, state]) => state.active) .sort(([, a], [, b]) => (attunementOrder.get(a.id) ?? 0) - (attunementOrder.get(b.id) ?? 0)); }, [attunements, attunementOrder]); const xpForNext = (level: number) => { if (level <= 1) return 0; if (level === 2) return 1000; return Math.floor(1000 * Math.pow(2, level - 2) * (level >= 3 ? 1.25 : 1)); }; return (
Attunements {activeAttunements.length} active
{activeAttunements.length === 0 ? (
No attunements active
) : ( activeAttunements.map(([id, state]) => { const def = ATTUNEMENTS_DEF[id]; if (!def) return null; const nextXp = xpForNext(state.level); const xpProgress = nextXp > 0 ? (state.experience / nextXp) * 100 : 0; return (
{def.icon}
{def.name} Lv.{state.level}
{SLOT_LABELS[def.slot] || def.slot} {nextXp > 0 && ( {Math.floor(state.experience).toLocaleString()}/{nextXp.toLocaleString()} XP )}
{nextXp > 0 && (
)}

{def.desc}

); }) )}
); } AttunementStatus.displayName = 'AttunementStatus';