"use client"; import { useEffect, useState } from "react"; import { X, ChevronRight } from "lucide-react"; interface PromoBanner { id: string; text: string; cta_text?: string | null; cta_link?: string | null; countdown_enabled: boolean; countdown_end_date?: string | null; gradient_from: string; gradient_to: string; text_color: string; cta_bg_color: string; cta_text_color: string; is_active: boolean; } function useCountdown(endDate: string | null | undefined) { const [timeLeft, setTimeLeft] = useState(""); useEffect(() => { if (!endDate) return; const calculateTimeLeft = () => { const now = new Date().getTime(); const end = new Date(endDate).getTime(); const diff = end - now; if (diff <= 0) { setTimeLeft("Terminé"); return; } const days = Math.floor(diff / (1000 * 60 * 60 * 24)); const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60)); const seconds = Math.floor((diff % (1000 * 60)) / 1000); if (days > 0) { setTimeLeft(`${days}j ${hours}h ${minutes}m ${seconds}s`); } else if (hours > 0) { setTimeLeft(`${hours}h ${minutes}m ${seconds}s`); } else if (minutes > 0) { setTimeLeft(`${minutes}m ${seconds}s`); } else { setTimeLeft(`${seconds}s`); } }; calculateTimeLeft(); const interval = setInterval(calculateTimeLeft, 1000); return () => clearInterval(interval); }, [endDate]); return timeLeft; } export function PromoBanner() { const [banner, setBanner] = useState(null); const [dismissed, setDismissed] = useState(false); const [loading, setLoading] = useState(true); const timeLeft = useCountdown(banner?.countdown_end_date); useEffect(() => { async function fetchBanner() { try { const res = await fetch("/api/promo-banners", { credentials: "include", cache: "no-store" }); if (!res.ok) throw new Error("Erreur fetch"); const data = await res.json(); if (data.banner) { setBanner(data.banner); // Vérifier si la bannière a été fermée dans ce session const dismissedId = sessionStorage.getItem("promo_banner_dismissed"); if (dismissedId === data.banner.id) { setDismissed(true); } } } catch (err) { console.error("Erreur lors du chargement de la bannière promo:", err); } finally { setLoading(false); } } fetchBanner(); }, []); const handleDismiss = () => { if (banner) { sessionStorage.setItem("promo_banner_dismissed", banner.id); } setDismissed(true); }; if (loading || !banner || dismissed || !banner.is_active) { return null; } // Convertir les classes Tailwind en couleurs CSS const getGradientColors = (tailwindClass: string): string => { const colorMap: Record = { 'slate-100': '#f1f5f9', 'slate-200': '#e2e8f0', 'indigo-100': '#e0e7ff', 'purple-100': '#f3e8ff', 'blue-50': '#eff6ff', 'cyan-100': '#cffafe', 'purple-50': '#faf5ff', 'pink-100': '#fce7f3', 'orange-50': '#fff7ed', 'amber-100': '#fef3c7', 'green-50': '#f0fdf4', 'teal-100': '#ccfbf1', }; return colorMap[tailwindClass] || '#f1f5f9'; }; const getTextColor = (tailwindClass: string): string => { const colorMap: Record = { 'slate-800': '#1e293b', 'slate-900': '#0f172a', 'white': '#ffffff', 'indigo-900': '#312e81', 'purple-900': '#581c87', }; return colorMap[tailwindClass] || '#1e293b'; }; const getCtaTextColor = (tailwindClass: string): string => { const colorMap: Record = { 'slate-800': '#1e293b', 'slate-900': '#0f172a', 'white': '#ffffff', }; return colorMap[tailwindClass] || '#0f172a'; }; const gradientFrom = getGradientColors(banner.gradient_from); const gradientTo = getGradientColors(banner.gradient_to); const textColor = getTextColor(banner.text_color || 'slate-800'); const ctaBgColor = banner.cta_bg_color || '#efc543'; const ctaTextColor = getCtaTextColor(banner.cta_text_color || 'slate-900'); return (
{/* Texte principal */}

{banner.text}

{/* Compte à rebours */} {banner.countdown_enabled && banner.countdown_end_date && timeLeft && (
{timeLeft}
)}
{/* CTA */} {banner.cta_text && banner.cta_link && ( {banner.cta_text} )} {/* Bouton fermer */}
); }