Files
biblical-guide.com/app/[locale]/auth/login/page.tsx
andupetcu 196ca00194 Fix authentication state persistence and admin role display
- 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>
2025-09-21 01:06:30 +03:00

133 lines
3.7 KiB
TypeScript

'use client'
import { useState } from 'react'
import { useRouter } from 'next/navigation'
import { useTranslations, useLocale } from 'next-intl'
import {
Container,
Paper,
Box,
Typography,
Tabs,
Tab,
Link,
Card,
CardContent,
Divider
} from '@mui/material'
import {
MenuBook,
Login as LoginIcon,
PersonAdd
} from '@mui/icons-material'
import { LoginForm } from '@/components/auth/login-form'
import { RegisterForm } from '@/components/auth/register-form'
export default function AuthPage() {
const [activeTab, setActiveTab] = useState(0)
const router = useRouter()
const locale = useLocale()
const t = useTranslations('auth')
const handleAuthSuccess = () => {
router.push(`/${locale}`)
}
const handleTabChange = (event: React.SyntheticEvent, newValue: number) => {
setActiveTab(newValue)
}
const getSubtitle = () => {
if (locale === 'en') {
return activeTab === 0
? 'Sign in to continue exploring Scripture'
: 'Create an account to begin your spiritual journey'
}
return activeTab === 0
? 'Conectează-te pentru a continua explorarea Scripturii'
: 'Creează un cont pentru a începe călătoria ta spirituală'
}
return (
<Container maxWidth="sm" sx={{ py: 4, minHeight: '100vh', display: 'flex', alignItems: 'center' }}>
<Card elevation={8} sx={{ width: '100%', borderRadius: 3 }}>
<CardContent sx={{ p: 4 }}>
{/* Header */}
<Box textAlign="center" mb={4}>
<Box display="flex" justifyContent="center" mb={2}>
<MenuBook sx={{ fontSize: 48, color: 'primary.main' }} />
</Box>
<Typography variant="h4" component="h1" gutterBottom fontWeight="bold">
{activeTab === 0 ? t('welcomeBack') : t('joinUs')}
</Typography>
<Typography variant="body1" color="text.secondary">
{getSubtitle()}
</Typography>
</Box>
<Divider sx={{ mb: 3 }} />
{/* Tabs */}
<Tabs
value={activeTab}
onChange={handleTabChange}
centered
sx={{
mb: 3,
'& .MuiTab-root': {
minWidth: 120,
fontWeight: 600
}
}}
TabIndicatorProps={{
style: { height: 3, borderRadius: 3 }
}}
>
<Tab
icon={<LoginIcon />}
iconPosition="start"
label={t('login')}
/>
<Tab
icon={<PersonAdd />}
iconPosition="start"
label={t('register')}
/>
</Tabs>
{/* Forms */}
<Box sx={{ minHeight: 300 }}>
{activeTab === 0 ? (
<LoginForm onSuccess={handleAuthSuccess} />
) : (
<RegisterForm onSuccess={handleAuthSuccess} />
)}
</Box>
<Divider sx={{ my: 3 }} />
{/* Switch Form Link */}
<Box textAlign="center">
<Typography variant="body2" color="text.secondary">
{activeTab === 0 ? t('noAccount') : t('alreadyHaveAccount')}{' '}
<Link
component="button"
variant="body2"
onClick={() => setActiveTab(activeTab === 0 ? 1 : 0)}
sx={{
textDecoration: 'none',
fontWeight: 600,
'&:hover': {
textDecoration: 'underline'
}
}}
>
{activeTab === 0 ? t('createAccount') : t('login')}
</Link>
</Typography>
</Box>
</CardContent>
</Card>
</Container>
)
}