7 Commits

Author SHA1 Message Date
fc281504eb Update src/app/portfolio/page.tsx 2026-03-12 12:37:58 +00:00
cb70d0e5e9 Update src/app/portfolio/page.tsx 2026-03-12 12:37:12 +00:00
c1e0019a5e Merge version_7 into main
Merge version_7 into main
2026-03-12 12:26:43 +00:00
f67a04ed63 Update src/app/portfolio/page.tsx 2026-03-12 12:26:39 +00:00
0dcfa33f04 Merge version_6 into main
Merge version_6 into main
2026-03-12 12:10:49 +00:00
7da2934daa Update src/app/portfolio/page.tsx 2026-03-12 12:10:45 +00:00
882b5fb286 Merge version_5 into main
Merge version_5 into main
2026-03-12 12:06:18 +00:00

View File

@@ -3,10 +3,10 @@
import Link from "next/link";
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import NavbarStyleCentered from "@/components/navbar/NavbarStyleCentered/NavbarStyleCentered";
import TestimonialCardOne from "@/components/sections/testimonial/TestimonialCardOne";
import FeatureCardOne from "@/components/sections/feature/FeatureCardOne";
import ContactText from "@/components/sections/contact/ContactText";
import FooterBaseCard from "@/components/sections/footer/FooterBaseCard";
import { Camera, Upload, Trash2 } from "lucide-react";
import { Camera, Upload, Trash2, Play, Maximize2 } from "lucide-react";
import { useState } from "react";
export default function PortfolioPage() {
@@ -104,6 +104,13 @@ export default function PortfolioPage() {
setUploadedMedia((prev) => prev.filter((media) => media.id !== id));
};
const featureItems = uploadedMedia.map((media) => ({
id: media.id,
title: media.name,
description: media.type === "photo" ? "📷 Photo du projet" : "🎥 Vidéo du projet", imageSrc: media.src,
imageAlt: media.name,
}));
return (
<ThemeProvider
defaultButtonVariant="directional-hover"
@@ -127,74 +134,40 @@ export default function PortfolioPage() {
/>
</div>
{/* Portfolio Projects Section */}
<div id="portfolio" data-section="portfolio">
<TestimonialCardOne
title="Nos Réalisations"
description="Découvrez tous nos projets réussis et les transformations que nous avons accomplies pour nos clients en Belgique. Nos réalisations incluent des photos et vidéos de chantiers."
tag="Portfolio Complet"
tagIcon={Camera}
testimonials={[
{
id: "1", name: "Rénovation Complète", role: "Maison - Bruxelles", company: "2024", rating: 5,
imageSrc: "http://img.b2bpic.net/free-photo/young-people-watching-smartphone-office_23-2147668943.jpg?_wi=2", imageAlt: "Rénovation complète intérieur maison bruxelles"},
{
id: "2", name: "Extension Résidentielle", role: "Addition 50m² - Liège", company: "2024", rating: 5,
videoSrc: "https://www.youtube.com/embed/dQw4w9WgXcQ?_wi=2", videoAriaLabel: "Vidéo extension résidentielle Liège"},
{
id: "3", name: "Terrasse Extérieure", role: "Piscine & Terrasse - Namur", company: "2023", rating: 5,
imageSrc: "http://img.b2bpic.net/free-photo/outdoor-swimming-pool_1203-2669.jpg?_wi=2", imageAlt: "Terrasse piscine extérieur namur belgique"},
{
id: "4", name: "Construction Neuve", role: "Maison moderne 150m² - Charleroi", company: "2023", rating: 5,
videoSrc: "https://www.youtube.com/embed/jNQXAC9IVRw?_wi=2", videoAriaLabel: "Vidéo construction maison neuve Charleroi"},
{
id: "5", name: "Rénovation Toiture", role: "Toiture complète - Anvers", company: "2023", rating: 5,
imageSrc: "http://img.b2bpic.net/free-photo/man-working-outdoors-high-angle_23-2149714277.jpg?_wi=2", imageAlt: "rénovation toiture ardoise anvers belgique"},
{
id: "6", name: "Aménagement Extérieur", role: "Jardin paysager - Mons", company: "2023", rating: 5,
imageSrc: "http://img.b2bpic.net/free-photo/table-chair-with-white-umbrella-outdoor-patio_74190-1917.jpg?_wi=2", imageAlt: "jardin paysager aménagement mons belgique"},
]}
gridVariant="three-columns-all-equal-width"
animationType="slide-up"
textboxLayout="default"
useInvertedBackground={false}
tagAnimation="slide-up"
/>
</div>
{/* Media Upload and Management Section */}
<div id="media-manager" data-section="media-manager">
{/* Media Upload Section */}
<div id="media-upload" data-section="media-upload">
<div className="w-full py-20 px-4 md:px-8">
<div className="max-w-6xl mx-auto">
<div className="max-w-7xl mx-auto">
{/* Header */}
<div className="text-center mb-16">
<div className="inline-flex items-center gap-2 mb-4 px-4 py-2 rounded-full bg-[var(--accent)] text-[var(--background)]">
<Upload size={16} />
<span className="text-sm font-medium">Gestion des Médias</span>
<Camera size={16} />
<span className="text-sm font-medium">Galerie Projets Complétés</span>
</div>
<h2 className="text-3xl md:text-5xl font-bold mb-4 text-[var(--foreground)]">
Galerie des Projets Réalisés
Photos & Vidéos de Nos Réalisations
</h2>
<p className="text-lg text-[var(--foreground)] opacity-75 max-w-2xl mx-auto">
Téléchargez et gérez les photos et vidéos de vos projets complétés. Présentez votre portefeuille aux clients potentiels.
Découvrez nos projets complétés en grand format. Visualisez la qualité de notre travail et les transformations que nous avons accomplies pour nos clients.
</p>
</div>
<div className="grid md:grid-cols-3 gap-8">
{/* Upload Section */}
<div className="md:col-span-1 space-y-6">
{/* Photo Upload */}
<div className="bg-[var(--card)] rounded-2xl p-8 border border-[var(--accent)] border-opacity-20">
<h3 className="text-lg font-bold mb-4 text-[var(--foreground)] flex items-center gap-2">
<Camera size={20} />
Télécharger des Photos
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
{/* Upload Controls - Sidebar */}
<div className="lg:col-span-1 space-y-6">
{/* Upload Controls */}
<div className="bg-[var(--card)] rounded-3xl p-6 border border-[var(--accent)] border-opacity-20 shadow-lg space-y-4">
<h3 className="text-lg font-bold text-[var(--foreground)] flex items-center gap-2">
<Upload size={20} />
Ajouter Médias
</h3>
<label className="flex flex-col items-center justify-center w-full h-32 border-2 border-dashed border-[var(--accent)] border-opacity-40 rounded-lg cursor-pointer hover:border-opacity-60 transition-all">
<div className="flex flex-col items-center justify-center pt-5 pb-6">
<Upload size={24} className="text-[var(--primary-cta)] mb-2" />
<p className="text-sm text-[var(--foreground)] opacity-75 text-center">
Cliquez pour télécharger<br />
<span className="text-xs">(JPG, PNG, WebP)</span>
{/* Photo Upload */}
<label className="flex flex-col items-center justify-center w-full h-24 border-2 border-dashed border-[var(--accent)] border-opacity-40 rounded-xl cursor-pointer hover:border-opacity-60 transition-all bg-[var(--background)] bg-opacity-50">
<div className="flex flex-col items-center justify-center">
<Camera size={20} className="text-[var(--primary-cta)] mb-1" />
<p className="text-xs font-medium text-[var(--foreground)] text-center">
Ajouter Photos
</p>
</div>
<input
@@ -206,20 +179,13 @@ export default function PortfolioPage() {
aria-label="Télécharger des photos"
/>
</label>
</div>
{/* Video Upload */}
<div className="bg-[var(--card)] rounded-2xl p-8 border border-[var(--accent)] border-opacity-20">
<h3 className="text-lg font-bold mb-4 text-[var(--foreground)] flex items-center gap-2">
<Camera size={20} />
Télécharger des Vidéos
</h3>
<label className="flex flex-col items-center justify-center w-full h-32 border-2 border-dashed border-[var(--accent)] border-opacity-40 rounded-lg cursor-pointer hover:border-opacity-60 transition-all">
<div className="flex flex-col items-center justify-center pt-5 pb-6">
<Upload size={24} className="text-[var(--primary-cta)] mb-2" />
<p className="text-sm text-[var(--foreground)] opacity-75 text-center">
Cliquez pour télécharger<br />
<span className="text-xs">(MP4, WebM, OGG)</span>
{/* Video Upload */}
<label className="flex flex-col items-center justify-center w-full h-24 border-2 border-dashed border-[var(--accent)] border-opacity-40 rounded-xl cursor-pointer hover:border-opacity-60 transition-all bg-[var(--background)] bg-opacity-50">
<div className="flex flex-col items-center justify-center">
<Play size={20} className="text-[var(--primary-cta)] mb-1" />
<p className="text-xs font-medium text-[var(--foreground)] text-center">
Ajouter Vidéos
</p>
</div>
<input
@@ -231,79 +197,62 @@ export default function PortfolioPage() {
aria-label="Télécharger des vidéos"
/>
</label>
</div>
{/* Feedback Messages */}
{uploadError && (
<div className="bg-red-50 border border-red-200 rounded-lg p-4">
<p className="text-red-800 text-sm">{uploadError}</p>
</div>
)}
{uploadSuccess && (
<div className="bg-green-50 border border-green-200 rounded-lg p-4">
<p className="text-green-800 text-sm font-semibold"> Fichier uploadé avec succès!</p>
</div>
)}
</div>
{/* Media Gallery */}
<div className="md:col-span-2">
<div className="bg-[var(--card)] rounded-2xl p-8 border border-[var(--accent)] border-opacity-20">
<h3 className="text-2xl font-bold mb-6 text-[var(--foreground)]">
Galerie ({uploadedMedia.length})
</h3>
{uploadedMedia.length === 0 ? (
<div className="text-center py-12">
<Camera size={48} className="mx-auto text-[var(--accent)] opacity-30 mb-4" />
<p className="text-[var(--foreground)] opacity-60">
Aucun média téléchargé. Commencez par ajouter des photos ou des vidéos de vos projets.
</p>
{/* Feedback Messages */}
{uploadError && (
<div className="bg-red-50 border border-red-200 rounded-lg p-3">
<p className="text-red-800 text-xs">{uploadError}</p>
</div>
) : (
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
{uploadedMedia.map((media) => (
<div
key={media.id}
className="relative group rounded-lg overflow-hidden border border-[var(--accent)] border-opacity-20"
>
{media.type === "photo" ? (
<img
src={media.src}
alt={media.name}
className="w-full h-48 object-cover group-hover:scale-105 transition-transform duration-300"
/>
) : (
<video
src={media.src}
controls
className="w-full h-48 object-cover bg-black"
aria-label={media.name}
/>
)}
<div className="absolute inset-0 bg-black opacity-0 group-hover:opacity-40 transition-opacity duration-300" />
{/* Delete Button */}
<button
onClick={() => handleDeleteMedia(media.id)}
className="absolute top-2 right-2 p-2 bg-red-500 hover:bg-red-600 text-white rounded-lg opacity-0 group-hover:opacity-100 transition-opacity duration-300"
aria-label={`Supprimer ${media.name}`}
>
<Trash2 size={16} />
</button>
{/* File Info */}
<div className="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black to-transparent p-4 text-white opacity-0 group-hover:opacity-100 transition-opacity duration-300">
<p className="text-sm font-semibold truncate">{media.name}</p>
<p className="text-xs opacity-75">
{media.type === "photo" ? "Photo" : "Vidéo"}
</p>
</div>
</div>
))}
)}
{uploadSuccess && (
<div className="bg-green-50 border border-green-200 rounded-lg p-3">
<p className="text-green-800 text-xs font-semibold"> Uploadé avec succès!</p>
</div>
)}
</div>
{/* Media Count */}
<div className="bg-[var(--card)] rounded-3xl p-6 border border-[var(--accent)] border-opacity-20 shadow-lg">
<div className="text-center">
<p className="text-3xl font-bold text-[var(--primary-cta)] mb-2">
{uploadedMedia.length}
</p>
<p className="text-sm text-[var(--foreground)] opacity-60">
{uploadedMedia.length === 1 ? "Média" : "Médias"} ajoutés
</p>
{uploadedMedia.length > 0 && (
<p className="text-xs text-[var(--foreground)] opacity-40 mt-3">
{uploadedMedia.filter((m) => m.type === "photo").length}📷 {uploadedMedia.filter((m) => m.type === "video").length}🎥
</p>
)}
</div>
</div>
</div>
{/* Feature Card Gallery - Takes 2 columns */}
<div className="lg:col-span-2">
{featureItems.length > 0 ? (
<FeatureCardOne
features={featureItems}
title="Vos Réalisations"
description="Galerie complète de vos projets de construction et rénovation"
tag="Projets"
animationType="slide-up"
textboxLayout="default"
useInvertedBackground={false}
gridVariant="uniform-all-items-equal"
/>
) : (
<div className="bg-[var(--card)] rounded-3xl p-12 border border-[var(--accent)] border-opacity-20 shadow-lg text-center">
<Camera size={48} className="mx-auto text-[var(--accent)] opacity-20 mb-4" />
<p className="text-[var(--foreground)] opacity-60 text-lg">
Aucun média ajouté pour le moment
</p>
<p className="text-[var(--foreground)] opacity-40 text-sm mt-2">
Commencez à ajouter des photos et vidéos de vos projets ci-contre
</p>
</div>
)}
</div>
</div>
</div>