fix: fix mobile features, like missing setting pages and items sizes
This commit is contained in:
@ -20,7 +20,7 @@ func GenerateToken(userID, email, role, secret string) (string, error) {
|
||||
Email: email,
|
||||
Role: role,
|
||||
RegisteredClaims: jwt.RegisteredClaims{
|
||||
ExpiresAt: jwt.NewNumericDate(time.Now().Add(24 * time.Hour)),
|
||||
ExpiresAt: jwt.NewNumericDate(time.Now().Add(7 * 24 * time.Hour)),
|
||||
IssuedAt: jwt.NewNumericDate(time.Now()),
|
||||
},
|
||||
}
|
||||
|
||||
@ -14,6 +14,12 @@ async function request<T>(path: string, options: RequestInit = {}): Promise<T> {
|
||||
...options.headers,
|
||||
},
|
||||
})
|
||||
if (res.status === 401) {
|
||||
localStorage.removeItem('token')
|
||||
localStorage.removeItem('user')
|
||||
window.location.href = '/login'
|
||||
throw new Error('Session expirée')
|
||||
}
|
||||
if (!res.ok) {
|
||||
const err = await res.json().catch(() => ({ error: res.statusText }))
|
||||
throw new Error(err.error || res.statusText)
|
||||
|
||||
@ -37,3 +37,8 @@
|
||||
::-webkit-scrollbar { width: 6px; height: 6px; }
|
||||
::-webkit-scrollbar-track { @apply bg-muted; }
|
||||
::-webkit-scrollbar-thumb { @apply bg-border rounded-full; }
|
||||
|
||||
@layer utilities {
|
||||
.scrollbar-none { scrollbar-width: none; }
|
||||
.scrollbar-none::-webkit-scrollbar { display: none; }
|
||||
}
|
||||
|
||||
@ -1,12 +1,47 @@
|
||||
import { Outlet, Navigate } from 'react-router-dom'
|
||||
import { NavLink, Outlet, Navigate } from 'react-router-dom'
|
||||
import { Cpu, Key, Database, ClipboardList, Users, CalendarDays, Settings } from 'lucide-react'
|
||||
import { useAuth } from '@/lib/auth'
|
||||
import { cn } from '@/lib/cn'
|
||||
|
||||
const adminItems = [
|
||||
{ to: '/admin/ai', icon: Cpu, label: 'Fournisseurs IA' },
|
||||
{ to: '/admin/credentials', icon: Key, label: 'Identifiants' },
|
||||
{ to: '/admin/sources', icon: Database, label: 'Sources' },
|
||||
{ to: '/admin/jobs', icon: ClipboardList,label: 'Jobs' },
|
||||
{ to: '/admin/users', icon: Users, label: 'Utilisateurs' },
|
||||
{ to: '/admin/schedule', icon: CalendarDays, label: 'Planning' },
|
||||
{ to: '/admin/settings', icon: Settings, label: 'Paramètres' },
|
||||
]
|
||||
|
||||
export function AdminLayout() {
|
||||
const { isAdmin } = useAuth()
|
||||
if (!isAdmin) return <Navigate to="/" replace />
|
||||
return (
|
||||
<div>
|
||||
{/* Mobile sub-nav — scrollable horizontal tabs */}
|
||||
<nav className="md:hidden flex overflow-x-auto border-b bg-card scrollbar-none sticky top-0 z-10">
|
||||
{adminItems.map(({ to, icon: Icon, label }) => (
|
||||
<NavLink
|
||||
key={to}
|
||||
to={to}
|
||||
className={({ isActive }) =>
|
||||
cn(
|
||||
'flex shrink-0 flex-col items-center gap-1 px-4 py-3 text-xs font-medium transition-colors border-b-2',
|
||||
isActive
|
||||
? 'border-primary text-primary'
|
||||
: 'border-transparent text-muted-foreground'
|
||||
)
|
||||
}
|
||||
>
|
||||
<Icon className="h-4 w-4" />
|
||||
{label}
|
||||
</NavLink>
|
||||
))}
|
||||
</nav>
|
||||
|
||||
<div className="p-6">
|
||||
<Outlet />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@ -34,12 +34,12 @@ export function Sources() {
|
||||
<div className="space-y-3">
|
||||
{sources.map(s => (
|
||||
<Card key={s.id}>
|
||||
<CardContent className="flex items-center justify-between py-4">
|
||||
<CardContent className="flex flex-col gap-3 py-4 sm:flex-row sm:items-center sm:justify-between">
|
||||
<div>
|
||||
<span className="font-semibold">{s.name}</span>
|
||||
<span className="ml-2 text-xs text-muted-foreground capitalize">({s.type})</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="flex items-center gap-2">
|
||||
<Badge variant={s.enabled ? 'default' : 'outline'}>
|
||||
{s.enabled ? 'Activée' : 'Désactivée'}
|
||||
</Badge>
|
||||
|
||||
Reference in New Issue
Block a user