- useAuthStore: 인증 상태 관리 (localStorage persist) - useScheduleStore: 스케줄 페이지 상태 (검색, 필터, 날짜, 뷰) - useUIStore: UI 상태 (토스트, 모달, 라이트박스, 확인 다이얼로그) - stores/index.js: 통합 export Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
121 lines
2.7 KiB
JavaScript
121 lines
2.7 KiB
JavaScript
import { create } from 'zustand';
|
|
|
|
/**
|
|
* UI 상태 스토어
|
|
* 모달, 토스트, 사이드바 등 전역 UI 상태 관리
|
|
*/
|
|
const useUIStore = create((set, get) => ({
|
|
// ===== 모달 =====
|
|
modalOpen: false,
|
|
modalContent: null,
|
|
modalProps: {},
|
|
|
|
openModal: (content, props = {}) => {
|
|
set({
|
|
modalOpen: true,
|
|
modalContent: content,
|
|
modalProps: props,
|
|
});
|
|
},
|
|
|
|
closeModal: () => {
|
|
set({
|
|
modalOpen: false,
|
|
modalContent: null,
|
|
modalProps: {},
|
|
});
|
|
},
|
|
|
|
// ===== 토스트 =====
|
|
toasts: [],
|
|
|
|
addToast: (message, type = 'info', duration = 3000) => {
|
|
const id = Date.now();
|
|
const toast = { id, message, type, duration };
|
|
|
|
set((state) => ({
|
|
toasts: [...state.toasts, toast],
|
|
}));
|
|
|
|
// 자동 제거
|
|
if (duration > 0) {
|
|
setTimeout(() => {
|
|
get().removeToast(id);
|
|
}, duration);
|
|
}
|
|
|
|
return id;
|
|
},
|
|
|
|
removeToast: (id) => {
|
|
set((state) => ({
|
|
toasts: state.toasts.filter((t) => t.id !== id),
|
|
}));
|
|
},
|
|
|
|
clearToasts: () => set({ toasts: [] }),
|
|
|
|
// 편의 메서드
|
|
showSuccess: (message, duration) => get().addToast(message, 'success', duration),
|
|
showError: (message, duration) => get().addToast(message, 'error', duration),
|
|
showWarning: (message, duration) => get().addToast(message, 'warning', duration),
|
|
showInfo: (message, duration) => get().addToast(message, 'info', duration),
|
|
|
|
// ===== 사이드바 (모바일) =====
|
|
sidebarOpen: false,
|
|
toggleSidebar: () => set((state) => ({ sidebarOpen: !state.sidebarOpen })),
|
|
openSidebar: () => set({ sidebarOpen: true }),
|
|
closeSidebar: () => set({ sidebarOpen: false }),
|
|
|
|
// ===== 라이트박스 =====
|
|
lightboxOpen: false,
|
|
lightboxImages: [],
|
|
lightboxIndex: 0,
|
|
|
|
openLightbox: (images, index = 0) => {
|
|
set({
|
|
lightboxOpen: true,
|
|
lightboxImages: Array.isArray(images) ? images : [images],
|
|
lightboxIndex: index,
|
|
});
|
|
},
|
|
|
|
closeLightbox: () => {
|
|
set({
|
|
lightboxOpen: false,
|
|
lightboxImages: [],
|
|
lightboxIndex: 0,
|
|
});
|
|
},
|
|
|
|
setLightboxIndex: (index) => set({ lightboxIndex: index }),
|
|
|
|
// ===== 로딩 =====
|
|
globalLoading: false,
|
|
setGlobalLoading: (value) => set({ globalLoading: value }),
|
|
|
|
// ===== 확인 다이얼로그 =====
|
|
confirmDialog: null,
|
|
|
|
showConfirm: (options) => {
|
|
return new Promise((resolve) => {
|
|
set({
|
|
confirmDialog: {
|
|
...options,
|
|
onConfirm: () => {
|
|
set({ confirmDialog: null });
|
|
resolve(true);
|
|
},
|
|
onCancel: () => {
|
|
set({ confirmDialog: null });
|
|
resolve(false);
|
|
},
|
|
},
|
|
});
|
|
});
|
|
},
|
|
|
|
closeConfirm: () => set({ confirmDialog: null }),
|
|
}));
|
|
|
|
export default useUIStore;
|