প্রাইস পেতে লিংকটি ভিজিট করুন

https://www.cpmrevenuegate.com/rh5ki6xzq?key=a011a56158e715d549d9281e2d981746

Wednesday, August 27, 2025

Lance break

import React, { useEffect, useMemo, useState } from "react"; import { ShoppingCart, Bike, ChefHat, Clock, MapPin, Phone, User, CheckCircle2, Loader2, Receipt, Download, Trash2 } from "lucide-react"; import { Card, CardContent } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Textarea } from "@/components/ui/textarea"; // --- Helper: localStorage wrapper --- const ls = { get(key, fallback) { try { const v = localStorage.getItem(key); return v ? JSON.parse(v) : fallback; } catch (e) { return fallback; } }, set(key, value) { try { localStorage.setItem(key, JSON.stringify(value)); } catch {} }, }; // --- Sample Menu (BDT) --- const MENU = [ { id: "m1", name: "ভাত বক্স (মুরগি)", price: 160, desc: "ভাত + মুরগি + ডাল + স্যালাড", cat: "লাঞ্চ" }, { id: "m2", name: "ভাত বক্স (গরু)", price: 220, desc: "ভাত + গরু + ডাল + স্যালাড", cat: "লাঞ্চ" }, { id: "m3", name: "চিকেন বিরিয়ানি", price: 180, desc: "সুগন্ধি বাসমতী চাল", cat: "বিরিয়ানি" }, { id: "m4", name: "বিফ বিরিয়ানি", price: 240, desc: "নরম মাংস + ডিম", cat: "বিরিয়ানি" }, { id: "m5", name: "বিফ/চিকেন বার্গার", price: 150, desc: "চিজ + সস", cat: "স্ন্যাকস" }, { id: "m6", name: "চিকেন রোল", price: 90, desc: "স্ট্রিট-স্টাইল", cat: "স্ন্যাকস" }, { id: "m7", name: "লেমনেড (৪০০মিলি)", price: 60, desc: "তাজা", cat: "পানীয়" }, { id: "m8", name: "কোল্ড কফি", price: 120, desc: "আইসি ব্লেন্ড", cat: "পানীয়" }, ]; const PAYMENT_METHODS = [ { id: "bkash", label: "বিকাশ" }, { id: "nagad", label: "নগদ" }, { id: "rocket", label: "রকেট" }, { id: "cod", label: "ক্যাশ অন ডেলিভারি" }, ]; const AREAS = [ "ধানমন্ডি", "মোহাম্মদপুর", "উত্তরা", "মিরপুর", "গুলশান", "বনানী", "বাড্ডা", "রামপুরা", "মতিঝিল", ]; const TIME_SLOTS = [ "আজ ১২:৩০ - ১:০০", "আজ ১:০০ - ১:৩০", "আজ ১:৩০ - ২:০০", "আজ ২:০০ - ২:৩০", ]; function Badge({ children }) { return {children}; } function currency(n) { return `৳${Number(n).toLocaleString("bn-BD")}`; } export default function LunchApp() { const [tab, setTab] = useState(ls.get("tab", "customer")); const [cart, setCart] = useState(ls.get("cart", {})); // {id: qty} const [orders, setOrders] = useState(ls.get("orders", [])); const [loading, setLoading] = useState(false); useEffect(() => ls.set("cart", cart), [cart]); useEffect(() => ls.set("orders", orders), [orders]); useEffect(() => ls.set("tab", tab), [tab]); const cartItems = useMemo(() => { return Object.entries(cart).map(([id, qty]) => { const item = MENU.find(m => m.id === id); return { ...item, qty, lineTotal: item.price * qty }; }); }, [cart]); const subtotal = useMemo(() => cartItems.reduce((s, i) => s + i.lineTotal, 0), [cartItems]); const deliveryFee = subtotal > 500 ? 0 : (subtotal > 0 ? 30 : 0); const grandTotal = subtotal + deliveryFee; // --- Customer Form State --- const [form, setForm] = useState({ name: "", phone: "", address: "", area: AREAS[0], timeSlot: TIME_SLOTS[0], note: "", payment: "bkash", txid: "", }); function addToCart(id) { setCart(prev => ({ ...prev, [id]: (prev[id] || 0) + 1 })); } function decFromCart(id) { setCart(prev => { const q = (prev[id] || 0) - 1; const next = { ...prev }; if (q <= 0) delete next[id]; else next[id] = q; return next; }); } function clearCart() { setCart({}); } function placeOrder() { // Basic validation if (!cartItems.length) return alert("কার্টে পণ্য নেই!"); if (!form.name.trim() || !form.phone.trim() || !form.address.trim()) { return alert("নাম, ফোন ও ঠিকানা দিন"); } if (["bkash", "nagad", "rocket"].includes(form.payment) && !form.txid.trim()) { return alert("ট্রানজ্যাকশন আইডি (TXID) দিন"); } setLoading(true); setTimeout(() => { const order = { id: `ORD-${Date.now()}`, createdAt: new Date().toISOString(), items: cartItems, totals: { subtotal, deliveryFee, grandTotal }, customer: { ...form }, status: "নতুন", }; const next = [order, ...orders]; setOrders(next); clearCart(); setForm(f => ({ ...f, note: "", txid: "" })); setLoading(false); alert("অর্ডার প্লেসড! আমরা শীঘ্রই যোগাযোগ করবো।"); }, 600); } function updateOrderStatus(id, status) { setOrders(prev => prev.map(o => (o.id === id ? { ...o, status } : o))); } function deleteOrder(id) { if (!confirm("অর্ডারটি ডিলিট করবেন?")) return; setOrders(prev => prev.filter(o => o.id !== id)); } function exportCSV() { const rows = [ ["OrderID","CreatedAt","Status","Name","Phone","Area","Address","TimeSlot","Payment","TXID","Subtotal","DeliveryFee","GrandTotal","Items"], ...orders.map(o => [ o.id, o.createdAt, o.status, o.customer.name, o.customer.phone, o.customer.area, o.customer.address, o.customer.timeSlot, o.customer.payment, o.customer.txid, o.totals.subtotal, o.totals.deliveryFee, o.totals.grandTotal, o.items.map(i => `${i.name} x${i.qty}`).join("; ") ]) ]; const csv = rows.map(r => r.map(x => `"${String(x).replaceAll('"', '""')}"`).join(",")).join("\n"); const blob = new Blob([csv], { type: "text/csv;charset=utf-8;" }); const url = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = `orders_${new Date().toISOString().slice(0,10)}.csv`; document.body.appendChild(a); a.click(); a.remove(); URL.revokeObjectURL(url); } return (
{/* Header */}

