Spaces:
Running
Running
File size: 9,202 Bytes
564baf9 9d7bd77 1dfed0f 564baf9 1dfed0f 564baf9 9a80bc9 9d7bd77 9a80bc9 9d7bd77 9a80bc9 9d7bd77 9a80bc9 9d7bd77 9a80bc9 9d7bd77 9a80bc9 564baf9 9a80bc9 564baf9 1dfed0f 564baf9 9a80bc9 564baf9 9a80bc9 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | 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>
);
}
|