diff --git a/app/api/dashboard/stats/route.ts b/app/api/dashboard/stats/route.ts index 8ae2085..5a72b30 100644 --- a/app/api/dashboard/stats/route.ts +++ b/app/api/dashboard/stats/route.ts @@ -2,6 +2,159 @@ import { NextRequest, NextResponse } from 'next/server'; import { prisma } from '@/lib/prisma'; import { getCurrentUser } from '@/lib/auth'; +// Types de période: day | 7days | 30days | month | quarter | year +// Ou plage personnalisée via from & to (format ISO) +function getDateRange(period: string | null, from: string | null, to: string | null): { + start: Date; + end: Date; + prevStart: Date; + prevEnd: Date; + periodLabel: string; +} { + const now = new Date(); + const endOfDay = (d: Date) => new Date(d.getFullYear(), d.getMonth(), d.getDate(), 23, 59, 59, 999); + const startOfDay = (d: Date) => new Date(d.getFullYear(), d.getMonth(), d.getDate()); + + if (from && to) { + const start = new Date(from); + const end = endOfDay(new Date(to)); + const diff = end.getTime() - start.getTime(); + const prevEnd = new Date(start.getTime() - 1); + const prevStart = new Date(prevEnd.getTime() - diff); + return { + start: startOfDay(start), + end, + prevStart: startOfDay(prevStart), + prevEnd: endOfDay(prevEnd), + periodLabel: `${start.toLocaleDateString('fr-FR')} - ${new Date(to).toLocaleDateString('fr-FR')}`, + }; + } + + switch (period) { + case 'day': { + const start = startOfDay(now); + const end = endOfDay(now); + const yesterday = new Date(now); + yesterday.setDate(yesterday.getDate() - 1); + return { + start, + end, + prevStart: startOfDay(yesterday), + prevEnd: endOfDay(yesterday), + periodLabel: "Aujourd'hui", + }; + } + case 'yesterday': { + const yesterday = new Date(now); + yesterday.setDate(yesterday.getDate() - 1); + const start = startOfDay(yesterday); + const end = endOfDay(yesterday); + const dayBefore = new Date(yesterday); + dayBefore.setDate(dayBefore.getDate() - 1); + return { + start, + end, + prevStart: startOfDay(dayBefore), + prevEnd: endOfDay(dayBefore), + periodLabel: 'Hier', + }; + } + case 'week': { + // Cette semaine : lundi à aujourd'hui (ISO week, lundi = 1) + const dayOfWeek = now.getDay(); + const mondayOffset = dayOfWeek === 0 ? -6 : 1 - dayOfWeek; + const startOfWeek = new Date(now); + startOfWeek.setDate(startOfWeek.getDate() + mondayOffset); + const start = startOfDay(startOfWeek); + const end = endOfDay(now); + const prevWeekStart = new Date(start); + prevWeekStart.setDate(prevWeekStart.getDate() - 7); + const prevWeekEnd = new Date(start); + prevWeekEnd.setDate(prevWeekEnd.getDate() - 1); + return { + start, + end, + prevStart: startOfDay(prevWeekStart), + prevEnd: endOfDay(prevWeekEnd), + periodLabel: 'Cette semaine', + }; + } + case '7days': { + const start = new Date(now); + start.setDate(start.getDate() - 6); + const end = endOfDay(now); + const prevEnd = new Date(start.getTime() - 1); + const prevStart = new Date(prevEnd); + prevStart.setDate(prevStart.getDate() - 6); + return { + start: startOfDay(start), + end, + prevStart: startOfDay(prevStart), + prevEnd: endOfDay(prevEnd), + periodLabel: '7 derniers jours', + }; + } + case '30days': { + const start = new Date(now); + start.setDate(start.getDate() - 29); + const end = endOfDay(now); + const prevEnd = new Date(start.getTime() - 1); + const prevStart = new Date(prevEnd); + prevStart.setDate(prevStart.getDate() - 29); + return { + start: startOfDay(start), + end, + prevStart: startOfDay(prevStart), + prevEnd: endOfDay(prevEnd), + periodLabel: '30 derniers jours', + }; + } + case 'quarter': { + const q = Math.floor(now.getMonth() / 3) + 1; + const startOfQuarter = new Date(now.getFullYear(), (q - 1) * 3, 1); + const endOfQuarter = new Date(now.getFullYear(), q * 3, 0, 23, 59, 59, 999); + const prevQuarter = q === 1 ? 4 : q - 1; + const prevYear = q === 1 ? now.getFullYear() - 1 : now.getFullYear(); + const prevStart = new Date(prevYear, (prevQuarter - 1) * 3, 1); + const prevEnd = new Date(prevYear, prevQuarter * 3, 0, 23, 59, 59, 999); + return { + start: startOfQuarter, + end: endOfQuarter, + prevStart: prevStart, + prevEnd: prevEnd, + periodLabel: `T${q} ${now.getFullYear()}`, + }; + } + case 'year': { + const startOfYear = new Date(now.getFullYear(), 0, 1); + const endOfYear = new Date(now.getFullYear(), 11, 31, 23, 59, 59, 999); + const prevStart = new Date(now.getFullYear() - 1, 0, 1); + const prevEnd = new Date(now.getFullYear() - 1, 11, 31, 23, 59, 59, 999); + return { + start: startOfYear, + end: endOfYear, + prevStart: prevStart, + prevEnd: prevEnd, + periodLabel: `Année ${now.getFullYear()}`, + }; + } + case 'month': + default: { + const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1); + const endOfMonth = new Date(now.getFullYear(), now.getMonth() + 1, 0, 23, 59, 59, 999); + const startOfLastMonth = new Date(now.getFullYear(), now.getMonth() - 1, 1); + const endOfLastMonth = new Date(now.getFullYear(), now.getMonth(), 0, 23, 59, 59, 999); + return { + start: startOfMonth, + end: endOfMonth, + prevStart: startOfLastMonth, + prevEnd: endOfLastMonth, + periodLabel: 'Mois en cours', + }; + } + } +} + // GET - Récupérer les statistiques du dashboard export async function GET(request: NextRequest) { try { @@ -10,26 +163,20 @@ export async function GET(request: NextRequest) { return NextResponse.json({ error: 'Non autorisé' }, { status: 401 }); } - const now = new Date(); - const startOfToday = new Date(now.getFullYear(), now.getMonth(), now.getDate()); - const endOfToday = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59, 999); - - const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1); - const endOfMonth = new Date(now.getFullYear(), now.getMonth() + 1, 0, 23, 59, 59, 999); - - const startOfLastMonth = new Date(now.getFullYear(), now.getMonth() - 1, 1); - const endOfLastMonth = new Date(now.getFullYear(), now.getMonth(), 0, 23, 59, 59, 999); - - const startOfYesterday = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 1); - const endOfYesterday = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 1, 23, 59, 59, 999); + const { searchParams } = new URL(request.url); + const period = searchParams.get('period') || 'month'; + const from = searchParams.get('from'); + const to = searchParams.get('to'); - // 1. Participations du mois (trajets validés/terminés ce mois) + const { start, end, prevStart, prevEnd, periodLabel } = getDateRange(period, from, to); + + // 1. Participations sur la période (trajets validés/terminés) const participationsMoisData = await prisma.participationFinanciere.findMany({ where: { trajet: { date: { - gte: startOfMonth, - lte: endOfMonth, + gte: start, + lte: end, }, }, }, @@ -44,57 +191,57 @@ export async function GET(request: NextRequest) { ); const nombreFactures = participationsCeMois.length; - // 2. Trajets aujourd'hui - const trajetsAujourdhui = await prisma.trajet.count({ + // 2. Trajets sur la période + const trajetsPeriode = await prisma.trajet.count({ where: { archived: false, date: { - gte: startOfToday, - lte: endOfToday, + gte: start, + lte: end, }, }, }); - // Trajets hier pour comparaison - const trajetsHier = await prisma.trajet.count({ + // Trajets période précédente pour comparaison + const trajetsPeriodePrecedente = await prisma.trajet.count({ where: { archived: false, date: { - gte: startOfYesterday, - lte: endOfYesterday, + gte: prevStart, + lte: prevEnd, }, }, }); - const differenceAujourdhui = trajetsAujourdhui - trajetsHier; + const differenceTrajets = trajetsPeriode - trajetsPeriodePrecedente; - // 3. Trajets réalisés ce mois (terminés) - const trajetsRealisesMois = await prisma.trajet.count({ + // 3. Trajets réalisés sur la période (terminés) + const trajetsRealisesPeriode = await prisma.trajet.count({ where: { archived: false, statut: 'Terminé', date: { - gte: startOfMonth, - lte: endOfMonth, + gte: start, + lte: end, }, }, }); - // Trajets réalisés le mois dernier pour comparaison - const trajetsRealisesMoisDernier = await prisma.trajet.count({ + // Trajets réalisés période précédente pour comparaison + const trajetsRealisesPeriodePrecedente = await prisma.trajet.count({ where: { archived: false, statut: 'Terminé', date: { - gte: startOfLastMonth, - lte: endOfLastMonth, + gte: prevStart, + lte: prevEnd, }, }, }); - const pourcentageEvolution = trajetsRealisesMoisDernier > 0 - ? Math.round(((trajetsRealisesMois - trajetsRealisesMoisDernier) / trajetsRealisesMoisDernier) * 100) - : trajetsRealisesMois > 0 ? 100 : 0; + const pourcentageEvolution = trajetsRealisesPeriodePrecedente > 0 + ? Math.round(((trajetsRealisesPeriode - trajetsRealisesPeriodePrecedente) / trajetsRealisesPeriodePrecedente) * 100) + : trajetsRealisesPeriode > 0 ? 100 : 0; // 4. Chauffeurs actifs (disponibles) const totalChauffeurs = await prisma.chauffeur.count(); @@ -105,16 +252,17 @@ export async function GET(request: NextRequest) { }); return NextResponse.json({ + periodLabel, participationsMois: { montant: participationsMois, nombreFactures: nombreFactures, }, trajetsAujourdhui: { - nombre: trajetsAujourdhui, - difference: differenceAujourdhui, + nombre: trajetsPeriode, + difference: differenceTrajets, }, trajetsRealisesMois: { - nombre: trajetsRealisesMois, + nombre: trajetsRealisesPeriode, pourcentageEvolution: pourcentageEvolution, }, chauffeursActifs: { diff --git a/app/dashboard/calendrier/page.tsx b/app/dashboard/calendrier/page.tsx index 2c571d3..3aed30d 100644 --- a/app/dashboard/calendrier/page.tsx +++ b/app/dashboard/calendrier/page.tsx @@ -18,7 +18,7 @@ export default async function CalendrierPage() { return ( -
+
diff --git a/app/layout.tsx b/app/layout.tsx index 5fb6551..046726a 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -12,8 +12,8 @@ const poppins = Poppins({ }); export const metadata: Metadata = { - title: "Platform SaaS", - description: "Plateforme SaaS", + title: "MAD - BackOffice", + description: "MAD", icons: { icon: "/logo.svg", }, diff --git a/components/CalendrierPageContent.tsx b/components/CalendrierPageContent.tsx index 89fc5ca..417b613 100644 --- a/components/CalendrierPageContent.tsx +++ b/components/CalendrierPageContent.tsx @@ -14,7 +14,7 @@ export default function CalendrierPageContent() { }; return ( -
+
{/* En-tête avec titre et bouton */}
@@ -37,12 +37,12 @@ export default function CalendrierPageContent() {
{/* Calendrier en haut */} -
+
{/* Liste des trajets en bas, triable par période */} -
+
diff --git a/components/CalendrierTrajets.tsx b/components/CalendrierTrajets.tsx index 7f00972..cc9c0e6 100644 --- a/components/CalendrierTrajets.tsx +++ b/components/CalendrierTrajets.tsx @@ -139,13 +139,13 @@ function DroppableDayCell({ @@ -411,18 +423,19 @@ export default function CalendrierTrajets({ refreshTrigger }: CalendrierTrajetsP <> {/* Grille du calendrier avec drag and drop */} -
- {/* En-têtes des jours */} - {days.map((day) => ( -
- {day} +
+ {/* En-têtes des jours - version courte sur mobile */} + {days.map((day, i) => ( +
+ {mobileDays[i]} + {day}
))} {/* Jours du calendrier */} {calendarDays.map((date, index) => { if (!date) { - return
; + return
; } const trajetsDuJour = getTrajetsForDate(date); @@ -445,24 +458,45 @@ export default function CalendrierTrajets({ refreshTrigger }: CalendrierTrajetsP isSelected={isSelected} onDateClick={handleDateClick} > -
+ {/* Numéro du jour */} +
{date.getDate()}
+ + {/* Mobile: indicateurs de points colorés */} {trajetsDuJour.length > 0 && ( -
- {trajetsDuJour.slice(0, 2).map((trajet) => ( - - ))} - {trajetsDuJour.length > 2 && ( -
- +{trajetsDuJour.length - 2} -
- )} -
+ <> +
+ {trajetsDuJour.length <= 3 ? ( + trajetsDuJour.map((t) => ( + + )) + ) : ( + <> + + {trajetsDuJour.length} + + )} +
+ + {/* Desktop: pastilles d'événements comme avant */} +
+ {trajetsDuJour.slice(0, 2).map((trajet) => ( + + ))} + {trajetsDuJour.length > 2 && ( +
+ +{trajetsDuJour.length - 2} +
+ )} +
+ )} ); @@ -488,8 +522,12 @@ export default function CalendrierTrajets({ refreshTrigger }: CalendrierTrajetsP {/* Détails des trajets du jour sélectionné */} {selectedDate && selectedTrajets.length > 0 && (
-

- Trajets du {formatDate(selectedDate)} +

+ Trajets du{' '} + {formatDate(selectedDate)} + + {selectedDate.toLocaleDateString('fr-FR', { day: 'numeric', month: 'short' })} +

{selectedTrajets.map((trajet) => { @@ -512,60 +550,63 @@ export default function CalendrierTrajets({ refreshTrigger }: CalendrierTrajetsP + {dropdownOpen && ( +
+
+

Période des statistiques

+
+
+ {PERIOD_OPTIONS.filter((o) => o.value !== 'custom').map((opt) => ( + + ))} +
+ + {period === 'custom' && ( +
+

Sélectionner une plage

+
+ setCustomFrom(e.target.value)} + className="flex-1 px-3 py-2 text-sm border border-gray-200 rounded-lg bg-white focus:ring-2 focus:ring-dyellow/30 focus:border-dyellow transition-shadow" + /> + + setCustomTo(e.target.value)} + className="flex-1 px-3 py-2 text-sm border border-gray-200 rounded-lg bg-white focus:ring-2 focus:ring-dyellow/30 focus:border-dyellow transition-shadow" + /> +
+ +
+ )} +
+
+ )} +
+
{/* Statistiques */} @@ -181,7 +304,9 @@ export default function DashboardContent({ userName }: DashboardContentProps) {
-

Participations du mois

+

+ Participations {period === 'month' ? 'ce mois-ci' : 'sur la période'} +

{stats ? `${stats.participationsMois.montant.toFixed(2).replace('.', ',')}€` : '0,00€'}

@@ -201,13 +326,15 @@ export default function DashboardContent({ userName }: DashboardContentProps) {
-

Trajets Aujourd'hui

+

+ Trajets {period === 'day' ? "aujourd'hui" : period === 'yesterday' ? 'hier' : 'sur la période'} +

{stats ? stats.trajetsAujourdhui.nombre : 0}

{stats && stats.trajetsAujourdhui.difference !== 0 - ? `${stats.trajetsAujourdhui.difference > 0 ? '+' : ''}${stats.trajetsAujourdhui.difference} vs hier` + ? `${stats.trajetsAujourdhui.difference > 0 ? '+' : ''}${stats.trajetsAujourdhui.difference} vs période précédente` : 'Aucun changement'}

@@ -223,13 +350,15 @@ export default function DashboardContent({ userName }: DashboardContentProps) {
-

Trajets réalisés ce mois

+

+ Trajets réalisés {period === 'month' ? 'ce mois-ci' : 'sur la période'} +

{stats ? stats.trajetsRealisesMois.nombre : 0}

{stats && stats.trajetsRealisesMois.pourcentageEvolution !== 0 - ? `${stats.trajetsRealisesMois.pourcentageEvolution > 0 ? '+' : ''}${stats.trajetsRealisesMois.pourcentageEvolution}% vs mois dernier` + ? `${stats.trajetsRealisesMois.pourcentageEvolution > 0 ? '+' : ''}${stats.trajetsRealisesMois.pourcentageEvolution}% vs période précédente` : 'Aucun changement'}

@@ -261,7 +390,14 @@ export default function DashboardContent({ userName }: DashboardContentProps) { {/* Actions Rapides */}
-

Actions Rapides

+

+ + + + + + Actions Rapides +

-
+
{loading ? (
Chargement...
) : trajetsRecents.length === 0 ? ( @@ -342,111 +485,74 @@ export default function DashboardContent({ userName }: DashboardContentProps) { Aucun trajet créé récemment
) : ( -
- {trajetsRecents.map((trajet) => ( -
setSelectedTrajet(trajet)} - className="p-3 sm:p-4 bg-gray-50 rounded-lg border border-gray-200 hover:border-gray-300 hover:shadow-sm transition-all cursor-pointer" - > -
- {/* Avatar adhérent */} -
- {getInitials(trajet.adherent.nom, trajet.adherent.prenom)} -
- - {/* Informations principales */} -
-
-
-

- {trajet.adherent.prenom} {trajet.adherent.nom} -

-
- {trajet.participations?.[0] && ( - - {getParticipationRef(trajet.participations[0].id)} - - )} - - - - - {formatDate(trajet.date)} - - - - - - {formatTime(trajet.date)} - - - {trajet.statut} +
+ + + + + + + + + + + {trajetsRecents.map((trajet) => ( + setSelectedTrajet(trajet)} + className="border-b border-gray-100 last:border-b-0 hover:bg-gray-50/80 transition-colors cursor-pointer" + > + + + + + + ))} + +
AdhérentStatutFichier
+
+
+ {getInitials(trajet.adherent.nom, trajet.adherent.prenom)} +
+
+ + {trajet.adherent.prenom} {trajet.adherent.nom} +

+ {formatDate(trajet.date)} · {formatTime(trajet.date)} +

- - - {/* Adresses */} -
-
- Départ:{' '} - {trajet.adresseDepart} -
-
- Arrivée:{' '} - {trajet.adresseArrivee} -
-
- - {/* Chauffeur */} -
- {trajet.chauffeur ? ( -
-
- {getInitials(trajet.chauffeur.nom, trajet.chauffeur.prenom)} -
-
-
Chauffeur
-
- {trajet.chauffeur.prenom} {trajet.chauffeur.nom} -
-
-
+
+ + {trajet.statut} + + + {trajet.participations?.[0] ? ( + + {getParticipationRef(trajet.participations[0].id)} + ) : ( -
- - - - - Aucun chauffeur assigné - -
+ )} - - - {/* Commentaire */} - {trajet.commentaire && ( -
-

{trajet.commentaire}

-
- )} - - - - ))} +
+ + + +
)}
@@ -460,7 +566,7 @@ export default function DashboardContent({ userName }: DashboardContentProps) { onSuccess={() => { setShowTrajetForm(false); fetchTrajetsRecents(); - fetchStats(); + refreshStats(); }} /> )} @@ -470,7 +576,7 @@ export default function DashboardContent({ userName }: DashboardContentProps) { adherent={null} onClose={() => { setShowAdherentForm(false); - fetchStats(); + refreshStats(); }} /> )} @@ -481,7 +587,7 @@ export default function DashboardContent({ userName }: DashboardContentProps) { onClose={() => setSelectedTrajet(null)} onUpdate={() => { fetchTrajetsRecents(); - fetchStats(); + refreshStats(); }} /> )} diff --git a/components/DashboardLayout.tsx b/components/DashboardLayout.tsx index e1dc390..d305ad8 100644 --- a/components/DashboardLayout.tsx +++ b/components/DashboardLayout.tsx @@ -489,7 +489,7 @@ export default function DashboardLayout({ user, children }: DashboardLayoutProps {/* Page Content */} -
+
{children}
diff --git a/components/ListeTrajets.tsx b/components/ListeTrajets.tsx index 70a05a1..213d927 100644 --- a/components/ListeTrajets.tsx +++ b/components/ListeTrajets.tsx @@ -2,6 +2,7 @@ import { useState, useEffect } from 'react'; import TrajetForm from './TrajetForm'; +import TrajetDetailModal from './TrajetDetailModal'; import { getParticipationRef } from '@/lib/participation-ref'; interface Trajet { @@ -54,6 +55,7 @@ export default function ListeTrajets({ onTrajetCreated, compact, hideNewTrajetBu const [startDate, setStartDate] = useState(''); const [endDate, setEndDate] = useState(''); const [showTrajetForm, setShowTrajetForm] = useState(false); + const [selectedTrajet, setSelectedTrajet] = useState(null); const getDateRange = (): { start: string; end: string } | null => { switch (filterPeriod) { @@ -174,7 +176,7 @@ export default function ListeTrajets({ onTrajetCreated, compact, hideNewTrajetBu return (
@@ -182,7 +184,7 @@ export default function ListeTrajets({ onTrajetCreated, compact, hideNewTrajetBu
{/* Barre de recherche */} -
+
@@ -190,10 +192,10 @@ export default function ListeTrajets({ onTrajetCreated, compact, hideNewTrajetBu
setSearch(e.target.value)} - className="block w-full pl-9 pr-3 py-2 text-sm border border-gray-300 rounded-lg bg-white text-gray-900 placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-lblue focus:border-lblue transition-all" + className="block w-full min-w-0 pl-9 pr-3 py-2 text-sm border border-gray-300 rounded-lg bg-white text-gray-900 placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-lblue focus:border-lblue transition-all" />
@@ -333,143 +335,183 @@ export default function ListeTrajets({ onTrajetCreated, compact, hideNewTrajetBu {/* Liste des trajets avec scrollbar */}
-
-

+
+

+ + + + + {filterPeriod === 'derniers' ? 'Derniers trajets créés' : 'Trajets'}

- {loading ? ( -
Chargement...
- ) : filteredTrajets.length === 0 ? ( -
- {trajets.length === 0 - ? filterPeriod === 'derniers' - ? 'Aucun trajet créé récemment' - : 'Aucun trajet pour cette période' - : 'Aucun trajet ne correspond à votre recherche'} -
- ) : ( -
- {filteredTrajets.map((trajet) => ( -
-
- {/* Avatar adhérent */} -
- {getInitials(trajet.adherent.nom, trajet.adherent.prenom)} -
- - {/* Informations principales */} -
-
-
-

- {trajet.adherent.prenom} {trajet.adherent.nom} -

-
- {participationRef(trajet) && ( - - {participationRef(trajet)} +
+ {loading ? ( +
Chargement...
+ ) : filteredTrajets.length === 0 ? ( +
+ {trajets.length === 0 + ? filterPeriod === 'derniers' + ? 'Aucun trajet créé récemment' + : 'Aucun trajet pour cette période' + : 'Aucun trajet ne correspond à votre recherche'} +
+ ) : ( + <> + {/* Mobile: layout en cartes */} +
+ {filteredTrajets.map((trajet) => ( +
+ + ))} +
- {/* Adresses */} -
-
- Départ:{' '} - {trajet.adresseDepart} -
-
- Arrivée:{' '} - {trajet.adresseArrivee} -
-
- - {/* Chauffeur */} -
- {trajet.chauffeur ? ( -
-
- {getInitials(trajet.chauffeur.nom, trajet.chauffeur.prenom)} -
-
-
Chauffeur
-
- {trajet.chauffeur.prenom} {trajet.chauffeur.nom} + {/* Desktop: tableau classique */} +
+ + + + + + + + + + + + {filteredTrajets.map((trajet) => ( + setSelectedTrajet(trajet)} + className="border-b border-gray-100 last:border-b-0 hover:bg-gray-50/80 transition-colors cursor-pointer" + > + + + + + + + ))} + +
AdhérentStatutFichierChauffeur assigné
+
+
+ {getInitials(trajet.adherent.nom, trajet.adherent.prenom)} +
+
+ + {trajet.adherent.prenom} {trajet.adherent.nom} + +

+ {formatDate(trajet.date)} · {formatTime(trajet.date)} +

+
- - - ) : ( -
- - - - - Aucun chauffeur assigné - -
- )} - - - {/* Commentaire */} - {trajet.commentaire && ( -
-

{trajet.commentaire}

-
- )} - +
+ + {trajet.statut} + + + {trajet.participations?.[0] ? ( + + {getParticipationRef(trajet.participations[0].id)} + + ) : ( + + )} + + {trajet.chauffeur ? ( + + {trajet.chauffeur.prenom} {trajet.chauffeur.nom} + + ) : ( + + )} + + + + +
-
- ))} + + )}
- )}
{/* Modal formulaire trajet */} @@ -484,6 +526,18 @@ export default function ListeTrajets({ onTrajetCreated, compact, hideNewTrajetBu }} /> )} + + {selectedTrajet && ( + setSelectedTrajet(null)} + onUpdate={() => { + fetchTrajets(); + setSelectedTrajet(null); + if (onTrajetCreated) onTrajetCreated(); + }} + /> + )}
); } diff --git a/components/NotificationProvider.tsx b/components/NotificationProvider.tsx index c2e0e1b..386431d 100644 --- a/components/NotificationProvider.tsx +++ b/components/NotificationProvider.tsx @@ -51,7 +51,7 @@ export function NotificationProvider({ children }: { children: ReactNode }) { return ( {children} -
+
{notifications.map((notification) => (