import { useState } from 'react' import { useParams } from 'react-router-dom' import { ShoppingCart, Plus, Minus, X, Clock, CheckCircle2, ChefHat, Truck, CreditCard, Receipt, ArrowLeft, } from 'lucide-react' import { cn, formatCurrency } from '../lib/utils' // ── Types ───────────────────────────────────────────────────────────────────── interface MenuItem { id: string name: string category: string price: number emoji: string time: number popular?: boolean stopList?: boolean } type Step = 'menu' | 'cart' | 'payment' | 'status' type OrderStatus = 'new' | 'preparing' | 'ready' | 'delivered' // ── Mock data (same menu as staff side) ─────────────────────────────────────── const MENU: MenuItem[] = [ { id: 'm1', name: 'Яичница с беконом', category: 'Завтраки', price: 450, emoji: '🍳', time: 15, popular: true }, { id: 'm2', name: 'Омлет с овощами', category: 'Завтраки', price: 380, emoji: '🥚', time: 12 }, { id: 'm3', name: 'Сырники', category: 'Завтраки', price: 320, emoji: '🧀', time: 10 }, { id: 'm4', name: 'Овсяная каша', category: 'Завтраки', price: 250, emoji: '🥣', time: 8 }, { id: 'm5', name: 'Стейк рибай', category: 'Основные', price: 1800, emoji: '🥩', time: 25, popular: true }, { id: 'm6', name: 'Куриная грудка', category: 'Основные', price: 750, emoji: '🍗', time: 20 }, { id: 'm7', name: 'Паста карбонара', category: 'Основные', price: 650, emoji: '🍝', time: 18 }, { id: 'm8', name: 'Лосось на гриле', category: 'Основные', price: 1200, emoji: '🐟', time: 22 }, { id: 'm9', name: 'Цезарь с курицей', category: 'Закуски', price: 550, emoji: '🥗', time: 10, popular: true }, { id: 'm10', name: 'Сэндвич клуб', category: 'Закуски', price: 420, emoji: '🥪', time: 8 }, { id: 'm11', name: 'Сырная тарелка', category: 'Закуски', price: 680, emoji: '🧀', time: 5 }, { id: 'm12', name: 'Кофе американо', category: 'Напитки', price: 180, emoji: '☕', time: 5, popular: true }, { id: 'm13', name: 'Капучино', category: 'Напитки', price: 220, emoji: '☕', time: 6 }, { id: 'm14', name: 'Свежевыжатый сок', category: 'Напитки', price: 280, emoji: '🍊', time: 5 }, { id: 'm15', name: 'Вино красное бокал', category: 'Напитки', price: 450, emoji: '🍷', time: 3 }, { id: 'm16', name: 'Тирамису', category: 'Десерты', price: 380, emoji: '🍮', time: 3 }, { id: 'm17', name: 'Чизкейк', category: 'Десерты', price: 350, emoji: '🍰', time: 3 }, ] const CATEGORIES = [...new Set(MENU.map(i => i.category))] const HOTEL_CONFIG: Record = { 'grand-palace': { name: 'Гранд Палас', color: '#2563eb', serviceChargePct: 15 }, } const DEFAULT_CONFIG = { name: 'Отель', color: '#2563eb', serviceChargePct: 15 } // ── Status display ───────────────────────────────────────────────────────────── const STATUS_STEPS: { key: OrderStatus; label: string; icon: React.ElementType; desc: string }[] = [ { key: 'new', label: 'Принят', icon: Receipt, desc: 'Заказ отправлен на кухню' }, { key: 'preparing', label: 'Готовится', icon: ChefHat, desc: 'Повар готовит ваш заказ' }, { key: 'ready', label: 'Готов', icon: CheckCircle2, desc: 'Заказ готов, передаём курьеру' }, { key: 'delivered', label: 'Доставлен', icon: Truck, desc: 'Курьер в пути к вашему номеру' }, ] // ── Component ───────────────────────────────────────────────────────────────── export function GuestRoomServicePage() { const { slug } = useParams<{ slug: string }>() const config = (slug ? HOTEL_CONFIG[slug] : null) ?? DEFAULT_CONFIG const [category, setCategory] = useState(CATEGORIES[0]) const [cart, setCart] = useState>({}) const [step, setStep] = useState('menu') const [roomNumber, setRoomNumber] = useState('') const [notes, setNotes] = useState('') const [payMode, setPayMode] = useState<'online' | 'bill'>('online') const [orderStatus, setOrderStatus] = useState('new') const cartItems = MENU.filter(i => (cart[i.id] ?? 0) > 0) const subtotal = cartItems.reduce((s, i) => s + i.price * cart[i.id], 0) const svcCharge = Math.round(subtotal * config.serviceChargePct / 100) const total = subtotal + svcCharge const cartCount = Object.values(cart).reduce((s, n) => s + n, 0) const add = (id: string) => setCart(p => ({ ...p, [id]: (p[id] ?? 0) + 1 })) const sub = (id: string) => setCart(p => { const n = Math.max(0, (p[id] ?? 0) - 1); return { ...p, [id]: n } }) const canOrder = cartCount > 0 && roomNumber.trim().length > 0 const placeOrder = () => { // Simulate status progression setStep('status') setOrderStatus('new') setTimeout(() => setOrderStatus('preparing'), 3000) setTimeout(() => setOrderStatus('ready'), 8000) setTimeout(() => setOrderStatus('delivered'), 13000) } const currentStatusIdx = STATUS_STEPS.findIndex(s => s.key === orderStatus) return (
{/* Header */}
{step !== 'menu' && step !== 'status' && ( )}

{config.name}

Room Service

{step === 'menu' && cartCount > 0 && ( )}
{/* ── MENU ── */} {step === 'menu' && (
{/* Category tabs */}
{CATEGORIES.map(cat => ( ))}
{/* Items */}
{MENU.filter(i => i.category === category && !i.stopList).map(item => (
{item.emoji}

{item.name}

{item.popular && ( Хит )}

{item.time} мин

{formatCurrency(item.price)}

{/* Counter */} {(cart[item.id] ?? 0) === 0 ? ( ) : (
{cart[item.id]}
)}
))}
{/* Sticky cart button */} {cartCount > 0 && (
)}
)} {/* ── CART ── */} {step === 'cart' && (

Ваш заказ

{cartItems.map((item, i) => (
{item.emoji}

{item.name}

{formatCurrency(item.price)} × {cart[item.id]}

{cart[item.id]}
{formatCurrency(item.price * cart[item.id])}
))}
Сумма заказа {formatCurrency(subtotal)}
Обслуживание {config.serviceChargePct}% +{formatCurrency(svcCharge)}
Итого {formatCurrency(total)}
{/* Room number */}
setRoomNumber(e.target.value)} />