mirror of
https://github.com/Ladebeze66/devsite.git
synced 2025-12-15 13:36:49 +01:00
carousel
This commit is contained in:
parent
4738405663
commit
65e2a18cac
@ -1,11 +1,22 @@
|
|||||||
|
"use client"; // ✅ Indique que ce composant fonctionne côté client
|
||||||
|
|
||||||
|
import { useParams } from "next/navigation"; // ✅ Nouvelle méthode pour récupérer `params`
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
import ContentSectionCompetencesContainer from "../../components/ContentSectionCompetencesContainer";
|
import ContentSectionCompetencesContainer from "../../components/ContentSectionCompetencesContainer";
|
||||||
|
|
||||||
export default function CompetencePage({ params }: { params: { slug?: string } }) {
|
export default function CompetencePage() {
|
||||||
// ✅ Vérification du slug avant d'afficher le composant
|
const params = useParams(); // ✅ Récupérer `params` correctement
|
||||||
if (!params?.slug) {
|
const [slug, setSlug] = useState<string | null>(null);
|
||||||
console.error("❌ [CompetencePage] Erreur : Aucun slug fourni !");
|
|
||||||
return <div className="text-center text-red-500">❌ Erreur : Compétence introuvable.</div>;
|
useEffect(() => {
|
||||||
|
if (params?.slug) {
|
||||||
|
setSlug(params.slug as string); // ✅ Assurer que `slug` est bien une string
|
||||||
|
}
|
||||||
|
}, [params]);
|
||||||
|
|
||||||
|
if (!slug) {
|
||||||
|
return <div className="text-center text-gray-500">⏳ Chargement...</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
return <ContentSectionCompetencesContainer collection="competences" slug={params.slug} />;
|
return <ContentSectionCompetencesContainer collection="competences" slug={slug} />;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
import { useParams } from "next/navigation"; // ✅ Nouvelle méthode pour récupérer `params`
|
import { useParams } from "next/navigation"; // ✅ Nouvelle méthode pour récupérer `params`
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import ContentSectionCompetencesContainer from "../../components/ContentSectionCompetencesContainer";
|
import ContentSection from "../../components/ContentSection";
|
||||||
|
|
||||||
export default function CompetencePage() {
|
export default function Page() {
|
||||||
const params = useParams(); // ✅ Récupérer `params` correctement
|
const params = useParams(); // ✅ Récupérer `params` correctement
|
||||||
const [slug, setSlug] = useState<string | null>(null);
|
const [slug, setSlug] = useState<string | null>(null);
|
||||||
|
|
||||||
@ -18,5 +18,5 @@ export default function CompetencePage() {
|
|||||||
return <div className="text-center text-gray-500">⏳ Chargement...</div>;
|
return <div className="text-center text-gray-500">⏳ Chargement...</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
return <ContentSectionCompetencesContainer collection="competences" slug={slug} />;
|
return <ContentSection collection="projects" slug={slug} />;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,17 +2,18 @@
|
|||||||
|
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { getApiUrl } from "../utils/getApiUrl"; // 🔥 Import de l'URL dynamique
|
import { getApiUrl } from "../utils/getApiUrl";
|
||||||
|
import Carousel from "../components/Carousel"; // ✅ Import du carrousel
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
const [projects, setProjects] = useState([]); // 🔥 Stocker les projets une seule fois
|
const [projects, setProjects] = useState([]); // ✅ Stocker les projets
|
||||||
const apiUrl = getApiUrl(); // 🔥 Définition de l'URL API
|
const apiUrl = getApiUrl();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function fetchProjects() {
|
async function fetchProjects() {
|
||||||
console.log("🔍 API utilisée pour les projets :", apiUrl);
|
console.log("🔍 API utilisée pour les projets :", apiUrl);
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`${apiUrl}/api/projects?populate=*`);
|
const response = await fetch(`${apiUrl}/api/projects?populate=picture`);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error(`Erreur de récupération des projets : ${response.statusText}`);
|
throw new Error(`Erreur de récupération des projets : ${response.statusText}`);
|
||||||
}
|
}
|
||||||
@ -23,34 +24,43 @@ export default function Page() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchProjects(); // 🔥 Exécuter une seule fois au montage du composant
|
fetchProjects();
|
||||||
}, [apiUrl]); // ✅ Exécuter `useEffect()` uniquement si `apiUrl` change
|
}, [apiUrl]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main className="w-full p-3 mt-5 mb-5">
|
<main className="w-full p-3 mt-5 mb-5">
|
||||||
{/* Titre de la page */}
|
{/* Titre de la page */}
|
||||||
<h1 className="text-3xl mb-3 font-bold text-gray-700 text-center">Portfolio formation 42</h1>
|
<h1 className="text-3xl mb-3 font-bold text-gray-700 text-center">Portfolio formation 42</h1>
|
||||||
|
|
||||||
{/* Grille améliorée avec une meilleure largeur et des colonnes plus équilibrées */}
|
{/* Grille des projets */}
|
||||||
<div className="grid gap-7 grid-cols-[repeat(auto-fit,minmax(300px,1fr))] max-w-7xl mx-auto">
|
<div className="grid gap-7 grid-cols-[repeat(auto-fit,minmax(300px,1fr))] max-w-7xl mx-auto">
|
||||||
{projects.map((project) => {
|
{projects.map((project) => {
|
||||||
const picture = project.picture?.[0];
|
const pictures = project.picture ?? [];
|
||||||
const imageUrl = picture?.url ? `${apiUrl}${picture.url}` : "/placeholder.jpg";
|
const images = pictures.map((img) => ({
|
||||||
|
url: `${apiUrl}${img.url}`,
|
||||||
|
alt: img.name || "Project image",
|
||||||
|
}));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={project.id}
|
key={project.id}
|
||||||
className="bg-white rounded-lg shadow-md overflow-hidden w-80 h-96 flex flex-col transform transition-all duration-300 hover:scale-105 hover:shadow-xl p-4"
|
className="bg-white rounded-lg shadow-md overflow-hidden w-80 h-96 flex flex-col transform transition-all duration-300 hover:scale-105 hover:shadow-xl p-4"
|
||||||
>
|
>
|
||||||
{/* Lien vers la page de détail du projet */}
|
{/* Lien vers la page de détail du projet */}
|
||||||
<Link href={`/portfolio/${project.slug}`}>
|
<Link href={`/portfolio/${project.slug}`}>
|
||||||
<div className="overflow-hidden w-full h-48 mb-4">
|
<div className="overflow-hidden w-full h-48 mb-4">
|
||||||
<img
|
{/* ✅ Ajout du carrousel au lieu d'une image unique */}
|
||||||
src={imageUrl}
|
{images.length > 1 ? (
|
||||||
alt={picture?.name || "Project image"}
|
<Carousel images={images} className="h-48" />
|
||||||
className="w-full h-full object-cover"
|
) : (
|
||||||
/>
|
<img
|
||||||
|
src={images[0]?.url || "/placeholder.jpg"}
|
||||||
|
alt={images[0]?.alt || "Project image"}
|
||||||
|
className="w-full h-full object-cover"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex-grow overflow-y-auto max-h-32 hide-scrollbar show-scrollbar">
|
<div className="flex-grow overflow-y-auto max-h-32 hide-scrollbar show-scrollbar">
|
||||||
<p className="font-bold text-xl mb-2">{project.name}</p>
|
<p className="font-bold text-xl mb-2">{project.name}</p>
|
||||||
<p className="text-gray-700 text-sm hover:text-base transition-all duration-200 ease-in-out">
|
<p className="text-gray-700 text-sm hover:text-base transition-all duration-200 ease-in-out">
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user