missions s3

This commit is contained in:
alma 2025-05-06 13:27:42 +02:00
parent 047cbde8a0
commit 4e1d0d0101

View File

@ -200,96 +200,99 @@ export default function MissionsPage() {
const niveauColor = getNiveauBadgeColor(mission.niveau);
return (
<div key={mission.id} className="bg-white shadow-sm hover:shadow-md transition-shadow duration-200 border border-gray-200 overflow-hidden h-full rounded-lg">
<div className="p-0">
{/* Card Header with Logo and ODD */}
<div className="flex items-start px-5 pt-5 pb-3">
<div className="flex-shrink-0 mr-4 w-16 h-16 relative">
{mission.logo ? (
<div key={mission.id} className="bg-white shadow-sm hover:shadow-md transition-shadow duration-200 border border-gray-200 overflow-hidden h-full rounded-lg flex flex-col">
{/* Card Header with Name and Level */}
<div className="px-5 pt-4 pb-3 flex justify-between items-center border-b border-gray-100">
<h2 className="text-base font-medium text-gray-900 line-clamp-2 flex-1">{mission.name}</h2>
<span className={`ml-2 flex-shrink-0 text-sm font-bold px-2.5 py-1.5 rounded-md ${niveauColor}`}>
{getNiveauLabel(mission.niveau)}
</span>
</div>
{/* Centered Logo */}
<div className="flex justify-center items-center p-4 flex-grow">
<div className="w-32 h-32 relative">
{mission.logo ? (
<img
src={mission.logo || ''}
alt={mission.name}
className="w-full h-full object-cover rounded-md border border-gray-200"
onError={(e) => {
console.log("Logo failed to load:", mission.logo);
console.log("Full URL attempted:", mission.logo);
// If the image fails to load, show the fallback
(e.currentTarget as HTMLImageElement).style.display = 'none';
// Show the fallback div
const fallbackDiv = e.currentTarget.parentElement?.querySelector('.logo-fallback');
if (fallbackDiv) {
(fallbackDiv as HTMLElement).style.display = 'flex';
}
}}
/>
) : null}
<div
className={`logo-fallback w-full h-full flex items-center justify-center bg-gray-100 rounded-md border border-gray-200 text-gray-500 text-2xl font-medium ${mission.logo ? 'hidden' : ''}`}
>
{mission.name.slice(0, 2).toUpperCase()}
</div>
</div>
</div>
{/* Card Content */}
<div className="px-5 pb-3">
<div className="flex flex-col space-y-2">
<div className="flex items-center text-sm text-gray-600">
<span className="font-medium mr-2">Type:</span>
{getMissionTypeLabel(mission.missionType)}
</div>
<div className="flex items-center text-sm text-gray-600">
<span className="font-medium mr-2">Durée:</span>
{getDuration(mission.projection)}
</div>
<div className="flex items-center text-sm text-gray-600">
<span className="font-medium mr-2">Participation:</span>
{getParticipationLabel(mission.participation)}
</div>
{mission.services && mission.services.length > 0 && (
<div className="mt-1">
<span className="text-sm font-medium text-gray-700 block mb-1">Services:</span>
<div className="flex flex-wrap gap-1.5">
{mission.services.map(service => (
<span key={service} className="bg-blue-50 text-blue-700 px-2 py-1 rounded-md text-xs font-medium">
{service}
</span>
))}
</div>
</div>
)}
</div>
</div>
{/* Card Footer */}
<div className="mt-auto px-5 py-3 border-t border-gray-100 bg-gray-50 flex justify-between items-center">
<span className="text-xs text-gray-500">
Créée le {formatDate(mission.createdAt)}
</span>
<div className="flex items-center gap-2">
{/* ODD scope icon */}
{oddInfo.number && (
<div className="flex items-center bg-gray-100 px-2 py-1 rounded-md">
<img
src={mission.logo || ''}
alt={mission.name}
className="w-full h-full object-cover rounded-md border border-gray-200"
src={oddInfo.iconPath}
alt={oddInfo.label}
className="w-7 h-7"
onError={(e) => {
console.log("Logo failed to load:", mission.logo);
console.log("Full URL attempted:", mission.logo);
// If the image fails to load, show the fallback
(e.currentTarget as HTMLImageElement).style.display = 'none';
// Show the fallback div
const fallbackDiv = e.currentTarget.parentElement?.querySelector('.logo-fallback');
if (fallbackDiv) {
(fallbackDiv as HTMLElement).style.display = 'flex';
}
// Fallback if image fails to load
(e.target as HTMLImageElement).style.display = 'none';
}}
/>
) : null}
<div
className={`logo-fallback w-full h-full flex items-center justify-center bg-gray-100 rounded-md border border-gray-200 text-gray-400 ${mission.logo ? 'hidden' : ''}`}
>
{mission.name.slice(0, 2).toUpperCase()}
</div>
</div>
<div className="flex-1">
<div className="flex items-center gap-2 mb-2">
{oddInfo.number && (
<div className="flex items-center bg-gray-100 px-2 py-1 rounded-md">
<img
src={oddInfo.iconPath}
alt={oddInfo.label}
className="w-8 h-8"
onError={(e) => {
// Fallback if image fails to load
(e.target as HTMLImageElement).style.display = 'none';
}}
/>
</div>
)}
<span className={`text-xs font-medium px-2 py-1 rounded-md ${niveauColor}`}>
{getNiveauLabel(mission.niveau)}
</span>
</div>
<h2 className="text-base font-medium text-gray-900 line-clamp-2">{mission.name}</h2>
</div>
</div>
{/* Card Content */}
<div className="px-5 pb-4">
<div className="flex flex-col space-y-2">
<div className="flex items-center text-sm text-gray-600">
<span className="font-medium mr-2">Type:</span>
{getMissionTypeLabel(mission.missionType)}
</div>
<div className="flex items-center text-sm text-gray-600">
<span className="font-medium mr-2">Durée:</span>
{getDuration(mission.projection)}
</div>
<div className="flex items-center text-sm text-gray-600">
<span className="font-medium mr-2">Participation:</span>
{getParticipationLabel(mission.participation)}
</div>
{mission.services && mission.services.length > 0 && (
<div className="mt-3">
<span className="text-sm font-medium text-gray-700 block mb-2">Services:</span>
<div className="flex flex-wrap gap-1.5">
{mission.services.map(service => (
<span key={service} className="bg-blue-50 text-blue-700 px-2 py-1 rounded-md text-xs font-medium">
{service}
</span>
))}
</div>
</div>
)}
</div>
</div>
{/* Card Footer */}
<div className="flex justify-between items-center px-5 py-3 border-t border-gray-100 bg-gray-50">
<span className="text-xs text-gray-500">
Créée le {formatDate(mission.createdAt)}
</span>
)}
<Link href={`/missions/${mission.id}`}>
<Button className="bg-black hover:bg-gray-800 text-white text-xs px-3 py-1 h-7 rounded-md">
Voir détails