Implemented complete design system and foundational infrastructure: **Design System Components:** - Button (all variants: primary, secondary, ghost, danger) - Input & Textarea (with validation and error states) - Card (elevated, outlined, flat variants) - Modal/Dialog (with focus trap and accessibility) - Avatar (with fallback initials) - Badge (all color variants) - Form helpers (FormField, Checkbox, Select) - Link component with Next.js integration - Navigation (Header, Footer with responsive design) **Layouts:** - MainLayout (with Header/Footer for public pages) - AuthLayout (minimal layout for auth flows) - DashboardLayout (with sidebar navigation) **Hooks & Utilities:** - useAuth() - authentication state management - useApi() - API calls with loading/error states - useLocalStorage() - persistent state management - apiClient - Axios instance with token refresh - authStore - Zustand store for auth state **Configuration:** - Tailwind config with design tokens - Dark mode support via CSS variables - Global styles with accessibility focus - WCAG 2.2 AA+ compliant focus indicators All components follow accessibility best practices with proper ARIA labels, keyboard navigation, and screen reader support. Job ID: MTAD-IMPL-2025-11-18-CL
93 lines
1.9 KiB
TypeScript
93 lines
1.9 KiB
TypeScript
'use client'
|
|
|
|
import { useAuthStore } from '../store/authStore'
|
|
import { useApi } from './useApi'
|
|
import { useRouter } from 'next/navigation'
|
|
|
|
export interface LoginCredentials {
|
|
email: string
|
|
password: string
|
|
}
|
|
|
|
export interface SignupData {
|
|
email: string
|
|
password: string
|
|
display_name?: string
|
|
}
|
|
|
|
export interface AuthResponse {
|
|
access_token: string
|
|
refresh_token: string
|
|
user: {
|
|
id: string
|
|
email: string
|
|
display_name?: string
|
|
is_verified: boolean
|
|
}
|
|
}
|
|
|
|
export function useAuth() {
|
|
const router = useRouter()
|
|
const { user, isAuthenticated, setAuth, clearAuth, updateUser } = useAuthStore()
|
|
const loginApi = useApi<AuthResponse>()
|
|
const signupApi = useApi<AuthResponse>()
|
|
|
|
const login = async (credentials: LoginCredentials) => {
|
|
const data = await loginApi.execute({
|
|
method: 'POST',
|
|
url: '/auth/login',
|
|
data: credentials,
|
|
})
|
|
|
|
if (data) {
|
|
setAuth(data.user, data.access_token, data.refresh_token)
|
|
router.push('/dashboard')
|
|
return true
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
const signup = async (signupData: SignupData) => {
|
|
const data = await signupApi.execute({
|
|
method: 'POST',
|
|
url: '/auth/signup',
|
|
data: signupData,
|
|
})
|
|
|
|
if (data) {
|
|
setAuth(data.user, data.access_token, data.refresh_token)
|
|
router.push('/dashboard')
|
|
return true
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
const logout = async () => {
|
|
try {
|
|
// Call logout endpoint
|
|
await loginApi.execute({
|
|
method: 'POST',
|
|
url: '/auth/logout',
|
|
})
|
|
} catch (error) {
|
|
console.error('Logout error:', error)
|
|
} finally {
|
|
// Clear auth state regardless of API result
|
|
clearAuth()
|
|
router.push('/')
|
|
}
|
|
}
|
|
|
|
return {
|
|
user,
|
|
isAuthenticated,
|
|
login,
|
|
signup,
|
|
logout,
|
|
updateUser,
|
|
isLoading: loginApi.isLoading || signupApi.isLoading,
|
|
error: loginApi.error || signupApi.error,
|
|
}
|
|
}
|