feat: add language context and translation support
- Introduced LanguageProvider to manage language state and translations. - Updated components (Header, Hero, About, Skills, Projects, Education, Contact) to utilize translations. - Added language toggle button in the header for switching between French and English. - Enhanced styling for language toggle button in the header.
This commit is contained in:
@@ -3,8 +3,10 @@ import { motion } from 'framer-motion';
|
||||
import { Mail, Phone, MapPin, Send, Github, Linkedin, MessageCircle, CheckCircle, AlertCircle } from 'lucide-react';
|
||||
import { sendContactEmail } from '../services/emailService';
|
||||
import type { ContactFormData } from '../services/emailService';
|
||||
import { useLanguage } from '../contexts/LanguageContext';
|
||||
|
||||
const Contact = () => {
|
||||
const { t } = useLanguage();
|
||||
const [formData, setFormData] = useState({
|
||||
name: '',
|
||||
email: '',
|
||||
@@ -93,7 +95,7 @@ const Contact = () => {
|
||||
{
|
||||
icon: <Linkedin size={24} />,
|
||||
name: "LinkedIn",
|
||||
url: "https://linkedin.com/in/dayronvanleemput", // Remplacez par votre profil
|
||||
url: "https://www.linkedin.com/in/dayron-van-leemput-992a94398", // Remplacez par votre profil
|
||||
color: "#0077B5"
|
||||
}
|
||||
];
|
||||
@@ -131,9 +133,9 @@ const Contact = () => {
|
||||
transition={{ duration: 0.8 }}
|
||||
viewport={{ once: true }}
|
||||
>
|
||||
<h2 className="section-title">Contactez-moi</h2>
|
||||
<h2 className="section-title">{t('contact.title')}</h2>
|
||||
<p className="section-subtitle">
|
||||
Une question, un projet ou simplement envie d'échanger ? N'hésitez pas à me contacter !
|
||||
{t('contact.subtitle')}
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
@@ -149,12 +151,10 @@ const Contact = () => {
|
||||
<div className="contact-intro">
|
||||
<h3>
|
||||
<MessageCircle size={24} />
|
||||
Restons en contact
|
||||
{t('contact.stayInTouch')}
|
||||
</h3>
|
||||
<p>
|
||||
Je suis toujours intéressé par de nouveaux projets, des collaborations
|
||||
ou simplement des discussions autour de la technologie. N'hésitez pas
|
||||
à me contacter !
|
||||
{t('contact.intro')}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -189,7 +189,7 @@ const Contact = () => {
|
||||
</div>
|
||||
|
||||
<div className="social-links">
|
||||
<h4>Retrouvez-moi aussi sur :</h4>
|
||||
<h4>{t('contact.findMeOn')}</h4>
|
||||
<div className="social-grid">
|
||||
{socialLinks.map((social, index) => (
|
||||
<motion.a
|
||||
@@ -223,7 +223,7 @@ const Contact = () => {
|
||||
|
||||
{/* Formulaire de contact */}
|
||||
<motion.div className="contact-form-container" variants={itemVariants}>
|
||||
<h3>Envoyez-moi un message</h3>
|
||||
<h3>{t('contact.sendMessage')}</h3>
|
||||
|
||||
{isSubmitted && (
|
||||
<motion.div
|
||||
@@ -233,7 +233,7 @@ const Contact = () => {
|
||||
exit={{ opacity: 0, scale: 0.8 }}
|
||||
>
|
||||
<CheckCircle size={20} />
|
||||
Message envoyé avec succès ! Je vous répondrai bientôt.
|
||||
{t('contact.success')}
|
||||
</motion.div>
|
||||
)}
|
||||
|
||||
@@ -258,7 +258,7 @@ const Contact = () => {
|
||||
transition={{ duration: 0.5, delay: 0.1 }}
|
||||
viewport={{ once: true }}
|
||||
>
|
||||
<label htmlFor="name">Nom complet</label>
|
||||
<label htmlFor="name">{t('contact.form.name')}</label>
|
||||
<input
|
||||
type="text"
|
||||
id="name"
|
||||
@@ -266,7 +266,7 @@ const Contact = () => {
|
||||
value={formData.name}
|
||||
onChange={handleChange}
|
||||
required
|
||||
placeholder="Votre nom"
|
||||
placeholder={t('contact.form.name')}
|
||||
/>
|
||||
</motion.div>
|
||||
|
||||
@@ -277,7 +277,7 @@ const Contact = () => {
|
||||
transition={{ duration: 0.5, delay: 0.2 }}
|
||||
viewport={{ once: true }}
|
||||
>
|
||||
<label htmlFor="email">Email</label>
|
||||
<label htmlFor="email">{t('contact.form.email')}</label>
|
||||
<input
|
||||
type="email"
|
||||
id="email"
|
||||
@@ -297,7 +297,7 @@ const Contact = () => {
|
||||
transition={{ duration: 0.5, delay: 0.3 }}
|
||||
viewport={{ once: true }}
|
||||
>
|
||||
<label htmlFor="subject">Sujet</label>
|
||||
<label htmlFor="subject">{t('contact.form.subject')}</label>
|
||||
<input
|
||||
type="text"
|
||||
id="subject"
|
||||
@@ -305,7 +305,7 @@ const Contact = () => {
|
||||
value={formData.subject}
|
||||
onChange={handleChange}
|
||||
required
|
||||
placeholder="Objet de votre message"
|
||||
placeholder={t('contact.form.subject')}
|
||||
/>
|
||||
</motion.div>
|
||||
|
||||
@@ -316,7 +316,7 @@ const Contact = () => {
|
||||
transition={{ duration: 0.5, delay: 0.4 }}
|
||||
viewport={{ once: true }}
|
||||
>
|
||||
<label htmlFor="message">Message</label>
|
||||
<label htmlFor="message">{t('contact.form.message')}</label>
|
||||
<textarea
|
||||
id="message"
|
||||
name="message"
|
||||
@@ -324,7 +324,7 @@ const Contact = () => {
|
||||
onChange={handleChange}
|
||||
required
|
||||
rows={6}
|
||||
placeholder="Votre message..."
|
||||
placeholder={t('contact.form.message')}
|
||||
/>
|
||||
</motion.div>
|
||||
|
||||
@@ -342,12 +342,12 @@ const Contact = () => {
|
||||
{isSubmitting ? (
|
||||
<>
|
||||
<div className="loading-spinner" />
|
||||
Envoi en cours...
|
||||
{t('contact.form.sending')}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Send size={20} />
|
||||
Envoyer le message
|
||||
{t('contact.form.send')}
|
||||
</>
|
||||
)}
|
||||
</motion.button>
|
||||
|
||||
Reference in New Issue
Block a user