'use client'; export const dynamic = 'force-dynamic'; import React, { useState, useEffect, useRef } from 'react'; import { Card } from 'primereact/card'; import { Button } from 'primereact/button'; import { DataTable } from 'primereact/datatable'; import { Column } from 'primereact/column'; import { Toast } from 'primereact/toast'; import { Toolbar } from 'primereact/toolbar'; import { TabView, TabPanel } from 'primereact/tabview'; import { InputText } from 'primereact/inputtext'; import { Dialog } from 'primereact/dialog'; import { Dropdown } from 'primereact/dropdown'; import { InputTextarea } from 'primereact/inputtextarea'; import { Tag } from 'primereact/tag'; import { ToggleButton } from 'primereact/togglebutton'; import { Panel } from 'primereact/panel'; import { Divider } from 'primereact/divider'; import { Password } from 'primereact/password'; import { Checkbox } from 'primereact/checkbox'; import { Calendar } from 'primereact/calendar'; import { InputNumber } from 'primereact/inputnumber'; import { Badge } from 'primereact/badge'; import { formatDate } from '../../../utils/formatters'; interface User { id: string; nom: string; prenom: string; email: string; telephone: string; role: 'ADMIN' | 'USER' | 'VIEWER'; actif: boolean; derniereConnexion: Date; dateCreation: Date; permissions: string[]; } interface SystemLog { id: string; timestamp: Date; niveau: 'INFO' | 'WARNING' | 'ERROR'; message: string; utilisateur: string; module: string; action: string; } interface SystemConfig { id: string; cle: string; valeur: string; description: string; type: 'string' | 'number' | 'boolean' | 'date'; modifiable: boolean; categorie: string; } const AdministrationPage = () => { const [users, setUsers] = useState([]); const [logs, setLogs] = useState([]); const [config, setConfig] = useState([]); const [loading, setLoading] = useState(true); const [activeIndex, setActiveIndex] = useState(0); const [globalFilter, setGlobalFilter] = useState(''); const [userDialog, setUserDialog] = useState(false); const [configDialog, setConfigDialog] = useState(false); const [deleteUserDialog, setDeleteUserDialog] = useState(false); const [user, setUser] = useState({ id: '', nom: '', prenom: '', email: '', telephone: '', role: 'USER', actif: true, derniereConnexion: new Date(), dateCreation: new Date(), permissions: [] }); const [configItem, setConfigItem] = useState({ id: '', cle: '', valeur: '', description: '', type: 'string', modifiable: true, categorie: 'general' }); const [submitted, setSubmitted] = useState(false); const [password, setPassword] = useState(''); const [confirmPassword, setConfirmPassword] = useState(''); const toast = useRef(null); const dt = useRef>(null); const roles = [ { label: 'Administrateur', value: 'ADMIN' }, { label: 'Utilisateur', value: 'USER' }, { label: 'Lecture seule', value: 'VIEWER' } ]; const configTypes = [ { label: 'Texte', value: 'string' }, { label: 'Nombre', value: 'number' }, { label: 'Booléen', value: 'boolean' }, { label: 'Date', value: 'date' } ]; const configCategories = [ { label: 'Général', value: 'general' }, { label: 'Sécurité', value: 'security' }, { label: 'Email', value: 'email' }, { label: 'Sauvegarde', value: 'backup' }, { label: 'Performance', value: 'performance' } ]; const availablePermissions = [ 'clients.read', 'clients.write', 'clients.delete', 'chantiers.read', 'chantiers.write', 'chantiers.delete', 'devis.read', 'devis.write', 'devis.delete', 'factures.read', 'factures.write', 'factures.delete', 'stock.read', 'stock.write', 'stock.delete', 'rapports.read', 'administration.read', 'administration.write' ]; useEffect(() => { loadData(); }, []); const loadData = async () => { try { setLoading(true); // Simulation de données const mockUsers: User[] = [ { id: '1', nom: 'Admin', prenom: 'BTP Xpress', email: 'admin@btpxpress.com', telephone: '06 12 34 56 78', role: 'ADMIN', actif: true, derniereConnexion: new Date(), dateCreation: new Date('2024-01-01'), permissions: availablePermissions }, { id: '2', nom: 'Dupont', prenom: 'Jean', email: 'jean.dupont@btpxpress.com', telephone: '06 98 76 54 32', role: 'USER', actif: true, derniereConnexion: new Date(Date.now() - 3600000), // 1 heure dateCreation: new Date('2024-02-01'), permissions: ['clients.read', 'clients.write', 'chantiers.read', 'chantiers.write'] } ]; const mockLogs: SystemLog[] = [ { id: '1', timestamp: new Date(), niveau: 'INFO', message: 'Utilisateur connecté', utilisateur: 'admin@btpxpress.com', module: 'Auth', action: 'LOGIN' }, { id: '2', timestamp: new Date(Date.now() - 600000), // 10 minutes niveau: 'INFO', message: 'Nouveau client créé', utilisateur: 'jean.dupont@btpxpress.com', module: 'Clients', action: 'CREATE' }, { id: '3', timestamp: new Date(Date.now() - 1800000), // 30 minutes niveau: 'WARNING', message: 'Tentative de connexion échouée', utilisateur: 'unknown@email.com', module: 'Auth', action: 'LOGIN_FAILED' } ]; const mockConfig: SystemConfig[] = [ { id: '1', cle: 'app.name', valeur: 'BTP Xpress', description: 'Nom de l\'application', type: 'string', modifiable: true, categorie: 'general' }, { id: '2', cle: 'app.version', valeur: '1.0.0', description: 'Version de l\'application', type: 'string', modifiable: false, categorie: 'general' }, { id: '3', cle: 'auth.session_timeout', valeur: '3600', description: 'Durée de session en secondes', type: 'number', modifiable: true, categorie: 'security' }, { id: '4', cle: 'email.smtp_enabled', valeur: 'true', description: 'Activation du serveur SMTP', type: 'boolean', modifiable: true, categorie: 'email' } ]; setUsers(mockUsers); setLogs(mockLogs); setConfig(mockConfig); } catch (error) { console.error('Erreur lors du chargement des données:', error); toast.current?.show({ severity: 'error', summary: 'Erreur', detail: 'Impossible de charger les données', life: 3000 }); } finally { setLoading(false); } }; const openNewUser = () => { setUser({ id: '', nom: '', prenom: '', email: '', telephone: '', role: 'USER', actif: true, derniereConnexion: new Date(), dateCreation: new Date(), permissions: [] }); setPassword(''); setConfirmPassword(''); setSubmitted(false); setUserDialog(true); }; const editUser = (user: User) => { setUser({ ...user }); setPassword(''); setConfirmPassword(''); setUserDialog(true); }; const confirmDeleteUser = (user: User) => { setUser(user); setDeleteUserDialog(true); }; const deleteUser = () => { const updatedUsers = users.filter(u => u.id !== user.id); setUsers(updatedUsers); setDeleteUserDialog(false); toast.current?.show({ severity: 'success', summary: 'Succès', detail: 'Utilisateur supprimé', life: 3000 }); }; const saveUser = () => { setSubmitted(true); if (user.nom.trim() && user.prenom.trim() && user.email.trim()) { if (!user.id && (!password || password !== confirmPassword)) { toast.current?.show({ severity: 'error', summary: 'Erreur', detail: 'Mot de passe requis et doit correspondre', life: 3000 }); return; } let updatedUsers = [...users]; if (user.id) { // Mise à jour const index = users.findIndex(u => u.id === user.id); updatedUsers[index] = user; toast.current?.show({ severity: 'success', summary: 'Succès', detail: 'Utilisateur mis à jour', life: 3000 }); } else { // Création const newUser = { ...user, id: Date.now().toString(), dateCreation: new Date() }; updatedUsers.push(newUser); toast.current?.show({ severity: 'success', summary: 'Succès', detail: 'Utilisateur créé', life: 3000 }); } setUsers(updatedUsers); setUserDialog(false); } }; const editConfig = (config: SystemConfig) => { setConfigItem({ ...config }); setConfigDialog(true); }; const saveConfig = () => { const updatedConfig = config.map(c => c.id === configItem.id ? configItem : c ); setConfig(updatedConfig); setConfigDialog(false); toast.current?.show({ severity: 'success', summary: 'Succès', detail: 'Configuration mise à jour', life: 3000 }); }; const onInputChange = (e: React.ChangeEvent, name: string) => { const val = (e.target && e.target.value) || ''; let _user = { ...user }; (_user as any)[name] = val; setUser(_user); }; const onDropdownChange = (e: any, name: string) => { let _user = { ...user }; (_user as any)[name] = e.value; setUser(_user); }; const onPermissionChange = (e: any, permission: string) => { let _user = { ...user }; if (e.checked) { _user.permissions = [..._user.permissions, permission]; } else { _user.permissions = _user.permissions.filter(p => p !== permission); } setUser(_user); }; const onConfigInputChange = (e: React.ChangeEvent, name: string) => { const val = (e.target && e.target.value) || ''; let _config = { ...configItem }; (_config as any)[name] = val; setConfigItem(_config); }; const leftToolbarTemplate = () => { return (
); }; const rightToolbarTemplate = () => { return ( setGlobalFilter(e.currentTarget.value)} /> ); }; const actionBodyTemplate = (rowData: User) => { return (
); }; const statusBodyTemplate = (rowData: User) => { return ( ); }; const roleBodyTemplate = (rowData: User) => { const roleLabels = { 'ADMIN': 'Administrateur', 'USER': 'Utilisateur', 'VIEWER': 'Lecture seule' }; return roleLabels[rowData.role] || rowData.role; }; const logLevelBodyTemplate = (rowData: SystemLog) => { const getSeverity = (level: string) => { switch (level) { case 'INFO': return 'info'; case 'WARNING': return 'warning'; case 'ERROR': return 'danger'; default: return 'info'; } }; return ( ); }; const configActionBodyTemplate = (rowData: SystemConfig) => { return (