mirror of
https://github.com/Ladebeze66/devsite.git
synced 2025-12-13 12:46:49 +01:00
responsive4
This commit is contained in:
parent
6d2e96ec5f
commit
a18f399ca8
@ -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>
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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 }>;
|
||||
|
||||
@ -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 }>;
|
||||
|
||||
@ -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 l’image 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 */
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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>
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -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>
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
@ -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'],
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user