restaurante / src /components /admin /DashboardOverview.jsx
Antigravity AI
Update login and dashboard, fix files
1dfed0f
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>
);
}