fix: persist CraftingTab sub-tab selection across tab navigation
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m28s
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m28s
- Add activeCraftingSubTab state + setActiveCraftingSubTab action to craftingStore (persisted to localStorage via zustand persist middleware) - Add CraftingAttunement type to craftingStore.types and re-export from stores/index.ts barrel - Update CraftingTab.tsx to read/write active sub-tab from store instead of local useState, so selection survives component remount - Add default 'fabricator' value in craft-initial-state.ts
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
# Circular Dependencies
|
# Circular Dependencies
|
||||||
Generated: 2026-06-09T13:31:30.036Z
|
Generated: 2026-06-09T16:48:20.172Z
|
||||||
Found: 2 circular chain(s) — these MUST be fixed before modifying involved files.
|
Found: 2 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,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"_meta": {
|
"_meta": {
|
||||||
"generated": "2026-06-09T13:31:28.048Z",
|
"generated": "2026-06-09T16:48:18.218Z",
|
||||||
"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,14 +1,13 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { useState } from 'react';
|
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { Hammer, Sparkles } from 'lucide-react';
|
import { Hammer, Sparkles } from 'lucide-react';
|
||||||
import { DebugName } from '@/components/game/debug/debug-context';
|
import { DebugName } from '@/components/game/debug/debug-context';
|
||||||
|
import { useCraftingStore } from '@/lib/game/stores/craftingStore';
|
||||||
|
import type { CraftingAttunement } from '@/lib/game/stores/craftingStore.types';
|
||||||
import { FabricatorSubTab } from './CraftingTab/FabricatorSubTab';
|
import { FabricatorSubTab } from './CraftingTab/FabricatorSubTab';
|
||||||
import { EnchanterSubTab } from './CraftingTab/EnchanterSubTab';
|
import { EnchanterSubTab } from './CraftingTab/EnchanterSubTab';
|
||||||
|
|
||||||
type CraftingAttunement = 'fabricator' | 'enchanter';
|
|
||||||
|
|
||||||
interface CraftingSubTab {
|
interface CraftingSubTab {
|
||||||
key: CraftingAttunement;
|
key: CraftingAttunement;
|
||||||
label: string;
|
label: string;
|
||||||
@@ -21,7 +20,8 @@ const CRAFTING_SUB_TABS: CraftingSubTab[] = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
export function CraftingTab() {
|
export function CraftingTab() {
|
||||||
const [activeSubTab, setActiveSubTab] = useState<CraftingAttunement>('fabricator');
|
const activeSubTab = useCraftingStore((s) => s.activeCraftingSubTab);
|
||||||
|
const setActiveSubTab = useCraftingStore((s) => s.setActiveCraftingSubTab);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DebugName name="CraftingTab">
|
<DebugName name="CraftingTab">
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ export function createDefaultCraftingState(): CraftingState {
|
|||||||
selectedEquipmentInstance: null,
|
selectedEquipmentInstance: null,
|
||||||
},
|
},
|
||||||
lastError: null,
|
lastError: null,
|
||||||
|
activeCraftingSubTab: 'fabricator',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -285,6 +285,8 @@ export const useCraftingStore = create<CraftingStore>()(
|
|||||||
|
|
||||||
clearLastError: () => set({ lastError: null }),
|
clearLastError: () => set({ lastError: null }),
|
||||||
|
|
||||||
|
setActiveCraftingSubTab: (tab) => set({ activeCraftingSubTab: tab }),
|
||||||
|
|
||||||
unlockEffects: (effectIds: string[]) => {
|
unlockEffects: (effectIds: string[]) => {
|
||||||
set((state) => {
|
set((state) => {
|
||||||
const existing = new Set(state.unlockedEffects);
|
const existing = new Set(state.unlockedEffects);
|
||||||
@@ -343,6 +345,7 @@ export const useCraftingStore = create<CraftingStore>()(
|
|||||||
lootInventory: state.lootInventory,
|
lootInventory: state.lootInventory,
|
||||||
enchantmentSelection: state.enchantmentSelection,
|
enchantmentSelection: state.enchantmentSelection,
|
||||||
lastError: state.lastError,
|
lastError: state.lastError,
|
||||||
|
activeCraftingSubTab: state.activeCraftingSubTab,
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ export interface CraftingError {
|
|||||||
timestamp: number;
|
timestamp: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type CraftingAttunement = 'fabricator' | 'enchanter';
|
||||||
|
|
||||||
export interface CraftingState {
|
export interface CraftingState {
|
||||||
designProgress: DesignProgress | null;
|
designProgress: DesignProgress | null;
|
||||||
designProgress2: DesignProgress | null;
|
designProgress2: DesignProgress | null;
|
||||||
@@ -39,6 +41,7 @@ export interface CraftingState {
|
|||||||
selectedEquipmentInstance: string | null;
|
selectedEquipmentInstance: string | null;
|
||||||
};
|
};
|
||||||
lastError: CraftingError | null;
|
lastError: CraftingError | null;
|
||||||
|
activeCraftingSubTab: CraftingAttunement;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CraftingActions {
|
export interface CraftingActions {
|
||||||
@@ -47,6 +50,7 @@ export interface CraftingActions {
|
|||||||
setPreparationProgress: (progress: PreparationProgress | null) => void;
|
setPreparationProgress: (progress: PreparationProgress | null) => void;
|
||||||
setApplicationProgress: (progress: ApplicationProgress | null) => void;
|
setApplicationProgress: (progress: ApplicationProgress | null) => void;
|
||||||
setEquipmentCraftingProgress: (progress: EquipmentCraftingProgress | null) => void;
|
setEquipmentCraftingProgress: (progress: EquipmentCraftingProgress | null) => void;
|
||||||
|
setActiveCraftingSubTab: (tab: CraftingAttunement) => void;
|
||||||
startDesigningEnchantment: (name: string, equipmentTypeId: string, effects: DesignEffect[]) => boolean;
|
startDesigningEnchantment: (name: string, equipmentTypeId: string, effects: DesignEffect[]) => boolean;
|
||||||
cancelDesign: (slot?: 1 | 2) => void;
|
cancelDesign: (slot?: 1 | 2) => void;
|
||||||
saveDesign: (design: EnchantmentDesign) => void;
|
saveDesign: (design: EnchantmentDesign) => void;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export { useCombatStore, makeInitialSpells } from './combatStore';
|
|||||||
export type { CombatState, CombatActions, CombatStore } from './combat-state.types';
|
export type { CombatState, CombatActions, CombatStore } from './combat-state.types';
|
||||||
|
|
||||||
export { useCraftingStore } from './craftingStore';
|
export { useCraftingStore } from './craftingStore';
|
||||||
export type { CraftingState, CraftingActions } from './craftingStore.types';
|
export type { CraftingState, CraftingActions, CraftingStore, CraftingAttunement } from './craftingStore.types';
|
||||||
|
|
||||||
export { useAttunementStore } from './attunementStore';
|
export { useAttunementStore } from './attunementStore';
|
||||||
export type { AttunementStoreState } from './attunementStore';
|
export type { AttunementStoreState } from './attunementStore';
|
||||||
|
|||||||
Reference in New Issue
Block a user