"use client"; import { useEffect, useState, useRef } from "react"; import { useSession } from "next-auth/react"; import { useRouter } from "next/navigation"; import Navigation from "@/components/Navigation"; import { useBackgroundImage } from "@/hooks/usePreferences"; interface UserProfile { id: string; email: string; username: string; avatar: string | null; hp: number; maxHp: number; xp: number; maxXp: number; level: number; score: number; createdAt: string; } const formatNumber = (num: number): string => { return num.toLocaleString("en-US"); }; export default function ProfilePage() { const { data: session, status } = useSession(); const router = useRouter(); const backgroundImage = useBackgroundImage("home", "/got-background.jpg"); const [profile, setProfile] = useState(null); const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); const [error, setError] = useState(null); const [success, setSuccess] = useState(null); const [username, setUsername] = useState(""); const [avatar, setAvatar] = useState(null); const fileInputRef = useRef(null); const [uploadingAvatar, setUploadingAvatar] = useState(false); // Password change form state const [showPasswordForm, setShowPasswordForm] = useState(false); const [currentPassword, setCurrentPassword] = useState(""); const [newPassword, setNewPassword] = useState(""); const [confirmPassword, setConfirmPassword] = useState(""); const [changingPassword, setChangingPassword] = useState(false); useEffect(() => { if (status === "unauthenticated") { router.push("/login"); return; } if (status === "authenticated" && session?.user) { fetchProfile(); } }, [status, session, router]); const fetchProfile = async () => { try { const response = await fetch("/api/profile"); if (response.ok) { const data = await response.json(); setProfile(data); setUsername(data.username); setAvatar(data.avatar); } else { setError("Erreur lors du chargement du profil"); } } catch (err) { console.error("Error fetching profile:", err); setError("Erreur lors du chargement du profil"); } finally { setLoading(false); } }; const handleAvatarUpload = async (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (!file) return; setUploadingAvatar(true); setError(null); try { const formData = new FormData(); formData.append("file", file); const response = await fetch("/api/profile/avatar", { method: "POST", body: formData, }); if (response.ok) { const data = await response.json(); setAvatar(data.url); setSuccess("Avatar mis à jour avec succès"); setTimeout(() => setSuccess(null), 3000); } else { const errorData = await response.json(); setError(errorData.error || "Erreur lors de l'upload de l'avatar"); } } catch (err) { console.error("Error uploading avatar:", err); setError("Erreur lors de l'upload de l'avatar"); } finally { setUploadingAvatar(false); if (fileInputRef.current) { fileInputRef.current.value = ""; } } }; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setSaving(true); setError(null); setSuccess(null); try { const response = await fetch("/api/profile", { method: "PUT", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ username, avatar, }), }); if (response.ok) { const data = await response.json(); setProfile(data); setSuccess("Profil mis à jour avec succès"); setTimeout(() => setSuccess(null), 3000); } else { const errorData = await response.json(); setError(errorData.error || "Erreur lors de la mise à jour"); } } catch (err) { console.error("Error updating profile:", err); setError("Erreur lors de la mise à jour du profil"); } finally { setSaving(false); } }; const handlePasswordChange = async (e: React.FormEvent) => { e.preventDefault(); setChangingPassword(true); setError(null); setSuccess(null); try { const response = await fetch("/api/profile/password", { method: "PUT", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ currentPassword, newPassword, confirmPassword, }), }); if (response.ok) { setSuccess("Mot de passe modifié avec succès"); setCurrentPassword(""); setNewPassword(""); setConfirmPassword(""); setShowPasswordForm(false); setTimeout(() => setSuccess(null), 3000); } else { const errorData = await response.json(); setError(errorData.error || "Erreur lors de la modification du mot de passe"); } } catch (err) { console.error("Error changing password:", err); setError("Erreur lors de la modification du mot de passe"); } finally { setChangingPassword(false); } }; if (loading || status === "loading") { return (
Chargement...
); } if (!profile) { return (
Erreur lors du chargement du profil
); } const hpPercentage = (profile.hp / profile.maxHp) * 100; const xpPercentage = (profile.xp / profile.maxXp) * 100; const hpColor = hpPercentage > 60 ? "from-green-600 to-green-700" : hpPercentage > 30 ? "from-yellow-600 to-orange-700" : "from-red-700 to-red-900"; return (
{/* Background Image */}
{/* Dark overlay for readability */}
{/* Content */}
{/* Title Section */}

PROFIL

Gérez votre profil
{/* Profile Card */}
{/* Messages */} {error && (
{error}
)} {success && (
{success}
)} {/* Avatar Section */}
{avatar ? ( {username} ) : ( {username.charAt(0).toUpperCase()} )}
{uploadingAvatar && (
Upload...
)}
{/* Username Field */}
setUsername(e.target.value)} className="w-full px-4 py-3 bg-black/40 border border-pixel-gold/30 rounded text-white focus:outline-none focus:border-pixel-gold transition" required minLength={3} maxLength={20} />

3-20 caractères

{/* Stats Display */}

Statistiques

Score
{formatNumber(profile.score)}
Niveau
Lv.{profile.level}
{/* HP Bar */}
HP {profile.hp} / {profile.maxHp}
{/* XP Bar */}
XP {formatNumber(profile.xp)} / {formatNumber(profile.maxXp)}
{/* Email (read-only) */}
{/* Submit Button */}
{/* Password Change Section - Separate form */}

Mot de passe

{!showPasswordForm && ( )}
{showPasswordForm && (
setCurrentPassword(e.target.value)} className="w-full px-4 py-3 bg-black/40 border border-pixel-gold/30 rounded text-white focus:outline-none focus:border-pixel-gold transition" required />
setNewPassword(e.target.value)} className="w-full px-4 py-3 bg-black/40 border border-pixel-gold/30 rounded text-white focus:outline-none focus:border-pixel-gold transition" required minLength={6} />

Minimum 6 caractères

setConfirmPassword(e.target.value)} className="w-full px-4 py-3 bg-black/40 border border-pixel-gold/30 rounded text-white focus:outline-none focus:border-pixel-gold transition" required minLength={6} />
)}
); }