Files
Mana-Loop/src/components/game/tabs/CraftingTab/EnchanterSubTab.tsx
T
n8n-gitea 1dce061cdd
Build and Publish Mana Loop Docker Image / build-and-publish (push) Failing after 1m2s
fix: persist enchantment design state across tab navigation
- EnchantmentDesigner now reads selection state directly from useCraftingStore
  instead of receiving it as props, so state survives tab unmount/remount
- EnchanterSubTab no longer uses local useState for selectedEquipmentType,
  selectedEffects, designName, selectedDesign — all sourced from store
- Removed unused EnchantmentDesignerProps interface from types
- All 1158 existing tests pass, no new type errors introduced

Fixes #366
2026-06-11 11:54:45 +02:00

97 lines
3.0 KiB
TypeScript

'use client';
import { useState } from 'react';
import clsx from 'clsx';
import { PenLine, FlaskConical, Sparkles } from 'lucide-react';
import {
EnchantmentDesigner,
EnchantmentPreparer,
EnchantmentApplier,
} from '@/components/game/crafting';
import { useCraftingStore } from '@/lib/game/stores';
import { DebugName } from '@/components/game/debug/debug-context';
type EnchanterPhase = 'design' | 'prepare' | 'apply';
const PHASES: { key: EnchanterPhase; label: string; icon: typeof PenLine }[] = [
{ key: 'design', label: 'Design', icon: PenLine },
{ key: 'prepare', label: 'Prepare', icon: FlaskConical },
{ key: 'apply', label: 'Apply', icon: Sparkles },
];
export function EnchanterSubTab() {
const [activePhase, setActivePhase] = useState<EnchanterPhase>('design');
const resetEnchantmentSelection = useCraftingStore((s) => s.resetEnchantmentSelection);
const setSelectedEquipmentInstance = useCraftingStore((s) => s.setSelectedEquipmentInstance);
const setSelectedDesign = useCraftingStore((s) => s.setSelectedDesign);
// Read persisted selection state from the store
const selectedEquipmentInstance = useCraftingStore(
(s) => s.enchantmentSelection.selectedEquipmentInstance,
);
const selectedDesign = useCraftingStore(
(s) => s.enchantmentSelection.selectedDesign,
);
const handlePhaseChange = (phase: EnchanterPhase) => {
setActivePhase(phase);
};
const handleEnchantmentApplied = () => {
// Reset selection after successful application
resetEnchantmentSelection();
setSelectedEquipmentInstance(null);
setSelectedDesign(null);
// Go back to design phase
setActivePhase('design');
};
return (
<DebugName name="EnchanterSubTab">
<div className="space-y-4">
{/* Phase selector */}
<div className="flex gap-2">
{PHASES.map(({ key, label, icon: Icon }) => (
<button
key={key}
onClick={() => handlePhaseChange(key)}
className={clsx('rounded px-3 py-1 text-sm font-medium flex items-center gap-1.5', {
'bg-purple-600 text-white': activePhase === key,
'text-gray-400 hover:text-gray-200': activePhase !== key,
})}
>
<Icon className="w-3.5 h-3.5" />
{label}
</button>
))}
</div>
{/* Phase content */}
{activePhase === 'design' && (
<EnchantmentDesigner />
)}
{activePhase === 'prepare' && (
<EnchantmentPreparer
selectedEquipmentInstance={selectedEquipmentInstance}
setSelectedEquipmentInstance={setSelectedEquipmentInstance}
/>
)}
{activePhase === 'apply' && (
<EnchantmentApplier
selectedEquipmentInstance={selectedEquipmentInstance}
setSelectedEquipmentInstance={setSelectedEquipmentInstance}
selectedDesign={selectedDesign}
setSelectedDesign={setSelectedDesign}
onEnchantmentApplied={handleEnchantmentApplied}
/>
)}
</div>
</DebugName>
);
}
EnchanterSubTab.displayName = 'EnchanterSubTab';