import { readJson } from './readJson.js'; document.addEventListener('DOMContentLoaded', async function() { const navbar = document.querySelector("nav"); const header = document.querySelector("header"); let pagePath = ""; const linkInterceptor = () => { const a = document.querySelectorAll('a'); a.forEach(function(link) { if( link.getAttribute('data-page') != "externe") { link.addEventListener('click', function(event) { event.preventDefault(); const href = link.getAttribute('data-page'); const id = link.getAttribute('id'); if (!href) { console.warn('Attribut data-page introuvable sur la balise:', link); return; } if(id != "admin") { loadPage(`./Views/${href}.html`); } else { window.location.href = href; } }); } }); } const loadPage = async (page) => { const mainContent = document.querySelector('.main-content'); const loadProjects = async () => { try { const data = await readJson('./data/projects.json'); return data; } catch (error) { console.error('Erreur lors du chargement des projets :', error); return []; } } const loadDataContacts = async () => { try { const data = await readJson('./data/contacts.json'); return data; } catch (error) { console.error('Erreur lors du chargement des projets :', error); return []; } } if (!mainContent) { console.error('Élément .main-content introuvable dans le document.'); return; } if(mainContent) { fetch(page) .then(response => { if(!response.ok) { throw new Error(`Erreur lors du chargement de la page : ${response.statusText}`); } pagePath = page; return response.text(); }) .then(async (html) => { mainContent.innerHTML = html; linkInterceptor(); const divProjectsGrid = document.querySelector('.projects-grid'); if (divProjectsGrid) { console.log("Projects grid found, loading projects..."); const data = await loadProjects(); if (data) { const projects = Object.values(data); console.log('Projets :', projects); projects.forEach(project => { if (project.active) { const projectDiv = document.createElement('div'); projectDiv.className = 'project-card'; projectDiv.innerHTML = `

${project.type}

${project.name}

${project.description}

${project.link ? `
Voir le projet
` : ''}

${project.technologies && project.technologies.length > 0 ? project.technologies.map(tech => `${tech}`).join('') : ''}
`; divProjectsGrid.appendChild(projectDiv); } }); } } const contactPage = document.querySelector('.contact-page'); if (contactPage) { console.log("Contact page found, loading contact data..."); const data = await loadDataContacts(); if (data) { const email = document.querySelector('[data-id="email"]'); const phone = document.querySelector('[data-id="phone"]'); const github = document.querySelector('[data-id="github"]'); const linkedin = document.querySelector('[data-id="linkedin"]'); const twitter = document.querySelector('[data-id="twitter"]'); email.textContent = data.email; email.href = `mailto:${data.email}`; phone.textContent = data.gsm; phone.href = `tel:${data.gsm}`; github.href = data.github; linkedin.href = data.linkedin; twitter.href = data.twitter; } } }); } } // Animation pour l'en-tête au défilement window.addEventListener('scroll', () => { if (window.scrollY > 50) { navbar.classList.add('scrolled'); } else { navbar.classList.remove('scrolled'); } }); // Ajout de la détection du mode sombre const prefersDarkScheme = window.matchMedia("(prefers-color-scheme: dark)"); if (prefersDarkScheme.matches) { document.body.classList.add("dark-theme"); } // Gestion des formulaires document.addEventListener('submit', (e) => { const form = e.target.closest('form'); if (form) { e.preventDefault(); // Simuler l'envoi du formulaire const submitBtn = form.querySelector('button[type="submit"]'); if (submitBtn) { const originalText = submitBtn.textContent; submitBtn.textContent = 'Envoi en cours...'; submitBtn.disabled = true; setTimeout(() => { form.innerHTML = `

Message envoyé avec succès!

Merci pour votre message. Je vous répondrai dans les plus brefs délais.

`; }, 1500); } } }); // Animation des particules dans le header const createParticles = () => { const particlesContainer = document.getElementById('particles'); if (!particlesContainer) return; // Nombre de particules const particleCount = 30; // Supprimer les particules existantes particlesContainer.innerHTML = ''; // Créer de nouvelles particules for (let i = 0; i < particleCount; i++) { const particle = document.createElement('span'); particle.classList.add('particle'); // Attributs aléatoires pour chaque particule const size = Math.random() * 15 + 5; const posX = Math.random() * 100; const posY = Math.random() * 100; const delay = Math.random() * 5; const duration = Math.random() * 5 + 5; particle.style.width = `${size}px`; particle.style.height = `${size}px`; particle.style.left = `${posX}%`; particle.style.top = `${posY}%`; particle.style.animation = `float ${duration}s infinite ${delay}s`; particle.style.opacity = Math.random() * 0.5 + 0.3; particlesContainer.appendChild(particle); } }; // Effet d'écriture au clavier const initTypeWriter = () => { const textElement = document.getElementById('typing-text'); if (!textElement) return; const phrases = [ "Développeur Web & Applications", "Développeur Python", "Développeur JavaScript", "Développeur C# & Unity", "Développeur EmberJS", "Développeur Typescript", "Développeur Angular", ]; let phraseIndex = 0; let charIndex = 0; let isDeleting = false; let typingSpeed = 100; let isWaiting = false; function typeWriter() { if (isWaiting) { setTimeout(typeWriter, typingSpeed); isWaiting = false; return; } const currentPhrase = phrases[phraseIndex]; if (isDeleting) { // Effacer le texte textElement.textContent = currentPhrase.substring(0, charIndex - 1); charIndex--; typingSpeed = 30; // Plus rapide pour effacer } else { // Écrire le texte textElement.textContent = currentPhrase.substring(0, charIndex + 1); charIndex++; // Variation aléatoire de la vitesse pour un effet plus naturel typingSpeed = Math.random() * 50 + 80; } // Si toute la phrase est écrite if (!isDeleting && charIndex === currentPhrase.length) { // Pause avant d'effacer isDeleting = true; typingSpeed = 2000; // Pause plus longue isWaiting = true; } // Si la phrase est effacée if (isDeleting && charIndex === 0) { isDeleting = false; phraseIndex = (phraseIndex + 1) % phrases.length; typingSpeed = 700; // Pause avant la prochaine phrase isWaiting = true; } setTimeout(typeWriter, typingSpeed); } typeWriter(); // Effet d'apparition du curseur const cursor = document.querySelector('.cursor'); if (cursor) { cursor.style.animation = 'blink 1s step-end infinite'; } }; // Effet de défilement doux lorsqu'on clique sur le header if (header) { header.addEventListener('click', () => { // Défilement vers la section suivante const nextSection = document.querySelector('nav'); if (nextSection) { window.scrollTo({ top: nextSection.offsetTop, behavior: 'smooth' }); } }); // Effet visuel au survol pour indiquer que le header est cliquable header.style.cursor = 'pointer'; header.addEventListener('mouseenter', () => { header.style.transform = 'scale(1.01)'; }); header.addEventListener('mouseleave', () => { header.style.transform = 'scale(1)'; }); } // Initialiser les particules et l'effet d'écriture createParticles(); initTypeWriter(); loadPage('Views/home.html'); });