"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 { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { ArrowLeft, Loader2, Save, Plus, X } from "lucide-react"; import { Badge } from "@/components/ui/badge"; import { toast } from "sonner"; // Mock project data (same as in the groups page) 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", 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"] }, ] }; }; // Type definitions interface Person { id: number; name: string; tags: string[]; } interface Group { id: number; name: string; persons: Person[]; } export default function CreateGroupsPage() { const params = useParams(); const router = useRouter(); const projectId = params.id as string; const [project, setProject] = useState(null); const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); // State for groups and available persons const [groups, setGroups] = useState([]); const [availablePersons, setAvailablePersons] = useState([]); const [newGroupName, setNewGroupName] = useState(""); // State for drag and drop const [draggedPerson, setDraggedPerson] = useState(null); const [draggedFromGroup, setDraggedFromGroup] = useState(null); const [dragOverGroup, setDragOverGroup] = useState(null); useEffect(() => { // Simulate API call to fetch project data const fetchProject = async () => { setLoading(true); try { // In a real app, this would be an API call await new Promise(resolve => setTimeout(resolve, 1000)); const data = getProjectData(projectId); setProject(data); setAvailablePersons(data.persons); } catch (error) { console.error("Error fetching project:", error); toast.error("Erreur lors du chargement du projet"); } finally { setLoading(false); } }; fetchProject(); }, [projectId]); const handleAddGroup = () => { if (!newGroupName.trim()) { toast.error("Veuillez entrer un nom de groupe"); return; } const newGroup: Group = { id: Date.now(), // Use timestamp as temporary ID name: newGroupName, persons: [] }; setGroups([...groups, newGroup]); setNewGroupName(""); }; const handleRemoveGroup = (groupId: number) => { const group = groups.find(g => g.id === groupId); if (group) { // Return persons from this group to available persons setAvailablePersons([...availablePersons, ...group.persons]); } setGroups(groups.filter(g => g.id !== groupId)); }; const handleDragStart = (person: Person, fromGroup: number | null) => { setDraggedPerson(person); setDraggedFromGroup(fromGroup); }; const handleDragOver = (e: React.DragEvent, toGroup: number | null) => { e.preventDefault(); setDragOverGroup(toGroup); }; const handleDrop = (e: React.DragEvent, toGroup: number | null) => { e.preventDefault(); if (!draggedPerson) return; // Remove person from source if (draggedFromGroup === null) { // From available persons setAvailablePersons(availablePersons.filter(p => p.id !== draggedPerson.id)); } else { // From another group const sourceGroup = groups.find(g => g.id === draggedFromGroup); if (sourceGroup) { const updatedGroups = groups.map(g => { if (g.id === draggedFromGroup) { return { ...g, persons: g.persons.filter(p => p.id !== draggedPerson.id) }; } return g; }); setGroups(updatedGroups); } } // Add person to destination if (toGroup === null) { // To available persons setAvailablePersons([...availablePersons, draggedPerson]); } else { // To a group const updatedGroups = groups.map(g => { if (g.id === toGroup) { return { ...g, persons: [...g.persons, draggedPerson] }; } return g; }); setGroups(updatedGroups); } // Reset drag state setDraggedPerson(null); setDraggedFromGroup(null); setDragOverGroup(null); }; const handleSaveGroups = async () => { setSaving(true); try { // Validate that all groups have at least one person const emptyGroups = groups.filter(g => g.persons.length === 0); if (emptyGroups.length > 0) { toast.error(`${emptyGroups.length} groupe(s) vide(s). Veuillez ajouter des personnes à tous les groupes.`); setSaving(false); return; } // In a real app, this would be an API call to save the groups await new Promise(resolve => setTimeout(resolve, 1000)); toast.success("Groupes enregistrés avec succès"); // Navigate back to the groups page router.push(`/projects/${projectId}/groups`); } catch (error) { console.error("Error saving groups:", error); toast.error("Erreur lors de l'enregistrement des groupes"); } finally { setSaving(false); } }; if (loading) { return (
); } if (!project) { return (

Projet non trouvé

); } return (

Créer des groupes

{/* Available persons */}
handleDragOver(e, null)} onDrop={(e) => handleDrop(e, null)} >

Personnes disponibles ({availablePersons.length})

{availablePersons.map(person => (
handleDragStart(person, null)} >

{person.name}

{person.tags.map((tag, index) => ( {tag} ))}
))} {availablePersons.length === 0 && (

Toutes les personnes ont été assignées à des groupes

)}
{/* Groups */}
{/* Add new group form */} Ajouter un nouveau groupe
setNewGroupName(e.target.value)} />
{/* Groups list */} {groups.length === 0 ? (

Aucun groupe créé. Commencez par ajouter un groupe.

) : (
{groups.map(group => ( handleDragOver(e, group.id)} onDrop={(e) => handleDrop(e, group.id)} > {group.name}
{group.persons.map(person => (
handleDragStart(person, group.id)} >

{person.name}

{person.tags.map((tag, index) => ( {tag} ))}
))} {group.persons.length === 0 && (
Glissez-déposez des personnes ici
)}
))}
)}
); }