responsive4

This commit is contained in:
Ladebeze66 2025-02-19 18:11:19 +01:00
parent 6d2e96ec5f
commit a18f399ca8
9 changed files with 123 additions and 83 deletions

View File

@ -4,6 +4,8 @@ import { useEffect, useState } from "react";
import Link from "next/link";
import { getApiUrl } from "../utils/getApiUrl";
import CarouselCompetences from "../components/CarouselCompetences";
import "../globals.css";
import "../assets/main.css";
export default function Page() {
const [competences, setCompetences] = useState([]);
@ -16,15 +18,23 @@ export default function Page() {
if (!response.ok) {
throw new Error(`Erreur de récupération des compétences : ${response.statusText}`);
}
const data = await response.json();
setCompetences(data.data ?? []);
// Tri sécurisé des compétences par `order`
const sortedCompetences = (data.data ?? []).sort((a, b) => ((a.attributes?.order ?? 999) - (b.attributes?.order ?? 999)));
setCompetences(sortedCompetences);
} catch (error) {
console.error("❌ Erreur lors de la récupération des compétences :", error);
}
}
fetchCompetences();
}, [apiUrl]);
return (
<main className="w-full p-3 mt-5 mb-5">
@ -43,21 +53,21 @@ export default function Page() {
return (
<div
key={competence.id}
className="bg-white/70 rounded-lg shadow-md overflow-hidden w-full h-auto flex flex-col transform transition-all duration-300 hover:scale-105 hover:shadow-xl p-4"
>
<Link href={`/competences/${competence.slug}`}>
<div className="overflow-hidden w-full h-64 mb-4">
<CarouselCompetences images={images} className="w-full h-full object-cover" />
</div>
<div className="flex-grow overflow-y-auto max-h-32 hide-scrollbar show-scrollbar">
<p className="font-orbitron-16-bold text-xl mb-2">{competence.name}</p>
<p className="text-gray-700 text-sm hover:text-base transition-all duration-200 ease-in-out">
{competence.description}
</p>
</div>
</Link>
</div>
key={competence.id}
className="bg-white/70 rounded-lg shadow-md overflow-hidden w-full max-w-xs sm:max-w-md md:max-w-lg lg:max-w-xl xl:max-w-2xl h-auto flex flex-col transform transition-all duration-300 hover:scale-105 hover:shadow-xl p-4"
>
<Link href={`/competences/${competence.slug}`}>
<div className="overflow-hidden w-full h-64 mb-4">
<CarouselCompetences images={images} className="w-full h-full object-cover" />
</div>
<div className="flex-grow overflow-y-auto max-h-32 hide-scrollbar show-scrollbar">
<p className="font-orbitron-16-bold text-xl mb-2">{competence.name}</p>
<p className="text-gray-700 text-sm hover:text-base transition-all duration-200 ease-in-out">
{competence.description}
</p>
</div>
</Link>
</div>
);
})}
</div>

View File

