Mission Refactor Big

This commit is contained in:
alma 2026-01-09 14:05:04 +01:00
parent 3e4c0cba05
commit 55585db2f1

View File

@ -374,18 +374,6 @@ export default function MissionDetailPage() {
<FileText className="h-4 w-4 mr-2" />
Général
</TabsTrigger>
<TabsTrigger
value="documents"
className="data-[state=active]:bg-blue-600 data-[state=active]:text-white px-6 py-2"
>
<FileIcon className="h-4 w-4 mr-2" />
Documents
{mission.attachments && mission.attachments.length > 0 && (
<span className="ml-2 bg-blue-100 text-blue-800 text-xs font-medium px-2 py-0.5 rounded-full">
{mission.attachments.length}
</span>
)}
</TabsTrigger>
<TabsTrigger
value="plan"
className="data-[state=active]:bg-blue-600 data-[state=active]:text-white px-6 py-2"
@ -393,6 +381,30 @@ export default function MissionDetailPage() {
<Sparkles className="h-4 w-4 mr-2" />
Plan d'actions
</TabsTrigger>
<TabsTrigger
value="equipe"
className="data-[state=active]:bg-blue-600 data-[state=active]:text-white px-6 py-2"
>
<Users className="h-4 w-4 mr-2" />
Équipe
{mission.missionUsers && mission.missionUsers.length > 0 && (
<span className="ml-2 bg-blue-100 text-blue-800 text-xs font-medium px-2 py-0.5 rounded-full">
{mission.missionUsers.length + 1}
</span>
)}
</TabsTrigger>
<TabsTrigger
value="documents"
className="data-[state=active]:bg-blue-600 data-[state=active]:text-white px-6 py-2"
>
<FileIcon className="h-4 w-4 mr-2" />
Ressources
{mission.attachments && mission.attachments.length > 0 && (
<span className="ml-2 bg-blue-100 text-blue-800 text-xs font-medium px-2 py-0.5 rounded-full">
{mission.attachments.length}
</span>
)}
</TabsTrigger>
</TabsList>
{/* General Tab */}
@ -526,52 +538,6 @@ export default function MissionDetailPage() {
</div>
</TabsContent>
{/* Documents Tab */}
<TabsContent value="documents" className="space-y-6">
<div className="bg-white rounded-lg shadow-sm border border-gray-100 p-6">
<h2 className="text-xl font-semibold text-gray-800 mb-4">Documents attachés</h2>
{mission.attachments && mission.attachments.length > 0 ? (
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
{mission.attachments.map((attachment) => (
<a
key={attachment.id}
href={attachment.publicUrl}
target="_blank"
rel="noopener noreferrer"
className="bg-green-50 p-4 rounded-lg flex flex-col hover:bg-green-100 transition-colors border border-green-100"
>
<div className="text-green-700 mb-2">
<FileIcon className="h-10 w-10" />
</div>
<div>
<p className="font-medium text-gray-800 mb-1 truncate">{attachment.filename}</p>
<p className="text-sm text-gray-500">
{attachment.fileType.split('/')[1]?.toUpperCase() || 'Fichier'}
</p>
<p className="text-xs text-gray-400 mt-1">
{(attachment.fileSize / 1024).toFixed(1)} KB
</p>
</div>
</a>
))}
</div>
) : (
<div className="flex flex-col items-center justify-center py-12 text-center">
<div className="w-16 h-16 bg-gray-100 rounded-full flex items-center justify-center mb-4">
<FileIcon className="h-8 w-8 text-gray-400" />
</div>
<h3 className="text-lg font-medium text-gray-900 mb-2">
Aucun document
</h3>
<p className="text-gray-500 max-w-md">
Cette mission n'a pas de documents attachés.
</p>
</div>
)}
</div>
</TabsContent>
{/* Plan d'actions Tab */}
<TabsContent value="plan" className="space-y-6">
<div className="bg-white rounded-lg shadow-sm border border-gray-100 p-6">
@ -697,6 +663,174 @@ export default function MissionDetailPage() {
)}
</div>
</TabsContent>
{/* Equipe Tab */}
<TabsContent value="equipe" className="space-y-6">
{/* Creator Section */}
<div className="bg-white rounded-lg shadow-sm border border-gray-100 p-6">
<h2 className="text-xl font-semibold text-gray-800 mb-4">Créateur de la mission</h2>
<div className="flex items-center p-4 bg-blue-50 rounded-lg border border-blue-100">
<div className="h-12 w-12 rounded-full bg-blue-600 flex items-center justify-center text-white font-medium text-lg mr-4">
{mission.creator.email.slice(0, 2).toUpperCase()}
</div>
<div>
<p className="font-medium text-gray-900">{mission.creator.email}</p>
<p className="text-sm text-blue-600 font-medium">Créateur</p>
</div>
</div>
</div>
{/* Guardians Section */}
{(() => {
const guardians = mission.missionUsers.filter(mu =>
mu.role === 'gardien-temps' || mu.role === 'gardien-parole' || mu.role === 'gardien-memoire'
);
if (guardians.length === 0) return null;
const getRoleLabel = (role: string) => {
switch(role) {
case 'gardien-temps': return 'Gardien du Temps';
case 'gardien-parole': return 'Gardien de la Parole';
case 'gardien-memoire': return 'Gardien de la Mémoire';
default: return role;
}
};
const getRoleColor = (role: string) => {
switch(role) {
case 'gardien-temps': return 'bg-amber-50 border-amber-100 text-amber-600';
case 'gardien-parole': return 'bg-purple-50 border-purple-100 text-purple-600';
case 'gardien-memoire': return 'bg-green-50 border-green-100 text-green-600';
default: return 'bg-gray-50 border-gray-100 text-gray-600';
}
};
return (
<div className="bg-white rounded-lg shadow-sm border border-gray-100 p-6">
<h2 className="text-xl font-semibold text-gray-800 mb-4">Les Gardiens de l'Intention</h2>
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
{guardians.map((guardian) => (
<div
key={guardian.id}
className={`flex items-center p-4 rounded-lg border ${getRoleColor(guardian.role)}`}
>
<div className={`h-12 w-12 rounded-full flex items-center justify-center font-medium text-lg mr-4 ${
guardian.role === 'gardien-temps' ? 'bg-amber-600 text-white' :
guardian.role === 'gardien-parole' ? 'bg-purple-600 text-white' :
'bg-green-600 text-white'
}`}>
{guardian.user.email.slice(0, 2).toUpperCase()}
</div>
<div>
<p className="font-medium text-gray-900">{guardian.user.email}</p>
<p className={`text-sm font-medium ${
guardian.role === 'gardien-temps' ? 'text-amber-600' :
guardian.role === 'gardien-parole' ? 'text-purple-600' :
'text-green-600'
}`}>
{getRoleLabel(guardian.role)}
</p>
</div>
</div>
))}
</div>
</div>
);
})()}
{/* Volunteers/Other Members Section */}
{(() => {
const volunteers = mission.missionUsers.filter(mu => mu.role === 'volontaire');
if (volunteers.length === 0) return null;
return (
<div className="bg-white rounded-lg shadow-sm border border-gray-100 p-6">
<h2 className="text-xl font-semibold text-gray-800 mb-4">Volontaires</h2>
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
{volunteers.map((volunteer) => (
<div
key={volunteer.id}
className="flex items-center p-3 bg-gray-50 rounded-lg border border-gray-100"
>
<div className="h-10 w-10 rounded-full bg-gray-400 flex items-center justify-center text-white font-medium mr-3">
{volunteer.user.email.slice(0, 2).toUpperCase()}
</div>
<div>
<p className="font-medium text-gray-900 text-sm">{volunteer.user.email}</p>
<p className="text-xs text-gray-500">Volontaire</p>
</div>
</div>
))}
</div>
</div>
);
})()}
{/* Empty state if no team members */}
{mission.missionUsers.length === 0 && (
<div className="bg-white rounded-lg shadow-sm border border-gray-100 p-6">
<div className="flex flex-col items-center justify-center py-12 text-center">
<div className="w-16 h-16 bg-gray-100 rounded-full flex items-center justify-center mb-4">
<Users className="h-8 w-8 text-gray-400" />
</div>
<h3 className="text-lg font-medium text-gray-900 mb-2">
Aucun membre assigné
</h3>
<p className="text-gray-500 max-w-md">
Cette mission n'a pas encore de membres assignés en dehors du créateur.
</p>
</div>
</div>
)}
</TabsContent>
{/* Documents/Ressources Tab */}
<TabsContent value="documents" className="space-y-6">
<div className="bg-white rounded-lg shadow-sm border border-gray-100 p-6">
<h2 className="text-xl font-semibold text-gray-800 mb-4">Ressources</h2>
{mission.attachments && mission.attachments.length > 0 ? (
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
{mission.attachments.map((attachment) => (
<a
key={attachment.id}
href={attachment.publicUrl}
target="_blank"
rel="noopener noreferrer"
className="bg-green-50 p-4 rounded-lg flex flex-col hover:bg-green-100 transition-colors border border-green-100"
>
<div className="text-green-700 mb-2">
<FileIcon className="h-10 w-10" />
</div>
<div>
<p className="font-medium text-gray-800 mb-1 truncate">{attachment.filename}</p>
<p className="text-sm text-gray-500">
{attachment.fileType.split('/')[1]?.toUpperCase() || 'Fichier'}
</p>
<p className="text-xs text-gray-400 mt-1">
{(attachment.fileSize / 1024).toFixed(1)} KB
</p>
</div>
</a>
))}
</div>
) : (
<div className="flex flex-col items-center justify-center py-12 text-center">
<div className="w-16 h-16 bg-gray-100 rounded-full flex items-center justify-center mb-4">
<FileIcon className="h-8 w-8 text-gray-400" />
</div>
<h3 className="text-lg font-medium text-gray-900 mb-2">
Aucune ressource
</h3>
<p className="text-gray-500 max-w-md">
Cette mission n'a pas de ressources attachées.
</p>
</div>
)}
</div>
</TabsContent>
</Tabs>
</div>
);