'use client'; import { Button } from '@/components/ui/button'; import { Progress } from '@/components/ui/progress'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Badge } from '@/components/ui/badge'; import { ScrollArea } from '@/components/ui/scroll-area'; import { Separator } from '@/components/ui/separator'; import { TooltipProvider } from '@/components/ui/tooltip'; import { Swords, BookOpen, ChevronUp, ChevronDown, RotateCcw, X } from 'lucide-react'; import type { GameStore } from '@/lib/game/types'; import { ELEMENTS, GUARDIANS, SPELLS_DEF, SKILLS_DEF } from '@/lib/game/constants'; import { fmt, fmtDec, getFloorElement, canAffordSpellCost } from '@/lib/game/store'; import { getActiveEquipmentSpells, getTotalDPS } from '@/lib/game/computed-stats'; import { formatSpellCost, getSpellCostColor, formatStudyTime } from '@/lib/game/formatting'; import { CraftingProgress, StudyProgress } from '@/components/game'; import { getUnifiedEffects } from '@/lib/game/effects'; interface SpireTabProps { store: GameStore; } export function SpireTab({ store }: SpireTabProps) { const floorElem = getFloorElement(store.currentFloor); const floorElemDef = ELEMENTS[floorElem]; const isGuardianFloor = !!GUARDIANS[store.currentFloor]; const currentGuardian = GUARDIANS[store.currentFloor]; const climbDirection = store.climbDirection || 'up'; const clearedFloors = store.clearedFloors || {}; // Check if current floor is cleared (for respawn indicator) const isFloorCleared = clearedFloors[store.currentFloor]; // Get active equipment spells const activeEquipmentSpells = getActiveEquipmentSpells(store.equippedInstances, store.equipmentInstances); // Get upgrade effects and DPS const upgradeEffects = getUnifiedEffects(store); const totalDPS = getTotalDPS(store, upgradeEffects, floorElem); const studySpeedMult = 1; // Base study speed const canCastSpell = (spellId: string): boolean => { const spell = SPELLS_DEF[spellId]; if (!spell) return false; return canAffordSpellCost(spell.cost, store.rawMana, store.elements); }; return (
{/* Current Floor Card */} Current Floor
{store.currentFloor} / 100 {floorElemDef?.sym} {floorElemDef?.name} {isGuardianFloor && ( GUARDIAN )}
{isGuardianFloor && currentGuardian && (
⚔️ {currentGuardian.name}
)} {/* HP Bar */}
{fmt(store.floorHP)} / {fmt(store.floorMaxHP)} HP DPS: {store.currentAction === 'climb' && activeEquipmentSpells.length > 0 ? fmtDec(totalDPS) : '—'}
{/* Floor Navigation - Direction indicator only */}
Direction
Up Down
{isFloorCleared && (
Floor cleared! Advancing...
)}
Best: Floor {store.maxFloorReached} • Pacts: {store.signedPacts.length}
{/* Active Spells Card - Shows all spells from equipped weapons */} Active Spells ({activeEquipmentSpells.length}) {activeEquipmentSpells.length > 0 ? (
{activeEquipmentSpells.map(({ spellId, equipmentId }) => { const spellDef = SPELLS_DEF[spellId]; if (!spellDef) return null; const spellState = store.equipmentSpellStates?.find( s => s.spellId === spellId && s.sourceEquipment === equipmentId ); const progress = spellState?.castProgress || 0; const canCast = canAffordSpellCost(spellDef.cost, store.rawMana, store.elements); return (
{spellDef.name} {spellDef.tier === 0 && Basic} {spellDef.tier >= 4 && Legendary}
{canCast ? '✓' : '✗'}
⚔️ {fmt(totalDPS)} DPS • {' '}{formatSpellCost(spellDef.cost)} {' '}• ⚡ {(spellDef.castSpeed || 1).toFixed(1)}/hr
{/* Cast progress bar when climbing */} {store.currentAction === 'climb' && (
Cast {(progress * 100).toFixed(0)}%
)} {spellDef.effects && spellDef.effects.length > 0 && (
{spellDef.effects.map((eff, i) => ( {eff.type === 'lifesteal' && `🩸 ${Math.round(eff.value * 100)}%`} {eff.type === 'burn' && `🔥 Burn`} {eff.type === 'freeze' && `❄️ Freeze`} ))}
)}
); })}
) : (
No spells on equipped weapons. Enchant a staff with spell effects in the Crafting tab.
)}
{/* Current Study (if any) */} {store.currentStudyTarget && ( {/* Parallel Study Progress */} {store.parallelStudyTarget && (
Parallel: {SKILLS_DEF[store.parallelStudyTarget.id]?.name} {store.parallelStudyTarget.type === 'skill' && ` Lv.${(store.skills[store.parallelStudyTarget.id] || 0) + 1}`}
{formatStudyTime(store.parallelStudyTarget.progress)} / {formatStudyTime(store.parallelStudyTarget.required)} 50% speed (Parallel Study)
)}
)} {/* Crafting Progress (if any) */} {(store.designProgress || store.preparationProgress || store.applicationProgress) && ( )} {/* Activity Log */} Activity Log
{store.log.slice(0, 20).map((entry, i) => (
{entry}
))}
); }