"use client"; import { useState, useMemo, useRef, useEffect } from "react"; 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 { UserProfile, Team } from "@/lib/types"; import { Search, Building2, ChevronDown, Check, Save, X } from "lucide-react"; import { useToast } from "@/hooks/use-toast"; interface AccountFormProps { initialProfile: UserProfile; teams: Team[]; } export function AccountForm({ initialProfile, teams }: AccountFormProps) { const [firstName, setFirstName] = useState(initialProfile.firstName); const [lastName, setLastName] = useState(initialProfile.lastName); const [teamId, setTeamId] = useState(initialProfile.teamId); const [searchTerm, setSearchTerm] = useState(""); const [isTeamDropdownOpen, setIsTeamDropdownOpen] = useState(false); const [isEditing, setIsEditing] = useState(false); const [loading, setLoading] = useState(false); const teamDropdownRef = useRef(null); const [dropdownPosition, setDropdownPosition] = useState<"below" | "above">( "below" ); const { toast } = useToast(); const hasChanges = firstName !== initialProfile.firstName || lastName !== initialProfile.lastName || teamId !== initialProfile.teamId; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); if (!hasChanges) return; setLoading(true); try { const response = await fetch("/api/auth/profile", { method: "PUT", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ firstName, lastName, teamId, }), }); if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.error || "Erreur lors de la mise à jour"); } const result = await response.json(); toast({ title: "Profil mis à jour", description: result.message || "Vos informations ont été modifiées avec succès.", }); setIsEditing(false); } catch (error: any) { console.error("Update failed:", error); toast({ title: "Erreur de mise à jour", description: error.message || "Erreur lors de la mise à jour du profil", variant: "destructive", }); } finally { setLoading(false); } }; const handleCancel = () => { setFirstName(initialProfile.firstName); setLastName(initialProfile.lastName); setTeamId(initialProfile.teamId); setIsEditing(false); }; // Group teams by direction and filter by search term const teamsByDirection = useMemo(() => { const filteredTeams = teams.filter( (team) => team.name.toLowerCase().includes(searchTerm.toLowerCase()) || team.direction.toLowerCase().includes(searchTerm.toLowerCase()) ); return filteredTeams.reduce((acc, team) => { if (!acc[team.direction]) { acc[team.direction] = []; } acc[team.direction].push(team); return acc; }, {} as Record); }, [teams, searchTerm]); // Calculate dropdown position when opening const handleDropdownToggle = () => { if (!isTeamDropdownOpen && teamDropdownRef.current) { const rect = teamDropdownRef.current.getBoundingClientRect(); const viewportHeight = window.innerHeight; const spaceBelow = viewportHeight - rect.bottom; const spaceAbove = rect.top; const dropdownHeight = 300; setDropdownPosition( spaceBelow >= dropdownHeight || spaceBelow > spaceAbove ? "below" : "above" ); } setIsTeamDropdownOpen(!isTeamDropdownOpen); }; // Close dropdown when clicking outside useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if ( teamDropdownRef.current && !teamDropdownRef.current.contains(event.target as Node) ) { setIsTeamDropdownOpen(false); } }; document.addEventListener("mousedown", handleClickOutside); return () => document.removeEventListener("mousedown", handleClickOutside); }, []); const selectedTeam = teams.find((team) => team.id === teamId); return ( Informations personnelles Modifiez vos informations personnelles. Vos identifiants de connexion (email et mot de passe) ne peuvent pas être modifiés ici.
setFirstName(e.target.value)} placeholder="Votre prénom" disabled={!isEditing} required />
setLastName(e.target.value)} placeholder="Votre nom" disabled={!isEditing} required />
{isTeamDropdownOpen && isEditing && (
setSearchTerm(e.target.value)} className="pl-8 h-8 text-sm" autoFocus />
{Object.entries(teamsByDirection).map( ([direction, directionTeams]) => (
{direction}
{directionTeams.map((team) => ( ))}
) )} {Object.keys(teamsByDirection).length === 0 && (
Aucune équipe trouvée pour "{searchTerm}"
)}
)}
{!isEditing ? ( ) : ( <> )}
); }