fix: persist enchantment design state across tab navigation
Build and Publish Mana Loop Docker Image / build-and-publish (push) Failing after 1m2s
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
This commit is contained in:
@@ -1,10 +1,11 @@
|
|||||||
# Circular Dependencies
|
# Circular Dependencies
|
||||||
Generated: 2026-06-11T07:08:59.875Z
|
Generated: 2026-06-11T09:37:23.110Z
|
||||||
Found: 3 circular chain(s) — these MUST be fixed before modifying involved files.
|
Found: 4 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) data/guardian-encounters.ts > data/guardian-procedural.ts
|
||||||
2. 2) stores/attunementStore.ts > stores/combatStore.ts > stores/combat-descent-actions.ts
|
2. 2) stores/golem-combat-actions.ts > stores/golem-combat-helpers.ts
|
||||||
3. 3) stores/attunementStore.ts > stores/combatStore.ts > stores/combat-descent-actions.ts > stores/non-combat-room-actions.ts
|
3. 3) stores/attunementStore.ts > stores/combatStore.ts > stores/combat-descent-actions.ts
|
||||||
|
4. 4) stores/attunementStore.ts > stores/combatStore.ts > stores/combat-descent-actions.ts > stores/non-combat-room-actions.ts
|
||||||
|
|
||||||
## How to fix
|
## How to fix
|
||||||
1. Identify which import in the chain can be extracted to a shared types/utils file.
|
1. Identify which import in the chain can be extracted to a shared types/utils file.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"_meta": {
|
"_meta": {
|
||||||
"generated": "2026-06-11T07:08:57.908Z",
|
"generated": "2026-06-11T09:37:21.146Z",
|
||||||
"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."
|
||||||
},
|
},
|
||||||
@@ -492,6 +492,11 @@
|
|||||||
],
|
],
|
||||||
"data/guardian-encounters.ts": [
|
"data/guardian-encounters.ts": [
|
||||||
"data/guardian-data.ts",
|
"data/guardian-data.ts",
|
||||||
|
"data/guardian-procedural.ts",
|
||||||
|
"types.ts"
|
||||||
|
],
|
||||||
|
"data/guardian-procedural.ts": [
|
||||||
|
"data/guardian-encounters.ts",
|
||||||
"types.ts",
|
"types.ts",
|
||||||
"utils/guardian-utils.ts"
|
"utils/guardian-utils.ts"
|
||||||
],
|
],
|
||||||
@@ -532,6 +537,7 @@
|
|||||||
"effects/upgrade-effects.ts",
|
"effects/upgrade-effects.ts",
|
||||||
"stores/attunementStore.ts",
|
"stores/attunementStore.ts",
|
||||||
"stores/combatStore.ts",
|
"stores/combatStore.ts",
|
||||||
|
"stores/craftingStore.ts",
|
||||||
"stores/gameStore.ts",
|
"stores/gameStore.ts",
|
||||||
"stores/manaStore.ts",
|
"stores/manaStore.ts",
|
||||||
"stores/prestigeStore.ts",
|
"stores/prestigeStore.ts",
|
||||||
@@ -613,6 +619,8 @@
|
|||||||
"crafting-design.ts",
|
"crafting-design.ts",
|
||||||
"crafting-utils.ts",
|
"crafting-utils.ts",
|
||||||
"effects/discipline-effects.ts",
|
"effects/discipline-effects.ts",
|
||||||
|
"effects/special-effects.ts",
|
||||||
|
"effects/upgrade-effects.ts",
|
||||||
"stores/combatStore.ts",
|
"stores/combatStore.ts",
|
||||||
"stores/crafting-equipment-tick.ts",
|
"stores/crafting-equipment-tick.ts",
|
||||||
"stores/crafting-initial-state.ts",
|
"stores/crafting-initial-state.ts",
|
||||||
@@ -790,7 +798,6 @@
|
|||||||
"crafting-prep.ts",
|
"crafting-prep.ts",
|
||||||
"effects/discipline-effects.ts",
|
"effects/discipline-effects.ts",
|
||||||
"effects/upgrade-effects.types.ts",
|
"effects/upgrade-effects.types.ts",
|
||||||
"stores/craftingStore.ts",
|
|
||||||
"stores/tick-pipeline.ts"
|
"stores/tick-pipeline.ts"
|
||||||
],
|
],
|
||||||
"stores/pipelines/equipment-crafting.ts": [
|
"stores/pipelines/equipment-crafting.ts": [
|
||||||
|
|||||||
@@ -2,8 +2,7 @@
|
|||||||
|
|
||||||
import { GameCard } from '@/components/ui/game-card';
|
import { GameCard } from '@/components/ui/game-card';
|
||||||
import { Separator } from '@/components/ui/separator';
|
import { Separator } from '@/components/ui/separator';
|
||||||
import type { EquipmentInstance, EnchantmentDesign, DesignEffect, EquipmentCraftingProgress, EquipmentCategory } from '@/lib/game/types';
|
import type { DesignEffect, EquipmentCategory } from '@/lib/game/types';
|
||||||
import type { EnchantmentDesignerProps } from './EnchantmentDesigner/types';
|
|
||||||
import { EquipmentTypeSelector } from './EnchantmentDesigner/EquipmentTypeSelector';
|
import { EquipmentTypeSelector } from './EnchantmentDesigner/EquipmentTypeSelector';
|
||||||
import { EffectSelector } from './EnchantmentDesigner/EffectSelector';
|
import { EffectSelector } from './EnchantmentDesigner/EffectSelector';
|
||||||
import { SavedDesigns } from './EnchantmentDesigner/SavedDesigns';
|
import { SavedDesigns } from './EnchantmentDesigner/SavedDesigns';
|
||||||
@@ -22,20 +21,21 @@ import {
|
|||||||
import { useCraftingStore, useAttunementStore } from '@/lib/game/stores';
|
import { useCraftingStore, useAttunementStore } from '@/lib/game/stores';
|
||||||
import { DebugName } from '@/components/game/debug/debug-context';
|
import { DebugName } from '@/components/game/debug/debug-context';
|
||||||
|
|
||||||
export function EnchantmentDesigner({
|
export function EnchantmentDesigner() {
|
||||||
selectedEquipmentType,
|
|
||||||
setSelectedEquipmentType,
|
|
||||||
selectedEffects,
|
|
||||||
setSelectedEffects,
|
|
||||||
designName,
|
|
||||||
setDesignName,
|
|
||||||
selectedDesign,
|
|
||||||
setSelectedDesign,
|
|
||||||
}: EnchantmentDesignerProps) {
|
|
||||||
// Attunement store — get Enchanter level for effect selector gating
|
// Attunement store — get Enchanter level for effect selector gating
|
||||||
const enchanterLevel = useAttunementStore((s) => s.attunements?.enchanter?.level ?? 0);
|
const enchanterLevel = useAttunementStore((s) => s.attunements?.enchanter?.level ?? 0);
|
||||||
|
|
||||||
// Crafting store selectors
|
// Crafting store selectors — persisted selection state
|
||||||
|
const selectedEquipmentType = useCraftingStore((s) => s.enchantmentSelection.selectedEquipmentType);
|
||||||
|
const setSelectedEquipmentType = useCraftingStore((s) => s.setSelectedEquipmentType);
|
||||||
|
const selectedEffects = useCraftingStore((s) => s.enchantmentSelection.selectedEffects);
|
||||||
|
const setSelectedEffects = useCraftingStore((s) => s.setSelectedEffects);
|
||||||
|
const designName = useCraftingStore((s) => s.enchantmentSelection.designName);
|
||||||
|
const setDesignName = useCraftingStore((s) => s.setDesignName);
|
||||||
|
const selectedDesign = useCraftingStore((s) => s.enchantmentSelection.selectedDesign);
|
||||||
|
const setSelectedDesign = useCraftingStore((s) => s.setSelectedDesign);
|
||||||
|
|
||||||
|
// Crafting store — other state
|
||||||
const enchantmentDesigns = useCraftingStore((s) => s.enchantmentDesigns);
|
const enchantmentDesigns = useCraftingStore((s) => s.enchantmentDesigns);
|
||||||
const designProgress = useCraftingStore((s) => s.designProgress);
|
const designProgress = useCraftingStore((s) => s.designProgress);
|
||||||
const startDesigningEnchantment = useCraftingStore((s) => s.startDesigningEnchantment);
|
const startDesigningEnchantment = useCraftingStore((s) => s.startDesigningEnchantment);
|
||||||
|
|||||||
@@ -1,15 +1,4 @@
|
|||||||
import type { EquipmentInstance, EnchantmentDesign, DesignEffect, DesignProgress, EquipmentCategory } from '@/lib/game/types';
|
import type { EnchantmentDesign, DesignEffect, DesignProgress, EquipmentCategory } from '@/lib/game/types';
|
||||||
|
|
||||||
export interface EnchantmentDesignerProps {
|
|
||||||
selectedEquipmentType: string | null;
|
|
||||||
setSelectedEquipmentType: (type: string | null) => void;
|
|
||||||
selectedEffects: DesignEffect[];
|
|
||||||
setSelectedEffects: (effects: DesignEffect[]) => void;
|
|
||||||
designName: string;
|
|
||||||
setDesignName: (name: string) => void;
|
|
||||||
selectedDesign: string | null;
|
|
||||||
setSelectedDesign: (id: string | null) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface EquipmentTypeSelectorProps {
|
export interface EquipmentTypeSelectorProps {
|
||||||
ownedEquipmentTypes: Array<{ id: string; name: string; baseCapacity: number }>;
|
ownedEquipmentTypes: Array<{ id: string; name: string; baseCapacity: number }>;
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import {
|
|||||||
EnchantmentApplier,
|
EnchantmentApplier,
|
||||||
} from '@/components/game/crafting';
|
} from '@/components/game/crafting';
|
||||||
import { useCraftingStore } from '@/lib/game/stores';
|
import { useCraftingStore } from '@/lib/game/stores';
|
||||||
import type { DesignEffect } from '@/lib/game/types';
|
|
||||||
import { DebugName } from '@/components/game/debug/debug-context';
|
import { DebugName } from '@/components/game/debug/debug-context';
|
||||||
|
|
||||||
type EnchanterPhase = 'design' | 'prepare' | 'apply';
|
type EnchanterPhase = 'design' | 'prepare' | 'apply';
|
||||||
@@ -23,14 +22,17 @@ const PHASES: { key: EnchanterPhase; label: string; icon: typeof PenLine }[] = [
|
|||||||
export function EnchanterSubTab() {
|
export function EnchanterSubTab() {
|
||||||
const [activePhase, setActivePhase] = useState<EnchanterPhase>('design');
|
const [activePhase, setActivePhase] = useState<EnchanterPhase>('design');
|
||||||
|
|
||||||
// Shared state for the enchantment flow
|
|
||||||
const [selectedEquipmentType, setSelectedEquipmentType] = useState<string | null>(null);
|
|
||||||
const [selectedEffects, setSelectedEffects] = useState<DesignEffect[]>([]);
|
|
||||||
const [designName, setDesignName] = useState('');
|
|
||||||
const [selectedDesign, setSelectedDesign] = useState<string | null>(null);
|
|
||||||
const [selectedEquipmentInstance, setSelectedEquipmentInstance] = useState<string | null>(null);
|
|
||||||
|
|
||||||
const resetEnchantmentSelection = useCraftingStore((s) => s.resetEnchantmentSelection);
|
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) => {
|
const handlePhaseChange = (phase: EnchanterPhase) => {
|
||||||
setActivePhase(phase);
|
setActivePhase(phase);
|
||||||
@@ -67,16 +69,7 @@ export function EnchanterSubTab() {
|
|||||||
|
|
||||||
{/* Phase content */}
|
{/* Phase content */}
|
||||||
{activePhase === 'design' && (
|
{activePhase === 'design' && (
|
||||||
<EnchantmentDesigner
|
<EnchantmentDesigner />
|
||||||
selectedEquipmentType={selectedEquipmentType}
|
|
||||||
setSelectedEquipmentType={setSelectedEquipmentType}
|
|
||||||
selectedEffects={selectedEffects}
|
|
||||||
setSelectedEffects={setSelectedEffects}
|
|
||||||
designName={designName}
|
|
||||||
setDesignName={setDesignName}
|
|
||||||
selectedDesign={selectedDesign}
|
|
||||||
setSelectedDesign={setSelectedDesign}
|
|
||||||
/>
|
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{activePhase === 'prepare' && (
|
{activePhase === 'prepare' && (
|
||||||
|
|||||||
Reference in New Issue
Block a user