From aaee2b595213b86344189fc0e67602c0abe64adc Mon Sep 17 00:00:00 2001 From: Ladebeze66 Date: Sun, 9 Feb 2025 17:36:50 +0100 Subject: [PATCH] okhttps --- app/Competences/[slug]/page.tsx | 7 ++-- app/components/ContentSectionCompetences.tsx | 41 +++++++++++++------ .../ContentSectionCompetencesContainer.tsx | 40 +++++++++++++++--- app/page.tsx | 2 +- app/utils/fetchDataCompetences.ts | 21 ++++++---- 5 files changed, 79 insertions(+), 32 deletions(-) diff --git a/app/Competences/[slug]/page.tsx b/app/Competences/[slug]/page.tsx index 609cbd8..f3d2e0b 100644 --- a/app/Competences/[slug]/page.tsx +++ b/app/Competences/[slug]/page.tsx @@ -1,9 +1,10 @@ import ContentSectionCompetencesContainer from "../../components/ContentSectionCompetencesContainer"; -export default function CompetencePage({ params }: { params: { slug: string } }) { - // Vérifie que le paramètre `slug` est bien défini +export default function CompetencePage({ params }: { params: { slug?: string } }) { + // ✅ Vérification du slug avant d'afficher le composant if (!params?.slug) { - return
Erreur : Slug introuvable.
; + console.error("❌ [CompetencePage] Erreur : Aucun slug fourni !"); + return
❌ Erreur : Compétence introuvable.
; } return ; diff --git a/app/components/ContentSectionCompetences.tsx b/app/components/ContentSectionCompetences.tsx index 1a03854..0f02700 100644 --- a/app/components/ContentSectionCompetences.tsx +++ b/app/components/ContentSectionCompetences.tsx @@ -1,7 +1,7 @@ "use client"; import { useState, useEffect } from "react"; -import { getApiUrl } from "../utils/getApiUrl"; // ✅ Importation de l'URL dynamique +import { getApiUrl } from "../utils/getApiUrl"; import CarouselCompetences from "./CarouselCompetences"; import ReactMarkdown from "react-markdown"; import rehypeRaw from "rehype-raw"; @@ -37,28 +37,42 @@ interface ContentSectionProps { contentClass?: string; } -// ✅ Composant principal -export default function ContentSectionCompetences({ competenceData, glossaireData, titleClass, contentClass }: ContentSectionProps) { +export default function ContentSectionCompetences({ + competenceData, + glossaireData, + titleClass, + contentClass, +}: ContentSectionProps) { console.log("🔍 [ContentSectionCompetences] Chargement du composant..."); - console.log("📌 [ContentSectionCompetences] Données reçues - competenceData :", competenceData); - console.log("📌 [ContentSectionCompetences] Données reçues - glossaireData :", glossaireData); const [selectedMot, setSelectedMot] = useState(null); - const apiUrl = getApiUrl(); // ✅ Détection automatique de l'URL API + const [loading, setLoading] = useState(competenceData === null); // ✅ Initialiser correctement loading + const apiUrl = getApiUrl(); + + useEffect(() => { + if (competenceData) { + setLoading(false); // ✅ Mise à jour de loading une seule fois après chargement + } + }, [competenceData]); + + // ✅ Affichage d'un message de chargement + if (loading) { + return
⏳ Chargement des détails de la compétence...
; + } if (!competenceData) { console.error("❌ [ContentSectionCompetences] Compétence introuvable !"); return
❌ Compétence introuvable.
; } - // ✅ Déstructuration des données de la compétence const { name, content, picture } = competenceData; // ✅ Transformation des images de Strapi en format attendu par le carrousel - const images = picture?.map((img) => ({ - url: `${apiUrl}${img.formats?.large?.url || img.url}`, // ✅ Correction ici - alt: img.name || "Image de compétence", - })) || []; + const images = + picture?.map((img) => ({ + url: `${apiUrl}${img.formats?.large?.url || img.url}`, + alt: img.name || "Image de compétence", + })) || []; console.log("✅ [ContentSectionCompetences] Images préparées :", images); @@ -68,7 +82,9 @@ export default function ContentSectionCompetences({ competenceData, glossaireDat let modifiedText = text; glossaireData.forEach(({ mot_clef, variantes }) => { - const regexVariants = variantes.map((v) => v.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|"); + const regexVariants = variantes + .map((v) => v.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")) + .join("|"); const regex = new RegExp(`\\b(${mot_clef}|${regexVariants})\\b`, "gi"); modifiedText = modifiedText.replace(regex, (match) => { @@ -101,7 +117,6 @@ export default function ContentSectionCompetences({ competenceData, glossaireDat return (
- {/* ✅ Ajout de logs visuels dans le rendu */}

{name}

