From 93633c31ae998a28bcdfd8a7dc570eb9a42b3272 Mon Sep 17 00:00:00 2001 From: alma Date: Tue, 6 May 2025 13:47:14 +0200 Subject: [PATCH] missions page 2 --- app/missions/[missionId]/page.tsx | 329 ++++++++++++++++++++++++++++++ 1 file changed, 329 insertions(+) create mode 100644 app/missions/[missionId]/page.tsx diff --git a/app/missions/[missionId]/page.tsx b/app/missions/[missionId]/page.tsx new file mode 100644 index 00000000..5d0f9721 --- /dev/null +++ b/app/missions/[missionId]/page.tsx @@ -0,0 +1,329 @@ +"use client"; + +import { useState, useEffect } from "react"; +import { Button } from "@/components/ui/button"; +import { FileIcon, Calendar, Eye, MapPin, DollarSign, Clock, ThumbsUp, Languages, BarChart } from "lucide-react"; +import { useToast } from "@/components/ui/use-toast"; +import { useParams } from "next/navigation"; + +// Define types for mission details +interface User { + id: string; + email: string; +} + +interface Attachment { + id: string; + filename: string; + filePath: string; + fileType: string; + fileSize: number; + publicUrl: string; + createdAt: string; +} + +interface Mission { + id: string; + name: string; + logo?: string | null; + logoUrl?: string | null; + oddScope: string[]; + niveau: string; + missionType: string; + projection: string; + intention?: string; + donneurDOrdre?: string; + participation?: string; + services?: string[]; + profils?: string[]; + attachments?: Attachment[]; + createdAt: string; + creator: User; + missionUsers: any[]; +} + +export default function MissionDetailPage() { + const [mission, setMission] = useState(null); + const [loading, setLoading] = useState(true); + const { toast } = useToast(); + const params = useParams(); + const missionId = params.missionId as string; + + // Fetch mission details + useEffect(() => { + const fetchMissionDetails = async () => { + try { + setLoading(true); + const response = await fetch(`/api/missions/${missionId}`); + if (!response.ok) { + throw new Error('Failed to fetch mission details'); + } + const data = await response.json(); + console.log("Mission details:", data); + setMission(data); + } catch (error) { + console.error('Error fetching mission details:', error); + toast({ + title: "Erreur", + description: "Impossible de charger les détails de la mission", + variant: "destructive", + }); + } finally { + setLoading(false); + } + }; + + if (missionId) { + fetchMissionDetails(); + } + }, [missionId, toast]); + + // Helper function to format date + const formatDate = (dateString: string) => { + const date = new Date(dateString); + return date.toLocaleDateString('fr-FR', { + day: '2-digit', + month: 'long', + year: 'numeric' + }); + }; + + // Helper functions to get labels + const getMissionTypeLabel = (type: string) => { + switch(type) { + case 'remote': return 'À distance'; + case 'onsite': return 'Sur site'; + case 'hybrid': return 'Hybride'; + default: return type; + } + }; + + const getDurationLabel = (projection: string) => { + switch(projection) { + case 'short': return '< 1 mois'; + case 'medium': return '1-3 mois'; + case 'long': return '> 3 mois'; + default: return projection; + } + }; + + const getNiveauLabel = (niveau: string) => { + switch(niveau) { + case 'a': return 'Apprentissage'; + case 'b': return 'Basique'; + case 'c': return 'Complexe'; + case 's': return 'Spécial'; + default: return niveau; + } + }; + + // Function to get odd info + const getODDInfo = (oddScope: string[]) => { + const oddCode = oddScope && oddScope.length > 0 + ? oddScope[0] + : null; + + // Extract number from odd code (e.g., "odd-3" -> "3") + const oddNumber = oddCode ? oddCode.replace('odd-', '') : null; + + return { + number: oddNumber, + label: oddNumber ? `ODD ${oddNumber}` : "Non catégorisé", + iconPath: oddNumber ? `/F SDG Icons 2019 WEB/F-WEB-Goal-${oddNumber.padStart(2, '0')}.png` : "" + }; + }; + + // Loading state + if (loading) { + return ( +
+
+
+ ); + } + + // Error state if mission not found + if (!mission) { + return ( +
+
+

Mission non trouvée

+

Cette mission n'existe pas ou a été supprimée.

+ +
+
+ ); + } + + const oddInfo = getODDInfo(mission.oddScope); + + return ( +
+ {/* Header */} +
+
+
+

{mission.name}

+
+
+ + {formatDate(mission.createdAt)} +
+
+ + {Math.floor(Math.random() * 100) + 1} Views +
+
+
+ +
+
+ + {/* Info Grid */} +
+
+
+ +
+
+

Type de mission

+

{getMissionTypeLabel(mission.missionType)}

+
+
+ +
+
+ +
+
+

Donneur d'ordre

+

{mission.donneurDOrdre || "Non spécifié"}

+
+
+ +
+
+ +
+
+

Durée

+

{getDurationLabel(mission.projection)}

+
+
+ +
+
+ +
+
+

Niveau

+

{getNiveauLabel(mission.niveau)}

+
+
+ +
+
+ +
+
+

Participation

+

{mission.participation || "Non spécifié"}

+
+
+ + {oddInfo.number && ( +
+
+ {oddInfo.label} +
+
+

ODD

+

{oddInfo.label}

+
+
+ )} +
+ + {/* Project Description */} +
+

Description de la mission

+
+ {mission.intention || "Aucune description disponible pour cette mission."} +
+
+ + {/* Attachments Section */} + {mission.attachments && mission.attachments.length > 0 && ( +
+

Documents

+
+ {mission.attachments.map((attachment) => ( + +
+ +
+
+

{attachment.filename}

+

+ {attachment.fileType.split('/')[1]?.toUpperCase() || 'Fichier'} +

+
+
+ ))} +
+
+ )} + + {/* Skills Required Section */} + {mission.profils && mission.profils.length > 0 && ( +
+

Profils recherchés

+
+ {mission.profils.map((profil, index) => ( + + {profil} + + ))} +
+
+ )} + + {/* Services Section */} + {mission.services && mission.services.length > 0 && ( +
+

Services

+
+ {mission.services.map((service, index) => ( + + {service} + + ))} +
+
+ )} +
+ ); +} \ No newline at end of file