NEXUS / src /app /sales /page.tsx
dimensionalpulsar's picture
Upload 29 files
8457d97 verified
"use client";
import React, { useState, useEffect } from "react";
import { db } from "@/lib/firebase";
import { collection, onSnapshot, addDoc, serverTimestamp } from "firebase/firestore";
import Link from "next/link";
interface Sale {
id: string;
client: string;
items: string;
total: number;
date: any;
}
export default function SalesPage() {
const [sales, setSales] = useState<Sale[]>([]);
const [products, setProducts] = useState<any[]>([]);
const [isModalOpen, setIsModalOpen] = useState(false);
const [newSale, setNewSale] = useState({ client: "", items: "", total: 0 });
useEffect(() => {
const unsubSales = onSnapshot(collection(db, "sales"), (snap) => {
const data = snap.docs.map(doc => ({ id: doc.id, ...doc.data() } as Sale));
setSales(data);
});
const unsubProducts = onSnapshot(collection(db, "products"), (snap) => {
setProducts(snap.docs.map(doc => ({ id: doc.id, ...doc.data() })));
});
return () => { unsubSales(); unsubProducts(); };
}, []);
const handleAdd = async (e: React.FormEvent) => {
e.preventDefault();
await addDoc(collection(db, "sales"), {
...newSale,
date: serverTimestamp()
});
setIsModalOpen(false);
setNewSale({ client: "", items: "", total: 0 });
};
return (
<div className="min-h-screen bg-[#0f172a] text-white p-6">
<header className="flex justify-between items-center mb-10">
<div>
<Link href="/" className="text-orange-400 hover:text-orange-300 transition-colors flex items-center gap-2 mb-2 font-medium">
← Home
</Link>
<h1 className="text-4xl font-black bg-gradient-to-r from-orange-400 to-yellow-500 bg-clip-text text-transparent">Historial de Ventas</h1>
</div>
<button
onClick={() => setIsModalOpen(true)}
className="px-10 py-4 bg-orange-600 hover:bg-orange-500 rounded-full font-black text-xs uppercase tracking-widest transition-all shadow-xl shadow-orange-900/40 transform hover:scale-105 active:scale-95"
>
➕ Registrar Transacción
</button>
</header>
<div className="bg-white/5 border border-white/10 rounded-[3rem] p-10 backdrop-blur-2xl">
<div className="space-y-6">
{sales.map((s) => (
<div key={s.id} className="flex items-center justify-between p-6 bg-white/5 border border-white/5 rounded-3xl hover:bg-white/10 transition-all group">
<div className="flex items-center gap-6">
<div className="w-14 h-14 bg-gradient-to-br from-orange-500 to-yellow-500 rounded-2xl flex items-center justify-center text-2xl shadow-lg">🧾</div>
<div>
<h3 className="font-bold text-lg group-hover:text-orange-400 transition-colors uppercase tracking-tight">{s.client}</h3>
<p className="text-gray-500 text-xs font-medium mt-1">PRODUCTOS: <span className="text-gray-400">{s.items}</span></p>
</div>
</div>
<div className="text-right">
<p className="text-2xl font-black text-white">${Number(s.total).toLocaleString()}</p>
<p className="text-[10px] text-gray-600 font-black uppercase mt-1">Completado</p>
</div>
</div>
))}
</div>
</div>
{isModalOpen && (
<div className="fixed inset-0 bg-[#0f172a]/95 backdrop-blur-3xl flex items-center justify-center p-6 z-50">
<div className="bg-white/5 border border-white/10 p-12 rounded-[50px] w-full max-w-lg shadow-2xl relative overflow-hidden">
<div className="absolute top-0 right-0 w-32 h-32 bg-orange-500/10 blur-[80px] rounded-full"></div>
<h2 className="text-3xl font-black mb-10 tracking-tighter italic">NUEVA VENTA /</h2>
<form onSubmit={handleAdd} className="space-y-6">
<input
placeholder="Nombre del Cliente" required
value={newSale.client} onChange={e => setNewSale({...newSale, client: e.target.value})}
className="w-full bg-white/5 border-b border-white/10 py-4 text-xl outline-none focus:border-orange-500 transition-all font-bold"
/>
<input
placeholder="Descripción de Ítems" required
value={newSale.items} onChange={e => setNewSale({...newSale, items: e.target.value})}
className="w-full bg-white/5 border-b border-white/10 py-4 text-lg outline-none focus:border-orange-500 transition-all"
/>
<div className="relative">
<span className="absolute left-0 top-1/2 -translate-y-1/2 text-3xl font-black text-gray-700">$</span>
<input
type="number" placeholder="0.00" required
value={newSale.total} onChange={e => setNewSale({...newSale, total: Number(e.target.value)})}
className="w-full bg-transparent border-b border-white/10 pl-10 py-6 text-6xl outline-none focus:border-orange-500 transition-all font-black text-orange-400 placeholder:text-gray-800"
/>
</div>
<div className="flex gap-4 pt-12">
<button type="button" onClick={() => setIsModalOpen(false)} className="px-8 py-5 text-gray-500 font-black text-xs uppercase hover:text-white transition-colors tracking-widest">Descartar</button>
<button type="submit" className="flex-1 bg-orange-600 hover:bg-orange-500 py-5 rounded-3xl font-black text-xs uppercase tracking-[0.2em] transition-all shadow-xl shadow-orange-900/20">Finalizar Venta</button>
</div>
</form>
</div>
</div>
)}
</div>
);
}