Spaces:
Sleeping
Sleeping
| import React, { useState, useEffect } from 'react'; | |
| import { db } from '../../firebase/config'; | |
| import { ref, onValue, push, set } from 'firebase/database'; | |
| import { TrendingUp, Users, ShoppingBag, AlertCircle, UtensilsCrossed, DollarSign, ShieldCheck, User, Utensils } from 'lucide-react'; | |
| import { useNavigate } from 'react-router-dom'; | |
| export default function DashboardOverview({ setActiveTab }) { | |
| const navigate = useNavigate(); | |
| const [stats, setStats] = useState({ ventasHoy: 0, mesasActivas: 0, stockBajo: 0 }); | |
| useEffect(() => { | |
| // Aquí iría la escucha de Firebase para stats en tiempo real | |
| setStats({ | |
| ventasHoy: 12500, | |
| mesasActivas: 4, | |
| stockBajo: 2 | |
| }); | |
| }, []); | |
| const cards = [ | |
| { title: 'Ventas de Hoy', value: `$${stats.ventasHoy.toLocaleString()}`, icon: <TrendingUp size={24} color="var(--success)" />, bg: 'rgba(32, 201, 151, 0.1)' }, | |
| { title: 'Mesas Activas', value: stats.mesasActivas, icon: <Users size={24} color="var(--info)" />, bg: 'rgba(50, 173, 230, 0.1)' }, | |
| { title: 'Órdenes', value: '45', icon: <ShoppingBag size={24} color="var(--primary)" />, bg: 'rgba(255, 90, 95, 0.1)' }, | |
| { title: 'Stock Bajo', value: stats.stockBajo, icon: <AlertCircle size={24} color="var(--warning)" />, bg: 'rgba(245, 166, 35, 0.1)' } | |
| ]; | |
| const seedData = async () => { | |
| if (!window.confirm('¿Deseas cargar toda la información de ejemplo en el sistema? Esto agregará productos, insumos, usuarios y mesas.')) return; | |
| try { | |
| // 1. Sembrar Menú (8 Productos + 5 Especialidades) | |
| const menuRef = ref(db, 'menu'); | |
| const menuExamples = [ | |
| { name: 'Hamburgesa Clásica', price: 12.50, category: 'Fuertes', image: '/images/burger.png', active: true }, | |
| { name: 'Pasta Pomodoro', price: 10.00, category: 'Pasta', image: '/images/pasta.png', active: true }, | |
| { name: 'Tacos de Pollo', price: 9.00, category: 'Entradas', image: '/images/tacos.png', active: true }, | |
| { name: 'Pizza Margherita', price: 14.00, category: 'Pizzas', image: '/images/pizza.png', active: true }, | |
| { name: 'Ensalada César', price: 8.50, category: 'Entradas', image: 'https://images.unsplash.com/photo-1550304943-4f24f54ddde9?auto=format&fit=crop&q=80&w=1000', active: true }, | |
| { name: 'Sopa de Tomate', price: 7.00, category: 'Entradas', image: 'https://images.unsplash.com/photo-1547592166-23ac45744acd?auto=format&fit=crop&q=80&w=1000', active: true }, | |
| { name: 'Sandwich Gourmet', price: 11.00, category: 'Fuertes', image: 'https://images.unsplash.com/photo-1528735602780-2552fd46c7af?auto=format&fit=crop&q=80&w=1000', active: true }, | |
| { name: 'Chocolate Muffin', price: 4.50, category: 'Postres', image: 'https://images.unsplash.com/photo-1582231222779-1adb0b322f84?auto=format&fit=crop&q=80&w=1000', active: true }, | |
| { name: 'Ribeye Premium', price: 35.00, category: 'Especialidades', image: '/images/steak.png', active: true }, | |
| { name: 'Risotto de Trufa', price: 28.00, category: 'Especialidades', image: '/images/risotto.png', active: true }, | |
| { name: 'Salmón Glaseado', price: 26.00, category: 'Especialidades', image: 'https://images.unsplash.com/photo-1467003909585-2f8a72700288?auto=format&fit=crop&q=80&w=1000', active: true }, | |
| { name: 'Pato a la Naranja', price: 32.00, category: 'Especialidades', image: 'https://images.unsplash.com/photo-1626082927389-6cd097cdc6ec?auto=format&fit=crop&q=80&w=1000', active: true }, | |
| { name: 'Langosta Thermidor', price: 45.00, category: 'Especialidades', image: 'https://images.unsplash.com/photo-1553243599-c052f82958d2?auto=format&fit=crop&q=80&w=1000', active: true } | |
| ]; | |
| for (const item of menuExamples) { await set(push(menuRef), item); } | |
| // 2. Sembrar Inventario | |
| const invRef = ref(db, 'inventory'); | |
| const invExamples = [ | |
| { name: 'Harina de Trigo', quantity: 100, unit: 'Kg', minStock: 20 }, | |
| { name: 'Tomate Cherry', quantity: 15, unit: 'Kg', minStock: 5 }, | |
| { name: 'Queso Mozzarella', quantity: 40, unit: 'Kg', minStock: 10 }, | |
| { name: 'Carne de Res Premium', quantity: 25, unit: 'Kg', minStock: 8 }, | |
| { name: 'Limones', quantity: 200, unit: 'Und', minStock: 50 }, | |
| { name: 'Papas', quantity: 120, unit: 'Kg', minStock: 30 }, | |
| { name: 'Cebolla', quantity: 30, unit: 'Kg', minStock: 10 } | |
| ]; | |
| for (const item of invExamples) { await set(push(invRef), item); } | |
| // 3. Sembrar Mesas | |
| const tableRef = ref(db, 'config/tables'); | |
| for (let i = 1; i <= 12; i++) { | |
| await set(push(tableRef), { number: i, capacity: i > 6 ? 6 : 4, status: 'available', x: 0, y: 0 }); | |
| } | |
| // 4. Sembrar Usuarios | |
| const usersRef = ref(db, 'users'); | |
| const users = [ | |
| { name: 'Juan Pérez', role: 'Mesero', shift: 'Mañana', pin: '1234' }, | |
| { name: 'Ana García', role: 'Cocinero', shift: 'Tarde', pin: '5678' }, | |
| { name: 'Carlos López', role: 'Cajero', shift: 'Completo', pin: '9999' } | |
| ]; | |
| for (const u of users) { await set(push(usersRef), u); } | |
| alert('¡Sistema poblado con datos de ejemplo con éxito! Ya puedes ver los insumos y los platillos. Ve al menú correspondiente para confirmarlo.'); | |
| } catch (err) { | |
| console.error(err); | |
| alert('Hubo un error al intentar subir los datos. Verifica la conexión de red o la consola.'); | |
| } | |
| }; | |
| return ( | |
| <div className="animate-fade-in"> | |
| <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '1.5rem' }}> | |
| <h2 className="text-gradient" style={{ fontSize: '2rem', fontWeight: '800' }}>Resumen General</h2> | |
| <button onClick={seedData} className="btn-glass" style={{ borderColor: 'var(--info)', color: 'var(--info)' }}> | |
| Cargar Datos de Ejemplo | |
| </button> | |
| </div> | |
| <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(240px, 1fr))', gap: '1.5rem', marginBottom: '3rem' }}> | |
| {cards.map((card, i) => ( | |
| <div key={i} className="glass-card" style={{ display: 'flex', alignItems: 'center', gap: '1.5rem' }}> | |
| <div style={{ width: '56px', height: '56px', borderRadius: '50%', background: card.bg, display: 'flex', alignItems: 'center', justifyContent: 'center' }}> | |
| {card.icon} | |
| </div> | |
| <div> | |
| <p style={{ color: 'var(--text-muted)', fontSize: '0.9rem', marginBottom: '0.25rem' }}>{card.title}</p> | |
| <h3 style={{ fontSize: '1.5rem', fontWeight: '700' }}>{card.value}</h3> | |
| </div> | |
| </div> | |
| ))} | |
| </div> | |
| <div style={{ marginBottom: '3rem' }}> | |
| <h3 className="text-gradient" style={{ marginBottom: '1.5rem', fontSize: '1.25rem' }}>Accesos Rápidos</h3> | |
| <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(180px, 1fr))', gap: '1rem' }}> | |
| {[ | |
| { label: 'Administrador', icon: <ShieldCheck size={28} />, action: () => setActiveTab && setActiveTab('overview'), color: 'var(--primary)', bg: 'rgba(255,90,95,0.1)' }, | |
| { label: 'Caja', icon: <DollarSign size={28} />, action: () => setActiveTab && setActiveTab('cash'), color: 'var(--success)', bg: 'rgba(32, 201, 151, 0.1)' }, | |
| { label: 'Mesero / POS', icon: <User size={28} />, action: () => navigate('/pos'), color: 'var(--info)', bg: 'rgba(50, 173, 230, 0.1)' }, | |
| { label: 'Cocina', icon: <UtensilsCrossed size={28} />, action: () => window.open('/kitchen', '_blank'), color: 'var(--warning)', bg: 'rgba(245, 166, 35, 0.1)' }, | |
| { label: 'Carta Digital', icon: <Utensils size={28} />, action: () => window.open('/menu', '_blank'), color: '#a855f7', bg: 'rgba(168, 85, 247, 0.1)' } | |
| ].map((btn, idx) => ( | |
| <button key={idx} onClick={btn.action} className="glass-card" style={{ padding: '1.5rem', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '1rem', border: `1px solid ${btn.bg}`, cursor: 'pointer', transition: 'all 0.3s ease' }} onMouseOver={e => e.currentTarget.style.transform = 'translateY(-5px)'} onMouseOut={e => e.currentTarget.style.transform = 'translateY(0)'}> | |
| <div style={{ width: '60px', height: '60px', borderRadius: '50%', background: btn.bg, color: btn.color, display: 'flex', alignItems: 'center', justifyContent: 'center' }}> | |
| {btn.icon} | |
| </div> | |
| <span style={{ fontWeight: '600', color: 'var(--text-main)' }}>{btn.label}</span> | |
| </button> | |
| ))} | |
| </div> | |
| </div> | |
| <div className="glass-card"> | |
| <h3 className="text-gradient" style={{ marginBottom: '1rem' }}>Misión del Sistema</h3> | |
| <p style={{ color: 'var(--text-muted)', lineHeight: '1.6' }}> | |
| Este sistema está diseñado para gestionar de manera integral un restaurante moderno. | |
| Desde la recepción del cliente en la <strong>Carta Digital</strong>, pasando por la toma de pedidos en el | |
| <strong> POS de Meseros</strong>, hasta la preparación coordinada en la <strong>Pantalla de Cocina</strong>. | |
| </p> | |
| </div> | |
| </div> | |
| ); | |
| } | |