import React, { useState, useEffect } from 'react'; import { db } from '../../firebase/config'; import { ref, onValue, push, set } from 'firebase/database'; import { DollarSign, ArrowUpCircle, ArrowDownCircle, Save, Calendar, Clock, History } from 'lucide-react'; export default function FinanceManager() { const [cashSessions, setCashSessions] = useState([]); const [expenses, setExpenses] = useState([]); const [activeSession, setActiveSession] = useState(null); const [openingBalance, setOpeningBalance] = useState(''); const [expenseData, setExpenseData] = useState({ concept: '', amount: '', category: 'Varios' }); useEffect(() => { // Fetch sessions onValue(ref(db, 'finance/sessions'), (snapshot) => { const data = snapshot.val(); if (data) { const list = Object.keys(data).map(id => ({ id, ...data[id] })).sort((a,b) => b.openedAt - a.openedAt); setCashSessions(list); const active = list.find(s => s.status === 'open'); setActiveSession(active || null); } }); // Fetch expenses onValue(ref(db, 'finance/expenses'), (snapshot) => { const data = snapshot.val(); setExpenses(data ? Object.keys(data).map(id => ({ id, ...data[id] })).sort((a,b) => b.timestamp - a.timestamp) : []); }); }, []); const openCash = async () => { if (!openingBalance) return; const newSessionRef = push(ref(db, 'finance/sessions')); await set(newSessionRef, { openedAt: Date.now(), openingBalance: parseFloat(openingBalance), status: 'open', totalSales: 0, totalExpenses: 0 }); setOpeningBalance(''); }; const closeCash = async () => { if (!activeSession) return; if (window.confirm('¿Deseas cerrar el turno de caja actual?')) { await set(ref(db, `finance/sessions/${activeSession.id}/status`), 'closed'); await set(ref(db, `finance/sessions/${activeSession.id}/closedAt`), Date.now()); } }; const addExpense = async (e) => { e.preventDefault(); if (!expenseData.concept || !expenseData.amount) return; const expenseRef = push(ref(db, 'finance/expenses')); await set(expenseRef, { ...expenseData, amount: parseFloat(expenseData.amount), timestamp: Date.now(), sessionId: activeSession?.id || 'none' }); setExpenseData({ concept: '', amount: '', category: 'Varios' }); }; return (

Control Financiero

Arqueo de caja, egresos y flujo de efectivo semanal

{/* Cash Arqueo Module */}

Turno de Caja (Arqueo)

{!activeSession ? (

Caja cerrada actualmente. Ingresa el fondo de apertura para iniciar.

setOpeningBalance(e.target.value)} style={inputStyle} />
) : (
Apertura
${activeSession.openingBalance.toFixed(2)}
Hora
{new Date(activeSession.openedAt).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}
Ventas Registradas
$0.00

Sincronizado con POS en tiempo real

)}
{/* Expenses Module */}

Registro de Egresos

setExpenseData({...expenseData, concept: e.target.value})} style={inputStyle} />
setExpenseData({...expenseData, amount: e.target.value})} style={inputStyle} />

Últimos Gastos

{expenses.map(exp => (
{exp.concept} -${exp.amount.toFixed(2)}
))} {expenses.length === 0 &&

No hay gastos registrados

}

Historial de Turnos Recientes

{cashSessions.map(sess => ( ))}
Fecha Apertura Cierre Ventas Estado
{new Date(sess.openedAt).toLocaleDateString()} ${sess.openingBalance.toFixed(2)} {sess.closedAt ? new Date(sess.closedAt).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }) : '-'} ${(sess.totalSales || 0).toFixed(2)} {sess.status.toUpperCase()}
); } const inputStyle = { width: '100%', padding: '0.8rem', borderRadius: '8px', background: 'rgba(255,255,255,0.05)', border: '1px solid var(--border-subtle)', color: '#fff', outline: 'none' }; const statBoxStyle = { padding: '1rem', borderRadius: '12px', background: 'rgba(255,255,255,0.02)', border: '1px solid var(--border-subtle)', display: 'flex', flexDirection: 'column', gap: '0.25rem' }; const Plus = ({ size }) => ;