'Affogato', option: '', qty: 1, notes: 'Kahvesi bol dökülsün', status: 'Hazırlanıyor', time: Date.now() - 1200000, category: 'Bar' } ]); // Güvenlik & İşlem Logları const [auditLogs, setAuditLogs] = useState([ { id: 'log1', time: '12:30', user: 'Yönetici', action: 'Sistem yerel sunucu ağında başlatıldı.' }, { id: 'log2', time: '12:35', user: 'Garson Ahmet', action: 'Masa 2 için yeni sipariş girdi.' } ]); // Muhasebe & Depo Yönetim State'leri const [inventoryItems, setInventoryItems] = useState(INITIAL_INVENTORY_ITEMS); const [inventoryLogs, setInventoryLogs] = useState(INITIAL_INVENTORY_LOGS); const [expenses, setExpenses] = useState(INITIAL_EXPENSES); const [completedSales, setCompletedSales] = useState(INITIAL_COMPLETED_SALES); // Envanter Tanımlama State'i const [newInvItem, setNewInvItem] = useState({ name: '', category: 'Kahveler', initialStock: '', costPrice: '' }); // Envanter Hareket State'i (Sürekli Hızlı Stok Giriş/Çıkış Formu) const [stockMovement, setStockMovement] = useState({ itemId: '', type: 'Stok Girişi', qty: '', price: '', note: '' }); // Gider Ekleme State'i const [newExpense, setNewExpense] = useState({ title: '', amount: '', category: 'Günlük Alışveriş' }); // Admin PIN Onay Modalı (Hassas işlemler için) const [adminVerifyAction, setAdminVerifyAction] = useState(null); const [adminPinInput, setAdminPinInput] = useState(''); const [adminPinError, setAdminPinError] = useState(''); // Yönetici Paneli Görünümü Aktifliği const [showAdminPanel, setShowAdminPanel] = useState(false); const [adminTab, setAdminTab] = useState('menu'); // 'menu' | 'tables' | 'inventory' | 'expenses' | 'users' | 'logs' // Yeni Ürün Ekleme Form State'leri const [newProduct, setNewProduct] = useState({ name: '', category: 'Sıcak İçecekler', price: '', stock: '', options: '' }); // Yeni Masa Ekleme Form State'leri const [newTable, setNewTable] = useState({ name: '', section: 'İç Mekan' }); // Fiyat Hızlı Düzenleme State const [editingProductId, setEditingProductId] = useState(null); const [editingProductPrice, setEditingProductPrice] = useState(''); // Yeni Şifre Düzenleme State'leri const [editingRoleKey, setEditingRoleKey] = useState(null); const [newRolePinInput, setNewRolePinInput] = useState(''); const [rolePinError, setRolePinError] = useState(''); // Yeni Garson Ekleme State'i const [newWaiterName, setNewWaiterName] = useState(''); // Termal Fiş Yazıcı Simülatörü Modalı const [receiptData, setReceiptData] = useState(null); // İnaktivite Sayacı (30 Saniye) const [secondsRemaining, setSecondsRemaining] = useState(30); const timerRef = useRef(null); useEffect(() => { if (currentUser && currentUser.code !== roles.KITCHEN.code) { resetTimer(); timerRef.current = setInterval(() => { setSecondsRemaining(prev => { if (prev <= 1) { handleLogout(); return 30; } return prev - 1; }); }, 1000); } return () => { if (timerRef.current) clearInterval(timerRef.current); }; }, [currentUser, roles]); // Ekran tıklandığında süreyi sıfırla const handleUserActivity = () => { resetTimer(); }; const resetTimer = () => { setSecondsRemaining(30); }; const handleLogout = () => { setCurrentUser(null); setPinInput(''); setPinError(''); setSelectedTable(null); setPaymentTable(null); setShowAdminPanel(false); if (timerRef.current) clearInterval(timerRef.current); }; const handlePinSubmit = (e) => { e?.preventDefault(); const matchedRole = Object.values(roles).find(r => r.code === pinInput); if (matchedRole) { setCurrentUser(matchedRole); setPinInput(''); setPinError(''); addLog(matchedRole.name, 'Sistem oturumu açtı.'); } else { setPinError('Hatalı PIN Kodu! Lütfen tekrar deneyin.'); setPinInput(''); } }; const handlePinKeyPress = (num) => { setPinError(''); if (pinInput.length < 4) { setPinInput(prev => prev + num); } }; const addLog = (user, action) => { const timeString = new Date().toLocaleTimeString('tr-TR', { hour: '2-digit', minute: '2-digit', second: '2-digit' }); setAuditLogs(prev => [{ id: 'log_' + Date.now(), time: timeString, user, action }, ...prev]); }; const handleTableClick = (table) => { resetTimer(); if (currentUser.code === roles.KITCHEN.code) return; // Mutfak masalara müdahale edemez. setSelectedTable(table); setCurrentOrderCart(table.orders || []); }; const handleAddToOrderCart = (item) => { resetTimer(); if (item.stock <= 0) { alert("Bu ürünün stoğu kalmamıştır!"); return; } if (item.options && item.options.length > 0) { setSelectedItemForOptions(item); setSelectedOption(item.options[0]); } else { addToCartWithOption(item, ''); } }; const addToCartWithOption = (item, option) => { const optionExtraPrice = option.includes('+') ? parseInt(option.split('+')[1]) : 0; const finalPrice = item.price + optionExtraPrice; setCurrentOrderCart(prev => { const existing = prev.find(x => x.name === item.name && x.option === option); if (existing) { return prev.map(x => (x.name === item.name && x.option === option) ? { ...x, qty: x.qty + 1 } : x); } else { return [...prev, { name: item.name, price: finalPrice, option, qty: 1, notes: orderNotes }]; } }); setMenuItems(prev => prev.map(m => m.id === item.id ? { ...m, stock: m.stock - 1 } : m)); setOrderNotes(''); setSelectedItemForOptions(null); }; const handleUpdateCartQty = (index, delta) => { resetTimer(); const cartItem = currentOrderCart[index]; const menuItem = menuItems.find(m => m.name === cartItem.name); if (delta > 0 && menuItem && menuItem.stock <= 0) { alert("Yeterli stok yok!"); return; } setCurrentOrderCart(prev => { const updated = [...prev]; updated[index].qty += delta; if (updated[index].qty <= 0) { if (currentUser.code !== roles.ADMIN.code) { // Garson silmeye çalışırsa şifre isteyeceğiz setAdminVerifyAction({ actionType: 'DELETE_CART_ITEM', data: { index, cartItem } }); return prev; } else { addLog(currentUser.name, `${selectedTable.name} masasından ${cartItem.name} siparişi silindi.`); updated.splice(index, 1); } } return updated; }); if (menuItem) { setMenuItems(prev => prev.map(m => m.id === menuItem.id ? { ...m, stock: m.stock - delta } : m)); } }; const handleConfirmOrder = () => { resetTimer(); if (currentOrderCart.length === 0) return; const updatedTables = tables.map(t => { if (t.id === selectedTable.id) { const totalAmount = currentOrderCart.reduce((acc, curr) => acc + (curr.price * curr.qty), 0); return { ...t, status: 'Dolu', orders: currentOrderCart, waiter: selectedTable.waiter || currentUser.name, total: totalAmount }; } return t; }); const newKdsOrders = currentOrderCart.map(cart => ({ id: 'kds_' + Date.now() + '_' + Math.random(), tableName: selectedTable.name, item: cart.name, option: cart.option, qty: cart.qty, notes: cart.notes, status: 'Hazırlanıyor', time: Date.now(), category: ['Sıcak İçecekler', 'Türk Kahvesi', 'Çay'].some(k => cart.name.includes(k)) ? 'Mutfak' : 'Bar' })); setKdsOrders(prev => [...prev, ...newKdsOrders]); setTables(updatedTables); addLog(currentUser.name, `${selectedTable.name} için siparişleri onayladı. Atanan Garson: ${selectedTable.waiter || currentUser.name}, Toplam: ${currentOrderCart.reduce((a, b) => a + (b.price * b.qty), 0)}₺`); setSelectedTable(null); }; const handleAdminVerify = (e) => { e.preventDefault(); if (adminPinInput === roles.ADMIN.code) { if (adminVerifyAction.actionType === 'DELETE_CART_ITEM') { const { index, cartItem } = adminVerifyAction.data; setCurrentOrderCart(prev => prev.filter((_, idx) => idx !== index)); addLog('Yönetici Onaylı', `${selectedTable.name} masasından ${cartItem.name} iptal edildi.`); } else if (adminVerifyAction.actionType === 'APPLY_CUSTOM_DISCOUNT') { setDiscountPercent(adminVerifyAction.data); addLog('Yönetici Onaylı', `İndirim uygulandı: %${adminVerifyAction.data}`); } setAdminVerifyAction(null); setAdminPinInput(''); setAdminPinError(''); } else { setAdminPinError('Yönetici PIN hatalı!'); setAdminPinInput(''); } }; const handleOpenPayment = (table) => { resetTimer(); setPaymentTable(table); setDiscountPercent(0); setNumSplits(1); setRemainingSplitAmount(table.total); setPaymentHistory([]); }; const handlePayPartial = (type, amount) => { resetTimer(); const nextRemaining = remainingSplitAmount - amount; const historyEntry = { id: 'p_' + Date.now(), type, amount }; setPaymentHistory(prev => [...prev, historyEntry]); setRemainingSplitAmount(nextRemaining); if (nextRemaining <= 1) { finalizeReceipt(paymentTable, paymentHistory.concat(historyEntry), discountPercent); } }; const finalizeReceipt = (table, payments, discount) => { const discountedTotal = table.total * (1 - discount / 100); // Satış Detayını Raporlama İçin Kaydet const paymentMethodsText = payments.map(p => `${p.type} (${p.amount}₺)`).join(', '); const newSale = { id: 'sale_' + Date.now(), tableName: table.name, total: discountedTotal, paymentMethod: paymentMethodsText, date: new Date().toLocaleDateString('tr-TR') }; setCompletedSales(prev => [newSale, ...prev]); setReceiptData({ tableName: table.name, waiter: table.waiter, orders: table.orders, discount, total: table.total, finalTotal: discountedTotal, payments, date: new Date().toLocaleString('tr-TR') }); setTables(prev => prev.map(t => t.id === table.id ? { ...t, status: 'Boş', orders: [], waiter: '', total: 0 } : t)); addLog(currentUser.name, `${table.name} hesabı kapatıldı. Toplam tahsilat: ${discountedTotal}₺`); setPaymentTable(null); }; const handleKdsStatusChange = (orderId, newStatus) => { setKdsOrders(prev => prev.map(o => o.id === orderId ? { ...o, status: newStatus } : o)); const target = kdsOrders.find(o => o.id === orderId); if (target) { addLog('Mutfak/Bar', `${target.tableName} için ${target.item} ${newStatus === 'Hazır' ? 'Hazırlandı' : 'Teslim Edildi'}`); } }; // --- YÖNETİCİ GEREKSİNİMLERİ (Menü & Masa & Şifre İşlemleri) --- // 1. Yeni Ürün Ekleme const handleAddProductSubmit = (e) => { e.preventDefault(); if (!newProduct.name || !newProduct.price) { alert("Lütfen ürün adı ve fiyatını giriniz."); return; } const newId = 'm_' + Date.now(); const formattedOptions = newProduct.options ? newProduct.options.split(',').map(o => o.trim()) : []; const newItem = { id: newId, category: newProduct.category, name: newProduct.name, price: parseFloat(newProduct.price), stock: parseInt(newProduct.stock) || 100, options: formattedOptions }; setMenuItems(prev => [...prev, newItem]); addLog(currentUser.name, `YENİ ÜRÜN EKLEDİ: ${newProduct.name} - ${newProduct.price}₺`); setNewProduct({ name: '', category: 'Sıcak İçecekler', price: '', stock: '', options: '' }); }; // 2. Ürün Fiyatı Inline Düzenleme const startEditingPrice = (item) => { setEditingProductId(item.id); setEditingProductPrice(item.price.toString()); }; const saveProductPrice = (id) => { const priceNum = parseFloat(editingProductPrice); if (isNaN(priceNum) || priceNum <= 0) { alert("Geçersiz fiyat girdiniz!"); return; } setMenuItems(prev => prev.map(item => { if (item.id === id) { addLog(currentUser.name, `${item.name} ürününün fiyatını ${item.price}₺ -> ${priceNum}₺ olarak güncelledi.`); return { ...item, price: priceNum }; } return item; })); setEditingProductId(null); }; // 3. Ürün Silme const handleDeleteProduct = (id, name) => { if (window.confirm(`${name} ürününü menüden tamamen silmek istediğinizden emin misiniz?`)) { setMenuItems(prev => prev.filter(item => item.id !== id)); addLog(currentUser.name, `ÜRÜN SİLİNDİ: ${name}`); } }; // 4. Yeni Masa Ekleme const handleAddTableSubmit = (e) => { e.preventDefault(); if (!newTable.name) { alert("Lütfen bir masa ismi yazın."); return; } const newId = 't_' + Date.now(); const tableItem = { id: newId, name: newTable.name, section: newTable.section, status: 'Boş', orders: [], waiter: '', total: 0 }; setTables(prev => [...prev, tableItem]); addLog(currentUser.name, `YENİ MASA EKLEDİ: ${newTable.name} (${newTable.section})`); setNewTable({ name: '', section: 'İç Mekan' }); }; // 5. Masa Silme const handleDeleteTable = (id, name) => { if (window.confirm(`${name} masasını sistemden kaldırmak istiyor musunuz?`)) { setTables(prev => prev.filter(t => t.id !== id)); addLog(currentUser.name, `MASA SİLİNDİ: ${name}`); } }; // 6. Masa Garsonu Değiştirme const handleTableWaiterChange = (tableId, waiterName) => { setTables(prev => prev.map(t => { if (t.id === tableId) { addLog(currentUser.name, `${t.name} masasına yeni sorumlu garson atandı: ${waiterName || 'YOK'}`); return { ...t, waiter: waiterName }; } return t; })); }; // 7. PIN Güncelleme İşlemi const startEditingRolePin = (roleKey, currentPin) => { setEditingRoleKey(roleKey); setNewRolePinInput(currentPin); setRolePinError(''); }; const saveRolePin = (roleKey) => { // 4 Haneli Sayı Kontrolü const pinRegex = /^[0-9]{4}$/; if (!pinRegex.test(newRolePinInput)) { setRolePinError('Şifre tam olarak 4 haneli rakamdan oluşmalıdır!'); return; } // Şifre Çakışması Kontrolü const otherRolesUsingPin = Object.entries(roles).filter(([k, r]) => k !== roleKey && r.code === newRolePinInput); if (otherRolesUsingPin.length > 0) { setRolePinError('Bu şifre başka bir rol tarafından kullanılıyor!'); return; } setRoles(prev => { const updated = { ...prev }; updated[roleKey] = { ...updated[roleKey], code: newRolePinInput }; addLog(currentUser.name, `${updated[roleKey].name} rolünün terminal giriş şifresini güncelledi.`); // Eğer kendi şifresini güncellediyse aktif kullanıcın import React, { useState, useEffect, useRef } from 'react'; import { LogIn, LogOut, Utensils, ClipboardList, Layers, Settings, Users, CheckCircle, RefreshCw, Trash2, Plus, Minus, DollarSign, Clock, ShieldAlert, Award, FileText, ShoppingBag, Coffee, ChevronRight, AlertTriangle, Printer, Edit, Save, PlusCircle, X, UserCheck, TrendingUp, TrendingDown, Box, FileSpreadsheet, Calendar } from 'lucide-react'; // Orijinal "noc" Geometrisine Sahip Bağımsız, Kusursuz Yan Yana Logo Tasarımı (Overlapping Yoktur) function NocLogo({ className = "w-28 h-10", color = "currentColor", subtext = true }) { return (
{/* 'n' Harfi - Kusursuz Kemer Yapısı ve Düz Ayaklar */} {/* 'o' Harfi - Tam Çember, 'n' ile Eşit Boşlukta */} {/* 'c' Harfi - Sağ Tarafı Açık Çember, 'o' ile Eşit Boşlukta ve Kesişmesiz */} {subtext && ( coffee )}
); } // Noc Coffee Görsellerinden Aktarılan Eksiksiz Menü Verisi const NOC_MENU_ITEMS = [ // Sıcak Kahveler & İçecekler (Görsel 1) { id: 'm1', category: 'Sıcak İçecekler', name: 'Espresso', price: 150, stock: 100, options: ['Tek Shot', 'Duble (+35₺)', 'Farklı Süt (+35₺)'] }, { id: 'm2', category: 'Sıcak İçecekler', name: 'Espresso Macchiato', price: 160, stock: 80, options: ['Ekstra Şurup (+35₺)', 'Ekstra Shot (+35₺)'] }, { id: 'm3', category: 'Sıcak İçecekler', name: 'Espresso Caramel Macchiato', price: 180, stock: 85, options: ['Ekstra Şurup (+35₺)', 'Farklı Süt (+35₺)'] }, { id: 'm4', category: 'Sıcak İçecekler', name: 'Americano', price: 180, stock: 120, options: ['Ekstra Shot (+35₺)'] }, { id: 'm5', category: 'Sıcak İçecekler', name: 'Filter Coffee', price: 180, stock: 90, options: ['Sade', 'Sütlü (+15₺)', 'Farklı Süt (+35₺)'] }, { id: 'm6', category: 'Sıcak İçecekler', name: 'Cortado', price: 170, stock: 70, options: ['Normal', 'Farklı Süt (+35₺)'] }, { id: 'm7', category: 'Sıcak İçecekler', name: 'Flat White', price: 180, stock: 75, options: ['Normal', 'Farklı Süt (+35₺)'] }, { id: 'm8', category: 'Sıcak İçecekler', name: 'Latte', price: 190, stock: 150, options: ['Normal Süt', 'Farklı Süt (+35₺)', 'Ekstra Şurup (+35₺)'] }, { id: 'm9', category: 'Sıcak İçecekler', name: 'Caramel Latte', price: 200, stock: 100, options: ['Normal Süt', 'Farklı Süt (+35₺)'] }, { id: 'm10', category: 'Sıcak İçecekler', name: 'Lotus Latte', price: 200, stock: 80, options: ['Normal Süt', 'Farklı Süt (+35₺)'] }, { id: 'm11', category: 'Sıcak İçecekler', name: 'Cookie Latte', price: 200, stock: 80, options: ['Normal Süt', 'Farklı Süt (+35₺)'] }, { id: 'm12', category: 'Sıcak İçecekler', name: 'Hazzel Nut Latte', price: 200, stock: 85, options: ['Normal Süt', 'Farklı Süt (+35₺)'] }, { id: 'm13', category: 'Sıcak İçecekler', name: 'Vanilia Latte', price: 200, stock: 90, options: ['Normal Süt', 'Farklı Süt (+35₺)'] }, { id: 'm14', category: 'Sıcak İçecekler', name: 'Spanish Latte', price: 200, stock: 75, options: ['Normal Süt', 'Farklı Süt (+35₺)'] }, { id: 'm15', category: 'Sıcak İçecekler', name: 'Tiramisu Latte', price: 200, stock: 80, options: ['Normal Süt', 'Farklı Süt (+35₺)'] }, { id: 'm16', category: 'Sıcak İçecekler', name: 'Mocha', price: 210, stock: 95, options: ['Normal Süt', 'Farklı Süt (+35₺)'] }, { id: 'm17', category: 'Sıcak İçecekler', name: 'White Mocha', price: 210, stock: 90, options: ['Normal Süt', 'Farklı Süt (+35₺)'] }, { id: 'm18', category: 'Sıcak İçecekler', name: 'Hot Chocolate', price: 190, stock: 110, options: ['Normal Süt', 'Farklı Süt (+35₺)'] }, { id: 'm19', category: 'Sıcak İçecekler', name: 'Türk Kahvesi', price: 150, stock: 300, options: ['Sade', 'Az Şekerli', 'Orta', 'Şekerli'] }, { id: 'm20', category: 'Sıcak İçecekler', name: 'Damla Sakızlı Türk Kahvesi', price: 150, stock: 120, options: ['Sade', 'Az Şekerli', 'Orta', 'Şekerli'] }, { id: 'm21', category: 'Sıcak İçecekler', name: 'Dibek', price: 150, stock: 130, options: ['Sade', 'Az Şekerli', 'Orta', 'Şekerli'] }, { id: 'm22', category: 'Sıcak İçecekler', name: 'Çay', price: 90, stock: 600, options: ['Açık', 'Demli', 'Duble (+30₺)'] }, // Soğuk Kahveler & Frappeler (Görsel 3) { id: 'm23', category: 'Soğuk İçecekler', name: 'Iced Americano', price: 190, stock: 150, options: ['Ekstra Shot (+35₺)'] }, { id: 'm24', category: 'Soğuk İçecekler', name: 'Iced Latte', price: 200, stock: 180, options: ['Normal Süt', 'Farklı Süt (+35₺)', 'Ekstra Şurup (+35₺)'] }, { id: 'm25', category: 'Soğuk İçecekler', name: 'Iced Lotus Latte', price: 210, stock: 90, options: ['Farklı Süt (+35₺)'] }, { id: 'm26', category: 'Soğuk İçecekler', name: 'Iced Spanish Latte', price: 210, stock: 85, options: ['Farklı Süt (+35₺)'] }, { id: 'm27', category: 'Soğuk İçecekler', name: 'Iced Hazel Nut Latte', price: 210, stock: 80, options: ['Farklı Süt (+35₺)'] }, { id: 'm28', category: 'Soğuk İçecekler', name: 'Iced Vanilia Latte', price: 210, stock: 90, options: ['Farklı Süt (+35₺)'] }, { id: 'm29', category: 'Soğuk İçecekler', name: 'Iced Caramel Latte', price: 210, stock: 95, options: ['Farklı Süt (+35₺)'] }, { id: 'm30', category: 'Soğuk İçecekler', name: 'Iced Tiramisu Latte', price: 210, stock: 80, options: ['Farklı Süt (+35₺)'] }, { id: 'm31', category: 'Soğuk İçecekler', name: 'Frappe Chocolate', price: 210, stock: 100, options: ['Farklı Süt (+35₺)'] }, { id: 'm32', category: 'Soğuk İçecekler', name: 'Frappe White Chocolate', price: 210, stock: 95, options: ['Farklı Süt (+35₺)'] }, { id: 'm33', category: 'Soğuk İçecekler', name: 'Frappe Cookie', price: 210, stock: 100, options: ['Farklı Süt (+35₺)'] }, { id: 'm34', category: 'Soğuk İçecekler', name: 'Frappe Caramel', price: 210, stock: 105, options: ['Farklı Süt (+35₺)'] }, { id: 'm35', category: 'Soğuk İçecekler', name: 'Frappe Tiramisu', price: 210, stock: 90, options: ['Farklı Süt (+35₺)'] }, { id: 'm36', category: 'Soğuk İçecekler', name: 'Frappe Vanilia', price: 210, stock: 95, options: ['Farklı Süt (+35₺)'] }, { id: 'm37', category: 'Soğuk İçecekler', name: 'Frappe Hazel Nut Latte', price: 210, stock: 90, options: ['Farklı Süt (+35₺)'] }, { id: 'm38', category: 'Soğuk İçecekler', name: 'Frappe Lotus', price: 210, stock: 90, options: ['Farklı Süt (+35₺)'] }, { id: 'm39', category: 'Soğuk İçecekler', name: 'Affogato', price: 170, stock: 60, options: [] }, { id: 'm40', category: 'Soğuk İçecekler', name: 'Iced White Mocha', price: 220, stock: 85, options: ['Farklı Süt (+35₺)'] }, { id: 'm41', category: 'Soğuk İçecekler', name: 'Iced Mocha', price: 220, stock: 90, options: ['Farklı Süt (+35₺)'] }, // Frozen & Shake (Görsel 2) { id: 'm42', category: 'Frozen & Shake', name: 'Frozen', price: 210, stock: 200, options: ['Limon', 'Kavun', 'Vişne', 'Kivi', 'Yabanmersini', 'Şeftali', 'Mango', 'Yuju', 'Elma', 'Karpuz'] }, { id: 'm43', category: 'Frozen & Shake', name: 'Vanilya Shake', price: 210, stock: 100, options: [] }, { id: 'm44', category: 'Frozen & Shake', name: 'Chocoate Shake', price: 210, stock: 100, options: [] }, { id: 'm45', category: 'Frozen & Shake', name: 'Caramel Shake', price: 210, stock: 100, options: [] }, { id: 'm46', category: 'Frozen & Shake', name: 'Çilek Shake', price: 210, stock: 100, options: [] }, { id: 'm47', category: 'Frozen & Shake', name: 'Antep Shake', price: 210, stock: 80, options: [] }, { id: 'm48', category: 'Frozen & Shake', name: 'Oreo Shake', price: 230, stock: 90, options: [] }, { id: 'm49', category: 'Frozen & Shake', name: 'Lotus Shake', price: 230, stock: 85, options: [] }, // Özel Karışımlar (Görsel 2) { id: 'm50', category: 'Özel Karışımlar', name: 'Satori', price: 260, stock: 60, options: [] }, { id: 'm51', category: 'Özel Karışımlar', name: 'Berry Hibiscus', price: 200, stock: 120, options: [] }, { id: 'm52', category: 'Özel Karışımlar', name: 'Cool Lime', price: 200, stock: 150, options: [] }, { id: 'm53', category: 'Özel Karışımlar', name: 'Orangethelime', price: 220, stock: 110, options: [] }, { id: 'm54', category: 'Özel Karışımlar', name: 'Kensho', price: 260, stock: 65, options: [] }, { id: 'm55', category: 'Özel Karışımlar', name: 'Melonandmango', price: 220, stock: 100, options: [] }, { id: 'm56', category: 'Özel Karışımlar', name: 'Blue Glassy', price: 220, stock: 90, options: [] }, { id: 'm57', category: 'Özel Karışımlar', name: 'Peach For Sugar', price: 220, stock: 80, options: [] }, { id: 'm58', category: 'Özel Karışımlar', name: 'Likeatekila', price: 220, stock: 75, options: [] }, { id: 'm59', category: 'Özel Karışımlar', name: 'Applelian', price: 220, stock: 85, options: [] } ]; const INITIAL_TABLES = [ { id: 't1', name: 'Masa 1', section: 'İç Mekan', status: 'Boş', orders: [], waiter: '', total: 0 }, { id: 't2', name: 'Masa 2', section: 'İç Mekan', status: 'Dolu', orders: [ { name: 'Latte', price: 190, option: 'Farklı Süt (+35₺)', qty: 2, notes: 'Çok sıcak olsun' }, { name: 'Oreo Shake', price: 230, option: '', qty: 1, notes: '' } ], waiter: 'Garson Ahmet', total: 610 }, { id: 't3', name: 'Masa 3', section: 'İç Mekan', status: 'Hesap İstendi', orders: [ { name: 'Satori', price: 260, option: '', qty: 1, notes: '' }, { name: 'Türk Kahvesi', price: 150, option: 'Orta', qty: 1, notes: 'Yanında çifte kavrulmuş lokum' } ], waiter: 'Garson Ayşe', total: 410 }, { id: 't4', name: 'Masa 4', section: 'İç Mekan', status: 'Boş', orders: [], waiter: '', total: 0 }, { id: 't5', name: 'Masa 5', section: 'İç Mekan', status: 'Rezerve', orders: [], waiter: '', total: 0 }, { id: 't6', name: 'Bahçe 1', section: 'Bahçe', status: 'Boş', orders: [], waiter: '', total: 0 }, { id: 't7', name: 'Bahçe 2', section: 'Bahçe', status: 'Dolu', orders: [ { name: 'Espresso', price: 150, option: 'Duble (+35₺)', qty: 1, notes: '' }, { name: 'Affogato', price: 170, option: '', qty: 1, notes: 'Kahvesi bol dökülsün' } ], waiter: 'Garson Ahmet', total: 320 }, { id: 't8', name: 'Bahçe 3', section: 'Bahçe', status: 'Boş', orders: [], waiter: '', total: 0 }, { id: 't9', name: 'Teras 1', section: 'Teras', status: 'Dolu', orders: [ { name: 'Frappe Caramel', price: 210, option: '', qty: 2, notes: '' } ], waiter: 'Garson Ayşe', total: 420 }, { id: 't10', name: 'Teras 2', section: 'Teras', status: 'Boş', orders: [], waiter: '', total: 0 } ]; // Başlangıç Rol Şifreleri (Dinamik) const INITIAL_ROLES = { ADMIN: { code: '1111', name: 'Yönetici (Mert Bey)', permissions: ['all'] }, CASHIER: { code: '2222', name: 'Kasiyer Can', permissions: ['tables', 'payments', 'orders'] }, WAITER: { code: '3333', name: 'Garson Ahmet', permissions: ['tables', 'orders'] }, KITCHEN: { code: '4444', name: 'Mutfak / Şef', permissions: ['kds'] } }; const INITIAL_WAITER_LIST = ['Garson Ahmet', 'Garson Ayşe', 'Garson Mehmet', 'Garson Elif']; // Başlangıç Depo ve Gider Listeleri const INITIAL_INVENTORY_ITEMS = [ { id: 'inv1', name: 'Espresso Kahve Çekirdeği (kg)', stock: 15, costPrice: 420, category: 'Kahveler' }, { id: 'inv2', name: 'Sütaş Barista Sütü (Litre)', stock: 64, costPrice: 32, category: 'Sütler' }, { id: 'inv3', name: 'Monin Karamel Şurubu (Adet)', stock: 8, costPrice: 280, category: 'Şuruplar' }, { id: 'inv4', name: 'Karton Bardak 8oz (Koli)', stock: 3, costPrice: 650, category: 'Sarf Malzemesi' }, { id: 'inv5', name: 'Lotus Bisküvi Ezmesi (Kavanoz)', stock: 4, costPrice: 190, category: 'Mutfak Malzemesi' } ]; const INITIAL_INVENTORY_LOGS = [ { id: 'ilog1', itemId: 'inv1', type: 'Stok Girişi', qty: 10, price: 420, date: '19.05.2026', note: 'Özdemir Kahve Toptancısı' }, { id: 'ilog2', itemId: 'inv2', type: 'Stok Girişi', qty: 24, price: 32, date: '19.05.2026', note: 'Sütaş Yerel Dağıtıcı' }, { id: 'ilog3', itemId: 'inv3', type: 'Zayi Çıkışı', qty: 1, price: 280, date: '19.05.2026', note: 'Zayi: Şişe bar arkasında kırıldı' } ]; const INITIAL_EXPENSES = [ { id: 'exp1', title: 'Günlük Taze Pastane Alımları', amount: 850, category: 'Günlük Alışveriş', date: '19.05.2026' }, { id: 'exp2', title: 'Dükkan Elektrik Faturası', amount: 5400, category: 'Fatura', date: '18.05.2026' }, { id: 'exp3', title: 'Barista Temizlik Malzemeleri', amount: 320, category: 'Temizlik', date: '19.05.2026' } ]; // Satış Raporu İçin Kapatılan Adisyonların Hafızası const INITIAL_COMPLETED_SALES = [ { id: 'sale1', tableName: 'Masa 4', total: 480, paymentMethod: 'Kredi Kartı', date: '19.05.2026' }, { id: 'sale2', tableName: 'Bahçe 1', total: 310, paymentMethod: 'Nakit', date: '19.05.2026' } ]; export default function App() { const [currentUser, setCurrentUser] = useState(null); const [pinInput, setPinInput] = useState(''); const [pinError, setPinError] = useState(''); // Dinamik Şifreler, Roller ve Personel State'leri const [roles, setRoles] = useState(INITIAL_ROLES); const [waiters, setWaiters] = useState(INITIAL_WAITER_LIST); const [tables, setTables] = useState(INITIAL_TABLES); const [menuItems, setMenuItems] = useState(NOC_MENU_ITEMS); const [activeSection, setActiveSection] = useState('İç Mekan'); const [selectedTable, setSelectedTable] = useState(null); // Sipariş Kurguları const [activeCategory, setActiveCategory] = useState('Sıcak İçecekler'); const [currentOrderCart, setCurrentOrderCart] = useState([]); const [selectedItemForOptions, setSelectedItemForOptions] = useState(null); const [selectedOption, setSelectedOption] = useState(''); const [orderNotes, setOrderNotes] = useState(''); // Ödeme Ekranı Kurguları const [paymentTable, setPaymentTable] = useState(null); const [discountPercent, setDiscountPercent] = useState(0); const [numSplits, setNumSplits] = useState(1); const [remainingSplitAmount, setRemainingSplitAmount] = useState(0); const [paymentHistory, setPaymentHistory] = useState([]); // KDS (Mutfak Siparişleri) const [kdsOrders, setKdsOrders] = useState([ { id: 'kds1', tableName: 'Masa 2', item: 'Latte', option: 'Farklı Süt (+35₺)', qty: 2, notes: 'Çok sıcak olsun', status: 'Hazırlanıyor', time: Date.now() - 600000, category: 'Bar' }, { id: 'kds2', tableName: 'Bahçe 2', item:
top of page