সিটি লাঞ্চ — অর্ডার অ্যাপ

আপনার শহরে দ্রুত হোম/অফিস ডেলিভারি

{tab === "customer" ? (
{/* Menu */}
{/* Filter by category */}
{Array.from(new Set(MENU.map(m => m.cat))).map(cat => ( {cat} ))}
{MENU.map(item => (

{item.name}

{item.desc}

{currency(item.price)}
{cart[item.id] || 0}
))}
{/* Cart & Checkout */}
Clear} /> {cartItems.length ? (
{cartItems.map(ci => (
{ci.name} ×{ci.qty}
{currency(ci.price)} /টি
{currency(ci.lineTotal)}
))}
সাবটোটাল{currency(subtotal)}
ডেলিভারি ফি{deliveryFee ? currency(deliveryFee) : "ফ্রি"}
মোট{currency(grandTotal)}
) : (
কার্ট খালি
)}
} label="নাম" value={form.name} onChange={e => setForm({ ...form, name: e.target.value })} placeholder="আপনার নাম" /> } label="ফোন" value={form.phone} onChange={e => setForm({ ...form, phone: e.target.value })} placeholder="01XXXXXXXXX" />
} label="এলাকা" value={form.area} onChange={e => setForm({ ...form, area: e.target.value })} as="select" options={AREAS} /> } label="টাইম স্লট" value={form.timeSlot} onChange={e => setForm({ ...form, timeSlot: e.target.value })} as="select" options={TIME_SLOTS} />