@ -88,25 +88,6 @@
@tailwind components;
@tailwind utilities;
.bg-wallpaper {
background-image: url('./images/wallpapersite_resultat.webp');
background-size: cover;
background-position: center center;
background-repeat: no-repeat;
min-height: 100vh;
width: 100%;
}
@media (max-width: 768px) {
.bg-wallpaper {
background-size: auto 100%;
background-position: center;
min-height: 100vh;
min-width: 200vw;
}
}
.homepage-content {
min-height: 50vh;
max-height: 80vh;
@ -179,3 +160,10 @@
.show-scrollbar:hover::-webkit-scrollbar {
display: block;
}
@media (max-width: 767px) and (orientation: landscape) {
.mobile-landscape {
grid-template-columns: repeat(2, minmax(150px, 1fr)) !important;
}
}

View File

@ -7,6 +7,8 @@ import { Navigation, Pagination, Autoplay } from "swiper/modules";
import "swiper/css";
import "swiper/css/navigation";
import "swiper/css/pagination";
import "../globals.css";
import "../assets/main.css";
interface CarouselProps {
images: Array<{ url: string; alt: string }>;

View File

@ -7,6 +7,8 @@ import { Navigation, Pagination, Autoplay } from "swiper/modules";
import "swiper/css";
import "swiper/css/navigation";
import "swiper/css/pagination";
import "../globals.css";
import "../assets/main.css";
interface CarouselProps {
images: Array<{ url: string; alt: string }>;

View File

@ -54,11 +54,38 @@ body {
animation: blink 1s infinite 0.4s;
}
/* Alignement général pour la mise en page */
.bg-wallpaper {
background-image: url('./assets/images/wallpapersite_resultat.webp');
background-size: cover;
background-position: center center;
background-repeat: no-repeat;
min-height: 100vh;
min-width: 100vw;
width: 100%;
height: 100%;
}
@media (max-width: 768px) {
.bg-wallpaper {
background-size: cover; /* Ajuste pour que limage soit totalement visible */
background-position: center;
width: 100vw;
min-height: 100vh;
height: auto;
}
}
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 16px;
width: 100%;
height: 100%;
position: relative;
}
/* Gestion du footer */

View File

@ -3,6 +3,7 @@
import React, { useEffect, useState, useRef } from "react";
import Footer from "./components/Footer";
import "./assets/main.css";
import "./globals.css";
import NavLink from "./components/NavLink";
export default function RootLayout({ children }) {
@ -64,7 +65,7 @@ export default function RootLayout({ children }) {
{/* Menu mobile */}
{isMenuOpen && (
<div ref={menuRef} className="fixed inset-0 bg-black/50 z-40 flex items-start justify-center p-4">
<div ref={menuRef} className="fixed inset-0 bg-black/50 z-40 flex items-start justify-end p-4">
<nav className="w-[60%] max-w-sm h-auto min-h-[50vh] max-h-[50vh] bg-gray-800/90 backdrop-blur-lg flex flex-col items-center justify-center space-y-4 z-50 md:hidden text-white font-orbitron-24-bold tracking-wide shadow-lg overflow-y-auto rounded-lg p-6">
{/* Bouton de fermeture */}
<button className="absolute top-4 right-4 text-2xl text-white" onClick={toggleMenu}>

View File

@ -35,7 +35,7 @@ export default function HomePage() {
const imageUrl = homepage.photo?.url ? `${apiUrl}${homepage.photo.url}` : null;
return (
<main className="max-w-3xl w-full mx-auto flex flex-col items-center justify-center p-6 bg-white/55 rounded-lg mt-12 mb-3">
<main className="w-full mx-auto flex flex-col items-center justify-center p-6 bg-white/55 rounded-lg mt-12 mb-3 max-w-7xl">
<h1 className="text-3xl font-orbitron-24-bold-italic text-gray-800 mb-4">{title}</h1>
{imageUrl ? (
@ -53,4 +53,4 @@ export default function HomePage() {
</div>
</main>
);
}
}

View File

@ -4,6 +4,8 @@ import { useEffect, useState } from "react";
import Link from "next/link";
import { getApiUrl } from "../utils/getApiUrl";
import Carousel from "../components/Carousel";
import "../assets/main.css";
import "../globals.css";
export default function Page() {
const [projects, setProjects] = useState([]);
@ -12,60 +14,65 @@ export default function Page() {
useEffect(() => {
async function fetchProjects() {
try {
const response = await fetch(`${apiUrl}/api/projects?populate=picture`);
const response = await fetch(`${apiUrl}/api/projects?populate=picture&sort=order:asc`); // Récupération triée depuis Strapi
if (!response.ok) {
throw new Error(`Erreur de récupération des projets : ${response.statusText}`);
}
const data = await response.json();
setProjects(data.data ?? []);
// Tri des projets côté Next.js (au cas où Strapi ne le fait pas)
const sortedProjects = (data.data ?? []).sort((a, b) => (a.order || 999) - (b.order || 999));
setProjects(sortedProjects);
} catch (error) {
console.error("❌ Erreur lors de la récupération des projets :", error);
}
}
fetchProjects();
}, [apiUrl]);
return (
<main className="w-full p-3 mt-5 mb-5">
<div className="grid gap-7 grid-cols-[repeat(auto-fit,minmax(300px,1fr))] max-w-7xl mx-auto">
{projects.map((project) => {
const pictures = project.picture ?? [];
const images = pictures.map((img) => ({
url: `${apiUrl}${img.url}`,
alt: img.name || "Project image",
}));
<div className="grid grid-cols-1 sm:grid-cols-[repeat(auto-fit,minmax(300px,1fr))] gap-7 max-w-7xl mx-auto mobile-landscape">
{projects.map((project) => {
const pictures = project.picture ?? [];
const images = pictures.map((img) => ({
url: `${apiUrl}${img.url}`,
alt: img.name || "Project image",
}));
return (
<div
key={project.id}
className="bg-white/80 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"
>
<Link href={`/portfolio/${project.slug}`}>
<div className="overflow-hidden w-full h-48 mb-4">
{images.length > 1 ? (
<Carousel images={images} className="h-48" />
) : (
<img
src={images[0]?.url || "/placeholder.jpg"}
alt={images[0]?.alt || "Project image"}
className="w-full h-full object-cover"
/>
)}
</div>
<div className="flex-grow overflow-y-auto max-h-32 hide-scrollbar show-scrollbar">
<p className="font-orbitron-16-bold text-xl mb-2">{project.name}</p>
<p className="text-gray-700 text-sm font-orbitron-12 hover:text-base transition-all duration-200 ease-in-out">
{project.description}
</p>
</div>
</Link>
return (
<div
key={project.id}
className="bg-white/80 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"
>
<Link href={`/portfolio/${project.slug}`}>
<div className="overflow-hidden w-full h-48 mb-4">
{images.length > 1 ? (
<Carousel images={images} className="h-48" />
) : (
<img
src={images[0]?.url || "/placeholder.jpg"}
alt={images[0]?.alt || "Project image"}
className="w-full h-full object-cover"
/>
)}
</div>
);
})}
</div>
</main>
<div className="flex-grow overflow-y-auto max-h-32 hide-scrollbar show-scrollbar">
<p className="font-orbitron-16-bold text-xl mb-2">{project.name}</p>
<p className="text-gray-700 text-sm font-orbitron-12 hover:text-base transition-all duration-200 ease-in-out">
{project.description}
</p>
</div>
</Link>
</div>
);
})}
</div>
</main>
);
}

View File

@ -12,6 +12,9 @@ export default {
background: "var(--background)",
foreground: "var(--foreground)",
},
screens: {
'mobile-landscape': { 'raw': '(max-width: 767px) and (orientation: landscape)' },
},
fontFamily: {
sans: ['Helvetica', 'Arial', 'sans-serif'],
serif: ['Georgia', 'serif'],