Akşam Yemeği Menüsü

Her gün 18.00-23.00 arasında servis edilir



İştah Açıcılar

Bu yemekler paylaşmak için idealdir




Ekmek ve Dip Sos

Ekşi maya ekmek yanında humus, pancar ve yoğurtlu beyaz peynir dip sos

₺45,00

Vejetaryen
Vejetaryen
Ekmek ve Dip Sos


Mevsim Salatası

Mevsim yeşillikleri ve kavrulmuş bademli yeşil salata

Küçük

₺35,00


Orta

₺55,00

Süt ürünsüz
Süt ürünsüz
Az Acılı
Az Acılı
Mevsim Salatası


Ton Balığı Sashimi

Mühürlenmiş taze ton balığı, taze otlar ve hafif bir acılık

₺45,00

Kişniş
Kişniş
Ton Balığı Sashimi



Ana Yemekler

Hepsi yerel ve günlük olarak temin edilen çok çeşitli lezzetler




El Yapımı Ravyoli

Fesleğenli pesto sosu içinde peynir karışımı dolgulu el yapımı geleneksel ravyoli

₺95,00

El Yapımı Ravyoli


Yer Fıstıklı Çıtır Biftek

Buharda pişmiş sebzeler eşliğinde servis edilen, damak zevkinize göre pişirilmiş yumuşak ve sulu biftek

