113 lines
3.0 KiB
TypeScript
113 lines
3.0 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) => {
|
|
set((state) => ({
|
|
selectedSteps: {
|
|
...state.selectedSteps,
|
|
[flowComponentId]: stepId,
|
|
},
|
|
}));
|
|
},
|
|
|
|
getCurrentStep: (flowComponentId) => {
|
|
const stepId = get().selectedSteps[flowComponentId] || null;
|
|
return stepId;
|
|
},
|
|
|
|
reset: () => {
|
|
set({ selectedSteps: {} });
|
|
},
|
|
|
|
resetFlow: (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;
|
|
});
|
|
};
|
|
|