import React, { useState, useEffect } from 'react'; import { Star, Lock, Gift, Clock, Sparkles, Trees as TreeIcon, Snowflake, AlertCircle } from 'lucide-react'; // --- Configuration des données --- const CALENDAR_DATA = [ { day: 19, month: 11, yearOffset: 0, content: "Pavé :3", icon: "📝" }, { day: 20, month: 11, yearOffset: 0, content: "Un petit chocolat chaud pour vous réchauffer ❤️", icon: "☕" }, { day: 21, month: 11, yearOffset: 0, content: "Soirée film de Noël ce soir ?", icon: "🎬" }, { day: 22, month: 11, yearOffset: 0, content: "Plus que 3 jours avant Noël !", icon: "🎄" }, { day: 23, month: 11, yearOffset: 0, content: "Une petite pensée douce pour vous deux.", icon: "❄️" }, { day: 24, month: 11, yearOffset: 0, content: "C'est le réveillon ! Profitez bien !", icon: "🎁" }, { day: 25, month: 11, yearOffset: 0, content: "JOYEUX NOËL CELIANE & SNIPES !", icon: "🎅" }, { day: 26, month: 11, yearOffset: 0, content: "On continue la fête, repos aujourd'hui.", icon: "🛏️" }, { day: 27, month: 11, yearOffset: 0, content: "Une blague : Quel est le comble pour un sapin ? Se faire enguirlander !", icon: "😂" }, { day: 28, month: 11, yearOffset: 0, content: "Prêts pour la nouvelle année ?", icon: "🎉" }, { day: 29, month: 11, yearOffset: 0, content: "Souvenez-vous des bons moments de 2025.", icon: "📸" }, { day: 30, month: 11, yearOffset: 0, content: "L'avant dernier jour de l'année...", icon: "⏳" }, { day: 31, month: 11, yearOffset: 0, content: "Bon réveillon du Nouvel An !", icon: "🥂" }, { day: 1, month: 0, yearOffset: 1, content: "BONNE ANNÉE 2026 ! Que du bonheur pour vous !", icon: "✨", isBonus: true }, ]; export default function AdventCalendar() { const [currentTime, setCurrentTime] = useState(new Date()); const [openedDoors, setOpenedDoors] = useState([]); const [selectedDay, setSelectedDay] = useState(null); const [shakingDay, setShakingDay] = useState(null); const [toastMessage, setToastMessage] = useState(null); // --- Gestion sécurisée du stockage (Anti-crash) --- useEffect(() => { try { const saved = localStorage.getItem('openedDoors_celiane_snipes'); if (saved) { setOpenedDoors(JSON.parse(saved)); } } catch (e) { console.warn("Le stockage local n'est pas disponible (navigation privée ou restreinte). L'app fonctionnera en mode mémoire.", e); } const timer = setInterval(() => { setCurrentTime(new Date()); }, 1000); return () => clearInterval(timer); }, []); const saveProgress = (newOpened: number[]) => { setOpenedDoors(newOpened); try { localStorage.setItem('openedDoors_celiane_snipes', JSON.stringify(newOpened)); } catch (e) { // Échec silencieux de la sauvegarde, mais l'état visuel est mis à jour } }; const isLocked = (item: any) => { const now = new Date(); const currentYear = now.getFullYear(); let targetDate = new Date(currentYear, item.month, item.day); if (item.yearOffset === 1) { if (now.getMonth() === 11) { targetDate = new Date(currentYear + 1, item.month, item.day); } else { targetDate = new Date(currentYear, item.month, item.day); } } targetDate.setHours(0, 0, 0, 0); const nowCheck = new Date(now); // --- MODE TEST (Décommenter pour tout ouvrir) --- // return false; return nowCheck < targetDate; }; const showToast = (msg: string) => { setToastMessage(msg); setTimeout(() => setToastMessage(null), 3000); }; const handleDoorClick = (item: any, index: number) => { if (isLocked(item)) { setShakingDay(index); const dateStr = `${item.day} ${item.month === 0 ? 'Janvier' : 'Décembre'}`; showToast(`🔒 Patience ! Cette case s'ouvrira le ${dateStr}`); setTimeout(() => setShakingDay(null), 500); return; } if (!openedDoors.includes(index)) { const newOpened = [...openedDoors, index]; saveProgress(newOpened); } setSelectedDay(item); }; const closeModal = () => { setSelectedDay(null); }; const getCountdown = () => { const now = new Date(); const currentYear = now.getFullYear(); const xmas = new Date(currentYear, 11, 25); const newYear = new Date(currentYear + 1, 0, 1); let target = xmas; let label = "avant Noël"; if (now > xmas && now < newYear) { target = newYear; label = "avant 2026"; } else if (now >= newYear) { return "Bonne Année !"; } const diff = target.getTime() - now.getTime(); if (diff <= 0) return "C'est l'heure !"; 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); return `${days}j ${hours}h ${minutes}m ${seconds}s ${label}`; }; return (
{/* --- Toast de Notification (Message d'erreur/info) --- */} {toastMessage && (
{toastMessage}
)} {/* --- DÉCORATIONS D'ARRIÈRE-PLAN --- */} {/* Neige */}
{[...Array(70)].map((_, i) => (
))}
{/* Père Noël animé */}
🦌🦌🦌🛷🎅
{/* Sapins en fond (fixe en bas) */}
{/* --- CONTENU PRINCIPAL --- */}
{/* Header */}

CELIANE - SNIPES

{getCountdown()}
{/* Grille du Calendrier */}
{CALENDAR_DATA.map((item, index) => { const isOpen = openedDoors.includes(index); const locked = isLocked(item); const isShaking = shakingDay === index; const isBonus = item.isBonus; // Classes de base let cardClasses = ` relative h-32 md:h-40 rounded-2xl cursor-pointer transition-all duration-500 transform perspective-1000 flex flex-col items-center justify-center border-2 shadow-xl backdrop-blur-sm ${isShaking ? 'animate-shake' : ''} ${isOpen ? 'rotate-y-180' : 'hover:-translate-y-1 hover:shadow-2xl group'} `; // Style spécifique État Fermé if (!isOpen) { if (isBonus) { // Bonus 1er Janvier (Or luxueux) cardClasses += ' bg-gradient-to-br from-yellow-300 via-yellow-500 to-yellow-700 border-yellow-200/50 text-yellow-900 overflow-hidden'; } else { // Jours normaux (Rouge rubis vitreux) cardClasses += ' bg-gradient-to-br from-red-600/90 to-red-900/90 border-red-400/30 text-white'; } } else { // État Ouvert (Fond sombre élégant) cardClasses += ' bg-slate-800/80 border-green-500/30 text-green-400'; } return (
handleDoorClick(item, index)} > {/* Effet brillant sur le bonus */} {isBonus && !isOpen && (
)} {/* Numéro du jour (visible si fermé) */} {!isOpen && ( <>
{item.month === 0 ? 'Jan' : 'Dec'}
{item.day}
{isBonus ? : }
{/* Cadenas si verrouillé */} {locked && (
)} )} {/* Contenu (visible si ouvert) */} {isOpen && (
{item.icon}
)}
); })}
{/* --- MODALE --- */} {selectedDay && (
{/* Intérieur de la modale */}
{/* Décoration de fond modale */} {/* Confettis pour le bonus */} {selectedDay.isBonus && (
)}
{selectedDay.icon}

{selectedDay.day} {selectedDay.month === 0 ? 'Janvier' : 'Décembre'}

{selectedDay.content}
{selectedDay.isBonus && (
BONUS DU NOUVEL AN
)}
)} {/* Styles globaux pour animations CSS */}
); }