feat: update portfolio with new contact form functionality and improved styling

- Removed outdated CV file and replaced with a new image for the profile.
- Implemented a new email service using EmailJS for contact form submissions.
- Enhanced the contact form to handle errors and success messages.
- Updated the About section for grammatical accuracy.
- Modified the Hero component to link to the new CV file and updated GitHub profile link.
- Updated project links to point to the correct GitHub repositories.
- Improved styling for error messages and avatar image with hover effects.
This commit is contained in:
Dayron
2025-11-12 00:47:02 +01:00
parent cdff0c8c5c
commit a4b4423ff4
16 changed files with 1657 additions and 35 deletions

View File

@@ -69,7 +69,7 @@ const About = () => {
<motion.div className="about-card" variants={itemVariants}>
<h3>Ma passion</h3>
<p>
Ce qui m'anime le plus, c'est la création d'solutions innovantes qui résolvent
Ce qui m'anime le plus, c'est la création de solutions innovantes qui résolvent
des problèmes réels. J'aime particulièrement le développement mobile avec
<strong> Flutter</strong> et le développement web moderne avec
<strong> React</strong> et <strong> TypeScript</strong>.

View File

@@ -1,6 +1,8 @@
import { useState } from 'react';
import { motion } from 'framer-motion';
import { Mail, Phone, MapPin, Send, Github, Linkedin, MessageCircle, CheckCircle } from 'lucide-react';
import { Mail, Phone, MapPin, Send, Github, Linkedin, MessageCircle, CheckCircle, AlertCircle } from 'lucide-react';
import { sendContactEmail } from '../services/emailService';
import type { ContactFormData } from '../services/emailService';
const Contact = () => {
const [formData, setFormData] = useState({
@@ -11,6 +13,7 @@ const Contact = () => {
});
const [isSubmitting, setIsSubmitting] = useState(false);
const [isSubmitted, setIsSubmitted] = useState(false);
const [error, setError] = useState<string | null>(null);
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
const { name, value } = e.target;
@@ -23,32 +26,51 @@ const Contact = () => {
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setIsSubmitting(true);
setError(null);
// Simulation d'envoi (remplacez par votre logique d'envoi réelle)
setTimeout(() => {
setIsSubmitting(false);
setIsSubmitted(true);
setFormData({ name: '', email: '', subject: '', message: '' });
try {
const contactData: ContactFormData = {
name: formData.name,
email: formData.email,
subject: formData.subject,
message: formData.message
};
// Reset du message de succès après 5 secondes
setTimeout(() => {
setIsSubmitted(false);
}, 5000);
}, 2000);
const result = await sendContactEmail(contactData);
if (result.success) {
setIsSubmitted(true);
setFormData({ name: '', email: '', subject: '', message: '' });
// Reset du message de succès après 5 secondes
setTimeout(() => {
setIsSubmitted(false);
}, 5000);
} else {
setError(result.message);
}
} catch (err) {
const errorMessage = err instanceof Error ? err.message : 'Une erreur est survenue lors de l\'envoi du message.';
setError(errorMessage);
console.error('Erreur lors de l\'envoi de l\'email:', err);
} finally {
setIsSubmitting(false);
}
};
const contactInfo = [
{
icon: <Mail size={24} />,
title: "Email",
content: "dayronvanleemput@gmail.com", // Remplacez par votre email
content: "dayronvanleemput@gmail.com",
link: "mailto:dayronvanleemput@gmail.com",
color: "#EA4335"
},
{
icon: <Phone size={24} />,
title: "Téléphone",
content: "+32 455 19 47 62", // Remplacez par votre numéro
content: "+32 455 19 47 62",
link: "tel:+32455194762",
color: "#34A853"
},
@@ -214,6 +236,18 @@ const Contact = () => {
Message envoyé avec succès ! Je vous répondrai bientôt.
</motion.div>
)}
{error && (
<motion.div
className="error-message"
initial={{ opacity: 0, scale: 0.8 }}
animate={{ opacity: 1, scale: 1 }}
exit={{ opacity: 0, scale: 0.8 }}
>
<AlertCircle size={20} />
{error}
</motion.div>
)}
<form onSubmit={handleSubmit} className="contact-form">
<div className="form-row">
@@ -330,7 +364,7 @@ const Contact = () => {
viewport={{ once: true }}
>
<p>
© 2025 Dayron Van Leemput. Développé avec ❤️ en React et TypeScript.
© 2025 Dayron Van Leemput.
</p>
</motion.footer>
</div>

View File

@@ -5,8 +5,8 @@ const Hero = () => {
const handleDownloadCV = () => {
// Ici, vous pouvez ajouter le lien vers votre CV
const link = document.createElement('a');
link.href = '/cv-dayron-van-leemput.pdf'; // Ajoutez votre CV dans le dossier public
link.download = 'CV-Dayron-Van-Leemput.pdf';
link.href = '/Dayron_Van_Leemput_CV.pdf'; // Ajoutez votre CV dans le dossier public
link.download = 'Dayron_Van_Leemput_CV.pdf';
link.click();
};
@@ -85,7 +85,7 @@ const Hero = () => {
transition={{ duration: 0.8, delay: 1.2 }}
>
<motion.a
href="https://github.com/dayronvanleemput" // Remplacez par votre profil GitHub
href="https://github.com/Dayron-HELHa" // Remplacez par votre profil GitHub
target="_blank"
rel="noopener noreferrer"
className="social-link"
@@ -119,10 +119,11 @@ const Hero = () => {
whileHover={{ scale: 1.05, rotate: 5 }}
transition={{ type: "spring", stiffness: 300, damping: 10 }}
>
{/* Vous pouvez remplacer ceci par votre photo */}
<div className="avatar-placeholder">
<span>DV</span>
</div>
<img
src="/dvl.jpg"
alt="Dayron Van Leemput - Portrait"
className="avatar-image"
/>
</motion.div>
</motion.div>
</div>

View File

@@ -18,7 +18,7 @@ const Projects = () => {
color: "#4CAF50",
icon: <MapPin size={24} />,
links: {
github: "#", // Remplacez par votre lien GitHub
github: "https://github.com/Dayron-HELHa/travel_mate", // Remplacez par votre lien GitHub
demo: "#"
},
image: "/travel-mate-preview.png" // Ajoutez votre image dans le dossier public
@@ -38,8 +38,8 @@ const Projects = () => {
color: "#2196F3",
icon: <ExternalLink size={24} />,
links: {
github: "https://github.com/dayronvanleemput/portfolio", // Remplacez par votre lien
demo: "https://dayronvanleemput.dev" // Remplacez par votre lien
github: "https://github.com/Dayron-HELHa/xeewy.eu", // Remplacez par votre lien
demo: "https://xeewy.eu" // Remplacez par votre lien
}
}
];