₺115,00

Yer fıstığı
Yer fıstığı
Çiğ
Çiğ
Yer Fıstıklı Çıtır Biftek


Günün Balığı

Kuşkonmaz ve tatlı patates kreması eşliğinde günlük tutulmuş balık

₺115,00

Balık
Balık
Kabuklu deniz ürünleri
Kabuklu deniz ürünleri
Günün Balığı


Tofu Şiş

Soya ve susam karışımında marine edilmiş ızgara tofu şiş, mevsim sebzeleri eşliğinde

₺100,00

Vegan
Vegan
Tofu Şiş


Klasik Burger

Marul, turşu, ata tohumu domates eşliğinde klasik burgerimiz, yanında kızarmış patates

Mantar

₺70,00


Tavuk

₺80,00


Dana eti

₺90,00

Klasik Burger


Şnitzel

Baharat ve parmesan ile kaplı, çıtır çıtır ve altın gibi kızarmış

₺80,00

Şnitzel



Tatlılar

Tatlılarımız kendi mutfağımızda pasta şefimiz tarafından yapılır




Hurmalı Islak Kek ve Dondurma

Vanilyalı dondurma, karamela sosu ve yer fıstığı parçaları ile servis edilir

₺70,00

Vejetaryen
Vejetaryen
Hurmalı Islak Kek ve Dondurma


