Mission Refactor Big
This commit is contained in:
parent
3e4c0cba05
commit
55585db2f1
@ -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>
|
||||
);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user