diff --git a/app/components/ContactForm.tsx b/app/components/ContactForm.tsx index 9cfa622..47076f3 100644 --- a/app/components/ContactForm.tsx +++ b/app/components/ContactForm.tsx @@ -3,98 +3,158 @@ import { useState } from "react"; import { sendMessage } from "../utils/sendMessage"; +/** + * Formulaire de contact — refonte "Digital Atelier" (étape 8). + * + * - Plus de `bg-white shadow-lg rounded-lg` sur le form : il est désormais + * monté dans la carte vellum de `app/contact/page.js`. + * - Champs : `bg-surface-container-low`, radius `rounded-tile`, `focus-visible:ring-2 focus-visible:ring-primary`. + * - CTA jewel : `bg-primary text-on-primary shadow-jewel` avec Material Symbol + * `send` + effet `-translate-y-0.5` au hover, état disabled en `bg-outline-variant/60`. + * - Bandeau status Stitch : succès en `primary-fixed`, erreur en `error-container`, + * chargement en `surface-container`. Chaque état porte une Material Symbol. + */ export default function ContactForm() { const [name, setName] = useState(""); const [email, setEmail] = useState(""); const [message, setMessage] = useState(""); const [status, setStatus] = useState(""); - const [isSuccess, setIsSuccess] = useState(null); - const [isLoading, setIsLoading] = useState(false); + const [statusKind, setStatusKind] = useState< + "idle" | "loading" | "success" | "error" + >("idle"); + + const isLoading = statusKind === "loading"; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); if (!name.trim() || !email.trim() || !message.trim()) { - setStatus("❌ Tous les champs sont obligatoires."); - setIsSuccess(false); + setStatus("Tous les champs sont obligatoires."); + setStatusKind("error"); return; } if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) { - setStatus("❌ Email invalide."); - setIsSuccess(false); + setStatus("Email invalide."); + setStatusKind("error"); return; } - setStatus("⏳ Envoi en cours..."); - setIsSuccess(null); - setIsLoading(true); + setStatus("Envoi en cours…"); + setStatusKind("loading"); try { await sendMessage(name, email, message); - setStatus("✅ Message envoyé avec succès !"); - setIsSuccess(true); + setStatus("Message envoyé. Merci, je reviens vers vous rapidement."); + setStatusKind("success"); setName(""); setEmail(""); setMessage(""); } catch (error) { - setStatus("❌ Erreur lors de l'envoi du message."); - setIsSuccess(false); - } finally { - setIsLoading(false); + setStatus("Erreur lors de l'envoi du message."); + setStatusKind("error"); } }; + const statusStyles: Record = { + idle: "", + loading: + "bg-surface-container text-on-surface-variant", + success: + "bg-primary-fixed/70 text-on-primary-fixed", + error: "bg-error-container text-on-error-container", + }; + + const statusIcon: Record = { + idle: "", + loading: "hourglass_top", + success: "check_circle", + error: "error", + }; + + const fieldClass = + "w-full rounded-tile bg-surface-container-low/90 px-4 py-3 font-body text-base text-on-surface placeholder:text-on-surface-variant/70 focus:outline-none focus-visible:ring-2 focus-visible:ring-primary"; + return ( -
-

📩 Contactez-moi

+ + - setName(e.target.value)} - className="w-full p-3 border border-gray-300 font-headline font-bold rounded mb-3 focus:outline-none focus:ring-2 focus:ring-blue-400" - required - /> + - setEmail(e.target.value)} - className="w-full p-3 border border-gray-300 rounded font-headline font-bold mb-3 focus:outline-none focus:ring-2 focus:ring-blue-400" - required - /> - -