Added more Responsive to Mobile Device
This commit is contained in:
@@ -139,13 +139,13 @@ function DroppableDayCell({
|
||||
<button
|
||||
ref={setNodeRef}
|
||||
onClick={() => onDateClick(date)}
|
||||
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 ${
|
||||
className={`h-12 sm:h-20 md:h-24 p-1 sm:p-1.5 md:p-2 rounded-md sm:rounded-lg border sm:border-2 transition-all flex flex-col items-center sm:items-stretch active:scale-95 sm:active:scale-100 ${
|
||||
isSelected
|
||||
? 'border-lblue bg-lblue/10'
|
||||
? 'border-lblue bg-lblue/10 sm:border-2'
|
||||
: isToday
|
||||
? 'border-lblue bg-lblue/5'
|
||||
? 'border-lblue bg-lblue/5 sm:border-2'
|
||||
: isOver
|
||||
? 'border-lgreen bg-lgreen/20 border-2'
|
||||
? 'border-lgreen bg-lgreen/20 sm:border-2'
|
||||
: 'border-gray-200 hover:border-gray-300 hover:bg-gray-50'
|
||||
}`}
|
||||
>
|
||||
@@ -370,35 +370,47 @@ export default function CalendrierTrajets({ refreshTrigger }: CalendrierTrajetsP
|
||||
calendarDays.push(new Date(year, month, day));
|
||||
}
|
||||
|
||||
const mobileDays = ['L', 'M', 'M', 'J', 'V', 'S', 'D'];
|
||||
|
||||
const getStatutDotColor = (statut: string) => {
|
||||
switch (statut) {
|
||||
case 'Validé': return 'bg-purple-500';
|
||||
case 'Terminé': return 'bg-green-500';
|
||||
case 'En cours': return 'bg-blue-500';
|
||||
case 'Annulé': return 'bg-red-500';
|
||||
default: return 'bg-lblue';
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="bg-white rounded-lg shadow-sm p-4 sm:p-6">
|
||||
<div className="bg-white rounded-lg shadow-sm p-3 sm:p-6 min-w-0 overflow-hidden">
|
||||
{/* En-tête du calendrier */}
|
||||
<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">
|
||||
<div className="flex items-center justify-between mb-4 sm:mb-6">
|
||||
<h2 className="text-base 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 w-full sm:w-auto">
|
||||
<div className="flex items-center gap-1.5 sm:gap-2">
|
||||
<button
|
||||
onClick={goToPreviousMonth}
|
||||
className="p-1.5 sm:p-2 rounded-lg hover:bg-gray-100 transition-colors"
|
||||
className="p-2 rounded-lg hover:bg-gray-100 transition-colors active:bg-gray-200"
|
||||
title="Mois précédent"
|
||||
>
|
||||
<svg className="w-4 h-4 sm:w-5 sm:h-5 text-gray-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<svg className="w-5 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-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"
|
||||
className="px-3 py-1.5 sm:px-4 sm:py-2 text-xs sm:text-sm font-medium text-gray-700 bg-gray-100 rounded-lg hover:bg-gray-200 transition-colors active:bg-gray-300"
|
||||
>
|
||||
Aujourd'hui
|
||||
Aujourd'hui
|
||||
</button>
|
||||
<button
|
||||
onClick={goToNextMonth}
|
||||
className="p-1.5 sm:p-2 rounded-lg hover:bg-gray-100 transition-colors"
|
||||
className="p-2 rounded-lg hover:bg-gray-100 transition-colors active:bg-gray-200"
|
||||
title="Mois suivant"
|
||||
>
|
||||
<svg className="w-4 h-4 sm:w-5 sm:h-5 text-gray-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<svg className="w-5 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>
|
||||
@@ -411,18 +423,19 @@ export default function CalendrierTrajets({ refreshTrigger }: CalendrierTrajetsP
|
||||
<>
|
||||
{/* Grille du calendrier avec drag and drop */}
|
||||
<DndContext onDragStart={handleDragStart} onDragEnd={handleDragEnd}>
|
||||
<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-[10px] sm:text-xs md:text-sm font-semibold text-gray-600 py-1 sm:py-2">
|
||||
{day}
|
||||
<div className="grid grid-cols-7 gap-0.5 sm:gap-2 mb-4 sm:mb-6">
|
||||
{/* En-têtes des jours - version courte sur mobile */}
|
||||
{days.map((day, i) => (
|
||||
<div key={day} className="text-center text-xs sm:text-xs md:text-sm font-semibold text-gray-500 py-1 sm:py-2">
|
||||
<span className="sm:hidden">{mobileDays[i]}</span>
|
||||
<span className="hidden sm:inline">{day}</span>
|
||||
</div>
|
||||
))}
|
||||
|
||||
{/* Jours du calendrier */}
|
||||
{calendarDays.map((date, index) => {
|
||||
if (!date) {
|
||||
return <div key={`empty-${index}`} className="h-24" />;
|
||||
return <div key={`empty-${index}`} className="h-12 sm:h-24" />;
|
||||
}
|
||||
|
||||
const trajetsDuJour = getTrajetsForDate(date);
|
||||
@@ -445,24 +458,45 @@ export default function CalendrierTrajets({ refreshTrigger }: CalendrierTrajetsP
|
||||
isSelected={isSelected}
|
||||
onDateClick={handleDateClick}
|
||||
>
|
||||
<div className="text-xs sm:text-sm font-medium text-gray-900 mb-0.5 sm:mb-1">
|
||||
{/* Numéro du jour */}
|
||||
<div className={`text-xs sm:text-sm font-medium mb-0.5 sm:mb-1 ${
|
||||
isToday ? 'text-lblue font-bold' : 'text-gray-900'
|
||||
}`}>
|
||||
{date.getDate()}
|
||||
</div>
|
||||
|
||||
{/* Mobile: indicateurs de points colorés */}
|
||||
{trajetsDuJour.length > 0 && (
|
||||
<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 > 2 && (
|
||||
<div className="text-[9px] sm:text-[10px] text-gray-500 font-semibold text-center pt-0.5">
|
||||
+{trajetsDuJour.length - 2}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<>
|
||||
<div className="flex items-center justify-center gap-0.5 flex-wrap sm:hidden">
|
||||
{trajetsDuJour.length <= 3 ? (
|
||||
trajetsDuJour.map((t) => (
|
||||
<span key={t.id} className={`w-1.5 h-1.5 rounded-full ${getStatutDotColor(t.statut)}`} />
|
||||
))
|
||||
) : (
|
||||
<>
|
||||
<span className={`w-1.5 h-1.5 rounded-full ${getStatutDotColor(trajetsDuJour[0].statut)}`} />
|
||||
<span className="text-[9px] font-bold text-gray-500 leading-none">{trajetsDuJour.length}</span>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Desktop: pastilles d'événements comme avant */}
|
||||
<div className="hidden sm:flex sm:flex-col 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 > 2 && (
|
||||
<div className="text-[10px] text-gray-500 font-semibold text-center pt-0.5">
|
||||
+{trajetsDuJour.length - 2}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</DroppableDayCell>
|
||||
);
|
||||
@@ -488,8 +522,12 @@ export default function CalendrierTrajets({ refreshTrigger }: CalendrierTrajetsP
|
||||
{/* Détails des trajets du jour sélectionné */}
|
||||
{selectedDate && selectedTrajets.length > 0 && (
|
||||
<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 className="text-sm sm:text-lg font-semibold text-gray-900 mb-3 sm:mb-4">
|
||||
Trajets du{' '}
|
||||
<span className="hidden sm:inline">{formatDate(selectedDate)}</span>
|
||||
<span className="sm:hidden">
|
||||
{selectedDate.toLocaleDateString('fr-FR', { day: 'numeric', month: 'short' })}
|
||||
</span>
|
||||
</h3>
|
||||
<div className="space-y-2 sm:space-y-3">
|
||||
{selectedTrajets.map((trajet) => {
|
||||
@@ -512,60 +550,63 @@ export default function CalendrierTrajets({ refreshTrigger }: CalendrierTrajetsP
|
||||
<button
|
||||
key={trajet.id}
|
||||
onClick={() => setSelectedTrajet(trajet)}
|
||||
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"
|
||||
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 active:bg-gray-100"
|
||||
>
|
||||
<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">
|
||||
{/* Header: nom + heure + statut */}
|
||||
<div className="flex items-center gap-2 mb-2 flex-wrap">
|
||||
<span className="text-sm font-semibold text-gray-900">
|
||||
{trajet.adherent.prenom} {trajet.adherent.nom}
|
||||
</span>
|
||||
{trajet.participations?.[0] && (
|
||||
<span className="px-1.5 sm:px-2 py-0.5 text-[10px] sm:text-xs font-mono font-medium rounded bg-lblue/10 text-lblue" title="Référence de prescription">
|
||||
{getParticipationRef(trajet.participations[0].id)}
|
||||
</span>
|
||||
)}
|
||||
<span className="px-1.5 sm:px-2 py-0.5 text-[10px] sm:text-xs font-medium rounded bg-lblue/10 text-lblue">
|
||||
<span className="px-1.5 py-0.5 text-[10px] sm:text-xs font-medium rounded bg-lblue/10 text-lblue">
|
||||
{formatTime(trajet.date)}
|
||||
</span>
|
||||
<span
|
||||
className={`px-1.5 sm:px-2 py-0.5 text-[10px] sm:text-xs font-medium rounded border ${getStatutColor(trajet.statut)}`}
|
||||
className={`px-1.5 py-0.5 text-[10px] sm:text-xs font-medium rounded border ${getStatutColor(trajet.statut)}`}
|
||||
>
|
||||
{trajet.statut}
|
||||
</span>
|
||||
{trajet.participations?.[0] && (
|
||||
<span className="px-1.5 py-0.5 text-[10px] sm:text-xs font-mono font-medium rounded bg-lblue/10 text-lblue" title="Référence de prescription">
|
||||
{getParticipationRef(trajet.participations[0].id)}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
{/* Adresses */}
|
||||
<div className="text-xs sm:text-sm text-gray-600 mb-1 break-words">
|
||||
<span className="font-medium">Départ:</span> {trajet.adresseDepart}
|
||||
<span className="font-medium">De:</span> {trajet.adresseDepart}
|
||||
</div>
|
||||
<div className="text-xs sm:text-sm text-gray-600 mb-2 break-words">
|
||||
<span className="font-medium">Arrivée:</span> {trajet.adresseArrivee}
|
||||
<div className="text-xs sm:text-sm text-gray-600 break-words">
|
||||
<span className="font-medium">A:</span> {trajet.adresseArrivee}
|
||||
</div>
|
||||
{/* Chauffeur */}
|
||||
{trajet.chauffeur ? (
|
||||
<div className="flex items-center gap-2 mt-2">
|
||||
<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" />
|
||||
<div className="flex items-center gap-1.5 mt-2">
|
||||
<svg className="w-3.5 h-3.5 text-gray-400 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" />
|
||||
</svg>
|
||||
<span className="text-xs sm:text-sm font-medium text-gray-900 truncate">
|
||||
Chauffeur: {trajet.chauffeur.prenom} {trajet.chauffeur.nom}
|
||||
<span className="text-xs font-medium text-gray-700">
|
||||
{trajet.chauffeur.prenom} {trajet.chauffeur.nom}
|
||||
</span>
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex items-center gap-2 mt-2">
|
||||
<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">
|
||||
<div className="flex items-center gap-1.5 mt-2">
|
||||
<svg className="w-3.5 h-3.5 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-xs sm:text-sm text-orange-600 font-medium">
|
||||
Aucun chauffeur assigné
|
||||
<span className="text-xs text-orange-600 font-medium">
|
||||
Sans chauffeur
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
{trajet.commentaire && (
|
||||
<div className="mt-2 text-xs sm:text-sm text-gray-500 italic line-clamp-2 break-words">
|
||||
<div className="mt-1.5 text-xs text-gray-500 italic line-clamp-2 break-words">
|
||||
{trajet.commentaire}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<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">
|
||||
<svg className="w-4 h-4 text-gray-400 flex-shrink-0 mt-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
|
||||
</svg>
|
||||
</div>
|
||||
@@ -578,7 +619,11 @@ export default function CalendrierTrajets({ refreshTrigger }: CalendrierTrajetsP
|
||||
|
||||
{selectedDate && selectedTrajets.length === 0 && (
|
||||
<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)}
|
||||
Aucun trajet prévu pour le{' '}
|
||||
<span className="hidden sm:inline">{formatDate(selectedDate)}</span>
|
||||
<span className="sm:hidden">
|
||||
{selectedDate.toLocaleDateString('fr-FR', { day: 'numeric', month: 'short' })}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
|
||||
Reference in New Issue
Block a user