86 lines
6.0 KiB
React
86 lines
6.0 KiB
React
import { useLocation, useNavigate } from 'react-router-dom';
|
|
import { useAuth } from '../context/AuthContext.jsx';
|
|
import UsersSection from './admin/UsersSection.jsx';
|
|
import AuditLogsSection from './admin/AuditLogsSection.jsx';
|
|
import JobLogsSection from './admin/JobLogsSection.jsx';
|
|
import IconsSection from './admin/IconsSection.jsx';
|
|
import SmtpSection from './admin/SmtpSection.jsx';
|
|
import GeneralSection from './admin/GeneralSection.jsx';
|
|
|
|
/* ── Icônes nav ───────────────────────────────────────────────── */
|
|
function IconUsers() { return <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>; }
|
|
function IconActivity() { return <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"><polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/></svg>; }
|
|
function IconShield() { return <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>; }
|
|
function IconImage() { return <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"><rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="8.5" cy="8.5" r="1.5"/><polyline points="21 15 16 10 5 21"/></svg>; }
|
|
function IconTax() { return <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/><polyline points="10 9 9 9 8 9"/></svg>; }
|
|
function IconDatabase() { return <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"><ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M21 12c0 1.66-4 3-9 3s-9-1.34-9-3"/><path d="M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5"/></svg>; }
|
|
function IconSettings() { return <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 1 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 1 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 1 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 1 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg>; }
|
|
function IconMail() { return <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg>; }
|
|
|
|
const NAV = [
|
|
{
|
|
group: 'Administration de la plateforme',
|
|
items: [
|
|
{ id: 'general', label: 'Général', icon: <IconSettings /> },
|
|
{ id: 'users', label: 'Utilisateurs', icon: <IconUsers /> },
|
|
{ id: 'audit-logs', label: 'Audit', icon: <IconShield /> },
|
|
{ id: 'job-logs', label: 'Logs des jobs', icon: <IconActivity /> },
|
|
{ id: 'icons', label: "Bibliothèque d'icônes", icon: <IconImage /> },
|
|
],
|
|
},
|
|
{
|
|
group: 'Référentiels',
|
|
items: [
|
|
{ id: 'plateformes', label: 'Plateformes', icon: <IconDatabase />, href: '/admin/plateformes' },
|
|
{ id: 'fiscalite', label: 'Fiscalité', icon: <IconTax />, href: '/admin/fiscalite' },
|
|
],
|
|
},
|
|
{
|
|
group: 'Notifications',
|
|
items: [
|
|
{ id: 'smtp', label: 'SMTP', icon: <IconMail /> },
|
|
],
|
|
},
|
|
];
|
|
|
|
export default function Admin() {
|
|
const { search } = useLocation();
|
|
const navigate = useNavigate();
|
|
const { user } = useAuth();
|
|
|
|
const section = new URLSearchParams(search).get('section') || 'users';
|
|
|
|
if (!user) return null;
|
|
|
|
return (
|
|
<div className="account-layout">
|
|
<aside className="account-sidebar">
|
|
<h1 className="account-title">Administration</h1>
|
|
{NAV.map(group => (
|
|
<div key={group.group} className="account-nav-group">
|
|
<span className="account-nav-label">{group.group}</span>
|
|
{group.items.map(item => (
|
|
<button
|
|
key={item.id}
|
|
className={`account-nav-item${section === item.id ? ' active' : ''}`}
|
|
onClick={() => item.href ? navigate(item.href) : navigate(`/admin?section=${item.id}`, { replace: true })}
|
|
>
|
|
{item.icon}
|
|
{item.label}
|
|
</button>
|
|
))}
|
|
</div>
|
|
))}
|
|
</aside>
|
|
<div className="account-content">
|
|
{section === 'general' && <GeneralSection />}
|
|
{section === 'users' && <UsersSection currentUserId={user?.id} />}
|
|
{section === 'audit-logs' && <AuditLogsSection />}
|
|
{section === 'job-logs' && <JobLogsSection />}
|
|
{section === 'icons' && <IconsSection />}
|
|
{section === 'smtp' && <SmtpSection />}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|