import { useEffect, useRef, useState } from 'react' import { getEmployeesApi, getEmployeeDeliveriesApi, getDeliveryByTicketCodeApi } from '../../services/admin' const STATUS_BADGES = { DELIVERED: { label: 'Lot remis', className: 'bg-green-100 text-green-700' }, PENDING: { label: 'En attente de retrait', className: 'bg-amber-100 text-amber-700' }, CANCELLED: { label: 'Expiré', className: 'bg-gray-200 text-gray-700' }, NOT_PLAYED: { label: 'Pas encore joué', className: 'bg-gray-100 text-gray-600' }, } const INPUT_CLASS = 'w-full border border-gray-200 rounded-lg px-3 py-2 text-sm text-gray-700 bg-white focus:outline-none focus:ring-1 focus:ring-[#006B6B] focus:border-[#006B6B]' const BUTTON_CLASS = 'bg-[#006B6B] hover:bg-[#005959] disabled:opacity-50 text-white font-semibold px-4 py-2 rounded-lg transition-colors text-xs sm:text-sm' function formatDateTime(dateStr) { return new Date(dateStr).toLocaleString('fr-FR', { day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit', }) } const fullName = (person) => `${person.firstname} ${person.lastname}` // Traçabilité des remises de lots : liste des employés, lots remis par chacun, // et recherche inverse par numéro de ticket. // `refreshKey` change quand un employé est créé, pour recharger la liste. export default function EmployeeDeliveries({ refreshKey, onAuthError }) { const [employees, setEmployees] = useState(null) const [employeesError, setEmployeesError] = useState('') const [filter, setFilter] = useState('') const [selected, setSelected] = useState(null) const [deliveries, setDeliveries] = useState(null) const [deliveriesLoading, setDeliveriesLoading] = useState(false) const [deliveriesError, setDeliveriesError] = useState('') const detailRef = useRef(null) const [ticketCode, setTicketCode] = useState('') const [ticketResult, setTicketResult] = useState(null) const [ticketLoading, setTicketLoading] = useState(false) const [ticketError, setTicketError] = useState('') useEffect(() => { getEmployeesApi() .then((data) => { setEmployees(data.employees) setEmployeesError('') }) .catch((err) => { if (!onAuthError(err)) setEmployeesError(err.message) }) }, [refreshKey, onAuthError]) const openEmployee = async (employee) => { setSelected(employee) setDeliveries(null) setDeliveriesError('') setDeliveriesLoading(true) try { const data = await getEmployeeDeliveriesApi(employee.id) setDeliveries(data.deliveries) } catch (err) { if (!onAuthError(err)) setDeliveriesError(err.message) } finally { setDeliveriesLoading(false) detailRef.current?.scrollIntoView({ behavior: 'smooth', block: 'nearest' }) } } const handleTicketSearch = async (e) => { e.preventDefault() setTicketError('') setTicketResult(null) setTicketLoading(true) try { setTicketResult(await getDeliveryByTicketCodeApi(ticketCode)) } catch (err) { if (!onAuthError(err)) setTicketError(err.message) } finally { setTicketLoading(false) } } const needle = filter.trim().toLowerCase() const visibleEmployees = (employees ?? []).filter((employee) => !needle || `${fullName(employee)} ${employee.email}`.toLowerCase().includes(needle) ) return (

Employés et remises des lots

Retrouvez quel employé a remis un lot et à quelle date, par numéro de ticket ou par employé.

{/* ── Recherche par numéro de ticket ── */}
setTicketCode(e.target.value)} required placeholder="Ex. A1B2C3D4E5" className={`${INPUT_CLASS} uppercase placeholder:normal-case`} />
{ticketError &&

{ticketError}

} {ticketResult && (

{ticketResult.ticketCode}

{STATUS_BADGES[ticketResult.status]?.label ?? ticketResult.status}

Lot : {ticketResult.lot.name}

{ticketResult.client && (

Gagné par : {fullName(ticketResult.client)}{' '} ({ticketResult.client.email}) {ticketResult.playedAt && <> le {formatDateTime(ticketResult.playedAt)}}

)} {ticketResult.deliveredBy ? (

Remis par :{' '} {' '} le {formatDateTime(ticketResult.deliveredAt)}

) : ( ticketResult.status !== 'NOT_PLAYED' && (

Ce lot n'a pas encore été remis.

) )}
)}
{/* ── Liste des employés ── */}

Comptes employés {employees && - {employees.length}}

setFilter(e.target.value)} placeholder="Rechercher un employé…" className={INPUT_CLASS} />
{employeesError &&

{employeesError}

} {!employees && !employeesError &&

Chargement…

} {employees && (
{visibleEmployees.length === 0 && ( )} {visibleEmployees.map((employee) => ( ))}
Nom Email Créé le Lots remis
{employees.length === 0 ? "Aucun compte employé pour l'instant" : 'Aucun employé ne correspond à la recherche'}
{employee.mustChangePassword && ( Première connexion en attente )} {employee.email} {new Date(employee.createdAt).toLocaleDateString('fr-FR')} {employee.deliveredCount}
)}
{/* ── Lots remis par l'employé sélectionné ── */} {selected && (

Lots remis par {fullName(selected)} {deliveries && — {deliveries.length}}

{deliveriesLoading &&

Chargement…

} {deliveriesError &&

{deliveriesError}

} {deliveries && (
{deliveries.length === 0 && ( )} {deliveries.map((delivery) => ( ))}
Ticket Lot Client Remis le
Cet employé n'a encore remis aucun lot
{delivery.ticketCode} {delivery.lot.name} {fullName(delivery.client)} {delivery.client.email} {formatDateTime(delivery.deliveredAt)}
)}
)}
) }