import React, { useState, useEffect } from 'react'; import { db, storage } from '../../firebase/config'; import { ref, onValue, push, set, remove, update } from 'firebase/database'; import { ref as sRef, uploadBytes, getDownloadURL } from 'firebase/storage'; import { Plus, Trash2, Edit3, X, Image as ImageIcon, Save, Palette, Upload, Loader2, ListTree, ChefHat } from 'lucide-react'; export default function MenuEditor() { const [products, setProducts] = useState([]); const [inventory, setInventory] = useState([]); const [formData, setFormData] = useState({ name: '', price: '', category: 'Principales', image: '', variants: [], ingredients: [], extras: [] }); const [editingItem, setEditingItem] = useState(null); const [isModalOpen, setIsModalOpen] = useState(false); const [menuTheme, setMenuTheme] = useState('dark'); const [uploading, setUploading] = useState(false); useEffect(() => { onValue(ref(db, 'menu'), (snapshot) => { const data = snapshot.val(); setProducts(data ? Object.keys(data).map(id => ({ id, ...data[id] })) : []); }); onValue(ref(db, 'inventory'), (snapshot) => { const data = snapshot.val(); setInventory(data ? Object.keys(data).map(id => ({ id, ...data[id] })) : []); }); onValue(ref(db, 'config/menuTheme'), (snapshot) => { if (snapshot.exists()) setMenuTheme(snapshot.val()); }); }, []); const handleToggleTheme = async () => { await set(ref(db, 'config/menuTheme'), menuTheme === 'dark' ? 'light' : 'dark'); }; const handleImageUpload = async (e, isEditing = false) => { const file = e.target.files[0]; if (!file || !file.type.startsWith('image/')) return; setUploading(true); try { const storagePath = `menu/${Date.now()}_${file.name}`; const fileRef = sRef(storage, storagePath); await uploadBytes(fileRef, file); const url = await getDownloadURL(fileRef); if (isEditing) setEditingItem(prev => ({ ...prev, image: url })); else setFormData(prev => ({ ...prev, image: url })); } catch (error) { console.error(error); } finally { setUploading(false); } }; const handleAddProduct = async (e) => { e.preventDefault(); if (!formData.name || !formData.price) return; const newRef = push(ref(db, 'menu')); await set(newRef, { ...formData, price: parseFloat(formData.price), active: true }); setFormData({ name: '', price: '', category: 'Principales', image: '', variants: [], ingredients: [], extras: [] }); }; const handleDelete = async (id) => { if(window.confirm('¿Eliminar producto?')) await remove(ref(db, `menu/${id}`)); }; const addIngredientToProduct = (isEditing) => { const newIng = { id: '', qty: 1 }; if (isEditing) setEditingItem({ ...editingItem, ingredients: [...(editingItem.ingredients || []), newIng] }); else setFormData({ ...formData, ingredients: [...formData.ingredients, newIng] }); }; const addExtraToProduct = (isEditing) => { const newExtra = { name: '', price: 0 }; if (isEditing) setEditingItem({ ...editingItem, extras: [...(editingItem.extras || []), newExtra] }); else setFormData({ ...formData, extras: [...(formData.extras || []), newExtra] }); }; const handleSaveEdit = async () => { const { id, ...updates } = editingItem; await update(ref(db, `menu/${id}`), { ...updates, price: parseFloat(updates.price) }); setIsModalOpen(false); }; const seedMenu = async () => { if (!window.confirm('¿Deseas cargar el menú de ejemplo de hamburguesas? Esto no borrará tus platos actuales.')) return; const examples = [ { name: 'Hamburgesa Clásica', price: 12.50, category: 'Fuertes', image: '/images/burger_classic.png', active: true, ingredients: [], extras: [{ name: 'Queso Extra', price: 1.50 }, { name: 'Tocineta', price: 2.00 }] }, { name: 'Pollo Crispy Burger', price: 11.00, category: 'Fuertes', image: '/images/burger_chicken.png', active: true, ingredients: [], extras: [{ name: 'Salsa Picante', price: 0.50 }] }, { name: 'Vegan Delight', price: 13.00, category: 'Fuertes', image: '/images/burger_vegan.png', active: true, ingredients: [], extras: [{ name: 'Aguacate', price: 1.50 }] }, { name: 'Papas Supremas', price: 8.50, category: 'Entradas', image: 'https://images.unsplash.com/photo-1573080496219-bb080dd4f877?auto=format&fit=crop&q=80&w=1000', active: true, ingredients: [], extras: [] } ]; for (const item of examples) { const newRef = push(ref(db, 'menu')); await set(newRef, item); } alert('Menú de ejemplo cargado con éxito'); }; return (
Gestión de productos y consumo de insumos