fix: complete store migration — fix all tab crashes and ghost field reads
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m22s

This commit is contained in:
Refactoring Agent
2026-05-05 12:45:07 +02:00
parent dc1aad3700
commit 221d3e4b41
20 changed files with 399 additions and 754 deletions
+20 -15
View File
@@ -1,13 +1,18 @@
'use client';
import { useState } from 'react';
import { useGameStore } from '@/lib/game/store';
import { useManaStore } from '@/lib/game/stores';
import { ELEMENTS, MANA_PER_ELEMENT } from '@/lib/game/constants';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
export function LabTab() {
const store = useGameStore();
const elements = useManaStore((s) => s.elements);
const rawMana = useManaStore((s) => s.rawMana);
const convertMana = useManaStore((s) => s.convertMana);
const unlockElement = useManaStore((s) => s.unlockElement);
const craftComposite = useManaStore((s) => s.craftComposite);
const [convertTarget, setConvertTarget] = useState('fire');
return (
@@ -19,7 +24,7 @@ export function LabTab() {
</CardHeader>
<CardContent>
<div className="grid grid-cols-3 sm:grid-cols-4 md:grid-cols-6 lg:grid-cols-8 gap-2">
{Object.entries(store.elements)
{Object.entries(elements)
.filter(([, state]) => state.unlocked && state.current >= 1)
.map(([id, state]) => {
const def = ELEMENTS[id];
@@ -55,24 +60,24 @@ export function LabTab() {
<Button
size="sm"
variant="outline"
onClick={() => store.convertMana(convertTarget, 1)}
disabled={!store.elements[convertTarget]?.unlocked || store.rawMana < MANA_PER_ELEMENT}
onClick={() => convertMana(convertTarget, 1)}
disabled={!elements[convertTarget]?.unlocked || rawMana < MANA_PER_ELEMENT}
>
+1 ({MANA_PER_ELEMENT})
</Button>
<Button
size="sm"
variant="outline"
onClick={() => store.convertMana(convertTarget, 10)}
disabled={!store.elements[convertTarget]?.unlocked || store.rawMana < MANA_PER_ELEMENT * 10}
onClick={() => convertMana(convertTarget, 10)}
disabled={!elements[convertTarget]?.unlocked || rawMana < MANA_PER_ELEMENT * 10}
>
+10 ({MANA_PER_ELEMENT * 10})
</Button>
<Button
size="sm"
variant="outline"
onClick={() => store.convertMana(convertTarget, 100)}
disabled={!store.elements[convertTarget]?.unlocked || store.rawMana < MANA_PER_ELEMENT * 100}
onClick={() => convertMana(convertTarget, 100)}
disabled={!elements[convertTarget]?.unlocked || rawMana < MANA_PER_ELEMENT * 100}
>
+100 ({MANA_PER_ELEMENT * 100})
</Button>
@@ -91,7 +96,7 @@ export function LabTab() {
</p>
<div className="grid grid-cols-2 sm:grid-cols-3 gap-2">
{Object.entries(store.elements)
{Object.entries(elements)
.filter(([id, state]) => !state.unlocked && ELEMENTS[id]?.cat !== 'exotic')
.map(([id]) => {
const def = ELEMENTS[id];
@@ -106,8 +111,8 @@ export function LabTab() {
size="sm"
variant="outline"
className="mt-1 w-full"
disabled={store.rawMana < 500}
onClick={() => store.unlockElement(id)}
disabled={rawMana < 500}
onClick={() => unlockElement(id, 500)}
>
Unlock
</Button>
@@ -128,10 +133,10 @@ export function LabTab() {
{Object.entries(ELEMENTS)
.filter(([, def]) => def.recipe)
.map(([id, def]) => {
const state = store.elements[id];
const state = elements[id];
const recipe = def.recipe!;
const canCraft = recipe.every(
(r) => (store.elements[r]?.current || 0) >= recipe.filter((x) => x === r).length
(r) => (elements[r]?.current || 0) >= recipe.filter((x) => x === r).length
);
return (
@@ -156,7 +161,7 @@ export function LabTab() {
variant={canCraft ? 'default' : 'outline'}
className="w-full"
disabled={!canCraft}
onClick={() => store.craftComposite(id)}
onClick={() => craftComposite(id, recipe)}
>
Craft
</Button>