import React, { useState, useEffect, useMemo } from 'react'; import { Book, Cross, Info, Mail, Menu, Phone, X, Search, ChevronRight, Star, ChevronLeft, Loader, ShoppingCart, Trash2, Send, Facebook, MessageCircle, FileText, ShieldCheck, Heart } from 'lucide-react'; // ============================================================================== // ⚙️ ZONE DE CONFIGURATION // ============================================================================== // Logo par défaut (utilisé pour le loader avant que le CMS ne charge) const DEFAULT_LOGO = "https://i.postimg.cc/7ZryvYzZ/logo.png"; // 1. LIEN CSV "INVENTAIRE" const LIEN_PRODUITS = "https://docs.google.com/spreadsheets/d/e/2PACX-1vTITtf_EgK3nylvhoxpEF_jMuQU5fIaabj3t9iKb_7TTd8OyD2DOVPbQEHAXlbHfpr3ik2aa42OspPp/pub?output=csv"; // 2. LIEN CSV "CONTENU" const LIEN_CONTENU = "https://docs.google.com/spreadsheets/d/e/2PACX-1vTITtf_EgK3nylvhoxpEF_jMuQU5fIaabj3t9iKb_7TTd8OyD2DOVPbQEHAXlbHfpr3ik2aa42OspPp/pub?gid=1846052469&single=true&output=csv"; // ============================================================================== // --- UTILITAIRES --- const parseCSV = (str) => { const arr = []; let quote = false; let col = 0, row = 0; for (let c = 0; c < str.length; c++) { let cc = str[c], nc = str[c+1]; arr[row] = arr[row] || []; arr[row][col] = arr[row][col] || ''; if (cc === '"' && quote && nc === '"') { arr[row][col] += cc; ++c; continue; } if (cc === '"') { quote = !quote; continue; } if (cc === ',' && !quote) { ++col; continue; } if (cc === '\r' && nc === '\n' && !quote) { ++row; col = 0; ++c; continue; } if (cc === '\n' && !quote) { ++row; col = 0; continue; } if (cc === '\r' && !quote) { ++row; col = 0; continue; } arr[row][col] += cc; } return arr; }; const parsePrice = (priceStr) => { if (!priceStr) return 0; const clean = priceStr.replace(/[^\d.,]/g, '').replace(',', '.'); return parseFloat(clean) || 0; }; // --- ICONS SVG --- const HolyDoveIcon = ({ className }) => (); const SealIcon = ({ className }) => (); // --- COMPOSANTS UI --- const BrandLogo = ({ url, className = "w-12 h-12", circle = false }) => { const [imageError, setImageError] = useState(false); const finalUrl = url || DEFAULT_LOGO; if (finalUrl && !imageError) { if (circle) return (
La Colombe setImageError(true)} />
); return (La Colombe setImageError(true)} />); } return (
); }; const ItemVisual = ({ item }) => { if (item.image_url && item.image_url.trim() !== "" && item.image_url.startsWith('http')) { return (
{item.name} {e.target.onerror = null; e.target.style.display = 'none'; e.target.parentElement.innerHTML = '
Image non disponible
';}} />
); } if (item.type === 'book') { let bookColor = "text-red-800"; let accentColor = "bg-red-800"; if (item.name.includes("Vol. 2") || item.name.includes("Bleu")) { bookColor = "text-blue-800"; accentColor = "bg-blue-800"; } else if (item.name.includes("Vol. 5") || item.name.includes("Or")) { bookColor = "text-yellow-700"; accentColor = "bg-yellow-600"; } return (
Livre de laVérité
Second
Avènement
); } if (item.type === 'cross' || item.type === 'cross_stand') return (
INRI
{item.type === 'cross_stand' &&
}
); if (item.type === 'medal_silver' || item.type === 'medal_gold') { const isGold = item.type === 'medal_gold'; return (
); } if (item.type === 'scapular') return (
Sceau
); return (
Article
); }; const RecommendationsCarousel = ({ items, onSelect }) => { const [currentIndex, setCurrentIndex] = useState(0); const [visibleItems, setVisibleItems] = useState(1); const carouselItems = items || []; const itemCount = carouselItems.length; // Calcul du nombre d'éléments visibles selon la taille de l'écran useEffect(() => { const handleResize = () => { if (window.innerWidth >= 1280) setVisibleItems(4); // Large Screens else if (window.innerWidth >= 1024) setVisibleItems(3); // Desktop else if (window.innerWidth >= 768) setVisibleItems(2); // Tablet else setVisibleItems(1); // Mobile }; // Initial call handleResize(); window.addEventListener('resize', handleResize); return () => window.removeEventListener('resize', handleResize); }, []); // Max index possible avant de montrer du vide const maxIndex = Math.max(0, itemCount - visibleItems); // Auto-scroll useEffect(() => { if (itemCount === 0) return; const timer = setInterval(() => { setCurrentIndex((prev) => prev >= maxIndex ? 0 : prev + 1); }, 4000); return () => clearInterval(timer); }, [itemCount, visibleItems, maxIndex]); const nextSlide = () => { setCurrentIndex((p) => p >= maxIndex ? 0 : p + 1); }; const prevSlide = () => { setCurrentIndex((p) => p === 0 ? maxIndex : p - 1); }; if (itemCount === 0) return null; return (

Nos Recommandations

{/* BANDE DE DÉFILEMENT RESPONSIVE */}
{carouselItems.map((item) => (
onSelect(item)} className="bg-white p-6 rounded-xl shadow-xl border border-stone-100 flex flex-col items-center cursor-pointer transform hover:scale-105 transition-all duration-300 w-full relative overflow-hidden group h-full justify-between">

{item.name}

{item.price}

Recommandé
))}
{/* Indicateurs simples */}
{/* On affiche des points pour chaque "page" possible, pas chaque item, pour éviter la surcharge */} {Array.from({ length: Math.ceil(itemCount / visibleItems) }).map((_, idx) => (
))}
); }; // --- APP PRINCIPALE --- export default function App() { const [currentPage, setCurrentPage] = useState("home"); const [selectedItem, setSelectedItem] = useState(null); const [isMenuOpen, setIsMenuOpen] = useState(false); const [isCartOpen, setIsCartOpen] = useState(false); const [showOrderSuccess, setShowOrderSuccess] = useState(false); const [searchQuery, setSearchQuery] = useState(""); const [inventory, setInventory] = useState([]); const [content, setContent] = useState({}); const [loading, setLoading] = useState(true); const [cart, setCart] = useState([]); // Default content const defaultContent = { brand_logo: DEFAULT_LOGO, hero_title: "Vérité & Rédemption", hero_badge: "Sceau du Dieu Vivant", hero_subtitle: "Priez pour le Sceau du Dieu Vivant et gardez-le près de vous.", hero_citation: "- Message du Livre de la Vérité", contact_email: "contact@lacolombe.com", cart_payment_info: "Le paiement se fera par virement ou chèque après validation.", about_title: "Notre Mission", about_text: "Diffusion des messages sacrés.", legal_mentions: "Association La Colombe.", privacy_policy: "Données confidentielles.", btn_books: "Livres", btn_objects: "Objets" }; useEffect(() => { // 1. TITRES DYNAMIQUES const pageTitle = currentPage === "home" ? "Accueil" : currentPage === "books" ? "Livres" : currentPage === "objects" ? "Objets" : currentPage === "about" ? "À Propos" : "Contact"; document.title = `La Colombe - ${pageTitle}`; const params = new URLSearchParams(window.location.search); if (params.get('success') === 'true') { setShowOrderSuccess(true); setCart([]); window.history.replaceState({}, document.title, "/"); } if (LIEN_PRODUITS.includes("xxxxxxxxxxxx")) { setLoading(false); setContent(defaultContent); return; } const fetchAllData = async () => { try { const prodRes = await fetch(LIEN_PRODUITS); if (!prodRes.ok) throw new Error("Erreur produits"); const prodRaw = parseCSV(await prodRes.text()); const headers = prodRaw[0].map(h => h.trim()); const cleanInventory = prodRaw.slice(1) .filter(row => row.length === headers.length && row[1]) .map(row => { let obj = {}; headers.forEach((h, i) => { obj[h] = row[i] ? row[i].trim() : ""; }); return { ...obj, id: obj.id || Math.random().toString(36).substr(2, 9), isRecommended: obj.recommanded && (obj.recommanded.toUpperCase() === 'TRUE' || obj.recommanded.toUpperCase() === 'VRAI' || obj.recommanded === '1'), stock: obj.stock !== undefined && obj.stock !== "" ? parseInt(obj.stock) : 1 }; }); setInventory(cleanInventory); let loadedContent = { ...defaultContent }; if (LIEN_CONTENU && !LIEN_CONTENU.includes("xxxxxxxxxxxx")) { try { const contRes = await fetch(LIEN_CONTENU); if (contRes.ok) { const contRaw = parseCSV(await contRes.text()); contRaw.slice(1).forEach(row => { if (row[0] && row[1]) { loadedContent[row[0].trim()] = row[1].trim(); } }); } } catch (e) { console.warn("Content load failed"); } } setContent(loadedContent); setLoading(false); } catch (err) { console.error(err); setLoading(false); setContent(defaultContent); } }; fetchAllData(); }, [currentPage]); const addToCart = (item) => { setCart([...cart, item]); setSelectedItem(null); setIsCartOpen(true); }; const removeFromCart = (index) => { setCart(cart.filter((_, i) => i !== index)); }; const cartTotal = useMemo(() => cart.reduce((total, item) => total + parsePrice(item.price), 0).toFixed(2), [cart]); const orderDetails = cart.map(item => `- ${item.name} (${item.price})`).join('\n'); const fullOrderMessage = `COMMANDE :\n${orderDetails}\n\nTOTAL ESTIMÉ : ${cartTotal}€`; const toggleMenu = () => setIsMenuOpen(!isMenuOpen); const getFilteredItems = () => { let items = []; if (currentPage === "books") items = inventory.filter(i => i.category === "Livres"); if (currentPage === "objects") items = inventory.filter(i => i.category === "Objets"); if (searchQuery.trim() !== "") { items = items.filter(i => i.name.toLowerCase().includes(searchQuery.toLowerCase())); } return items; }; const recommendedItems = inventory.filter(item => item.isRecommended); if (loading) return (

