- Implement complete authentication system with JWT token validation - Add auth provider with persistent login state across page refreshes - Create multilingual login/register forms with Material-UI components - Fix token validation using raw SQL queries to bypass Prisma sync issues - Add comprehensive error handling for expired/invalid tokens - Create profile and settings pages with full i18n support - Add proper user role management (admin/user) with database sync - Implement secure middleware with CSRF protection and auth checks - Add debug endpoints for troubleshooting authentication issues - Fix Zustand store persistence for authentication state 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
48 lines
1.1 KiB
TypeScript
48 lines
1.1 KiB
TypeScript
'use client'
|
|
|
|
import { ReactNode, useEffect } from 'react'
|
|
import { useRouter } from 'next/navigation'
|
|
import { useLocale } from 'next-intl'
|
|
import { useAuth } from './auth-provider'
|
|
import { Box, CircularProgress, Typography } from '@mui/material'
|
|
|
|
interface ProtectedRouteProps {
|
|
children: ReactNode
|
|
fallback?: ReactNode
|
|
}
|
|
|
|
export function ProtectedRoute({ children, fallback }: ProtectedRouteProps) {
|
|
const { isAuthenticated, isLoading } = useAuth()
|
|
const router = useRouter()
|
|
const locale = useLocale()
|
|
|
|
useEffect(() => {
|
|
if (!isLoading && !isAuthenticated) {
|
|
router.push(`/${locale}/login`)
|
|
}
|
|
}, [isAuthenticated, isLoading, router, locale])
|
|
|
|
if (isLoading) {
|
|
return fallback || (
|
|
<Box
|
|
display="flex"
|
|
flexDirection="column"
|
|
alignItems="center"
|
|
justifyContent="center"
|
|
minHeight="60vh"
|
|
gap={2}
|
|
>
|
|
<CircularProgress />
|
|
<Typography variant="body2" color="text.secondary">
|
|
Loading...
|
|
</Typography>
|
|
</Box>
|
|
)
|
|
}
|
|
|
|
if (!isAuthenticated) {
|
|
return null
|
|
}
|
|
|
|
return <>{children}</>
|
|
} |