스킬 정리 및 리팩토링

This commit is contained in:
2026-02-26 09:05:17 +09:00
parent 4c52d6d82f
commit 406af7408a
71 changed files with 3776 additions and 3934 deletions

View File

@@ -1,79 +0,0 @@
import { create } from "zustand";
import { persist } from "zustand/middleware";
/**
* [사용자 정보 타입]
*/
export interface User {
id: string;
email: string;
name?: string;
avatar?: string;
createdAt?: string;
}
/**
* [인증 상태 인터페이스]
*/
interface AuthState {
// ========== 상태 ==========
user: User | null;
isAuthenticated: boolean;
// ========== 액션 ==========
setUser: (user: User | null) => void;
updateUser: (updates: Partial<User>) => void;
logout: () => void;
}
/**
* [인증 스토어]
*
* 전역 사용자 인증 상태를 관리합니다.
* - localStorage에 자동 저장 (persist 미들웨어)
* - 페이지 새로고침 시에도 상태 유지
*
* @example
* ```tsx
* import { useAuthStore } from '@/stores/auth-store';
*
* function Profile() {
* const { user, isAuthenticated, setUser } = useAuthStore();
*
* if (!isAuthenticated) return <Login />;
* return <div>Welcome, {user?.email}</div>;
* }
* ```
*/
export const useAuthStore = create<AuthState>()(
persist(
(set) => ({
// ========== 초기 상태 ==========
user: null,
isAuthenticated: false,
// ========== 사용자 설정 ==========
setUser: (user) =>
set({
user,
isAuthenticated: !!user,
}),
// ========== 사용자 정보 업데이트 ==========
updateUser: (updates) =>
set((state) => ({
user: state.user ? { ...state.user, ...updates } : null,
})),
// ========== 로그아웃 ==========
logout: () =>
set({
user: null,
isAuthenticated: false,
}),
}),
{
name: "auth-storage", // localStorage 키 이름
},
),
);

View File

@@ -1,111 +0,0 @@
import { create } from "zustand";
import { persist } from "zustand/middleware";
/**
* [UI 상태 인터페이스]
*/
interface UIState {
// ========== 테마 ==========
theme: "light" | "dark" | "system";
setTheme: (theme: "light" | "dark" | "system") => void;
// ========== 사이드바 ==========
isSidebarOpen: boolean;
toggleSidebar: () => void;
setSidebarOpen: (isOpen: boolean) => void;
// ========== 모달 ==========
isModalOpen: boolean;
modalContent: React.ReactNode | null;
openModal: (content: React.ReactNode) => void;
closeModal: () => void;
// ========== 토스트/알림 ==========
toasts: Toast[];
addToast: (toast: Omit<Toast, "id">) => void;
removeToast: (id: string) => void;
}
/**
* [토스트 메시지 타입]
*/
export interface Toast {
id: string;
type: "success" | "error" | "warning" | "info";
message: string;
duration?: number;
}
/**
* [UI 스토어]
*
* 전역 UI 상태를 관리합니다.
* - 테마 설정 (다크/라이트 모드)
* - 사이드바 열림/닫힘
* - 모달 상태
* - 토스트 알림
*
* @example
* ```tsx
* import { useUIStore } from '@/stores/ui-store';
*
* function Header() {
* const { theme, setTheme, toggleSidebar } = useUIStore();
*
* return (
* <header>
* <button onClick={toggleSidebar}>Menu</button>
* <button onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}>
* Toggle Theme
* </button>
* </header>
* );
* }
* ```
*/
export const useUIStore = create<UIState>()(
persist(
(set) => ({
// ========== 테마 ==========
theme: "system",
setTheme: (theme) => set({ theme }),
// ========== 사이드바 ==========
isSidebarOpen: true,
toggleSidebar: () =>
set((state) => ({ isSidebarOpen: !state.isSidebarOpen })),
setSidebarOpen: (isOpen) => set({ isSidebarOpen: isOpen }),
// ========== 모달 ==========
isModalOpen: false,
modalContent: null,
openModal: (content) => set({ isModalOpen: true, modalContent: content }),
closeModal: () => set({ isModalOpen: false, modalContent: null }),
// ========== 토스트 ==========
toasts: [],
addToast: (toast) =>
set((state) => ({
toasts: [
...state.toasts,
{
...toast,
id: `toast-${Date.now()}-${Math.random()}`,
},
],
})),
removeToast: (id) =>
set((state) => ({
toasts: state.toasts.filter((toast) => toast.id !== id),
})),
}),
{
name: "ui-storage", // localStorage 키 이름
// 일부 상태는 지속하지 않음 (모달, 토스트)
partialize: (state) => ({
theme: state.theme,
isSidebarOpen: state.isSidebarOpen,
}),
},
),
);