diff --git a/app/components/ContentSectionCompetencesContainer.tsx b/app/components/ContentSectionCompetencesContainer.tsx index 6bb439e..e6fdaf3 100644 --- a/app/components/ContentSectionCompetencesContainer.tsx +++ b/app/components/ContentSectionCompetencesContainer.tsx @@ -1,3 +1,6 @@ +"use client"; // ✅ Indique que ce composant fonctionne côté client + +import { useEffect, useState } from "react"; import { fetchDataCompetences, fetchDataGlossaire } from "../utils/fetchDataCompetences"; import ContentSectionCompetences from "./ContentSectionCompetences"; @@ -8,14 +11,39 @@ interface ContentSectionProps { contentClass?: string; } -export default async function ContentSectionCompetencesContainer({ collection, slug, titleClass, contentClass }: ContentSectionProps) { +export default function ContentSectionCompetencesContainer({ collection, slug, titleClass, contentClass }: ContentSectionProps) { console.log("🔍 [ContentSectionCompetencesContainer] Chargement des données..."); - - const competenceData = await fetchDataCompetences(collection, slug); - console.log("✅ [ContentSectionCompetencesContainer] Données compétences :", JSON.stringify(competenceData, null, 2)); - const glossaireData = await fetchDataGlossaire(); - console.log("✅ [ContentSectionCompetencesContainer] Données glossaire :", JSON.stringify(glossaireData, null, 2)); + // ✅ États pour stocker les données récupérées + const [competenceData, setCompetenceData] = useState(null); + const [glossaireData, setGlossaireData] = useState([]); + const [loading, setLoading] = useState(true); + + useEffect(() => { + async function fetchData() { + setLoading(true); + try { + const competence = await fetchDataCompetences(collection, slug); + console.log("✅ [ContentSectionCompetencesContainer] Données compétences :", competence); + setCompetenceData(competence); + + const glossaire = await fetchDataGlossaire(); + console.log("✅ [ContentSectionCompetencesContainer] Données glossaire :", glossaire); + setGlossaireData(glossaire); + } catch (error) { + console.error("❌ [ContentSectionCompetencesContainer] Erreur lors de la récupération des données :", error); + } finally { + setLoading(false); + } + } + + fetchData(); + }, [collection, slug]); // ⚡ S'exécute à chaque changement de `collection` ou `slug` + + // ✅ Affichage d'un message de chargement + if (loading) { + return
⏳ Chargement des compétences...
; + } return ( setHomepage(data)); }, []); - if (!homepage) return

Erreur lors du chargement du contenu.

; + if (!homepage) return

Chargement de la page...

; const title = homepage.title ?? "Titre par défaut"; const cv = homepage.cv ?? ""; diff --git a/app/utils/fetchDataCompetences.ts b/app/utils/fetchDataCompetences.ts index 0c5ef3d..f991874 100644 --- a/app/utils/fetchDataCompetences.ts +++ b/app/utils/fetchDataCompetences.ts @@ -3,6 +3,11 @@ import { getApiUrl } from "./getApiUrl"; export async function fetchDataCompetences(collection: string, slug: string) { const apiUrl = getApiUrl(); + if (!apiUrl) { + console.error("❌ [fetchDataCompetences] URL de l'API invalide !"); + return null; + } + const query = qs.stringify({ filters: { slug: { $eq: slug } }, populate: "picture", @@ -14,11 +19,8 @@ export async function fetchDataCompetences(collection: string, slug: string) { try { const response = await fetch(fullUrl, { cache: "no-store" }); - console.log(`📡 [fetchDataCompetences] Réponse HTTP : ${response.status} ${response.statusText}`); - if (!response.ok) { - console.error(`❌ [fetchDataCompetences] Erreur HTTP ${response.status} : ${response.statusText}`); - return null; + throw new Error(`HTTP ${response.status} : ${response.statusText}`); } const data = await response.json(); @@ -32,18 +34,19 @@ export async function fetchDataCompetences(collection: string, slug: string) { export async function fetchDataGlossaire() { const apiUrl = getApiUrl(); - const fullUrl = `${apiUrl}/api/glossaires?populate=images`; + if (!apiUrl) { + console.error("❌ [fetchDataGlossaire] URL de l'API invalide !"); + return []; + } + const fullUrl = `${apiUrl}/api/glossaires?populate=images`; console.log("🔍 [fetchDataGlossaire] Requête API :", fullUrl); try { const response = await fetch(fullUrl, { cache: "no-store" }); - console.log(`📡 [fetchDataGlossaire] Réponse HTTP : ${response.status} ${response.statusText}`); - if (!response.ok) { - console.error(`❌ [fetchDataGlossaire] Erreur HTTP ${response.status} : ${response.statusText}`); - return []; + throw new Error(`HTTP ${response.status} : ${response.statusText}`); } const data = await response.json();