"use client"; import { useState, useEffect } from "react"; import { useParams, useRouter } from "next/navigation"; import Link from "next/link"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { PlusCircle, Users, Wand2, ArrowLeft, Loader2, RefreshCw } from "lucide-react"; import { Badge } from "@/components/ui/badge"; import { toast } from "sonner"; import { useSocket } from "@/lib/socket-context"; // Mock project data const getProjectData = (id: string) => { return { id: parseInt(id), name: "Projet Formation Dev Web", description: "Création de groupes pour la formation développement web", date: "2025-05-15", groups: [ { id: 1, name: "Groupe A", persons: [ { id: 1, name: "Jean Dupont", tags: ["Frontend", "React", "Junior"] }, { id: 2, name: "Marie Martin", tags: ["Backend", "Node.js", "Senior"] }, { id: 3, name: "Pierre Durand", tags: ["Fullstack", "JavaScript", "Medior"] }, { id: 4, name: "Sophie Lefebvre", tags: ["UX/UI", "Design", "Senior"] }, ] }, { id: 2, name: "Groupe B", persons: [ { id: 5, name: "Thomas Bernard", tags: ["Backend", "Java", "Senior"] }, { id: 6, name: "Julie Petit", tags: ["Frontend", "Vue", "Junior"] }, { id: 7, name: "Nicolas Moreau", tags: ["DevOps", "Docker", "Medior"] }, { id: 8, name: "Emma Dubois", tags: ["Frontend", "Angular", "Junior"] }, ] }, { id: 3, name: "Groupe C", persons: [ { id: 9, name: "Lucas Leroy", tags: ["Backend", "Python", "Medior"] }, { id: 10, name: "Camille Roux", tags: ["Fullstack", "TypeScript", "Senior"] }, { id: 11, name: "Hugo Fournier", tags: ["Frontend", "React", "Medior"] }, { id: 12, name: "Léa Girard", tags: ["UX/UI", "Figma", "Junior"] }, ] }, { id: 4, name: "Groupe D", persons: [ { id: 13, name: "Mathis Bonnet", tags: ["Backend", "PHP", "Junior"] }, { id: 14, name: "Chloé Lambert", tags: ["Frontend", "CSS", "Senior"] }, { id: 15, name: "Nathan Mercier", tags: ["DevOps", "Kubernetes", "Senior"] }, { id: 16, name: "Zoé Faure", tags: ["Fullstack", "MERN", "Medior"] }, ] } ], persons: [ { id: 1, name: "Jean Dupont", tags: ["Frontend", "React", "Junior"] }, { id: 2, name: "Marie Martin", tags: ["Backend", "Node.js", "Senior"] }, { id: 3, name: "Pierre Durand", tags: ["Fullstack", "JavaScript", "Medior"] }, { id: 4, name: "Sophie Lefebvre", tags: ["UX/UI", "Design", "Senior"] }, { id: 5, name: "Thomas Bernard", tags: ["Backend", "Java", "Senior"] }, { id: 6, name: "Julie Petit", tags: ["Frontend", "Vue", "Junior"] }, { id: 7, name: "Nicolas Moreau", tags: ["DevOps", "Docker", "Medior"] }, { id: 8, name: "Emma Dubois", tags: ["Frontend", "Angular", "Junior"] }, { id: 9, name: "Lucas Leroy", tags: ["Backend", "Python", "Medior"] }, { id: 10, name: "Camille Roux", tags: ["Fullstack", "TypeScript", "Senior"] }, { id: 11, name: "Hugo Fournier", tags: ["Frontend", "React", "Medior"] }, { id: 12, name: "Léa Girard", tags: ["UX/UI", "Figma", "Junior"] }, { id: 13, name: "Mathis Bonnet", tags: ["Backend", "PHP", "Junior"] }, { id: 14, name: "Chloé Lambert", tags: ["Frontend", "CSS", "Senior"] }, { id: 15, name: "Nathan Mercier", tags: ["DevOps", "Kubernetes", "Senior"] }, { id: 16, name: "Zoé Faure", tags: ["Fullstack", "MERN", "Medior"] }, ] }; }; export default function ProjectGroupsPage() { const params = useParams(); const router = useRouter(); const projectId = params.id as string; const [project, setProject] = useState(null); const [loading, setLoading] = useState(true); const [refreshing, setRefreshing] = useState(false); const [activeTab, setActiveTab] = useState("existing"); // Socket connection for real-time updates const { isConnected, joinProject, leaveProject, onGroupCreated, onGroupUpdated, onPersonAddedToGroup, onPersonRemovedFromGroup } = useSocket(); // Fetch project data from API const fetchProject = async () => { setLoading(true); try { // Use the API service to get project and groups data const { projectsAPI, groupsAPI } = await import('@/lib/api'); const projectData = await projectsAPI.getProject(projectId); const groupsData = await groupsAPI.getGroups(projectId); // Combine project data with groups data const data = { ...projectData, groups: groupsData || [] }; setProject(data); } catch (error) { console.error("Error fetching project:", error); toast.error("Erreur lors du chargement du projet"); // Fallback to mock data for development const data = getProjectData(projectId); setProject(data); } finally { setLoading(false); setRefreshing(false); } }; // Initial fetch useEffect(() => { fetchProject(); }, [projectId]); // Join project room for real-time updates when connected useEffect(() => { if (!isConnected) return; // Join the project room to receive updates joinProject(projectId); // Clean up when component unmounts return () => { leaveProject(projectId); }; }, [isConnected, joinProject, leaveProject, projectId]); // Listen for group created events useEffect(() => { if (!isConnected) return; const unsubscribe = onGroupCreated((data) => { console.log("Group created:", data); if (data.action === "created" && data.group) { // Add the new group to the list setProject((prev: any) => ({ ...prev, groups: [...prev.groups, data.group] })); toast.success(`Nouveau groupe créé: ${data.group.name}`); } }); return () => { unsubscribe(); }; }, [isConnected, onGroupCreated]); // Listen for group updated events useEffect(() => { if (!isConnected) return; const unsubscribe = onGroupUpdated((data) => { console.log("Group updated:", data); if (data.action === "updated" && data.group) { // Update the group in the list setProject((prev: any) => ({ ...prev, groups: prev.groups.map((group: any) => group.id === data.group.id ? data.group : group ) })); toast.info(`Groupe mis à jour: ${data.group.name}`); } else if (data.action === "deleted" && data.group) { // Remove the group from the list setProject((prev: any) => ({ ...prev, groups: prev.groups.filter((group: any) => group.id !== data.group.id) })); toast.info(`Groupe supprimé: ${data.group.name}`); } }); return () => { unsubscribe(); }; }, [isConnected, onGroupUpdated]); // Listen for person added to group events useEffect(() => { if (!isConnected) return; const unsubscribe = onPersonAddedToGroup((data) => { console.log("Person added to group:", data); if (data.group && data.person) { // Update the group with the new person setProject((prev: any) => ({ ...prev, groups: prev.groups.map((group: any) => { if (group.id === data.group.id) { return { ...group, persons: [...group.persons, data.person] }; } return group; }) })); toast.success(`${data.person.name} a été ajouté au groupe ${data.group.name}`); } }); return () => { unsubscribe(); }; }, [isConnected, onPersonAddedToGroup]); // Listen for person removed from group events useEffect(() => { if (!isConnected) return; const unsubscribe = onPersonRemovedFromGroup((data) => { console.log("Person removed from group:", data); if (data.group && data.person) { // Update the group by removing the person setProject((prev: any) => ({ ...prev, groups: prev.groups.map((group: any) => { if (group.id === data.group.id) { return { ...group, persons: group.persons.filter((person: any) => person.id !== data.person.id) }; } return group; }) })); toast.info(`${data.person.name} a été retiré du groupe ${data.group.name}`); } }); return () => { unsubscribe(); }; }, [isConnected, onPersonRemovedFromGroup]); const handleCreateGroups = () => { router.push(`/projects/${projectId}/groups/create`); }; const handleAutoCreateGroups = () => { router.push(`/projects/${projectId}/groups/auto-create`); }; if (loading) { return (
); } if (!project) { return (

Projet non trouvé

); } return (

{project.name} - Groupes

Groupes existants Créer des groupes {project.groups.length === 0 ? ( Aucun groupe Ce projet ne contient pas encore de groupes. Créez-en un maintenant. ) : (
{project.groups.map((group: any) => ( {group.name} {group.persons.length} personnes
{group.persons.map((person: any) => (

{person.name}

{person.tags.map((tag: string, index: number) => ( {tag} ))}
))}
))}
)}
Création manuelle Créez des groupes manuellement en glissant-déposant les personnes

Utilisez l'interface de glisser-déposer pour créer vos groupes selon vos critères

Création automatique Laissez l'assistant créer des groupes équilibrés automatiquement

L'assistant prendra en compte les tags et niveaux pour créer des groupes équilibrés

); }