fromis_9/frontend-temp/src/stores/useUIStore.js

122 lines
2.7 KiB
JavaScript
Raw Normal View History

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;