NEXUS / src /app /page.tsx
dimensionalpulsar's picture
Upload 29 files
8457d97 verified
"use client";
import React, { useState, useEffect } from "react";
import { db, auth } from "@/lib/firebase";
import { collection, onSnapshot, query, orderBy, limit } from "firebase/firestore";
import Link from "next/link";
export default function Dashboard() {
const [stats, setStats] = useState({
products: 0,
clients: 0,
salesCount: 0,
revenue: 0,
});
useEffect(() => {
// Real-time stats from Firestore
const unsubProducts = onSnapshot(collection(db, "products"), (snap) => {
setStats((prev) => ({ ...prev, products: snap.size }));
});
const unsubClients = onSnapshot(collection(db, "clients"), (snap) => {
setStats((prev) => ({ ...prev, clients: snap.size }));
});
const unsubSales = onSnapshot(collection(db, "sales"), (snap) => {
let rev = 0;
snap.forEach((doc) => {
rev += doc.data().total || 0;
});
setStats((prev) => ({ ...prev, salesCount: snap.size, revenue: rev }));
});
return () => {
unsubProducts();
unsubClients();
unsubSales();
};
}, []);
return (
<div className="min-h-screen bg-[#0f172a] text-white p-6 font-sans">
<header className="flex justify-between items-center mb-10">
<div>
<h1 className="text-4xl font-extrabold bg-gradient-to-r from-blue-400 to-indigo-500 bg-clip-text text-transparent">
ERP Premium Dashboard
</h1>
<p className="text-gray-400 mt-1">Bienvenido al centro de control de tu negocio</p>
</div>
<div className="flex gap-4">
<button
onClick={() => auth.signOut()}
className="px-6 py-2 bg-white/10 hover:bg-white/20 rounded-full border border-white/10 transition-all text-sm font-medium backdrop-blur-md"
>
Cerrar Sesión
</button>
</div>
</header>
{/* Stats Grid */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-10">
<StatCard title="Productos" value={stats.products} icon="📦" color="from-blue-500 to-cyan-400" />
<StatCard title="Clientes" value={stats.clients} icon="👥" color="from-purple-500 to-pink-500" />
<StatCard title="Ventas Totales" value={stats.salesCount} icon="🛒" color="from-orange-500 to-yellow-400" />
<StatCard title="Ingresos" value={`$${stats.revenue.toLocaleString()}`} icon="💰" color="from-green-500 to-emerald-400" />
</div>
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
{/* Quick Actions */}
<div className="lg:col-span-1 bg-white/5 border border-white/10 rounded-3xl p-8 backdrop-blur-xl">
<h2 className="text-xl font-bold mb-6">Acciones Rápidas</h2>
<div className="space-y-4">
<QuickAction href="/inventory" label="Nueva Existencia" icon="➕" />
<QuickAction href="/sales" label="Registrar Venta" icon="🏷️" />
<QuickAction href="/clients" label="Añadir Cliente" icon="👤" />
<QuickAction href="/hr" label="Gestionar Personal" icon="👔" />
</div>
</div>
{/* Charts Mockup / Future Widget */}
<div className="lg:col-span-2 bg-white/5 border border-white/10 rounded-3xl p-8 backdrop-blur-xl relative overflow-hidden group">
<div className="absolute inset-0 bg-gradient-to-br from-blue-600/20 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-700"></div>
<div className="relative z-10">
<h2 className="text-xl font-bold mb-6">Rendimiento Semanal</h2>
<div className="h-64 flex items-end justify-between gap-2">
{[60, 45, 80, 55, 95, 70, 85].map((h, i) => (
<div key={i} className="flex-1 flex flex-col items-center">
<div
className="w-full bg-gradient-to-t from-blue-600 to-cyan-400 rounded-t-lg transition-all duration-1000 delay-150"
style={{ height: `${h}%` }}
></div>
<span className="text-[10px] text-gray-500 mt-2">{['L', 'M', 'X', 'J', 'V', 'S', 'D'][i]}</span>
</div>
))}
</div>
<p className="mt-8 text-sm text-gray-400 items-center flex gap-2">
<span className="w-2 h-2 rounded-full bg-green-400 animate-pulse"></span>
Actualizado en tiempo real con Firestore
</p>
</div>
</div>
</div>
</div>
);
}
function StatCard({ title, value, icon, color }: { title: string, value: string | number, icon: string, color: string }) {
return (
<div className="bg-white/5 border border-white/10 rounded-3xl p-6 backdrop-blur-md relative overflow-hidden group hover:scale-[1.02] transition-all">
<div className={`absolute -right-4 -top-4 w-24 h-24 bg-gradient-to-br ${color} opacity-20 blur-2xl rounded-full group-hover:opacity-40 transition-opacity`}></div>
<div className="flex items-center gap-4 relative z-10">
<div className="text-3xl">{icon}</div>
<div>
<p className="text-sm text-gray-400 uppercase tracking-wider font-semibold">{title}</p>
<p className="text-2xl font-bold">{value}</p>
</div>
</div>
</div>
);
}
function QuickAction({ href, label, icon }: { href: string, label: string, icon: string }) {
return (
<Link href={href} className="flex items-center gap-4 p-4 rounded-2xl bg-white/5 border border-white/5 hover:bg-white/10 hover:border-white/20 transition-all group">
<span className="text-xl group-hover:scale-125 transition-transform">{icon}</span>
<span className="font-medium text-gray-200">{label}</span>
<span className="ml-auto opacity-0 group-hover:opacity-100 transition-opacity"></span>
</Link>
);
}