mirror of
https://github.com/Ladebeze66/devsite.git
synced 2025-12-15 13:36:49 +01:00
okhttps
This commit is contained in:
parent
d45d36465c
commit
aaee2b5952
@ -1,9 +1,10 @@
|
|||||||
import ContentSectionCompetencesContainer from "../../components/ContentSectionCompetencesContainer";
|
import ContentSectionCompetencesContainer from "../../components/ContentSectionCompetencesContainer";
|
||||||
|
|
||||||
export default function CompetencePage({ params }: { params: { slug: string } }) {
|
export default function CompetencePage({ params }: { params: { slug?: string } }) {
|
||||||
// Vérifie que le paramètre `slug` est bien défini
|
// ✅ Vérification du slug avant d'afficher le composant
|
||||||
if (!params?.slug) {
|
if (!params?.slug) {
|
||||||
return <div>Erreur : Slug introuvable.</div>;
|
console.error("❌ [CompetencePage] Erreur : Aucun slug fourni !");
|
||||||
|
return <div className="text-center text-red-500">❌ Erreur : Compétence introuvable.</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
return <ContentSectionCompetencesContainer collection="competences" slug={params.slug} />;
|
return <ContentSectionCompetencesContainer collection="competences" slug={params.slug} />;
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useState, useEffect } from "react";
|
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 CarouselCompetences from "./CarouselCompetences";
|
||||||
import ReactMarkdown from "react-markdown";
|
import ReactMarkdown from "react-markdown";
|
||||||
import rehypeRaw from "rehype-raw";
|
import rehypeRaw from "rehype-raw";
|
||||||
@ -37,28 +37,42 @@ interface ContentSectionProps {
|
|||||||
contentClass?: string;
|
contentClass?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ✅ Composant principal
|
export default function ContentSectionCompetences({
|
||||||
export default function ContentSectionCompetences({ competenceData, glossaireData, titleClass, contentClass }: ContentSectionProps) {
|
competenceData,
|
||||||
|
glossaireData,
|
||||||
|
titleClass,
|
||||||
|
contentClass,
|
||||||
|
}: ContentSectionProps) {
|
||||||
console.log("🔍 [ContentSectionCompetences] Chargement du composant...");
|
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<GlossaireItem | null>(null);
|
const [selectedMot, setSelectedMot] = useState<GlossaireItem | null>(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 <div className="text-center text-gray-500">⏳ Chargement des détails de la compétence...</div>;
|
||||||
|
}
|
||||||
|
|
||||||
if (!competenceData) {
|
if (!competenceData) {
|
||||||
console.error("❌ [ContentSectionCompetences] Compétence introuvable !");
|
console.error("❌ [ContentSectionCompetences] Compétence introuvable !");
|
||||||
return <div className="text-red-500 text-center">❌ Compétence introuvable.</div>;
|
return <div className="text-red-500 text-center">❌ Compétence introuvable.</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ✅ Déstructuration des données de la compétence
|
|
||||||
const { name, content, picture } = competenceData;
|
const { name, content, picture } = competenceData;
|
||||||
|
|
||||||
// ✅ Transformation des images de Strapi en format attendu par le carrousel
|
// ✅ Transformation des images de Strapi en format attendu par le carrousel
|
||||||
const images = picture?.map((img) => ({
|
const images =
|
||||||
url: `${apiUrl}${img.formats?.large?.url || img.url}`, // ✅ Correction ici
|
picture?.map((img) => ({
|
||||||
alt: img.name || "Image de compétence",
|
url: `${apiUrl}${img.formats?.large?.url || img.url}`,
|
||||||
})) || [];
|
alt: img.name || "Image de compétence",
|
||||||
|
})) || [];
|
||||||
|
|
||||||
console.log("✅ [ContentSectionCompetences] Images préparées :", images);
|
console.log("✅ [ContentSectionCompetences] Images préparées :", images);
|
||||||
|
|
||||||
@ -68,7 +82,9 @@ export default function ContentSectionCompetences({ competenceData, glossaireDat
|
|||||||
|
|
||||||
let modifiedText = text;
|
let modifiedText = text;
|
||||||
glossaireData.forEach(({ mot_clef, variantes }) => {
|
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");
|
const regex = new RegExp(`\\b(${mot_clef}|${regexVariants})\\b`, "gi");
|
||||||
|
|
||||||
modifiedText = modifiedText.replace(regex, (match) => {
|
modifiedText = modifiedText.replace(regex, (match) => {
|
||||||
@ -101,7 +117,6 @@ export default function ContentSectionCompetences({ competenceData, glossaireDat
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="max-w-3xl mx-auto p-6">
|
<div className="max-w-3xl mx-auto p-6">
|
||||||
{/* ✅ Ajout de logs visuels dans le rendu */}
|
|
||||||
<h1 className={titleClass || "text-3xl mb-6 font-bold text-gray-700"}>{name}</h1>
|
<h1 className={titleClass || "text-3xl mb-6 font-bold text-gray-700"}>{name}</h1>
|
||||||
<CarouselCompetences images={images} className="w-full h-64" />
|
<CarouselCompetences images={images} className="w-full h-64" />
|
||||||
<div className={contentClass || "mt-6 text-lg text-black-700"}>
|
<div className={contentClass || "mt-6 text-lg text-black-700"}>
|
||||||
|
|||||||
@ -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 { fetchDataCompetences, fetchDataGlossaire } from "../utils/fetchDataCompetences";
|
||||||
import ContentSectionCompetences from "./ContentSectionCompetences";
|
import ContentSectionCompetences from "./ContentSectionCompetences";
|
||||||
|
|
||||||
@ -8,14 +11,39 @@ interface ContentSectionProps {
|
|||||||
contentClass?: string;
|
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...");
|
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();
|
// ✅ États pour stocker les données récupérées
|
||||||
console.log("✅ [ContentSectionCompetencesContainer] Données glossaire :", JSON.stringify(glossaireData, null, 2));
|
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 <div className="text-center text-gray-500">⏳ Chargement des compétences...</div>;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ContentSectionCompetences
|
<ContentSectionCompetences
|
||||||
|
|||||||
@ -28,7 +28,7 @@ export default function HomePage() {
|
|||||||
getHomepageData().then((data) => setHomepage(data));
|
getHomepageData().then((data) => setHomepage(data));
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
if (!homepage) return <p className="text-center text-red-500">Erreur lors du chargement du contenu.</p>;
|
if (!homepage) return <p className="text-center text-blue-500">Chargement de la page...</p>;
|
||||||
|
|
||||||
const title = homepage.title ?? "Titre par défaut";
|
const title = homepage.title ?? "Titre par défaut";
|
||||||
const cv = homepage.cv ?? "";
|
const cv = homepage.cv ?? "";
|
||||||
|
|||||||
@ -3,6 +3,11 @@ import { getApiUrl } from "./getApiUrl";
|
|||||||
|
|
||||||
export async function fetchDataCompetences(collection: string, slug: string) {
|
export async function fetchDataCompetences(collection: string, slug: string) {
|
||||||
const apiUrl = getApiUrl();
|
const apiUrl = getApiUrl();
|
||||||
|
if (!apiUrl) {
|
||||||
|
console.error("❌ [fetchDataCompetences] URL de l'API invalide !");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const query = qs.stringify({
|
const query = qs.stringify({
|
||||||
filters: { slug: { $eq: slug } },
|
filters: { slug: { $eq: slug } },
|
||||||
populate: "picture",
|
populate: "picture",
|
||||||
@ -14,11 +19,8 @@ export async function fetchDataCompetences(collection: string, slug: string) {
|
|||||||
try {
|
try {
|
||||||
const response = await fetch(fullUrl, { cache: "no-store" });
|
const response = await fetch(fullUrl, { cache: "no-store" });
|
||||||
|
|
||||||
console.log(`📡 [fetchDataCompetences] Réponse HTTP : ${response.status} ${response.statusText}`);
|
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
console.error(`❌ [fetchDataCompetences] Erreur HTTP ${response.status} : ${response.statusText}`);
|
throw new Error(`HTTP ${response.status} : ${response.statusText}`);
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
@ -32,18 +34,19 @@ export async function fetchDataCompetences(collection: string, slug: string) {
|
|||||||
|
|
||||||
export async function fetchDataGlossaire() {
|
export async function fetchDataGlossaire() {
|
||||||
const apiUrl = getApiUrl();
|
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);
|
console.log("🔍 [fetchDataGlossaire] Requête API :", fullUrl);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(fullUrl, { cache: "no-store" });
|
const response = await fetch(fullUrl, { cache: "no-store" });
|
||||||
|
|
||||||
console.log(`📡 [fetchDataGlossaire] Réponse HTTP : ${response.status} ${response.statusText}`);
|
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
console.error(`❌ [fetchDataGlossaire] Erreur HTTP ${response.status} : ${response.statusText}`);
|
throw new Error(`HTTP ${response.status} : ${response.statusText}`);
|
||||||
return [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user