"use client"; import { useState, useRef, useTransition, type ChangeEvent } from "react"; import { Avatar, Input, Textarea, Button, Alert, Card, BackgroundSection, SectionTitle, ProgressBar } from "@/components/ui"; import { updateProfile } from "@/actions/profile/update-profile"; import { updatePassword } from "@/actions/profile/update-password"; type CharacterClass = | "WARRIOR" | "MAGE" | "ROGUE" | "RANGER" | "PALADIN" | "ENGINEER" | "MERCHANT" | "SCHOLAR" | "BERSERKER" | "NECROMANCER" | null; interface UserProfile { id: string; email: string; username: string; avatar: string | null; bio: string | null; characterClass: CharacterClass; hp: number; maxHp: number; xp: number; maxXp: number; level: number; score: number; createdAt: string; } interface ProfileFormProps { initialProfile: UserProfile; backgroundImage: string; } const formatNumber = (num: number): string => { return num.toLocaleString("en-US"); }; export default function ProfileForm({ initialProfile, backgroundImage, }: ProfileFormProps) { const [profile, setProfile] = useState(initialProfile); const [isPending, startTransition] = useTransition(); const [error, setError] = useState(null); const [success, setSuccess] = useState(null); const [username, setUsername] = useState(initialProfile.username); const [avatar, setAvatar] = useState(initialProfile.avatar); const [bio, setBio] = useState(initialProfile.bio || null); const [characterClass, setCharacterClass] = useState( initialProfile.characterClass || 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 [isChangingPassword, startPasswordTransition] = useTransition(); const handleAvatarUpload = async (e: 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(); setError(null); setSuccess(null); startTransition(async () => { const result = await updateProfile({ username, avatar, bio, characterClass, }); if (result.success && result.data) { setProfile({ ...result.data, createdAt: result.data.createdAt instanceof Date ? result.data.createdAt.toISOString() : result.data.createdAt, } as UserProfile); setBio(result.data.bio || null); setCharacterClass(result.data.characterClass as CharacterClass || null); setSuccess("Profil mis à jour avec succès"); setTimeout(() => setSuccess(null), 3000); } else { setError(result.error || "Erreur lors de la mise à jour"); } }); }; const handlePasswordChange = async (e: React.FormEvent) => { e.preventDefault(); setError(null); setSuccess(null); startPasswordTransition(async () => { const result = await updatePassword({ currentPassword, newPassword, confirmPassword, }); if (result.success) { setSuccess(result.message || "Mot de passe modifié avec succès"); setCurrentPassword(""); setNewPassword(""); setConfirmPassword(""); setShowPasswordForm(false); setTimeout(() => setSuccess(null), 3000); } else { setError(result.error || "Erreur lors de la modification du mot de passe"); } }); }; return (
{/* Title Section */} PROFIL {/* Profile Card */}
{/* Messages */} {error && {error}} {success && {success}} {/* Avatar Section */}
{uploadingAvatar && (
Upload...
)}
{/* Avatars par défaut */}
{[ "/avatar-1.jpg", "/avatar-2.jpg", "/avatar-3.jpg", "/avatar-4.jpg", "/avatar-5.jpg", "/avatar-6.jpg", ].map((defaultAvatar) => ( ))}
{/* Username Field */} setUsername(e.target.value)} required minLength={3} maxLength={20} className="bg-black/40" />

3-20 caractères

{/* Bio Field */}