ERP-node/frontend/stores/flowStepStore.ts

136 lines
3.8 KiB
TypeScript

"use client";
import { create } from "zustand";
import { devtools } from "zustand/middleware";
/**
* 플로우 단계 전역 상태 관리
*
* 플로우 위젯에서 단계를 선택하면 이 스토어에 저장되고,
* 버튼 컴포넌트들이 현재 선택된 단계를 구독하여 표시/숨김을 결정합니다.
*/
interface FlowStepState {
/**
* 화면당 여러 플로우의 현재 선택된 단계
* key: flowComponentId (예: "component-123")
* value: stepId (플로우 단계 ID) 또는 null (선택 해제)
*/
selectedSteps: Record<string, number | null>;
/**
* 플로우 단계 선택
* @param flowComponentId 플로우 컴포넌트 고유 ID
* @param stepId 선택된 단계 ID (null이면 선택 해제)
*/
setSelectedStep: (flowComponentId: string, stepId: number | null) => void;
/**
* 현재 단계 조회
* @param flowComponentId 플로우 컴포넌트 고유 ID
* @returns 현재 선택된 단계 ID 또는 null
*/
getCurrentStep: (flowComponentId: string) => number | null;
/**
* 모든 플로우 초기화 (화면 전환 시 사용)
*/
reset: () => void;
/**
* 특정 플로우만 초기화 (플로우 위젯 언마운트 시 사용)
* @param flowComponentId 플로우 컴포넌트 고유 ID
*/
resetFlow: (flowComponentId: string) => void;
}
export const useFlowStepStore = create<FlowStepState>()(
devtools(
(set, get) => ({
selectedSteps: {},
setSelectedStep: (flowComponentId, stepId) => {
console.log("🔄 [FlowStepStore] 플로우 단계 변경:", {
flowComponentId,
stepId,
stepName: stepId ? `Step ${stepId}` : "선택 해제",
});
set((state) => ({
selectedSteps: {
...state.selectedSteps,
[flowComponentId]: stepId,
},
}));
// 개발 모드에서 현재 상태 출력
if (process.env.NODE_ENV === "development") {
const currentState = get().selectedSteps;
console.log("📊 [FlowStepStore] 현재 상태:", currentState);
}
},
getCurrentStep: (flowComponentId) => {
const stepId = get().selectedSteps[flowComponentId] || null;
if (process.env.NODE_ENV === "development") {
console.log("🔍 [FlowStepStore] 현재 단계 조회:", {
flowComponentId,
stepId,
});
}
return stepId;
},
reset: () => {
console.log("🔄 [FlowStepStore] 모든 플로우 단계 초기화");
set({ selectedSteps: {} });
},
resetFlow: (flowComponentId) => {
console.log("🔄 [FlowStepStore] 플로우 단계 초기화:", flowComponentId);
set((state) => {
const { [flowComponentId]: _, ...rest } = state.selectedSteps;
return { selectedSteps: rest };
});
},
}),
{ name: "FlowStepStore" }
)
);
/**
* 특정 플로우의 현재 단계를 구독하는 Hook
*
* @example
* const currentStep = useCurrentFlowStep("component-123");
* if (currentStep === null) {
* // 단계가 선택되지 않음
* }
*/
export const useCurrentFlowStep = (flowComponentId: string | null | undefined) => {
return useFlowStepStore((state) => {
if (!flowComponentId) return null;
return state.getCurrentStep(flowComponentId);
});
};
/**
* 여러 플로우의 현재 단계를 한 번에 구독하는 Hook
*
* @example
* const steps = useMultipleFlowSteps(["component-123", "component-456"]);
* // { "component-123": 1, "component-456": null }
*/
export const useMultipleFlowSteps = (flowComponentIds: string[]) => {
return useFlowStepStore((state) => {
const result: Record<string, number | null> = {};
flowComponentIds.forEach((id) => {
result[id] = state.getCurrentStep(id);
});
return result;
});
};