feat(frontend): i18n common + nav + auth (Layout, LoginPage, ProtectedRoute)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { Link, NavLink, Outlet, useNavigate } from 'react-router-dom';
|
||||
import { Moon, Sun, Monitor } from 'lucide-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useAuth } from '@/hooks/useAuth';
|
||||
import { useTheme } from '@/hooks/useTheme';
|
||||
import type { Theme } from '@/hooks/useTheme';
|
||||
@@ -20,6 +21,7 @@ export function Layout(): JSX.Element {
|
||||
const { user, isAdmin, isRedteam, logout } = useAuth();
|
||||
const navigate = useNavigate();
|
||||
const { theme, cycleTheme } = useTheme();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleLogout = async () => {
|
||||
await logout();
|
||||
@@ -52,7 +54,7 @@ export function Layout(): JSX.Element {
|
||||
onClick={handleLogout}
|
||||
className="text-[14px] underline-offset-2 hover:underline"
|
||||
>
|
||||
Sign out
|
||||
{t('nav.signOut')}
|
||||
</button>
|
||||
</div>
|
||||
) : null}
|
||||
@@ -78,7 +80,7 @@ export function Layout(): JSX.Element {
|
||||
}`
|
||||
}
|
||||
>
|
||||
Engagements
|
||||
{t('nav.engagements')}
|
||||
</NavLink>
|
||||
{isAdmin || isRedteam ? (
|
||||
<NavLink
|
||||
@@ -91,7 +93,7 @@ export function Layout(): JSX.Element {
|
||||
}`
|
||||
}
|
||||
>
|
||||
Templates
|
||||
{t('nav.templates')}
|
||||
</NavLink>
|
||||
) : null}
|
||||
{isAdmin ? (
|
||||
@@ -105,7 +107,7 @@ export function Layout(): JSX.Element {
|
||||
}`
|
||||
}
|
||||
>
|
||||
Users
|
||||
{t('nav.users')}
|
||||
</NavLink>
|
||||
) : null}
|
||||
</nav>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { useEffect } from 'react';
|
||||
import { Navigate, Outlet, useLocation } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useAuth } from '@/hooks/useAuth';
|
||||
import { useToast } from '@/hooks/useToast';
|
||||
import type { Role } from '@/api/types';
|
||||
@@ -23,6 +24,7 @@ export function ProtectedRoute({
|
||||
}: ProtectedRouteProps): JSX.Element {
|
||||
const { user, status } = useAuth();
|
||||
const { push } = useToast();
|
||||
const { t } = useTranslation();
|
||||
const location = useLocation();
|
||||
|
||||
const roleDenied = Boolean(
|
||||
@@ -31,12 +33,12 @@ export function ProtectedRoute({
|
||||
|
||||
useEffect(() => {
|
||||
if (roleDenied) {
|
||||
push('Accès refusé', 'error');
|
||||
push(t('auth.forbidden'), 'error');
|
||||
}
|
||||
}, [roleDenied, push]);
|
||||
}, [roleDenied, push, t]);
|
||||
|
||||
if (status === 'loading') {
|
||||
return <LoadingState label="Loading session…" />;
|
||||
return <LoadingState label={t('auth.loadingSession')} />;
|
||||
}
|
||||
|
||||
if (status === 'unauthenticated' || !user) {
|
||||
|
||||
Reference in New Issue
Block a user