'use client' import { useEffect, useMemo, useState } from 'react' import { Badge } from '@/components/ui/badge' import { Button } from '@/components/ui/button' import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger, } from '@/components/ui/dialog' import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select' import { Switch } from '@/components/ui/switch' import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from '@/components/ui/table' import { ScrollArea } from '@/components/ui/scroll-area' import { Plus, Search, Shield, Trash2, UserCog, Users } from 'lucide-react' type RoleEmploye = 'VENDEUR' | 'RESPONSABLE' | 'ADMIN' interface Employee { id: string email: string nom: string prenom: string role: RoleEmploye actif: boolean createdAt: string updatedAt: string _count?: { ventes: number facturesAchat: number paiements: number patients: number } } const roleLabels: Record = { VENDEUR: 'Vendeur', RESPONSABLE: 'Responsable', ADMIN: 'Administrateur', } const emptyForm = { email: '', nom: '', prenom: '', role: 'VENDEUR' as RoleEmploye, actif: true, password: '', } export function EmployeeManagement() { const [employees, setEmployees] = useState([]) const [searchTerm, setSearchTerm] = useState('') const [statusFilter, setStatusFilter] = useState<'all' | 'active' | 'inactive'>('all') const [loading, setLoading] = useState(true) const [saving, setSaving] = useState(false) const [error, setError] = useState('') const [dialogOpen, setDialogOpen] = useState(false) const [editingEmployee, setEditingEmployee] = useState(null) const [form, setForm] = useState(emptyForm) useEffect(() => { fetchEmployees() }, []) const filteredEmployees = useMemo(() => { const term = searchTerm.toLowerCase() return employees.filter((employee) => { const matchesSearch = !term || employee.nom.toLowerCase().includes(term) || employee.prenom.toLowerCase().includes(term) || employee.email.toLowerCase().includes(term) || roleLabels[employee.role].toLowerCase().includes(term) const matchesStatus = statusFilter === 'all' || (statusFilter === 'active' && employee.actif) || (statusFilter === 'inactive' && !employee.actif) return matchesSearch && matchesStatus }) }, [employees, searchTerm, statusFilter]) const activeCount = employees.filter((employee) => employee.actif).length const adminCount = employees.filter((employee) => employee.actif && employee.role === 'ADMIN').length async function fetchEmployees() { setLoading(true) setError('') try { const response = await fetch('/api/employes') const data = await response.json() if (!response.ok) { throw new Error(data.error || 'Erreur lors du chargement des employes') } setEmployees(data) } catch (err) { setError(err instanceof Error ? err.message : 'Erreur inconnue') } finally { setLoading(false) } } function openCreateDialog() { setEditingEmployee(null) setForm(emptyForm) setError('') setDialogOpen(true) } function openEditDialog(employee: Employee) { setEditingEmployee(employee) setForm({ email: employee.email, nom: employee.nom, prenom: employee.prenom, role: employee.role, actif: employee.actif, password: '', }) setError('') setDialogOpen(true) } async function saveEmployee(event: React.FormEvent) { event.preventDefault() setSaving(true) setError('') try { const payload: Record = { email: form.email, nom: form.nom, prenom: form.prenom, role: form.role, actif: form.actif, } if (form.password) { payload.password = form.password } const response = await fetch( editingEmployee ? `/api/employes/${editingEmployee.id}` : '/api/employes', { method: editingEmployee ? 'PUT' : 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload), } ) const data = await response.json() if (!response.ok) { throw new Error(data.error || 'Enregistrement impossible') } setDialogOpen(false) setEditingEmployee(null) setForm(emptyForm) await fetchEmployees() } catch (err) { setError(err instanceof Error ? err.message : 'Erreur inconnue') } finally { setSaving(false) } } async function deleteEmployee(employee: Employee) { if (!confirm(`Supprimer ou desactiver ${employee.prenom} ${employee.nom} ?`)) return setError('') const response = await fetch(`/api/employes/${employee.id}`, { method: 'DELETE' }) const data = await response.json() if (!response.ok) { setError(data.error || 'Suppression impossible') return } await fetchEmployees() } return (

Utilisateurs et acces

Gere les employes, leur statut et leur niveau d'acces.

{editingEmployee ? 'Modifier un employe' : 'Nouvel employe'} Les administrateurs peuvent gerer les utilisateurs et les acces.
setForm({ ...form, prenom: event.target.value })} required />
setForm({ ...form, nom: event.target.value })} required />
setForm({ ...form, email: event.target.value })} required />
setForm({ ...form, password: event.target.value })} required={!editingEmployee} placeholder={editingEmployee ? 'Laisser vide pour conserver' : ''} />

Autorise la connexion

setForm({ ...form, actif: checked })} />
{error &&

{error}

}

Total

{employees.length}

Comptes actifs

{activeCount}

Administrateurs

{adminCount}

{error && !dialogOpen &&

{error}

} Recherche et filtres
setSearchTerm(event.target.value)} className="pl-10" />
Employe Acces Statut Activite liee Actions {loading ? ( Chargement... ) : filteredEmployees.length === 0 ? ( Aucun employe trouve ) : ( filteredEmployees.map((employee) => (
{employee.prenom} {employee.nom}
{employee.email}
{roleLabels[employee.role]} {employee.actif ? 'Actif' : 'Inactif'} {(employee._count?.ventes || 0) + (employee._count?.facturesAchat || 0)} operations
)) )}
) }