feat: composant SyncHistory
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
'use client'
|
||||
import { useState } from 'react'
|
||||
import React from 'react'
|
||||
import type { SyncHistoryEntry } from '@/types/sync'
|
||||
|
||||
interface SyncHistoryProps {
|
||||
entries: SyncHistoryEntry[]
|
||||
}
|
||||
|
||||
const STATUS_STYLE = {
|
||||
success: 'text-green-400',
|
||||
partial: 'text-yellow-400',
|
||||
error: 'text-red-400',
|
||||
}
|
||||
|
||||
export function SyncHistory({ entries }: SyncHistoryProps) {
|
||||
const [expandedId, setExpandedId] = useState<string | null>(null)
|
||||
|
||||
if (entries.length === 0) {
|
||||
return <p className="text-slate-600 text-sm text-center py-6">Aucune synchronisation effectuée.</p>
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="border border-slate-700 rounded-xl overflow-hidden">
|
||||
<table className="w-full text-xs">
|
||||
<thead className="bg-slate-800 text-slate-400">
|
||||
<tr>
|
||||
<th className="px-3 py-2 text-left">Date</th>
|
||||
<th className="px-3 py-2 text-left">Utilisateur</th>
|
||||
<th className="px-3 py-2 text-right">Créés</th>
|
||||
<th className="px-3 py-2 text-right">MàJ</th>
|
||||
<th className="px-3 py-2 text-right">Désactivés</th>
|
||||
<th className="px-3 py-2 text-right">Erreurs</th>
|
||||
<th className="px-3 py-2 text-left">Statut</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{entries.map((entry) => (
|
||||
<React.Fragment key={entry.id}>
|
||||
<tr
|
||||
onClick={() => setExpandedId(expandedId === entry.id ? null : entry.id)}
|
||||
className="border-t border-slate-800 hover:bg-slate-800/50 cursor-pointer"
|
||||
>
|
||||
<td className="px-3 py-2 text-slate-400">
|
||||
{new Date(entry.createdAt).toLocaleString('fr-FR', {
|
||||
day: '2-digit', month: '2-digit', year: '2-digit',
|
||||
hour: '2-digit', minute: '2-digit',
|
||||
})}
|
||||
</td>
|
||||
<td className="px-3 py-2 text-slate-300">{entry.userName}</td>
|
||||
<td className="px-3 py-2 text-right text-green-400">{entry.created}</td>
|
||||
<td className="px-3 py-2 text-right text-blue-400">{entry.updated}</td>
|
||||
<td className="px-3 py-2 text-right text-red-400">{entry.deactivated}</td>
|
||||
<td className="px-3 py-2 text-right text-yellow-400">{entry.errors || '—'}</td>
|
||||
<td className={`px-3 py-2 font-semibold ${STATUS_STYLE[entry.status]}`}>
|
||||
{entry.status}
|
||||
</td>
|
||||
</tr>
|
||||
{expandedId === entry.id && (
|
||||
<tr className="border-t border-slate-800 bg-slate-950">
|
||||
<td colSpan={7} className="px-3 py-3">
|
||||
<div className="font-mono text-xs max-h-32 overflow-y-auto space-y-0.5">
|
||||
{entry.log.map((l, i) => (
|
||||
<p key={i} className={l.status === 'error' ? 'text-red-400' : 'text-slate-400'}>
|
||||
{l.message}
|
||||
</p>
|
||||
))}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
</React.Fragment>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user