Added optimizations for mobile

This commit is contained in:
2026-02-08 15:27:44 +01:00
parent f1e9e3f8d4
commit da2e32d004
28 changed files with 1667 additions and 1075 deletions

View File

@@ -97,16 +97,16 @@ function DraggableTrajetEvent({ trajet, onClick }: { trajet: Trajet; onClick: (e
{...listeners}
{...attributes}
onClick={(e) => onClick(e, trajet)}
className={`text-[10px] px-1.5 py-0.5 rounded border ${styleObj.bg} ${styleObj.text} ${styleObj.border} font-semibold truncate w-full text-left transition-all flex items-center gap-1 ${canDrag ? 'hover:shadow-md cursor-grab active:cursor-grabbing' : 'cursor-default opacity-75'} ${isDragging ? 'opacity-50' : ''}`}
className={`text-[9px] sm:text-[10px] px-1 sm:px-1.5 py-0.5 rounded border ${styleObj.bg} ${styleObj.text} ${styleObj.border} font-semibold truncate w-full text-left transition-all flex items-center gap-0.5 sm:gap-1 ${canDrag ? 'hover:shadow-md cursor-grab active:cursor-grabbing' : 'cursor-default opacity-75'} ${isDragging ? 'opacity-50' : ''}`}
title={`${trajet.adherent.prenom} ${trajet.adherent.nom} - ${trajet.chauffeur ? `${trajet.chauffeur.prenom} ${trajet.chauffeur.nom}` : 'Sans chauffeur'} - ${trajet.statut}`}
>
<span className="font-bold">
<span className="font-bold text-[8px] sm:text-[9px]">
{trajet.chauffeur
? `${trajet.chauffeur.prenom.charAt(0)}${trajet.chauffeur.nom.charAt(0)}`
: '?'}
</span>
<span className="opacity-90"></span>
<span className="opacity-90">{formatTime(trajet.date)}</span>
<span className="opacity-90 hidden sm:inline"></span>
<span className="opacity-90 truncate">{formatTime(trajet.date)}</span>
</button>
);
}
@@ -137,7 +137,7 @@ function DroppableDayCell({
<button
ref={setNodeRef}
onClick={() => onDateClick(date)}
className={`h-24 p-2 rounded-lg border-2 transition-all flex flex-col ${
className={`h-16 sm:h-20 md:h-24 p-1 sm:p-1.5 md:p-2 rounded-lg border-2 transition-all flex flex-col ${
isSelected
? 'border-lblue bg-lblue/10'
: isToday
@@ -369,34 +369,34 @@ export default function CalendrierTrajets({ refreshTrigger }: CalendrierTrajetsP
}
return (
<div className="bg-white rounded-lg shadow-sm p-6">
<div className="bg-white rounded-lg shadow-sm p-4 sm:p-6">
{/* En-tête du calendrier */}
<div className="flex items-center justify-between mb-6">
<h2 className="text-xl font-semibold text-gray-900">
<div className="flex flex-col sm:flex-row items-start sm:items-center justify-between gap-3 sm:gap-0 mb-4 sm:mb-6">
<h2 className="text-lg sm:text-xl font-semibold text-gray-900 capitalize">
{currentDate.toLocaleDateString('fr-FR', { month: 'long', year: 'numeric' })}
</h2>
<div className="flex items-center gap-2">
<div className="flex items-center gap-2 w-full sm:w-auto">
<button
onClick={goToPreviousMonth}
className="p-2 rounded-lg hover:bg-gray-100 transition-colors"
className="p-1.5 sm:p-2 rounded-lg hover:bg-gray-100 transition-colors"
title="Mois précédent"
>
<svg className="w-5 h-5 text-gray-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<svg className="w-4 h-4 sm:w-5 sm:h-5 text-gray-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
</svg>
</button>
<button
onClick={goToToday}
className="px-4 py-2 text-sm font-medium text-gray-700 bg-gray-100 rounded-lg hover:bg-gray-200 transition-colors"
className="px-3 sm:px-4 py-1.5 sm:py-2 text-xs sm:text-sm font-medium text-gray-700 bg-gray-100 rounded-lg hover:bg-gray-200 transition-colors flex-1 sm:flex-initial"
>
Aujourd'hui
</button>
<button
onClick={goToNextMonth}
className="p-2 rounded-lg hover:bg-gray-100 transition-colors"
className="p-1.5 sm:p-2 rounded-lg hover:bg-gray-100 transition-colors"
title="Mois suivant"
>
<svg className="w-5 h-5 text-gray-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<svg className="w-4 h-4 sm:w-5 sm:h-5 text-gray-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
</svg>
</button>
@@ -404,15 +404,15 @@ export default function CalendrierTrajets({ refreshTrigger }: CalendrierTrajetsP
</div>
{loading ? (
<div className="text-center py-8 text-gray-500">Chargement...</div>
<div className="text-center py-6 sm:py-8 text-sm text-gray-500">Chargement...</div>
) : (
<>
{/* Grille du calendrier avec drag and drop */}
<DndContext onDragStart={handleDragStart} onDragEnd={handleDragEnd}>
<div className="grid grid-cols-7 gap-2 mb-6">
<div className="grid grid-cols-7 gap-1 sm:gap-2 mb-4 sm:mb-6">
{/* En-têtes des jours */}
{days.map((day) => (
<div key={day} className="text-center text-sm font-semibold text-gray-600 py-2">
<div key={day} className="text-center text-[10px] sm:text-xs md:text-sm font-semibold text-gray-600 py-1 sm:py-2">
{day}
</div>
))}
@@ -442,21 +442,21 @@ export default function CalendrierTrajets({ refreshTrigger }: CalendrierTrajetsP
isSelected={isSelected}
onDateClick={handleDateClick}
>
<div className="text-sm font-medium text-gray-900 mb-1">
<div className="text-xs sm:text-sm font-medium text-gray-900 mb-0.5 sm:mb-1">
{date.getDate()}
</div>
{trajetsDuJour.length > 0 && (
<div className="space-y-1 flex-1 overflow-hidden">
{trajetsDuJour.slice(0, 3).map((trajet) => (
<div className="space-y-0.5 sm:space-y-1 flex-1 overflow-hidden">
{trajetsDuJour.slice(0, 2).map((trajet) => (
<DraggableTrajetEvent
key={trajet.id}
trajet={trajet}
onClick={handleTrajetClick}
/>
))}
{trajetsDuJour.length > 3 && (
<div className="text-[10px] text-gray-500 font-semibold text-center pt-0.5">
+{trajetsDuJour.length - 3}
{trajetsDuJour.length > 2 && (
<div className="text-[9px] sm:text-[10px] text-gray-500 font-semibold text-center pt-0.5">
+{trajetsDuJour.length - 2}
</div>
)}
</div>
@@ -484,11 +484,11 @@ export default function CalendrierTrajets({ refreshTrigger }: CalendrierTrajetsP
{/* Détails des trajets du jour sélectionné */}
{selectedDate && selectedTrajets.length > 0 && (
<div className="mt-6 pt-6 border-t border-gray-200">
<h3 className="text-lg font-semibold text-gray-900 mb-4">
<div className="mt-4 sm:mt-6 pt-4 sm:pt-6 border-t border-gray-200">
<h3 className="text-base sm:text-lg font-semibold text-gray-900 mb-3 sm:mb-4">
Trajets du {formatDate(selectedDate)}
</h3>
<div className="space-y-3">
<div className="space-y-2 sm:space-y-3">
{selectedTrajets.map((trajet) => {
const getStatutColor = (statut: string) => {
switch (statut) {
@@ -509,55 +509,55 @@ export default function CalendrierTrajets({ refreshTrigger }: CalendrierTrajetsP
<button
key={trajet.id}
onClick={() => setSelectedTrajet(trajet)}
className="w-full p-4 bg-gray-50 rounded-lg border border-gray-200 hover:border-gray-300 hover:shadow-sm transition-all text-left"
className="w-full p-3 sm:p-4 bg-gray-50 rounded-lg border border-gray-200 hover:border-gray-300 hover:shadow-sm transition-all text-left"
>
<div className="flex items-start justify-between">
<div className="flex-1">
<div className="flex items-center gap-2 mb-2">
<span className="text-sm font-semibold text-gray-900">
<div className="flex items-start justify-between gap-2">
<div className="flex-1 min-w-0">
<div className="flex flex-wrap items-center gap-1.5 sm:gap-2 mb-2">
<span className="text-xs sm:text-sm font-semibold text-gray-900">
{trajet.adherent.prenom} {trajet.adherent.nom}
</span>
<span className="px-2 py-0.5 text-xs font-medium rounded bg-lblue/10 text-lblue">
<span className="px-1.5 sm:px-2 py-0.5 text-[10px] sm:text-xs font-medium rounded bg-lblue/10 text-lblue">
{formatTime(trajet.date)}
</span>
<span
className={`px-2 py-0.5 text-xs font-medium rounded border ${getStatutColor(trajet.statut)}`}
className={`px-1.5 sm:px-2 py-0.5 text-[10px] sm:text-xs font-medium rounded border ${getStatutColor(trajet.statut)}`}
>
{trajet.statut}
</span>
</div>
<div className="text-sm text-gray-600 mb-1">
<div className="text-xs sm:text-sm text-gray-600 mb-1 break-words">
<span className="font-medium">Départ:</span> {trajet.adresseDepart}
</div>
<div className="text-sm text-gray-600 mb-2">
<div className="text-xs sm:text-sm text-gray-600 mb-2 break-words">
<span className="font-medium">Arrivée:</span> {trajet.adresseArrivee}
</div>
{trajet.chauffeur ? (
<div className="flex items-center gap-2 mt-2">
<svg className="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<svg className="w-3.5 h-3.5 sm:w-4 sm:h-4 text-gray-400 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 17a2 2 0 11-4 0 2 2 0 014 0zM19 17a2 2 0 11-4 0 2 2 0 014 0z" />
</svg>
<span className="text-sm font-medium text-gray-900">
<span className="text-xs sm:text-sm font-medium text-gray-900 truncate">
Chauffeur: {trajet.chauffeur.prenom} {trajet.chauffeur.nom}
</span>
</div>
) : (
<div className="flex items-center gap-2 mt-2">
<svg className="w-4 h-4 text-orange-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<svg className="w-3.5 h-3.5 sm:w-4 sm:h-4 text-orange-400 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
</svg>
<span className="text-sm text-orange-600 font-medium">
<span className="text-xs sm:text-sm text-orange-600 font-medium">
Aucun chauffeur assigné
</span>
</div>
)}
{trajet.commentaire && (
<div className="mt-2 text-sm text-gray-500 italic line-clamp-2">
<div className="mt-2 text-xs sm:text-sm text-gray-500 italic line-clamp-2 break-words">
{trajet.commentaire}
</div>
)}
</div>
<svg className="w-5 h-5 text-gray-400 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<svg className="w-4 h-4 sm:w-5 sm:h-5 text-gray-400 flex-shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
</svg>
</div>
@@ -569,7 +569,7 @@ export default function CalendrierTrajets({ refreshTrigger }: CalendrierTrajetsP
)}
{selectedDate && selectedTrajets.length === 0 && (
<div className="mt-6 pt-6 border-t border-gray-200 text-center text-gray-500">
<div className="mt-4 sm:mt-6 pt-4 sm:pt-6 border-t border-gray-200 text-center text-xs sm:text-sm text-gray-500">
Aucun trajet prévu pour le {formatDate(selectedDate)}
</div>
)}