mirror of
https://github.com/Ladebeze66/devsite.git
synced 2025-12-15 13:36:49 +01:00
endcontact
This commit is contained in:
parent
ed31d784a6
commit
ae85204879
24
app/admin/messages/page.tsx
Normal file
24
app/admin/messages/page.tsx
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
export default async function MessagesPage() {
|
||||||
|
const res = await fetch("http://localhost:1337/api/messages");
|
||||||
|
const { data } = await res.json();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="max-w-3xl mx-auto p-6">
|
||||||
|
<h1 className="text-3xl font-bold text-center mb-6">📬 Messages reçus</h1>
|
||||||
|
{data.length === 0 ? (
|
||||||
|
<p className="text-center text-gray-600">Aucun message reçu.</p>
|
||||||
|
) : (
|
||||||
|
<ul className="space-y-4">
|
||||||
|
{data.map((msg: any) => (
|
||||||
|
<li key={msg.id} className="p-4 border rounded shadow">
|
||||||
|
<p><strong>👤 {msg.name}</strong> ({msg.email})</p>
|
||||||
|
<p>📅 {new Date(msg.createdAt).toLocaleString("fr-FR")}</p>
|
||||||
|
<p className="mt-2">{msg.message}</p>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
102
app/components/ContactForm.tsx
Normal file
102
app/components/ContactForm.tsx
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useState } from "react";
|
||||||
|
import { sendMessage } from "../utils/sendMessage";
|
||||||
|
|
||||||
|
export default function ContactForm() {
|
||||||
|
const [name, setName] = useState("");
|
||||||
|
const [email, setEmail] = useState("");
|
||||||
|
const [message, setMessage] = useState("");
|
||||||
|
const [status, setStatus] = useState("");
|
||||||
|
const [isSuccess, setIsSuccess] = useState<boolean | null>(null);
|
||||||
|
const [isLoading, setIsLoading] = useState(false); // ✅ Nouvel état pour désactiver le bouton
|
||||||
|
|
||||||
|
const handleSubmit = async (e: React.FormEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
if (!name.trim() || !email.trim() || !message.trim()) {
|
||||||
|
setStatus("❌ Tous les champs sont obligatoires.");
|
||||||
|
setIsSuccess(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
|
||||||
|
setStatus("❌ Email invalide.");
|
||||||
|
setIsSuccess(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setStatus("⏳ Envoi en cours...");
|
||||||
|
setIsSuccess(null);
|
||||||
|
setIsLoading(true); // ✅ Désactive le bouton pendant l'envoi
|
||||||
|
|
||||||
|
try {
|
||||||
|
await sendMessage(name, email, message);
|
||||||
|
setStatus("✅ Message envoyé avec succès !");
|
||||||
|
setIsSuccess(true);
|
||||||
|
setName("");
|
||||||
|
setEmail("");
|
||||||
|
setMessage("");
|
||||||
|
} catch (error) {
|
||||||
|
setStatus("❌ Erreur lors de l'envoi du message.");
|
||||||
|
setIsSuccess(false);
|
||||||
|
} finally {
|
||||||
|
setIsLoading(false); // ✅ Réactive le bouton après l'envoi
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form
|
||||||
|
onSubmit={handleSubmit}
|
||||||
|
className="max-w-lg mx-auto p-6 bg-white shadow-lg rounded-lg animate-fade-in"
|
||||||
|
>
|
||||||
|
<h2 className="text-2xl font-bold mb-4 text-center">📩 Contactez-moi</h2>
|
||||||
|
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="Votre nom"
|
||||||
|
value={name}
|
||||||
|
onChange={(e) => setName(e.target.value)}
|
||||||
|
className="w-full p-3 border border-gray-300 rounded mb-3 focus:outline-none focus:ring-2 focus:ring-blue-400"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
placeholder="Votre email"
|
||||||
|
value={email}
|
||||||
|
onChange={(e) => setEmail(e.target.value)}
|
||||||
|
className="w-full p-3 border border-gray-300 rounded mb-3 focus:outline-none focus:ring-2 focus:ring-blue-400"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
|
||||||
|
<textarea
|
||||||
|
placeholder="Votre message"
|
||||||
|
value={message}
|
||||||
|
onChange={(e) => setMessage(e.target.value)}
|
||||||
|
className="w-full p-3 border border-gray-300 rounded mb-3 focus:outline-none focus:ring-2 focus:ring-blue-400"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
disabled={isLoading} // ✅ Désactive le bouton pendant l'envoi
|
||||||
|
className={`w-full py-3 rounded transition ${
|
||||||
|
isLoading ? "bg-gray-400 cursor-not-allowed" : "bg-blue-500 hover:bg-blue-600 text-white"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{isLoading ? "⏳ Envoi..." : "Envoyer"}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{/* ✅ Affichage du message de confirmation */}
|
||||||
|
{status && (
|
||||||
|
<p
|
||||||
|
className={`mt-4 text-center ${isSuccess ? "text-green-600" : "text-red-600"}`}
|
||||||
|
aria-live="polite" // ✅ Accessibilité pour les lecteurs d’écran
|
||||||
|
>
|
||||||
|
{status}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -1,7 +1,22 @@
|
|||||||
export default function Page() {
|
import ContactForm from "../components/ContactForm";
|
||||||
return (
|
|
||||||
<div>
|
export default function ContactPage() {
|
||||||
<h1>A propos de nous!!!</h1>
|
return (
|
||||||
|
<div className="max-w-3xl mx-auto p-6">
|
||||||
|
<h1 className="text-3xl font-bold text-center mb-6">Contactez-moi</h1>
|
||||||
|
<p className="text-lg text-center mb-4">
|
||||||
|
Vous pouvez me contacter via ce formulaire ou sur mes réseaux sociaux.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{/* Liens vers les réseaux sociaux */}
|
||||||
|
<div className="flex justify-center space-x-4 mb-6">
|
||||||
|
<a href="https://linkedin.com/in/votreprofil" className="text-blue-500">LinkedIn</a>
|
||||||
|
<a href="https://twitter.com/votreprofil" className="text-blue-500">Twitter</a>
|
||||||
|
<a href="mailto:votre@email.com" className="text-blue-500">Email</a>
|
||||||
</div>
|
</div>
|
||||||
)
|
|
||||||
}
|
{/* Formulaire de contact */}
|
||||||
|
<ContactForm />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@ -19,3 +19,19 @@ body {
|
|||||||
background: var(--background);
|
background: var(--background);
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes fade-in {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(-10px);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-fade-in {
|
||||||
|
animation: fade-in 0.5s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
32
app/utils/sendMessage.ts
Normal file
32
app/utils/sendMessage.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
export async function sendMessage(name: string, email: string, message: string) {
|
||||||
|
const dateTime = new Date().toLocaleString("fr-FR", { timeZone: "Europe/Paris" }); // ✅ Date formatée en français
|
||||||
|
|
||||||
|
const messageWithDate = `${message}\n\n📅 Envoyé le : ${dateTime}`; // ✅ Ajout de la date à la fin du message
|
||||||
|
|
||||||
|
console.log("📨 Envoi du message...", { name, email, messageWithDate });
|
||||||
|
|
||||||
|
const res = await fetch("http://localhost:1337/api/messages", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
data: {
|
||||||
|
name: name,
|
||||||
|
email: email,
|
||||||
|
message: messageWithDate, // ✅ Message modifié avec la date
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const responseData = await res.json();
|
||||||
|
|
||||||
|
if (!res.ok) {
|
||||||
|
console.error("❌ Erreur API Strapi :", responseData);
|
||||||
|
throw new Error(`Échec de l'envoi du message: ${responseData.error.message}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("✅ Message envoyé avec succès !", responseData);
|
||||||
|
return responseData;
|
||||||
|
}
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user