Initial commit
This commit is contained in:
158
components/dashboard/ChantiersList.tsx
Normal file
158
components/dashboard/ChantiersList.tsx
Normal file
@@ -0,0 +1,158 @@
|
||||
/**
|
||||
* Composant liste des chantiers récents
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { Card } from 'primereact/card';
|
||||
import { DataTable } from 'primereact/datatable';
|
||||
import { Column } from 'primereact/column';
|
||||
import { Badge } from 'primereact/badge';
|
||||
import { Button } from 'primereact/button';
|
||||
import { Skeleton } from 'primereact/skeleton';
|
||||
import { ChantierRecent, StatutChantier } from '../../types/btp';
|
||||
|
||||
interface ChantiersListProps {
|
||||
chantiers: ChantierRecent[];
|
||||
loading?: boolean;
|
||||
onViewAll?: () => void;
|
||||
}
|
||||
|
||||
const ChantiersList: React.FC<ChantiersListProps> = ({
|
||||
chantiers,
|
||||
loading = false,
|
||||
onViewAll
|
||||
}) => {
|
||||
const getStatutSeverity = (statut: StatutChantier) => {
|
||||
switch (statut) {
|
||||
case StatutChantier.EN_COURS:
|
||||
return 'info';
|
||||
case StatutChantier.PLANIFIE:
|
||||
return 'warning';
|
||||
case StatutChantier.TERMINE:
|
||||
return 'success';
|
||||
case StatutChantier.ANNULE:
|
||||
return 'danger';
|
||||
case StatutChantier.SUSPENDU:
|
||||
return 'secondary';
|
||||
default:
|
||||
return 'info';
|
||||
}
|
||||
};
|
||||
|
||||
const getStatutLabel = (statut: StatutChantier) => {
|
||||
switch (statut) {
|
||||
case StatutChantier.EN_COURS:
|
||||
return 'En cours';
|
||||
case StatutChantier.PLANIFIE:
|
||||
return 'Planifié';
|
||||
case StatutChantier.TERMINE:
|
||||
return 'Terminé';
|
||||
case StatutChantier.ANNULE:
|
||||
return 'Annulé';
|
||||
case StatutChantier.SUSPENDU:
|
||||
return 'Suspendu';
|
||||
default:
|
||||
return statut;
|
||||
}
|
||||
};
|
||||
|
||||
const statutBodyTemplate = (rowData: ChantierRecent) => {
|
||||
return (
|
||||
<Badge
|
||||
value={getStatutLabel(rowData.statut)}
|
||||
severity={getStatutSeverity(rowData.statut)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const montantBodyTemplate = (rowData: ChantierRecent) => {
|
||||
return rowData.montantPrevu
|
||||
? `${rowData.montantPrevu.toLocaleString()} €`
|
||||
: '-';
|
||||
};
|
||||
|
||||
const dateBodyTemplate = (rowData: ChantierRecent) => {
|
||||
return new Date(rowData.dateDebut).toLocaleDateString('fr-FR');
|
||||
};
|
||||
|
||||
const header = (
|
||||
<div className="flex align-items-center justify-content-between">
|
||||
<h5 className="m-0">Chantiers récents</h5>
|
||||
{onViewAll && (
|
||||
<Button
|
||||
label="Voir tout"
|
||||
icon="pi pi-external-link"
|
||||
className="p-button-text p-button-sm"
|
||||
onClick={onViewAll}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<Card>
|
||||
<div className="flex align-items-center justify-content-between mb-3">
|
||||
<Skeleton width="8rem" height="1.5rem" />
|
||||
<Skeleton width="5rem" height="2rem" />
|
||||
</div>
|
||||
<div className="space-y-3">
|
||||
{[...Array(5)].map((_, i) => (
|
||||
<div key={i} className="flex align-items-center justify-content-between p-3 border-1 border-200 border-round">
|
||||
<div className="flex-1">
|
||||
<Skeleton width="60%" height="1rem" className="mb-2" />
|
||||
<Skeleton width="40%" height="0.8rem" />
|
||||
</div>
|
||||
<Skeleton width="5rem" height="1.5rem" />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<DataTable
|
||||
value={chantiers}
|
||||
header={header}
|
||||
responsiveLayout="scroll"
|
||||
showHeaders={false}
|
||||
emptyMessage="Aucun chantier récent"
|
||||
className="p-datatable-sm"
|
||||
>
|
||||
<Column
|
||||
field="nom"
|
||||
header="Nom"
|
||||
style={{ width: '35%' }}
|
||||
body={(rowData: ChantierRecent) => (
|
||||
<div>
|
||||
<div className="font-medium text-900">{rowData.nom}</div>
|
||||
<div className="text-500 text-sm">{rowData.client}</div>
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
<Column
|
||||
field="statut"
|
||||
header="Statut"
|
||||
style={{ width: '25%' }}
|
||||
body={statutBodyTemplate}
|
||||
/>
|
||||
<Column
|
||||
field="dateDebut"
|
||||
header="Date"
|
||||
style={{ width: '20%' }}
|
||||
body={dateBodyTemplate}
|
||||
/>
|
||||
<Column
|
||||
field="montantPrevu"
|
||||
header="Montant"
|
||||
style={{ width: '20%' }}
|
||||
body={montantBodyTemplate}
|
||||
/>
|
||||
</DataTable>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
export default ChantiersList;
|
||||
Reference in New Issue
Block a user