feat: remove Spells tab UI
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m20s

- Remove Spells tab trigger from TabTriggers in page.tsx
- Remove TabsContent value='spells' block in page.tsx
- Remove lazy import of SpellsTab in page.tsx
- Change default activeTab from 'spells' to 'disciplines'
- Remove SpellsTab re-export from tabs/index.ts
- Remove SpellsTab re-export from game/index.ts
- Delete src/components/game/tabs/SpellsTab.tsx

Spell data (SPELLS_DEF, spells store state) preserved - spells still exist as enchantments.
This commit is contained in:
2026-06-08 16:02:48 +02:00
parent f31eaac59f
commit d07e74c396
7 changed files with 3 additions and 140 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
# Circular Dependencies # Circular Dependencies
Generated: 2026-06-08T13:03:26.382Z Generated: 2026-06-08T13:51:45.536Z
Found: 1 circular chain(s) — these MUST be fixed before modifying involved files. Found: 1 circular chain(s) — these MUST be fixed before modifying involved files.
1. 1) stores/golem-combat-actions.ts > stores/golem-combat-helpers.ts 1. 1) stores/golem-combat-actions.ts > stores/golem-combat-helpers.ts
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"_meta": { "_meta": {
"generated": "2026-06-08T13:03:24.191Z", "generated": "2026-06-08T13:51:43.381Z",
"description": "Import dependency graph for src/lib/game. Keys are files, values are arrays of files they import.", "description": "Import dependency graph for src/lib/game. Keys are files, values are arrays of files they import.",
"usage": "To find what a file affects, search for its path in the VALUES. To find what a file depends on, look at its KEY entry." "usage": "To find what a file affects, search for its path in the VALUES. To find what a file depends on, look at its KEY entry."
}, },
-1
View File
@@ -145,7 +145,6 @@ Mana-Loop/
│ │ │ │ ├── GuardianPactsTab.tsx │ │ │ │ ├── GuardianPactsTab.tsx
│ │ │ │ ├── PrestigeTab.test.ts │ │ │ │ ├── PrestigeTab.test.ts
│ │ │ │ ├── PrestigeTab.tsx │ │ │ │ ├── PrestigeTab.tsx
│ │ │ │ ├── SpellsTab.tsx
│ │ │ │ ├── SpireSummaryTab.helpers.tsx │ │ │ │ ├── SpireSummaryTab.helpers.tsx
│ │ │ │ ├── SpireSummaryTab.test.ts │ │ │ │ ├── SpireSummaryTab.test.ts
│ │ │ │ ├── SpireSummaryTab.tsx │ │ │ │ ├── SpireSummaryTab.tsx
+1 -4
View File
@@ -33,7 +33,6 @@ import { LeftPanel } from './components/LeftPanel';
// Lazy load tab components // Lazy load tab components
const DisciplinesTab = lazy(() => import('@/components/game/tabs').then(m => ({ default: m.DisciplinesTab }))); const DisciplinesTab = lazy(() => import('@/components/game/tabs').then(m => ({ default: m.DisciplinesTab })));
const SpellsTab = lazy(() => import('@/components/game/tabs').then(m => ({ default: m.SpellsTab })));
const StatsTab = lazy(() => import('@/components/game/tabs').then(m => ({ default: m.StatsTab }))); const StatsTab = lazy(() => import('@/components/game/tabs').then(m => ({ default: m.StatsTab })));
const DebugTab = lazy(() => import('@/components/game/tabs').then(m => ({ default: m.DebugTab }))); const DebugTab = lazy(() => import('@/components/game/tabs').then(m => ({ default: m.DebugTab })));
const AchievementsTab = lazy(() => import('@/components/game/tabs').then(m => ({ default: m.AchievementsTab }))); const AchievementsTab = lazy(() => import('@/components/game/tabs').then(m => ({ default: m.AchievementsTab })));
@@ -114,7 +113,6 @@ function useGameDerivedStats() {
function TabTriggers() { function TabTriggers() {
return ( return (
<TabsList className="flex flex-wrap gap-1 w-full mb-4 h-auto"> <TabsList className="flex flex-wrap gap-1 w-full mb-4 h-auto">
<TabsTrigger value="spells" className="text-xs px-2 py-1">🔮 Spells</TabsTrigger>
<TabsTrigger value="stats" className="text-xs px-2 py-1">📊 Stats</TabsTrigger> <TabsTrigger value="stats" className="text-xs px-2 py-1">📊 Stats</TabsTrigger>
<TabsTrigger value="disciplines" className="text-xs px-2 py-1">📚 Disciplines</TabsTrigger> <TabsTrigger value="disciplines" className="text-xs px-2 py-1">📚 Disciplines</TabsTrigger>
<TabsTrigger value="debug" className="text-xs px-2 py-1">🐛 Debug</TabsTrigger> <TabsTrigger value="debug" className="text-xs px-2 py-1">🐛 Debug</TabsTrigger>
@@ -145,7 +143,7 @@ function LazyTab({ name, children }: { name: string; children: React.ReactNode }
// ─── Main Game Component ───────────────────────────────────────────────────── // ─── Main Game Component ─────────────────────────────────────────────────────
export default function ManaLoopGame() { export default function ManaLoopGame() {
const [activeTab, setActiveTab] = useState('spells'); const [activeTab, setActiveTab] = useState('disciplines');
useGameLoop(); useGameLoop();
@@ -211,7 +209,6 @@ export default function ManaLoopGame() {
<Tabs value={activeTab} onValueChange={setActiveTab}> <Tabs value={activeTab} onValueChange={setActiveTab}>
<TabTriggers /> <TabTriggers />
<TabsContent value="spells"><LazyTab name="spells"><SpellsTab /></LazyTab></TabsContent>
<TabsContent value="stats"><LazyTab name="stats"><StatsTab /></LazyTab></TabsContent> <TabsContent value="stats"><LazyTab name="stats"><StatsTab /></LazyTab></TabsContent>
<TabsContent value="disciplines"><LazyTab name="disciplines"><DisciplinesTab /></LazyTab></TabsContent> <TabsContent value="disciplines"><LazyTab name="disciplines"><DisciplinesTab /></LazyTab></TabsContent>
<TabsContent value="debug"><LazyTab name="debug"><DebugTab /></LazyTab></TabsContent> <TabsContent value="debug"><LazyTab name="debug"><DebugTab /></LazyTab></TabsContent>
-1
View File
@@ -2,7 +2,6 @@
// Re-exports all game tab components for cleaner imports // Re-exports all game tab components for cleaner imports
// Tab components (consolidated in tabs/ subfolder) // Tab components (consolidated in tabs/ subfolder)
export { SpellsTab } from './tabs/SpellsTab';
export { StatsTab } from './tabs/StatsTab'; export { StatsTab } from './tabs/StatsTab';
// UI components // UI components
-131
View File
@@ -1,131 +0,0 @@
'use client';
import { canAffordSpellCost } from '@/lib/game/stores';
import { useCombatStore, useManaStore } from '@/lib/game/stores';
import { ELEMENTS, SPELLS_DEF } from '@/lib/game/constants';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { DebugName } from '@/components/game/debug/debug-context';
// Format spell cost for display
function formatSpellCost(cost: { type: 'raw' | 'element'; element?: string; amount: number }): string {
if (cost.type === 'raw') {
return `${cost.amount} raw`;
}
const elemDef = ELEMENTS[cost.element || ''];
return `${cost.amount} ${elemDef?.sym || '?'}`;
}
// Get cost color
function getSpellCostColor(cost: { type: 'raw' | 'element'; element?: string; amount: number }): string {
if (cost.type === 'raw') {
return '#60A5FA';
}
return ELEMENTS[cost.element || '']?.color || '#9CA3AF';
}
export function SpellsTab() {
const spells = useCombatStore((s) => s.spells);
const activeSpell = useCombatStore((s) => s.activeSpell);
const setSpell = useCombatStore((s) => s.setSpell);
const rawMana = useManaStore((s) => s.rawMana);
const elements = useManaStore((s) => s.elements);
const spellTiers = [0, 1, 2, 3, 4];
return (
<DebugName name="SpellsTab">
<div className="space-y-6">
{spellTiers.map(tier => {
const spellsInTier = Object.entries(SPELLS_DEF).filter(([, def]) => def.tier === tier);
if (spellsInTier.length === 0) return null;
const tierNames = ['Basic Spells (Raw Mana)', 'Tier 1 - Elemental', 'Tier 2 - Advanced', 'Tier 3 - Master', 'Tier 4 - Legendary'];
const tierColors = ['text-gray-400', 'text-green-400', 'text-blue-400', 'text-purple-400', 'text-amber-400'];
return (
<div key={tier}>
<h3 className={`text-lg font-semibold mb-3 ${tierColors[tier]}`}>{tierNames[tier]}</h3>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
{spellsInTier.map(([id, def]) => {
const state = spells?.[id];
const learned = state?.learned;
const elemDef = def.elem === 'raw' ? null : ELEMENTS[def.elem];
const isActive = activeSpell === id;
const canCast = learned && canAffordSpellCost(def.cost, rawMana, elements);
return (
<Card
key={id}
className={`bg-gray-900/80 border-gray-700 ${learned ? '' : 'opacity-75'} ${canCast ? 'ring-1 ring-green-500/30' : ''}`}
>
<CardHeader className="pb-2">
<div className="flex items-center justify-between">
<CardTitle className="text-sm game-panel-title" style={{ color: def.elem === 'raw' ? '#60A5FA' : elemDef?.color }}>
{def.name}
</CardTitle>
{def.tier > 0 && (
<Badge variant="outline" className="text-xs">
T{def.tier}
</Badge>
)}
</div>
</CardHeader>
<CardContent className="space-y-2">
<div className="text-xs text-gray-400">
{def.elem !== 'raw' && <span className="mr-2">{elemDef?.sym} {elemDef?.name}</span>}
<span className="mr-2"> {def.dmg} dmg</span>
</div>
{/* Cost display */}
<div className="text-xs game-mono" style={{ color: getSpellCostColor(def.cost) }}>
Cost: {formatSpellCost(def.cost)}
</div>
{def.desc && (
<div className="text-xs text-gray-500 italic">{def.desc}</div>
)}
{def.effects && Array.isArray(def.effects) && def.effects.length > 0 && (
<div className="flex gap-1 flex-wrap">
{def.effects.map((eff, i) => (
<Badge key={i} variant="outline" className="text-xs">
{eff.type === 'burn' && `🔥 Burn`}
{eff.type === 'stun' && `⚡ Stun`}
{eff.type === 'pierce' && `🎯 Pierce`}
{eff.type === 'multicast' && `✨ Multicast`}
</Badge>
))}
</div>
)}
{learned ? (
<div className="flex gap-2">
<Badge className="bg-green-900/50 text-green-300">Learned</Badge>
{isActive && <Badge className="bg-amber-900/50 text-amber-300">Active</Badge>}
{!isActive && (
<Button size="sm" variant="outline" onClick={() => setSpell(id)}>
Set Active
</Button>
)}
</div>
) : (
<div className="text-xs text-gray-500">
Not yet learned
</div>
)}
</CardContent>
</Card>
);
})}
</div>
</div>
);
})}
</div>
</DebugName>
);
}
SpellsTab.displayName = "SpellsTab";
-1
View File
@@ -2,7 +2,6 @@
// Re-exports all existing tab components for lazy loading from page.tsx // Re-exports all existing tab components for lazy loading from page.tsx
export { DisciplinesTab } from './DisciplinesTab'; export { DisciplinesTab } from './DisciplinesTab';
export { SpellsTab } from './SpellsTab';
export { StatsTab } from './StatsTab'; export { StatsTab } from './StatsTab';
export { DebugTab } from './DebugTab'; export { DebugTab } from './DebugTab';
export { AchievementsTab } from './AchievementsTab'; export { AchievementsTab } from './AchievementsTab';