diff --git a/frontend/app/providers.tsx b/frontend/app/providers.tsx index b79ccde..22f8b8d 100644 --- a/frontend/app/providers.tsx +++ b/frontend/app/providers.tsx @@ -2,6 +2,7 @@ import React from 'react'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { AuthInitializer } from '@/components/auth/AuthInitializer'; const queryClient = new QueryClient({ defaultOptions: { @@ -14,6 +15,9 @@ const queryClient = new QueryClient({ export function Providers({ children }: { children: React.ReactNode }) { return ( - {children} + + + {children} + ); } diff --git a/frontend/components/auth/AuthInitializer.tsx b/frontend/components/auth/AuthInitializer.tsx new file mode 100644 index 0000000..94d4a2d --- /dev/null +++ b/frontend/components/auth/AuthInitializer.tsx @@ -0,0 +1,12 @@ +'use client'; + +import { useEffect } from 'react'; +import { useAuthStore } from '@/store/auth.store'; + +export function AuthInitializer() { + useEffect(() => { + useAuthStore.getState().initialize(); + }, []); + + return null; +} diff --git a/frontend/middleware.ts b/frontend/middleware.ts index b51d2df..6d1b9a1 100644 --- a/frontend/middleware.ts +++ b/frontend/middleware.ts @@ -1,34 +1,46 @@ import { NextResponse } from 'next/server'; import type { NextRequest } from 'next/server'; -const PROTECTED = [ '/assets', '/departments', '/users']; + +const PROTECTED_ROUTES = ['/dashboard', '/assets', '/departments', '/users', '/reports', '/settings']; const AUTH_PAGES = ['/login', '/register']; -export const middleware = (req: NextRequest) => { +export function middleware(req: NextRequest) { const token = req.cookies.get('auth-token')?.value; const { pathname } = req.nextUrl; - const isProtected = PROTECTED.some((route) => pathname.startsWith(route)); - const isAuthPage = AUTH_PAGES.includes(pathname); + const isAuthenticated = !!token; + const isProtectedRoute = PROTECTED_ROUTES.some((route) => pathname.startsWith(route)); + const isAuthPage = AUTH_PAGES.some((route) => pathname.startsWith(route)); + + // Redirect root to dashboard + if (pathname === '/') { + return NextResponse.redirect(new URL('/dashboard', req.url)); + } - if (isProtected && !token) { + // Redirect unauthenticated users from protected routes to login + if (isProtectedRoute && !isAuthenticated) { const url = new URL('/login', req.url); url.searchParams.set('redirect', pathname); return NextResponse.redirect(url); } - // if (isAuthPage && token) { - // return NextResponse.redirect(new URL('/dashboard', req.url)); - // } + // Redirect authenticated users away from auth pages to dashboard + if (isAuthPage && isAuthenticated) { + return NextResponse.redirect(new URL('/dashboard', req.url)); + } return NextResponse.next(); -}; +} export const config = { matcher: [ + '/', '/dashboard/:path*', '/assets/:path*', '/departments/:path*', '/users/:path*', + '/reports/:path*', + '/settings/:path*', '/login', '/register', ], diff --git a/frontend/store/auth.store.ts b/frontend/store/auth.store.ts index 9949964..32153a1 100644 --- a/frontend/store/auth.store.ts +++ b/frontend/store/auth.store.ts @@ -14,8 +14,10 @@ interface AuthStore { user: User | null; token: string | null; isAuthenticated: boolean; + isInitialized: boolean; setAuth: (token: string, user: User) => void; logout: () => void; + initialize: () => void; loadAuthFromStorage: () => void; } @@ -25,6 +27,7 @@ export const useAuthStore = create()( user: null, token: null, isAuthenticated: false, + isInitialized: false, setAuth: (token: string, user: User) => { // Store token in localStorage for API calls @@ -52,11 +55,29 @@ export const useAuthStore = create()( }); }, + initialize: () => { + const { isInitialized } = get(); + if (isInitialized) return; + + const token = localStorage.getItem('token'); + if (token) { + const user = JSON.parse(localStorage.getItem('user') || 'null'); + if (user) { + set({ + token, + user, + isAuthenticated: true, + isInitialized: true, + }); + return; + } + } + set({ isInitialized: true }); + }, + loadAuthFromStorage: () => { const token = localStorage.getItem('token'); if (token) { - // For now, we'll need to validate the token or decode it - // In a real app, you might want to validate the token on app load const user = JSON.parse(localStorage.getItem('user') || 'null'); if (user) { set({ @@ -74,6 +95,7 @@ export const useAuthStore = create()( user: state.user, token: state.token, isAuthenticated: state.isAuthenticated, + isInitialized: state.isInitialized, }), } )