Klasik Cheesecake

Üzerinde ahududu reçeli ve çilek dilimleri ile servis edilir

₺65,00

Süt ürünleri
Süt ürünleri
Klasik Cheesecake


Limonlu Mereng Turta

Krem şanti ile sevis edilen antep fıstığı parçaları ile süslü limonlu mereng

₺55,00

Kabuklu yemişler
Kabuklu yemişler
Limonlu Mereng Turta


Çikolatalı Mus

Hafif ancak yoğun lezzetli, ünlü çikolatalı mus tatlımız

Tek porsiyon

₺40,00


Çift porsiyon

₺70,00

Çikolatalı Mus


Havuçlu Kek

Krem peyniri kremalı, hafif baharatlı havuçlu kek

₺55,00

Havuçlu Kek


Brownie

Bitter çikolata parçacıklı ve cevizli, fırından yeni çıkmış brownie

₺50,00

Süt ürünsüz
Süt ürünsüz
Brownie



İçecekler




Sağlıklı Smoothie

Sağlıklı smoothie çeşitlerimizle vücudunuzu besleyin

₺45,00



Taze Meyve Suyu

Taze sıkılmış portakal, karpuz, havuç ve zencefil karışımı

Küçük

₺20,00


Orta

₺30,00


Büyük

₺45,00



Şarap

Kırmızı, beyaz veya roze

₺60,00



Alkolsuz İçecek

Soda, Sprite, Pepsi ve Diyet Kola

₺30,00



Kahve

Taze kavrulmuş kahve

₺45,00



Kokteyller

Aperol Spritz, Cin Tonik, Mojito

₺70,00


551 179 1899 

Yeni İnsanları Anında Keşfedin! Sadece parmağınızı kaydırarak video üzerinden dünyanın dört bir yanından milyonlarca yeni insanla yüz yüze tanışın.

  • White Facebook Icon
  • White Twitter Icon
  • White YouTube Icon
bottom of page