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:
25
src/App.tsx
25
src/App.tsx
@@ -1,4 +1,5 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { LanguageProvider } from './contexts/LanguageContext';
|
||||
import Header from './components/Header';
|
||||
import Hero from './components/Hero';
|
||||
import About from './components/About';
|
||||
@@ -31,17 +32,19 @@ function App() {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={`app ${darkMode ? 'dark' : 'light'}`}>
|
||||
<Header darkMode={darkMode} toggleDarkMode={toggleDarkMode} />
|
||||
<main>
|
||||
<Hero />
|
||||
<About />
|
||||
<Skills />
|
||||
<Projects />
|
||||
<Education />
|
||||
<Contact />
|
||||
</main>
|
||||
</div>
|
||||
<LanguageProvider>
|
||||
<div className={`app ${darkMode ? 'dark' : 'light'}`}>
|
||||
<Header darkMode={darkMode} toggleDarkMode={toggleDarkMode} />
|
||||
<main>
|
||||
<Hero />
|
||||
<About />
|
||||
<Skills />
|
||||
<Projects />
|
||||
<Education />
|
||||
<Contact />
|
||||
</main>
|
||||
</div>
|
||||
</LanguageProvider>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
import { motion } from 'framer-motion';
|
||||
import { User, Heart, Target, Coffee } from 'lucide-react';
|
||||
import { useLanguage } from '../contexts/LanguageContext';
|
||||
|
||||
const About = () => {
|
||||
const { t } = useLanguage();
|
||||
|
||||
const stats = [
|
||||
{ icon: <User size={24} />, value: "3ème", label: "Année d'études" },
|
||||
{ icon: <Heart size={24} />, value: "100%", label: "Passion" },
|
||||
{ icon: <Target size={24} />, value: "∞", label: "Objectifs" },
|
||||
{ icon: <Coffee size={24} />, value: "☕", label: "Fuel quotidien" }
|
||||
{ icon: <User size={24} />, value: t('about.stats.year'), label: t('about.stats.yearLabel') },
|
||||
{ icon: <Heart size={24} />, value: t('about.stats.passion'), label: t('about.stats.passionLabel') },
|
||||
{ icon: <Target size={24} />, value: t('about.stats.goals'), label: t('about.stats.goalsLabel') },
|
||||
{ icon: <Coffee size={24} />, value: t('about.stats.fuel'), label: t('about.stats.fuelLabel') }
|
||||
];
|
||||
|
||||
const containerVariants = {
|
||||
@@ -42,9 +45,9 @@ const About = () => {
|
||||
transition={{ duration: 0.8 }}
|
||||
viewport={{ once: true }}
|
||||
>
|
||||
<h2 className="section-title">À propos de moi</h2>
|
||||
<h2 className="section-title">{t('about.title')}</h2>
|
||||
<p className="section-subtitle">
|
||||
Découvrez qui je suis et ce qui me passionne
|
||||
{t('about.subtitle')}
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
@@ -57,32 +60,23 @@ const About = () => {
|
||||
viewport={{ once: true }}
|
||||
>
|
||||
<motion.div className="about-card" variants={itemVariants}>
|
||||
<h3>Mon parcours</h3>
|
||||
<h3>{t('about.journey.title')}</h3>
|
||||
<p>
|
||||
Actuellement en 3ème année de <strong>Technologies de l'Informatique</strong> à la
|
||||
HELHa de Tournai, je me passionne pour le développement d'applications et les
|
||||
nouvelles technologies. Mon parcours m'a permis d'acquérir une solide base
|
||||
technique et une approche méthodique du développement.
|
||||
{t('about.journey.content')}
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div className="about-card" variants={itemVariants}>
|
||||
<h3>Ma passion</h3>
|
||||
<h3>{t('about.passion.title')}</h3>
|
||||
<p>
|
||||
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>.
|
||||
{t('about.passion.content')}
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div className="about-card" variants={itemVariants}>
|
||||
<h3>Mes objectifs</h3>
|
||||
<h3>{t('about.goals.title')}</h3>
|
||||
<p>
|
||||
Je cherche constamment à améliorer mes compétences et à rester à jour avec
|
||||
les dernières tendances technologiques. Mon objectif est de devenir un
|
||||
développeur full-stack polyvalent et de contribuer à des projets qui ont
|
||||
un impact positif.
|
||||
{t('about.goals.content')}
|
||||
</p>
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
@@ -123,13 +117,11 @@ const About = () => {
|
||||
viewport={{ once: true }}
|
||||
>
|
||||
<div className="highlight-content">
|
||||
<h3>En quelques mots</h3>
|
||||
<h3>{t('about.quote.title')}</h3>
|
||||
<p>
|
||||
"La technologie n'est rien. Ce qui est important, c'est d'avoir la foi en les gens,
|
||||
qu'ils soient fondamentalement bons et intelligents, et si vous leur donnez des outils,
|
||||
ils feront des choses merveilleuses avec."
|
||||
"{t('about.quote.content')}"
|
||||
</p>
|
||||
<cite>- Steve Jobs</cite>
|
||||
<cite>- {t('about.quote.author')}</cite>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -1,24 +1,26 @@
|
||||
import { motion } from 'framer-motion';
|
||||
import { GraduationCap, Calendar, MapPin, Award, BookOpen, Target } from 'lucide-react';
|
||||
import { useLanguage } from '../contexts/LanguageContext';
|
||||
|
||||
const Education = () => {
|
||||
const { t } = useLanguage();
|
||||
const education = [
|
||||
{
|
||||
id: 1,
|
||||
degree: "Bachelier en Technologies de l'Informatique",
|
||||
school: "HELHa - Haute École Louvain en Hainaut",
|
||||
location: "Tournai, Belgique",
|
||||
period: "2023 - 2026",
|
||||
currentYear: "3ème année",
|
||||
status: "En cours",
|
||||
description: "Formation complète en développement logiciel, programmation, bases de données, réseaux et gestion de projets informatiques.",
|
||||
degree: t('education.degree'),
|
||||
school: t('education.school'),
|
||||
location: t('education.location'),
|
||||
period: t('education.period'),
|
||||
currentYear: t('education.currentYear'),
|
||||
status: t('education.status'),
|
||||
description: t('education.description'),
|
||||
highlights: [
|
||||
"Programmation orientée objet (Java, C#)",
|
||||
"Développement web (HTML, CSS, JavaScript, React)",
|
||||
"Développement mobile (Flutter, Dart)",
|
||||
"Bases de données et SQL",
|
||||
"Gestion de projets",
|
||||
"Réseaux et systèmes"
|
||||
t('education.highlights.0'),
|
||||
t('education.highlights.1'),
|
||||
t('education.highlights.2'),
|
||||
t('education.highlights.3'),
|
||||
t('education.highlights.4'),
|
||||
t('education.highlights.5')
|
||||
],
|
||||
color: "#4CAF50",
|
||||
icon: <GraduationCap size={24} />
|
||||
@@ -27,16 +29,16 @@ const Education = () => {
|
||||
|
||||
const certifications = [
|
||||
{
|
||||
title: "Développement Mobile Flutter",
|
||||
provider: "Formation autodidacte",
|
||||
date: "2024",
|
||||
title: t('education.cert1.title'),
|
||||
provider: t('education.cert1.provider'),
|
||||
date: t('education.cert1.date'),
|
||||
skills: ["Dart", "Flutter", "Firebase", "API REST"],
|
||||
color: "#2196F3"
|
||||
},
|
||||
{
|
||||
title: "React & TypeScript",
|
||||
provider: "Projets personnels",
|
||||
date: "2024",
|
||||
title: t('education.cert2.title'),
|
||||
provider: t('education.cert2.provider'),
|
||||
date: t('education.cert2.date'),
|
||||
skills: ["React", "TypeScript", "Hooks", "Context API"],
|
||||
color: "#FF9800"
|
||||
}
|
||||
@@ -75,9 +77,9 @@ const Education = () => {
|
||||
transition={{ duration: 0.8 }}
|
||||
viewport={{ once: true }}
|
||||
>
|
||||
<h2 className="section-title">Formation & Apprentissage</h2>
|
||||
<h2 className="section-title">{t('education.title')}</h2>
|
||||
<p className="section-subtitle">
|
||||
Mon parcours académique et mes apprentissages continus
|
||||
{t('education.subtitle')}
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
@@ -178,7 +180,7 @@ const Education = () => {
|
||||
>
|
||||
<h3 className="certifications-title">
|
||||
<Award size={24} />
|
||||
Formations complémentaires & Autodidacte
|
||||
{t('education.certifications.title')}
|
||||
</h3>
|
||||
<div className="certifications-grid">
|
||||
{certifications.map((cert, index) => (
|
||||
@@ -224,13 +226,13 @@ const Education = () => {
|
||||
transition={{ duration: 0.8, delay: 0.4 }}
|
||||
viewport={{ once: true }}
|
||||
>
|
||||
<h3>Objectifs d'apprentissage 2025</h3>
|
||||
<h3>{t('education.learningGoals2025')}</h3>
|
||||
<div className="goals-grid">
|
||||
{[
|
||||
{ goal: "Maîtriser Firebase et les services cloud", progress: 60 },
|
||||
{ goal: "Approfondir Spring Boot pour le backend", progress: 30 },
|
||||
{ goal: "Apprendre Docker et les conteneurs", progress: 20 },
|
||||
{ goal: "Développer mes compétences en UI/UX", progress: 45 }
|
||||
{ goal: t('education.goal1'), progress: 60 },
|
||||
{ goal: t('education.goal2'), progress: 30 },
|
||||
{ goal: t('education.goal3'), progress: 20 },
|
||||
{ goal: t('education.goal4'), progress: 45 }
|
||||
].map((item, index) => (
|
||||
<motion.div
|
||||
key={index}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useState } from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
import { Menu, X, Sun, Moon } from 'lucide-react';
|
||||
import { Menu, X, Sun, Moon, Globe } from 'lucide-react';
|
||||
import { useLanguage } from '../contexts/LanguageContext';
|
||||
|
||||
interface HeaderProps {
|
||||
darkMode: boolean;
|
||||
@@ -9,14 +10,15 @@ interface HeaderProps {
|
||||
|
||||
const Header = ({ darkMode, toggleDarkMode }: HeaderProps) => {
|
||||
const [isMenuOpen, setIsMenuOpen] = useState(false);
|
||||
const { language, setLanguage, t } = useLanguage();
|
||||
|
||||
const menuItems = [
|
||||
{ name: 'Accueil', href: '#hero' },
|
||||
{ name: 'À propos', href: '#about' },
|
||||
{ name: 'Compétences', href: '#skills' },
|
||||
{ name: 'Projets', href: '#projects' },
|
||||
{ name: 'Formation', href: '#education' },
|
||||
{ name: 'Contact', href: '#contact' }
|
||||
{ name: t('nav.home'), href: '#hero' },
|
||||
{ name: t('nav.about'), href: '#about' },
|
||||
{ name: t('nav.skills'), href: '#skills' },
|
||||
{ name: t('nav.projects'), href: '#projects' },
|
||||
{ name: t('nav.education'), href: '#education' },
|
||||
{ name: t('nav.contact'), href: '#contact' }
|
||||
];
|
||||
|
||||
const scrollToSection = (href: string) => {
|
||||
@@ -27,6 +29,10 @@ const Header = ({ darkMode, toggleDarkMode }: HeaderProps) => {
|
||||
setIsMenuOpen(false);
|
||||
};
|
||||
|
||||
const toggleLanguage = () => {
|
||||
setLanguage(language === 'fr' ? 'en' : 'fr');
|
||||
};
|
||||
|
||||
return (
|
||||
<motion.header
|
||||
initial={{ y: -100 }}
|
||||
@@ -68,13 +74,26 @@ const Header = ({ darkMode, toggleDarkMode }: HeaderProps) => {
|
||||
</ul>
|
||||
|
||||
<div className="nav-controls">
|
||||
{/* Toggle langue */}
|
||||
<motion.button
|
||||
whileHover={{ scale: 1.1 }}
|
||||
whileTap={{ scale: 0.9 }}
|
||||
onClick={toggleLanguage}
|
||||
className="language-toggle"
|
||||
aria-label={t('btn.changeLang')}
|
||||
title={t('btn.changeLang')}
|
||||
>
|
||||
<Globe size={18} />
|
||||
<span className="language-text">{language === 'fr' ? 'EN' : 'FR'}</span>
|
||||
</motion.button>
|
||||
|
||||
{/* Toggle thème */}
|
||||
<motion.button
|
||||
whileHover={{ scale: 1.1 }}
|
||||
whileTap={{ scale: 0.9 }}
|
||||
onClick={toggleDarkMode}
|
||||
className="theme-toggle"
|
||||
aria-label="Changer de thème"
|
||||
aria-label={t('btn.changeTheme')}
|
||||
>
|
||||
{darkMode ? <Sun size={20} /> : <Moon size={20} />}
|
||||
</motion.button>
|
||||
@@ -85,7 +104,7 @@ const Header = ({ darkMode, toggleDarkMode }: HeaderProps) => {
|
||||
whileTap={{ scale: 0.9 }}
|
||||
onClick={() => setIsMenuOpen(!isMenuOpen)}
|
||||
className="menu-toggle"
|
||||
aria-label="Menu"
|
||||
aria-label={t('btn.menu')}
|
||||
>
|
||||
{isMenuOpen ? <X size={24} /> : <Menu size={24} />}
|
||||
</motion.button>
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import { motion } from 'framer-motion';
|
||||
import { Download, Github, Linkedin, Mail } from 'lucide-react';
|
||||
import { useLanguage } from '../contexts/LanguageContext';
|
||||
|
||||
const Hero = () => {
|
||||
const { t } = useLanguage();
|
||||
|
||||
const handleDownloadCV = () => {
|
||||
// Ici, vous pouvez ajouter le lien vers votre CV
|
||||
const link = document.createElement('a');
|
||||
@@ -25,7 +28,7 @@ const Hero = () => {
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
transition={{ duration: 0.8, delay: 0.4 }}
|
||||
>
|
||||
Dayron Van Leemput
|
||||
{t('hero.title')}
|
||||
</motion.h1>
|
||||
|
||||
<motion.h2
|
||||
@@ -34,7 +37,7 @@ const Hero = () => {
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
transition={{ duration: 0.8, delay: 0.6 }}
|
||||
>
|
||||
Étudiant en Technologies de l'Informatique
|
||||
{t('hero.subtitle')}
|
||||
</motion.h2>
|
||||
|
||||
<motion.p
|
||||
@@ -43,8 +46,7 @@ const Hero = () => {
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8, delay: 0.8 }}
|
||||
>
|
||||
Bac 3 à la HELHa de Tournai | Jeune développeur passionné par les nouvelles technologies
|
||||
et le développement d'applications innovantes
|
||||
{t('hero.description')}
|
||||
</motion.p>
|
||||
|
||||
<motion.div
|
||||
@@ -60,7 +62,7 @@ const Hero = () => {
|
||||
whileTap={{ scale: 0.95 }}
|
||||
>
|
||||
<Download size={20} />
|
||||
Télécharger mon CV
|
||||
{t('btn.downloadCV')}
|
||||
</motion.button>
|
||||
|
||||
<motion.a
|
||||
@@ -74,7 +76,7 @@ const Hero = () => {
|
||||
whileTap={{ scale: 0.95 }}
|
||||
>
|
||||
<Mail size={20} />
|
||||
Me contacter
|
||||
{t('btn.contactMe')}
|
||||
</motion.a>
|
||||
</motion.div>
|
||||
|
||||
@@ -96,7 +98,7 @@ const Hero = () => {
|
||||
</motion.a>
|
||||
|
||||
<motion.a
|
||||
href="https://linkedin.com/in/dayronvanleemput" // Remplacez par votre profil LinkedIn
|
||||
href="https://www.linkedin.com/in/dayron-van-leemput-992a94398" // Remplacez par votre profil LinkedIn
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="social-link"
|
||||
|
||||
@@ -1,19 +1,21 @@
|
||||
import { motion } from 'framer-motion';
|
||||
import { ExternalLink, Github, MapPin } from 'lucide-react';
|
||||
import { useLanguage } from '../contexts/LanguageContext';
|
||||
|
||||
const Projects = () => {
|
||||
const { t } = useLanguage();
|
||||
const projects = [
|
||||
{
|
||||
id: 1,
|
||||
title: "Travel Mate",
|
||||
description: "Application mobile conçue pour simplifier l'organisation de voyages de groupe. Elle permet de centraliser toutes les informations importantes d'un voyage : planification, gestion des dépenses, découverte d'activités et coordination entre les participants.",
|
||||
status: "Bientôt disponible sur App Store et Play Store",
|
||||
title: t('projects.travelMate.title'),
|
||||
description: t('projects.travelMate.description'),
|
||||
status: t('projects.status.available'),
|
||||
technologies: ["Dart", "Flutter", "Firebase"],
|
||||
features: [
|
||||
"Planification de voyage collaborative",
|
||||
"Gestion des dépenses partagées",
|
||||
"Découverte d'activités locales",
|
||||
"Coordination en temps réel"
|
||||
t('projects.travelMate.feature1'),
|
||||
t('projects.travelMate.feature2'),
|
||||
t('projects.travelMate.feature3'),
|
||||
t('projects.travelMate.feature4')
|
||||
],
|
||||
color: "#4CAF50",
|
||||
icon: <MapPin size={24} />,
|
||||
@@ -25,15 +27,15 @@ const Projects = () => {
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: "Portfolio Web",
|
||||
description: "Site web personnel moderne et responsive développé avec React et TypeScript. Inclut des animations fluides, un mode sombre/clair et une architecture modulaire.",
|
||||
status: "Projet actuel",
|
||||
title: t('projects.portfolio.title'),
|
||||
description: t('projects.portfolio.description'),
|
||||
status: t('projects.status.current'),
|
||||
technologies: ["React", "TypeScript", "Framer Motion", "CSS3"],
|
||||
features: [
|
||||
"Design responsive",
|
||||
"Animations fluides",
|
||||
"Mode sombre/clair",
|
||||
"Performance optimisée"
|
||||
t('projects.portfolio.feature1'),
|
||||
t('projects.portfolio.feature2'),
|
||||
t('projects.portfolio.feature3'),
|
||||
t('projects.portfolio.feature4')
|
||||
],
|
||||
color: "#2196F3",
|
||||
icon: <ExternalLink size={24} />,
|
||||
@@ -77,9 +79,9 @@ const Projects = () => {
|
||||
transition={{ duration: 0.8 }}
|
||||
viewport={{ once: true }}
|
||||
>
|
||||
<h2 className="section-title">Mes Projets</h2>
|
||||
<h2 className="section-title">{t('projects.title')}</h2>
|
||||
<p className="section-subtitle">
|
||||
Découvrez les projets sur lesquels j'ai travaillé et qui me tiennent à cœur
|
||||
{t('projects.subtitle')}
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
@@ -138,7 +140,7 @@ const Projects = () => {
|
||||
</div>
|
||||
|
||||
<div className="project-features">
|
||||
<h4>Fonctionnalités principales :</h4>
|
||||
<h4>{t('projects.features')}</h4>
|
||||
<ul>
|
||||
{project.features.map((feature, featureIndex) => (
|
||||
<motion.li
|
||||
@@ -170,7 +172,7 @@ const Projects = () => {
|
||||
whileTap={{ scale: 0.95 }}
|
||||
>
|
||||
<Github size={20} />
|
||||
Code
|
||||
{t('projects.btn.code')}
|
||||
</motion.a>
|
||||
)}
|
||||
{project.links.demo !== "#" && (
|
||||
@@ -183,7 +185,7 @@ const Projects = () => {
|
||||
whileTap={{ scale: 0.95 }}
|
||||
>
|
||||
<ExternalLink size={20} />
|
||||
Voir le projet
|
||||
{t('projects.btn.viewProject')}
|
||||
</motion.a>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import { motion } from 'framer-motion';
|
||||
import { Code, Database, Smartphone, Globe, Server, Wrench } from 'lucide-react';
|
||||
import { useLanguage } from '../contexts/LanguageContext';
|
||||
|
||||
const Skills = () => {
|
||||
const { t } = useLanguage();
|
||||
const skillCategories = [
|
||||
{
|
||||
icon: <Smartphone size={32} />,
|
||||
title: "Mobile",
|
||||
title: t('skills.category.mobile'),
|
||||
color: "#4FC3F7",
|
||||
skills: [
|
||||
{ name: "Dart", level: 85, color: "#0175C2" },
|
||||
@@ -14,7 +16,7 @@ const Skills = () => {
|
||||
},
|
||||
{
|
||||
icon: <Globe size={32} />,
|
||||
title: "Frontend",
|
||||
title: t('skills.category.frontend'),
|
||||
color: "#42A5F5",
|
||||
skills: [
|
||||
{ name: "React", level: 75, color: "#61DAFB" },
|
||||
@@ -24,7 +26,7 @@ const Skills = () => {
|
||||
},
|
||||
{
|
||||
icon: <Server size={32} />,
|
||||
title: "Backend",
|
||||
title: t('skills.category.backend'),
|
||||
color: "#66BB6A",
|
||||
skills: [
|
||||
{ name: "Java", level: 75, color: "#ED8B00" },
|
||||
@@ -33,7 +35,7 @@ const Skills = () => {
|
||||
},
|
||||
{
|
||||
icon: <Database size={32} />,
|
||||
title: "Outils & Autres",
|
||||
title: t('skills.category.tools'),
|
||||
color: "#AB47BC",
|
||||
skills: [
|
||||
{ name: "Git", level: 70, color: "#F05032" },
|
||||
@@ -76,9 +78,9 @@ const Skills = () => {
|
||||
transition={{ duration: 0.8 }}
|
||||
viewport={{ once: true }}
|
||||
>
|
||||
<h2 className="section-title">Compétences & Technologies</h2>
|
||||
<h2 className="section-title">{t('skills.title')}</h2>
|
||||
<p className="section-subtitle">
|
||||
Les technologies que je maîtrise et avec lesquelles j'aime travailler
|
||||
{t('skills.subtitle')}
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
@@ -157,13 +159,13 @@ const Skills = () => {
|
||||
transition={{ duration: 0.8, delay: 0.3 }}
|
||||
viewport={{ once: true }}
|
||||
>
|
||||
<h3 className="soft-skills-title">Autres compétences</h3>
|
||||
<h3 className="soft-skills-title">{t('skills.otherSkills')}</h3>
|
||||
<div className="soft-skills-grid">
|
||||
{[
|
||||
{ name: "Résolution de problèmes", icon: <Wrench size={20} /> },
|
||||
{ name: "Travail en équipe", icon: <Code size={20} /> },
|
||||
{ name: "Apprentissage continu", icon: <Database size={20} /> },
|
||||
{ name: "Communication", icon: <Globe size={20} /> }
|
||||
{ name: t('skills.problemSolving'), icon: <Wrench size={20} /> },
|
||||
{ name: t('skills.teamwork'), icon: <Code size={20} /> },
|
||||
{ name: t('skills.continuousLearning'), icon: <Database size={20} /> },
|
||||
{ name: t('skills.communication'), icon: <Globe size={20} /> }
|
||||
].map((softSkill, index) => (
|
||||
<motion.div
|
||||
key={softSkill.name}
|
||||
|
||||
296
src/contexts/LanguageContext.tsx
Normal file
296
src/contexts/LanguageContext.tsx
Normal file
@@ -0,0 +1,296 @@
|
||||
// ========================
|
||||
// CONTEXTE DE LANGUE
|
||||
// ========================
|
||||
|
||||
import React, { createContext, useContext, useState } from 'react';
|
||||
import type { ReactNode } from 'react';
|
||||
|
||||
// Types pour les langues supportées
|
||||
export type Language = 'fr' | 'en';
|
||||
|
||||
// Interface pour le contexte
|
||||
interface LanguageContextType {
|
||||
language: Language;
|
||||
setLanguage: (lang: Language) => void;
|
||||
t: (key: string) => string;
|
||||
}
|
||||
|
||||
// Textes traduits
|
||||
const translations = {
|
||||
fr: {
|
||||
// Navigation
|
||||
'nav.home': 'Accueil',
|
||||
'nav.about': 'À propos',
|
||||
'nav.skills': 'Compétences',
|
||||
'nav.projects': 'Projets',
|
||||
'nav.education': 'Formation',
|
||||
'nav.contact': 'Contact',
|
||||
|
||||
// Boutons
|
||||
'btn.changeTheme': 'Changer de thème',
|
||||
'btn.menu': 'Menu',
|
||||
'btn.changeLang': 'English',
|
||||
'btn.downloadCV': 'Télécharger CV',
|
||||
'btn.viewProjects': 'Voir mes projets',
|
||||
'btn.contactMe': 'Me contacter',
|
||||
|
||||
// Hero
|
||||
'hero.greeting': 'Salut, je suis',
|
||||
'hero.title': 'Dayron Van Leemput',
|
||||
'hero.subtitle': 'Étudiant en Technologies de l\'Informatique',
|
||||
'hero.description': 'Bac 3 à la HELHa de Tournai | Jeune développeur passionné par les nouvelles technologies et le développement d\'applications innovantes',
|
||||
|
||||
// About
|
||||
'about.title': 'À propos de moi',
|
||||
'about.subtitle': 'Découvrez mon parcours et mes passions',
|
||||
'about.stats.year': '3ème',
|
||||
'about.stats.yearLabel': 'Année d\'études',
|
||||
'about.stats.passion': '100%',
|
||||
'about.stats.passionLabel': 'Passion',
|
||||
'about.stats.goals': '∞',
|
||||
'about.stats.goalsLabel': 'Objectifs',
|
||||
'about.stats.fuel': '☕',
|
||||
'about.stats.fuelLabel': 'Fuel quotidien',
|
||||
'about.journey.title': 'Mon parcours',
|
||||
'about.journey.content': 'Actuellement en 3ème année de Technologies de l\'Informatique à la HELHa de Tournai, je me passionne pour le développement d\'applications et les nouvelles technologies. Mon parcours m\'a permis d\'acquérir une solide base technique et une approche méthodique du développement.',
|
||||
'about.passion.title': 'Ma passion',
|
||||
'about.passion.content': '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 Flutter et le développement web moderne avec React et TypeScript.',
|
||||
'about.goals.title': 'Mes objectifs',
|
||||
'about.goals.content': 'Je cherche constamment à améliorer mes compétences et à rester à jour avec les dernières tendances technologiques. Mon objectif est de devenir un développeur full-stack polyvalent et de contribuer à des projets qui ont un impact positif.',
|
||||
'about.quote.title': 'En quelques mots',
|
||||
'about.quote.content': 'La technologie n\'est rien. Ce qui est important, c\'est d\'avoir la foi en les gens, qu\'ils soient fondamentalement bons et intelligents, et si vous leur donnez des outils, ils feront des choses merveilleuses avec.',
|
||||
'about.quote.author': 'Steve Jobs',
|
||||
|
||||
// Skills
|
||||
'skills.title': 'Mes Compétences',
|
||||
'skills.subtitle': 'Technologies et outils que je maîtrise',
|
||||
'skills.category.mobile': 'Mobile',
|
||||
'skills.category.frontend': 'Frontend',
|
||||
'skills.category.backend': 'Backend',
|
||||
'skills.category.tools': 'Outils & Autres',
|
||||
'skills.otherSkills': 'Autres compétences',
|
||||
'skills.problemSolving': 'Résolution de problèmes',
|
||||
'skills.teamwork': 'Travail en équipe',
|
||||
'skills.continuousLearning': 'Apprentissage continu',
|
||||
'skills.communication': 'Communication',
|
||||
|
||||
// Projects
|
||||
'projects.title': 'Mes Projets',
|
||||
'projects.subtitle': 'Découvrez mes réalisations et mes expériences',
|
||||
'projects.status.available': 'Bientôt disponible sur App Store et Play Store',
|
||||
'projects.status.current': 'Projet actuel',
|
||||
'projects.features': 'Fonctionnalités principales :',
|
||||
'projects.btn.code': 'Code',
|
||||
'projects.btn.viewProject': 'Voir le projet',
|
||||
'projects.travelMate.title': 'Travel Mate',
|
||||
'projects.travelMate.description': 'Application mobile conçue pour simplifier l\'organisation de voyages de groupe. Elle permet de centraliser toutes les informations importantes d\'un voyage : planification, gestion des dépenses, découverte d\'activités et coordination entre les participants.',
|
||||
'projects.travelMate.feature1': 'Planification de voyage collaborative',
|
||||
'projects.travelMate.feature2': 'Gestion des dépenses partagées',
|
||||
'projects.travelMate.feature3': 'Découverte d\'activités locales',
|
||||
'projects.travelMate.feature4': 'Coordination en temps réel',
|
||||
'projects.portfolio.title': 'Portfolio Web',
|
||||
'projects.portfolio.description': 'Site web personnel moderne et responsive développé avec React et TypeScript. Inclut des animations fluides, un mode sombre/clair et une architecture modulaire.',
|
||||
'projects.portfolio.feature1': 'Design responsive',
|
||||
'projects.portfolio.feature2': 'Animations fluides',
|
||||
'projects.portfolio.feature3': 'Mode sombre/clair',
|
||||
'projects.portfolio.feature4': 'Performance optimisée',
|
||||
|
||||
// Education
|
||||
'education.title': 'Formation',
|
||||
'education.subtitle': 'Mon parcours académique et professionnel',
|
||||
'education.learningGoals2025': 'Objectifs d\'apprentissage 2025',
|
||||
'education.goal1': 'Maîtriser Firebase et les services cloud',
|
||||
'education.goal2': 'Approfondir Spring Boot pour le backend',
|
||||
'education.goal3': 'Apprendre Docker et les conteneurs',
|
||||
'education.goal4': 'Développer mes compétences en UI/UX',
|
||||
'education.degree': 'Bachelier en Technologies de l\'Informatique',
|
||||
'education.school': 'HELHa - Haute École Louvain en Hainaut',
|
||||
'education.location': 'Tournai, Belgique',
|
||||
'education.period': '2023 - 2026',
|
||||
'education.currentYear': '3ème année',
|
||||
'education.status': 'En cours',
|
||||
'education.description': 'Formation complète en développement logiciel, programmation, bases de données, réseaux et gestion de projets informatiques.',
|
||||
'education.highlights.0': 'Programmation orientée objet (Java, C#)',
|
||||
'education.highlights.1': 'Développement web (HTML, CSS, JavaScript, React)',
|
||||
'education.highlights.2': 'Développement mobile (Flutter, Dart)',
|
||||
'education.highlights.3': 'Bases de données et SQL',
|
||||
'education.highlights.4': 'Gestion de projets',
|
||||
'education.highlights.5': 'Réseaux et systèmes',
|
||||
'education.certifications.title': 'Certifications & Formations',
|
||||
'education.cert1.title': 'Développement Mobile Flutter',
|
||||
'education.cert1.provider': 'Formation autodidacte',
|
||||
'education.cert1.date': '2024',
|
||||
'education.cert2.title': 'React & TypeScript',
|
||||
'education.cert2.provider': 'Projets personnels',
|
||||
'education.cert2.date': '2024',
|
||||
|
||||
// Contact
|
||||
'contact.title': 'Contactez-moi',
|
||||
'contact.subtitle': 'Une question, un projet ou simplement envie d\'échanger ? N\'hésitez pas à me contacter !',
|
||||
'contact.form.name': 'Nom complet',
|
||||
'contact.form.email': 'Email',
|
||||
'contact.form.subject': 'Sujet',
|
||||
'contact.form.message': 'Message',
|
||||
'contact.form.send': 'Envoyer le message',
|
||||
'contact.form.sending': 'Envoi en cours...',
|
||||
'contact.success': 'Message envoyé avec succès ! Je vous répondrai bientôt.',
|
||||
'contact.stayInTouch': 'Restons en contact',
|
||||
'contact.intro': '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 !',
|
||||
'contact.findMeOn': 'Retrouvez-moi aussi sur :',
|
||||
'contact.sendMessage': 'Envoyez-moi un message',
|
||||
},
|
||||
en: {
|
||||
// Navigation
|
||||
'nav.home': 'Home',
|
||||
'nav.about': 'About',
|
||||
'nav.skills': 'Skills',
|
||||
'nav.projects': 'Projects',
|
||||
'nav.education': 'Education',
|
||||
'nav.contact': 'Contact',
|
||||
|
||||
// Boutons
|
||||
'btn.changeTheme': 'Change theme',
|
||||
'btn.menu': 'Menu',
|
||||
'btn.changeLang': 'Français',
|
||||
'btn.downloadCV': 'Download CV',
|
||||
'btn.viewProjects': 'View my projects',
|
||||
'btn.contactMe': 'Contact me',
|
||||
|
||||
// Hero
|
||||
'hero.greeting': 'Hi, I am',
|
||||
'hero.title': 'Dayron Van Leemput',
|
||||
'hero.subtitle': 'Computer Technology Student',
|
||||
'hero.description': 'Bachelor 3 at HELHa Tournai | Young developer passionate about new technologies and innovative application development',
|
||||
|
||||
// About
|
||||
'about.title': 'About me',
|
||||
'about.subtitle': 'Discover my journey and passions',
|
||||
'about.stats.year': '3rd',
|
||||
'about.stats.yearLabel': 'Year of studies',
|
||||
'about.stats.passion': '100%',
|
||||
'about.stats.passionLabel': 'Passion',
|
||||
'about.stats.goals': '∞',
|
||||
'about.stats.goalsLabel': 'Goals',
|
||||
'about.stats.fuel': '☕',
|
||||
'about.stats.fuelLabel': 'Daily fuel',
|
||||
'about.journey.title': 'My journey',
|
||||
'about.journey.content': 'Currently in my 3rd year of Computer Technology at HELHa Tournai, I am passionate about application development and new technologies. My journey has allowed me to acquire a solid technical foundation and a methodical approach to development.',
|
||||
'about.passion.title': 'My passion',
|
||||
'about.passion.content': 'What drives me most is creating innovative solutions that solve real problems. I particularly enjoy mobile development with Flutter and modern web development with React and TypeScript.',
|
||||
'about.goals.title': 'My goals',
|
||||
'about.goals.content': 'I constantly seek to improve my skills and stay up to date with the latest technological trends. My goal is to become a versatile full-stack developer and contribute to projects that have a positive impact.',
|
||||
'about.quote.title': 'In a few words',
|
||||
'about.quote.content': 'Technology is nothing. What\'s important is that you have a faith in people, that they\'re basically good and smart, and if you give them tools, they\'ll do wonderful things with them.',
|
||||
'about.quote.author': 'Steve Jobs',
|
||||
|
||||
// Skills
|
||||
'skills.title': 'My Skills',
|
||||
'skills.subtitle': 'Technologies and tools I master',
|
||||
'skills.category.mobile': 'Mobile',
|
||||
'skills.category.frontend': 'Frontend',
|
||||
'skills.category.backend': 'Backend',
|
||||
'skills.category.tools': 'Tools & Others',
|
||||
'skills.otherSkills': 'Other skills',
|
||||
'skills.problemSolving': 'Problem solving',
|
||||
'skills.teamwork': 'Teamwork',
|
||||
'skills.continuousLearning': 'Continuous learning',
|
||||
'skills.communication': 'Communication',
|
||||
|
||||
// Projects
|
||||
'projects.title': 'My Projects',
|
||||
'projects.subtitle': 'Discover my achievements and experiences',
|
||||
'projects.status.available': 'Coming soon on App Store and Play Store',
|
||||
'projects.status.current': 'Current project',
|
||||
'projects.features': 'Main features:',
|
||||
'projects.btn.code': 'Code',
|
||||
'projects.btn.viewProject': 'View project',
|
||||
'projects.travelMate.title': 'Travel Mate',
|
||||
'projects.travelMate.description': 'Mobile application designed to simplify group travel organization. It allows centralizing all important travel information: planning, expense management, activity discovery and coordination between participants.',
|
||||
'projects.travelMate.feature1': 'Collaborative travel planning',
|
||||
'projects.travelMate.feature2': 'Shared expense management',
|
||||
'projects.travelMate.feature3': 'Local activity discovery',
|
||||
'projects.travelMate.feature4': 'Real-time coordination',
|
||||
'projects.portfolio.title': 'Web Portfolio',
|
||||
'projects.portfolio.description': 'Modern and responsive personal website developed with React and TypeScript. Includes fluid animations, dark/light mode and modular architecture.',
|
||||
'projects.portfolio.feature1': 'Responsive design',
|
||||
'projects.portfolio.feature2': 'Fluid animations',
|
||||
'projects.portfolio.feature3': 'Dark/light mode',
|
||||
'projects.portfolio.feature4': 'Optimized performance',
|
||||
|
||||
// Education
|
||||
'education.title': 'Education',
|
||||
'education.subtitle': 'My academic and professional journey',
|
||||
'education.learningGoals2025': '2025 Learning Goals',
|
||||
'education.goal1': 'Master Firebase and cloud services',
|
||||
'education.goal2': 'Deepen Spring Boot for backend',
|
||||
'education.goal3': 'Learn Docker and containers',
|
||||
'education.goal4': 'Develop my UI/UX skills',
|
||||
'education.degree': 'Bachelor in Computer Technology',
|
||||
'education.school': 'HELHa - Haute École Louvain en Hainaut',
|
||||
'education.location': 'Tournai, Belgium',
|
||||
'education.period': '2023 - 2026',
|
||||
'education.currentYear': '3rd year',
|
||||
'education.status': 'In progress',
|
||||
'education.description': 'Complete training in software development, programming, databases, networks and IT project management.',
|
||||
'education.highlights.0': 'Object-oriented programming (Java, C#)',
|
||||
'education.highlights.1': 'Web development (HTML, CSS, JavaScript, React)',
|
||||
'education.highlights.2': 'Mobile development (Flutter, Dart)',
|
||||
'education.highlights.3': 'Databases and SQL',
|
||||
'education.highlights.4': 'Project management',
|
||||
'education.highlights.5': 'Networks and systems',
|
||||
'education.certifications.title': 'Certifications & Training',
|
||||
'education.cert1.title': 'Flutter Mobile Development',
|
||||
'education.cert1.provider': 'Self-taught training',
|
||||
'education.cert1.date': '2024',
|
||||
'education.cert2.title': 'React & TypeScript',
|
||||
'education.cert2.provider': 'Personal projects',
|
||||
'education.cert2.date': '2024',
|
||||
|
||||
// Contact
|
||||
'contact.title': 'Contact me',
|
||||
'contact.subtitle': 'A question, a project or just want to chat? Feel free to contact me!',
|
||||
'contact.form.name': 'Full name',
|
||||
'contact.form.email': 'Email',
|
||||
'contact.form.subject': 'Subject',
|
||||
'contact.form.message': 'Message',
|
||||
'contact.form.send': 'Send message',
|
||||
'contact.form.sending': 'Sending...',
|
||||
'contact.success': 'Message sent successfully! I will reply soon.',
|
||||
'contact.stayInTouch': 'Let\'s stay in touch',
|
||||
'contact.intro': 'I am always interested in new projects, collaborations or simply discussions about technology. Feel free to contact me!',
|
||||
'contact.findMeOn': 'Find me also on:',
|
||||
'contact.sendMessage': 'Send me a message',
|
||||
}
|
||||
};
|
||||
|
||||
// Création du contexte
|
||||
const LanguageContext = createContext<LanguageContextType | undefined>(undefined);
|
||||
|
||||
// Provider
|
||||
interface LanguageProviderProps {
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export const LanguageProvider: React.FC<LanguageProviderProps> = ({ children }) => {
|
||||
const [language, setLanguage] = useState<Language>('fr');
|
||||
|
||||
// Fonction de traduction
|
||||
const t = (key: string): string => {
|
||||
return translations[language][key as keyof typeof translations['fr']] || key;
|
||||
};
|
||||
|
||||
return (
|
||||
<LanguageContext.Provider value={{ language, setLanguage, t }}>
|
||||
{children}
|
||||
</LanguageContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
// Hook personnalisé
|
||||
export const useLanguage = (): LanguageContextType => {
|
||||
const context = useContext(LanguageContext);
|
||||
if (!context) {
|
||||
throw new Error('useLanguage must be used within a LanguageProvider');
|
||||
}
|
||||
return context;
|
||||
};
|
||||
@@ -93,7 +93,8 @@
|
||||
}
|
||||
|
||||
.theme-toggle,
|
||||
.menu-toggle {
|
||||
.menu-toggle,
|
||||
.language-toggle {
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--text-secondary);
|
||||
@@ -113,6 +114,25 @@
|
||||
}
|
||||
}
|
||||
|
||||
.language-toggle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 6px 10px;
|
||||
|
||||
.language-text {
|
||||
font-size: map-get($font-sizes, sm);
|
||||
font-weight: 600;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
@include respond-to(sm) {
|
||||
.language-text {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.menu-toggle {
|
||||
display: none;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user