fix: split SpireTab.tsx to 395 lines, remove require() imports, import from data modules; complete store migration
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 30m15s

This commit is contained in:
Refactoring Agent
2026-05-04 13:36:10 +02:00
parent 0eabd604b0
commit 837d963b63
41 changed files with 727 additions and 3935 deletions
+67 -2
View File
@@ -3,7 +3,7 @@
'use client';
import { useState } from 'react';
import { useGameStore } from '@/lib/game/store';
import { useGameStore, usePrestigeStore, useSkillStore, useManaStore } from '@/lib/game/stores';
import { useGameLoop } from '@/lib/game/stores/gameHooks';
import { getUnifiedEffects } from '@/lib/game/effects';
import {
@@ -15,13 +15,19 @@ import {
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
import { fmt } from '@/lib/game/computed-stats';
import { fmt } from '@/lib/game/stores';
export function PrestigeTab() {
const [selectedManaType, setSelectedManaType] = useState<string>('');
const store = useGameStore();
useGameLoop();
const skills = useSkillStore((s) => s.skills);
const prestigeUpgrades = usePrestigeStore((s) => s.prestigeUpgrades);
const rawMana = useManaStore((s) => s.rawMana);
const elements = useManaStore((s) => s.elements);
const upgradeEffects = getUnifiedEffects(store);
// Get unlocked elements for mana type selector
@@ -38,3 +44,62 @@ export function PrestigeTab() {
<ScrollArea className="h-full">
<div className="p-4 space-y-4">
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
{/* Prestige Upgrades */}
{Object.entries(PRESTIGE_DEF || {}).map(([id, def]) => {
const level = prestigeUpgrades[id] || 0;
const canAfford = rawMana >= def.cost;
const effect = upgradeEffects ? upgradeEffects.specials.has(id) : false;
return (
<Card key={id} className={effect ? "border-[var(--color-success)]/50 bg-[var(--color-success)]/10" : "bg-gray-900/80 border-gray-700">
<CardHeader>
<CardTitle className="text-sm flex items-center gap-2">
<span>{def.name}</span>
{effect && <Badge className="bg-[var(--color-success)]/20 text-[var(--color-success)]">Active</Badge>}
</CardTitle>
</CardHeader>
<CardContent>
<p className="text-xs text-gray-400 mb-2">{def.description}</p>
<div className="flex items-center justify-between">
<span className="text-xs text-gray-400">Level: {level}/{def.maxLevel}</span>
<Button
size="sm"
disabled={!canAfford || level >= def.maxLevel}
onClick={() => store.doPrestige(id)}
>
{level >= def.maxLevel ? 'Maxed' : `Upgrade (${fmt(def.cost)})`}
</Button>
</div>
</CardContent>
</Card>
);
})}
{/* Mana Type Selection for Attunements */}
<Card className="bg-gray-900/80 border-gray-700">
<CardHeader>
<CardTitle className="text-sm">Select Mana Type for Attunement</CardTitle>
</CardHeader>
<CardContent>
<div className="grid grid-cols-2 gap-2">
{unlockedElements.map(elem => (
<Button
key={elem.id}
variant={selectedManaType === elem.id ? "default" : "outline"}
onClick={() => setSelectedManaType(elem.id)}
className="justify-start"
>
<span className="mr-2" style={{ color: elem.color }}>{elem.sym}</span>
{elem.name}
</Button>
))}
</div>
</CardContent>
</Card>
</div>
</div>
</ScrollArea>
);
}
PrestigeTab.displayName = "PrestigeTab";