LA COLOMBE

Chargement de la collection...

); return (
{/* NAVBAR */} {/* CONTENU */}
{/* === HOME === */} {currentPage === "home" && ( <>
Fond e.target.style.display='none'} />
{content.hero_badge}

{content.hero_title}

{content.hero_subtitle}
{content.hero_citation}

{/* SECTION RECOMMANDATIONS (DÉPLACÉE AU-DESSUS DES TÉMOIGNAGES) */}
{inventory.length === 0 &&

Connexion à la base de données...

} {recommendedItems.length > 0 && }
{/* SECTION TÉMOIGNAGES (DÉPLACÉE EN-DESSOUS) */} {content.testi_1_text && (

Témoignages

"

{content.testi_1_text}

- {content.testi_1_author}

{content.testi_2_text && (
"

{content.testi_2_text}

- {content.testi_2_author}

)}
)} )} {/* ... (Reste du code inchangé pour les autres pages) ... */} {/* === CATALOGUE === */} {(currentPage === "books" || currentPage === "objects") && (
{currentPage === "books" ? : }

{currentPage === "books" ? "La Librairie" : "Objets de Piété"}

Collection Officielle

setSearchQuery(e.target.value)} className="w-full pl-10 pr-4 py-2 border border-stone-300 rounded-full focus:ring-2 focus:ring-amber-500 focus:outline-none" />
{getFilteredItems().map((item) => (
setSelectedItem(item)} className={`group bg-white rounded-xl shadow-sm hover:shadow-2xl border border-stone-100 cursor-pointer overflow-hidden flex flex-col transition-all duration-500 hover:-translate-y-2 ${item.stock === 0 ? 'opacity-70 grayscale' : ''}`}>
{item.isRecommended && (
POPULAIRE
)} {item.stock === 0 &&
Épuisé
}
{item.category}

{item.name}

{item.price}Voir Détail
))}
{getFilteredItems().length === 0 &&

Aucun article trouvé.

}
)} {/* === ABOUT, LEGAL, PRIVACY PAGES === */} {(currentPage === "about" || currentPage === "legal" || currentPage === "privacy") && (

{currentPage === "about" ? content.about_title : currentPage === "legal" ? "Mentions Légales" : "Politique de Confidentialité"}

{currentPage === "about" ? content.about_text : currentPage === "legal" ? content.legal_mentions : content.privacy_policy}
)} {/* === CONTACT FORM === */} {currentPage === "contact" && (

Formulaire de Contact

)}
{/* --- MODAL DÉTAIL ARTICLE --- */} {selectedItem && (
setSelectedItem(null)}>
e.stopPropagation()}>
{selectedItem.category}

{selectedItem.name}

{selectedItem.price}

{selectedItem.description}

{selectedItem.stock > 0 ? ( ) : ( )}
)} {/* --- MODAL PANIER --- */} {isCartOpen && (
setIsCartOpen(false)}>
e.stopPropagation()}>

Mon Panier

{cart.length === 0 ? (

Votre panier est vide.

) : ( <>
{cart.map((item, idx) => (
{item.name}
{item.price}
))}
Total estimé{cartTotal} €

Finaliser la commande

{content.cart_payment_info}

)}
)} {/* --- MODAL SUCCÈS COMMANDE --- */} {showOrderSuccess && (
setShowOrderSuccess(false)}>
e.stopPropagation()}>

Merci !

Votre demande a bien été envoyée. Nous vous recontacterons très vite pour le paiement.

)} {/* FOOTER */}
); }