1dce061cdd
Build and Publish Mana Loop Docker Image / build-and-publish (push) Failing after 1m2s
- 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
97 lines
3.0 KiB
TypeScript
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';
|