"use client"; import { useState, useEffect, useCallback } from "react"; import { useSession } from "next-auth/react"; import { ProductGrid } from "@/components/pos/product-grid"; import { Cart, CartItem } from "@/components/pos/cart"; import { PaymentDialog } from "@/components/pos/payment-dialog"; import { CashRegisterStatus } from "@/components/pos/cash-register-status"; import { Card, CardContent } from "@/components/ui/card"; interface Site { id: string; name: string; } interface Product { id: string; name: string; description: string | null; sku: string | null; price: number; stock: number; minStock: number; trackStock: boolean; image: string | null; lowStock: boolean; category: { id: string; name: string; }; } export default function POSPage() { const { data: session } = useSession(); const [sites, setSites] = useState([]); const [selectedSiteId, setSelectedSiteId] = useState(null); const [cartItems, setCartItems] = useState([]); const [showPayment, setShowPayment] = useState(false); const [registerOpen, setRegisterOpen] = useState(false); const [registerId, setRegisterId] = useState(); const [siteLoading, setSiteLoading] = useState(true); const [successMessage, setSuccessMessage] = useState(null); // Fetch sites on mount useEffect(() => { async function fetchSites() { try { const response = await fetch("/api/sites"); if (response.ok) { const data = await response.json(); const siteList = data.data || []; setSites(siteList); // Auto-select first site or user's site if (siteList.length > 0) { setSelectedSiteId(siteList[0].id); } } } catch (error) { console.error("Failed to fetch sites:", error); } finally { setSiteLoading(false); } } fetchSites(); }, []); // Handle register status change const handleRegisterStatusChange = useCallback( (isOpen: boolean, regId?: string) => { setRegisterOpen(isOpen); setRegisterId(regId); }, [] ); // Add product to cart const handleAddToCart = useCallback((product: Product) => { setCartItems((prev) => { const existingItem = prev.find((item) => item.id === product.id); if (existingItem) { // Check stock before incrementing if (product.trackStock && existingItem.quantity >= product.stock) { return prev; } return prev.map((item) => item.id === product.id ? { ...item, quantity: item.quantity + 1 } : item ); } return [ ...prev, { id: product.id, name: product.name, price: product.price, quantity: 1, stock: product.stock, trackStock: product.trackStock, }, ]; }); }, []); // Update item quantity const handleUpdateQuantity = useCallback( (productId: string, quantity: number) => { setCartItems((prev) => prev.map((item) => item.id === productId ? { ...item, quantity } : item ) ); }, [] ); // Remove item from cart const handleRemoveItem = useCallback((productId: string) => { setCartItems((prev) => prev.filter((item) => item.id !== productId)); }, []); // Clear cart const handleClearCart = useCallback(() => { setCartItems([]); }, []); // Show payment dialog const handleCheckout = useCallback(() => { if (!registerOpen) { return; } setShowPayment(true); }, [registerOpen]); // Handle payment completion const handlePaymentComplete = useCallback((saleId: string) => { setShowPayment(false); setCartItems([]); setSuccessMessage("Venta completada exitosamente"); setTimeout(() => setSuccessMessage(null), 3000); }, []); // Calculate total const total = cartItems.reduce( (sum, item) => sum + item.price * item.quantity, 0 ); // Loading state if (siteLoading) { return (

Cargando punto de venta...

); } // No sites available if (sites.length === 0) { return (
🏢

No hay sedes disponibles

Contacta al administrador para configurar una sede.

); } return (
{/* Page Header */}

Punto de Venta

Registra ventas de productos y servicios

{/* Success Message */} {successMessage && (
{successMessage}
)} {/* Cash Register Status */} {selectedSiteId && ( )} {/* Main Layout */}
{/* Products Grid - 70% */}
{selectedSiteId ? ( ) : (
Selecciona una sede para ver productos
)}
{/* Cart - 30% */}
{/* Payment Dialog */} {showPayment && selectedSiteId && ( setShowPayment(false)} onPaymentComplete={handlePaymentComplete} /> )} {/* Register Closed Warning */} {!registerOpen && cartItems.length > 0 && (
Abre la caja para poder cobrar
)}
); }