인증 영역 개발 완료 (로그인, 회원가입, 프로필 관리)

- 로그인 페이지: 이메일 + 비밀번호 로그인, 소셜 로그인 버튼
- 회원가입 페이지: 3단계 funnel (계정정보, 개인정보, 사업장정보)
- 프로필 관리 페이지: 기본정보/매장정보 수정, 비밀번호 변경, 로그아웃
- MUI v6 + React Hook Form + Zod 검증
- Next.js 14 App Router, TypeScript 5

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
cherry2250
2025-10-24 11:27:15 +09:00
parent ca4dff559c
commit 4df7ba0697
23 changed files with 8921 additions and 0 deletions
+40
View File
@@ -0,0 +1,40 @@
import { create } from 'zustand';
import { persist } from 'zustand/middleware';
interface User {
id: string;
name: string;
email: string;
phone: string;
businessName?: string;
businessType?: string;
}
interface AuthState {
user: User | null;
token: string | null;
isAuthenticated: boolean;
setUser: (user: User | null) => void;
setToken: (token: string | null) => void;
login: (user: User, token: string) => void;
logout: () => void;
}
export const useAuthStore = create<AuthState>()(
persist(
(set) => ({
user: null,
token: null,
isAuthenticated: false,
setUser: (user) => set({ user, isAuthenticated: !!user }),
setToken: (token) => set({ token }),
login: (user, token) =>
set({ user, token, isAuthenticated: true }),
logout: () =>
set({ user: null, token: null, isAuthenticated: false }),
}),
{
name: 'auth-storage',
}
)
);
+31
View File
@@ -0,0 +1,31 @@
import { create } from 'zustand';
interface UIState {
isLoading: boolean;
isSidebarOpen: boolean;
toast: {
open: boolean;
message: string;
severity: 'success' | 'error' | 'warning' | 'info';
};
setLoading: (isLoading: boolean) => void;
toggleSidebar: () => void;
showToast: (message: string, severity?: 'success' | 'error' | 'warning' | 'info') => void;
hideToast: () => void;
}
export const useUIStore = create<UIState>((set) => ({
isLoading: false,
isSidebarOpen: false,
toast: {
open: false,
message: '',
severity: 'info',
},
setLoading: (isLoading) => set({ isLoading }),
toggleSidebar: () => set((state) => ({ isSidebarOpen: !state.isSidebarOpen })),
showToast: (message, severity = 'info') =>
set({ toast: { open: true, message, severity } }),
hideToast: () =>
set((state) => ({ toast: { ...state.toast, open: false } })),
}));