hypothesis / hypothesis/h

atelier-du-sac-web⁠

Open
#10,177 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
3.2k
Forks
459
Avg merge
27d 1h
Merged PRs (30d)
1

Description

Import React, { useState, useMemo, useEffect } from "react";
Import {
Search, ShoppingBag, Home, Phone, Info, X, Plus, Minus,
MessageCircle, Star, Trash2, ChevronLeft, Check, Sparkles,
Tag, Truck, ShieldCheck, LayoutDashboard
} from "lucide-react";

Const WHATSAPP_NUMBER = "237691630724";
Const CATEGORIES = ["Tous", "Sacs à main", "Sacs de voyage", "Portefeuilles"];

Const INITIAL_PRODUCTS = [
{ id: 1, name: "Sac Aurore", cat: "Sacs à main", price: 28000, promo: null, popular: true, new: true, colors: ["Noir", "Doré", "Beige"], rating: 4.8, reviews: 12, desc: "Sac à main en cuir texturé, fermoir doré et anse chaîne amovible." },
{ id: 2, name: "Sac Voyageur Prestige", cat: "Sacs de voyage", price: 45000, promo: 39000, popular: true, new: false, colors: ["Noir", "Brun"], rating: 4.6, reviews: 9, desc: "Grand sac de voyage rigide, compartiment chaussures dédié." },
{ id: 3, name: "Portefeuille Élégance", cat: "Portefeuilles", price: 12000, promo: null, popular: false, new: true, colors: ["Noir", "Beige"], rating: 4.9, reviews: 21, desc: "Portefeuille compact en cuir grainé, 8 compartiments cartes." },
{ id: 4, name: "Sac Baobab", cat: "Sacs à main", price: 32000, promo: 27000, popular: true, new: false, colors: ["Beige", "Doré"], rating: 4.7, reviews: 15, desc: "Sac cabas structuré, doublure intérieure poche zippée." },
{ id: 5, name: "Sac Weekend Nomade", cat: "Sacs de voyage", price: 38000, promo: null, popular: false, new: false, colors: ["Noir"], rating: 4.5, reviews: 6, desc: "Sac week-end souple, format cabine, poignées matelassées." },
{ id: 6, name: "Portefeuille Héritage", cat: "Portefeuilles", price: 15000, promo: null, popular: false, new: false, colors: ["Brun", "Noir"], rating: 4.4, reviews: 8, desc: "Portefeuille long à rabat, porte-monnaie pressionné." },
{ id: 7, name: "Sac Étoile du Soir", cat: "Sacs à main", price: 34000, promo: null, popular: false, new: true, colors: ["Doré", "Noir"], rating: 5.0, reviews: 4, desc: "Pochette de soirée à chaîne fine dorée." },
{ id: 8, name: "Sac Trotteur Beige", cat: "Sacs à main", price: 24000, promo: 21000, popular: true, new: false, colors: ["Beige"], rating: 4.6, reviews: 18, desc: "Sac bandoulière léger du quotidien, poche avant zippée." },
];

Function formatFCFA(n) {
Return n.toLocaleString("fr-FR") + " FCFA";
}

Function Logo({ size = "text-xl" }) {
Return (






L'Atelier du Sac

BY AS



);
}

Function TagCard({ children, className = "" }) {
Return (


{children}

);
}

Export default function App() {
Const [page, setPage] = useState("accueil");
Const [activeCat, setActiveCat] = useState("Tous");
Const [query, setQuery] = useState("");
Const [selectedProduct, setSelectedProduct] = useState(null);
Const [selectedColor, setSelectedColor] = useState(null);

// Persistance du panier dans localStorage
Const [cart, setCart] = useState(() => {
Const saved = localStorage.getItem("atelier_cart");
Return saved ? JSON.parse(saved) : [];
});

useEffect(() => {
LocalStorage.setItem("atelier_cart", JSON.stringify(cart));
}, [cart]);

Const [products, setProducts] = useState(INITIAL_PRODUCTS);
Const [paymentMethod, setPaymentMethod] = useState("orange");
Const [orderConfirmed, setOrderConfirmed] = useState(false);
Const [adminOpen, setAdminOpen] = useState(false);

// Formulaire Admin
Const [newProduct, setNewProduct] = useState({ name: "", price: "", cat: "Sacs à main" });

// Formulaire Contact
Const [contactForm, setContactForm] = useState({ name: "", phone: "", message: "" });

Const filteredProducts = useMemo(() => {
Return products.filter((p) => {
Const matchCat = activeCat === "Tous" || p.cat === activeCat;
Const matchQuery = p.name.toLowerCase().includes(query.toLowerCase());
Return matchCat && matchQuery;
});
}, [products, activeCat, query]);

Const cartTotal = cart.reduce((sum, item) => sum + (item.promo || item.price) * item.qty, 0);
Const cartCount = cart.reduce((sum, item) => sum + item.qty, 0);

Function addToCart(p, color) {
SetCart((prev) => {
Const existing = prev.find((i) => i.id === p.id && i.color === color);
If (existing) {
Return prev.map((i) => i.id === p.id && i.color === color ? { ...i, qty: i.qty + 1 } : i);
}
Return [...prev, { ...p, color, qty: 1 }];
});
}

Function handleAddProductAdmin() {
If (!newProduct.name.trim() || !newProduct.price) return;
Const newEntry = {
Id: Date.now(),
Name: newProduct.name,
Cat: newProduct.cat,
Price: Number(newProduct.price),
Promo: null,
Popular: false,
New: true,
Colors: ["Noir"],
Rating: 5,
Reviews: 0,
Desc: "Produit récemment ajouté.",
};
SetProducts((prev) => [newEntry, ...prev]);
SetNewProduct({ name: "", price: "", cat: "Sacs à main" });
}

Function handleContactSubmit(e) {
E.preventDefault();
Const text = `Bonjour, je suis ${contactForm.name} (${contactForm.phone}). Message : ${contactForm.message}`;
Window.open(`https://wa.me/${WHATSAPP_NUMBER}?text=${encodeURIComponent(text)}`, "_blank");
}

Return (


{/* Navigation Header */}

{page !== "accueil" ? (
setPage("accueil")} className="p-1">
) :
}

setPage("panier")} className="relative p-1">

{cartCount > 0 && (

{cartCount}

)}

{/* Vue dynamique basée sur la variable 'page' */}
{/* ... [Rendu du reste de la page identique avec l'intégration des handlers] */}

{/* Bottom Navigation */}

{[
{ id: "accueil", icon: Home, label: "Accueil" },
{ id: "boutique", icon: ShoppingBag, label: "Boutique" },
{ id: "panier", icon: ShoppingBag, label: "Panier", badge: cartCount },
{ id: "contact", icon: Phone, label: "Contact" },
{ id: "apropos", icon: Info, label: "À propos" },
].map((t) => (
setPage(t.id)}
className={`flex flex-col items-center gap-0.5 px-2 relative ${page === t.id ? "text-[#1B1712]" : "text-[#c2b7a3]"}`}
>

{t.label}

))}

Contributor guide

No contributing guide indexed for this repository

Research direction

The issue contains an inline React application but does not identify a repository file, test, entry point, or requested change. First clarify the intended scope and locate where this application belongs in the repository; completion criteria cannot be established until the expected change is specified.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, react, tailwindcss
Domain
frontend, web-dev
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.