64 lines
2.4 KiB
React
64 lines
2.4 KiB
React
|
|
import React, { useEffect, useState } from 'react';
|
||
|
|
import { useStore } from '../stores/store';
|
||
|
|
import { api } from '../stores/api';
|
||
|
|
|
||
|
|
export default function JournalActions() {
|
||
|
|
const { setPage } = useStore();
|
||
|
|
const [actions, setActions] = useState([]);
|
||
|
|
const [loading, setLoading] = useState(true);
|
||
|
|
const [error, setError] = useState('');
|
||
|
|
|
||
|
|
useEffect(() => {
|
||
|
|
api.get('/journal/actions?limite=100')
|
||
|
|
.then(setActions)
|
||
|
|
.catch((e) => setError(e.message))
|
||
|
|
.finally(() => setLoading(false));
|
||
|
|
}, []);
|
||
|
|
|
||
|
|
const formatDate = (value) => new Date(value).toLocaleString('fr-CA', {
|
||
|
|
dateStyle: 'medium',
|
||
|
|
timeStyle: 'short',
|
||
|
|
});
|
||
|
|
|
||
|
|
return (
|
||
|
|
<div className="min-h-screen bg-gray-100">
|
||
|
|
<div className="bg-aa-blue text-white p-4 flex items-center gap-3">
|
||
|
|
<button onClick={() => setPage('accueil')} className="text-2xl">←</button>
|
||
|
|
<div>
|
||
|
|
<h1 className="text-lg font-bold">Journal</h1>
|
||
|
|
<p className="text-sm text-blue-100">Changements enregistrés</p>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div className="p-4 space-y-3">
|
||
|
|
{loading && <p className="text-gray-500 text-center py-8">Chargement...</p>}
|
||
|
|
{error && <div className="bg-red-50 text-red-600 p-3 rounded-xl text-sm">{error}</div>}
|
||
|
|
{!loading && actions.length === 0 && (
|
||
|
|
<p className="text-gray-500 text-center py-8">Aucun changement journalisé.</p>
|
||
|
|
)}
|
||
|
|
{actions.map((action) => (
|
||
|
|
<div key={action.id} className="bg-white rounded-2xl p-4 shadow-sm">
|
||
|
|
<div className="flex items-start justify-between gap-3">
|
||
|
|
<div>
|
||
|
|
<p className="font-bold text-gray-800">{action.methode} {action.chemin}</p>
|
||
|
|
<p className="text-xs text-gray-400 mt-1">{formatDate(action.cree_le)}</p>
|
||
|
|
</div>
|
||
|
|
<span className="text-xs font-bold rounded-full bg-gray-100 text-gray-600 px-2 py-1">
|
||
|
|
{action.statut_http}
|
||
|
|
</span>
|
||
|
|
</div>
|
||
|
|
<div className="mt-3 text-xs text-gray-500 space-y-1">
|
||
|
|
<p>Membre: {action.membre_id}</p>
|
||
|
|
{action.admin_id && <p>Admin: {action.admin_id}</p>}
|
||
|
|
{action.adresse_ip && <p>IP: {action.adresse_ip}</p>}
|
||
|
|
{action.details?.impersonification && (
|
||
|
|
<p className="text-amber-700 font-medium">Action faite en impersonification</p>
|
||
|
|
)}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
))}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|