From 9f37a8fdf7e1e8b0fb2444cdea3712ba18a9d3bd Mon Sep 17 00:00:00 2001 From: alma Date: Tue, 6 May 2025 14:34:19 +0200 Subject: [PATCH] missions page 2 --- app/mission-tab/[missionId]/page.tsx | 391 +++++++++++++++++++++++++++ app/mission-tab/page.tsx | 18 +- 2 files changed, 404 insertions(+), 5 deletions(-) create mode 100644 app/mission-tab/[missionId]/page.tsx diff --git a/app/mission-tab/[missionId]/page.tsx b/app/mission-tab/[missionId]/page.tsx new file mode 100644 index 00000000..d175aa9c --- /dev/null +++ b/app/mission-tab/[missionId]/page.tsx @@ -0,0 +1,391 @@ +"use client"; + +import { useState, useEffect } from "react"; +import { Button } from "@/components/ui/button"; +import { FileIcon, Calendar, Eye, MapPin, Users, Clock, ThumbsUp, Languages, ArrowLeft } from "lucide-react"; +import { useToast } from "@/components/ui/use-toast"; +import { useParams, useRouter } from "next/navigation"; +import Link from "next/link"; + +// 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 MissionTabDetailPage() { + const [mission, setMission] = useState(null); + const [loading, setLoading] = useState(true); + const { toast } = useToast(); + const params = useParams(); + const router = useRouter(); + 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 ( +
+
+ {/* Back Button */} +
+ +
+ + {/* Page Title */} +
+

Détails de la Mission

+
+
+ + {/* Header */} +
+
+
+

{mission.name}

+
+
+ + {formatDate(mission.createdAt)} +
+
+ + {Math.floor(Math.random() * 100) + 1} Views +
+
+
+ + {/* Display logo */} +
+ {mission.logoUrl ? ( + {mission.name} { + console.log("Logo failed to load:", mission.logoUrl); + // Show placeholder on error + (e.currentTarget as HTMLImageElement).style.display = 'none'; + const parent = e.currentTarget.parentElement; + if (parent) { + parent.classList.add('bg-gray-100'); + parent.classList.add('flex'); + parent.classList.add('items-center'); + parent.classList.add('justify-center'); + parent.innerHTML = `${mission.name.slice(0, 2).toUpperCase()}`; + } + }} + /> + ) : ( +
+ {mission.name.slice(0, 2).toUpperCase()} +
+ )} +
+
+
+ + {/* 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} +
+
+

Objectif

+

Développement durable

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

Description de la mission

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

Documents

+ +
+ )} + + {/* 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} + + ))} +
+
+ )} + + {/* Actions Footer */} +
+ + + +
+
+
+ ); +} \ No newline at end of file diff --git a/app/mission-tab/page.tsx b/app/mission-tab/page.tsx index 3208659e..101d3934 100644 --- a/app/mission-tab/page.tsx +++ b/app/mission-tab/page.tsx @@ -125,10 +125,17 @@ export default function MissionTabPage() { }; return ( -
-
+
+ {/* Page Title */} +
+

Le Tableau des Missions

+
+
+ + {/* Search Header */} +
-

Toutes les missions disponibles

+

Toutes les missions disponibles

-
+ {/* Missions Grid */} +
{loading ? (
@@ -237,7 +245,7 @@ export default function MissionTabPage() { Créée le {formatDate(mission.createdAt)} - +