'use client'; import { useState, useEffect } from 'react'; import { Calendar, Users, DollarSign, TrendingUp, Clock, ArrowUpRight, Play, CheckSquare, Loader } from 'lucide-react'; interface DashboardProps { onNavigate: (page: string) => void; } const statusMap: Record = { confirmed: { label: 'Confirmado', cls: 'badge-info' }, pending: { label: 'Pendente', cls: 'badge-warning' }, completed: { label: 'Concluído', cls: 'badge-success' }, cancelled: { label: 'Cancelado', cls: 'badge-danger' }, serving: { label: 'Em Atendimento', cls: 'badge-purple' }, in_progress: { label: 'Em Atendimento', cls: 'badge-purple' }, }; export default function Dashboard({ onNavigate }: DashboardProps) { const [appointments, setAppointments] = useState([]); const [kpis, setKpis] = useState({ appointmentsToday: 0, revenueToday: 0, totalClients: 0, occupancy: 0, weekChange: 0 }); const [weeklyPerformance, setWeeklyPerformance] = useState([]); const [loading, setLoading] = useState(true); const [currentServingId, setCurrentServingId] = useState(null); useEffect(() => { const fetchDashboard = async () => { const slug = localStorage.getItem('agendapro_tenant_slug') || 'barbearia-premium'; try { const res = await fetch(`/api/tenant/dashboard?slug=${slug}`); if (res.ok) { const data = await res.json(); setAppointments(data.appointments || []); setKpis(data.kpis || { appointmentsToday: 0, revenueToday: 0, totalClients: 0, occupancy: 0, weekChange: 0 }); setWeeklyPerformance(data.weeklyPerformance || []); } } catch (err) { console.error('Erro ao carregar dashboard:', err); } finally { setLoading(false); } }; fetchDashboard(); }, []); const handleStartServing = async (id: string) => { setCurrentServingId(id); setAppointments(prev => prev.map(a => a.id === id ? { ...a, status: 'in_progress' } : a)); // Atualiza no banco try { const slug = localStorage.getItem('agendapro_tenant_slug') || 'barbearia-premium'; await fetch('/api/tenant/agenda', { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id, status: 'in_progress', slug }) }); } catch (err) { console.error('Erro ao iniciar atendimento:', err); } }; const handleFinishServing = async (id: string) => { setCurrentServingId(null); setAppointments(prev => prev.map(a => a.id === id ? { ...a, status: 'completed' } : a)); // Atualiza no banco try { const slug = localStorage.getItem('agendapro_tenant_slug') || 'barbearia-premium'; await fetch('/api/tenant/agenda', { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id, status: 'completed', slug }) }); } catch (err) { console.error('Erro ao finalizar atendimento:', err); } }; const servingApt = appointments.find(a => a.id === currentServingId || a.status === 'in_progress'); const activeQueue = appointments.filter(a => a.status !== 'completed' && a.status !== 'cancelled' && a.id !== servingApt?.id); const nextInQueue = activeQueue[0]; const weekChangeLabel = kpis.weekChange > 0 ? `↑ ${kpis.weekChange}% vs semana anterior` : kpis.weekChange < 0 ? `↓ ${Math.abs(kpis.weekChange)}% vs semana anterior` : 'Sem dados da semana anterior'; if (loading) { return (
Carregando dashboard...
); } return (
{/* Painel de Fila de Atendimento */}
Fila de Atendimento {servingApt ? (

Atendendo agora: {servingApt.client}

{servingApt.service} com {servingApt.professional} • R$ {Number(servingApt.price).toFixed(2)}

) : nextInQueue ? (

Próximo da Fila: {nextInQueue.client}

Agendado para {nextInQueue.time} ({nextInQueue.service})

) : (

{appointments.length === 0 ? 'Nenhum agendamento para hoje' : 'Todos os atendimentos do dia foram concluídos'}

{appointments.length === 0 ? 'Acesse a Agenda para criar novos agendamentos.' : 'Parabéns! Todos os clientes foram atendidos.'}

)}
{servingApt ? ( ) : nextInQueue ? ( ) : null}
{servingApt && (
Próximo da Fila: {activeQueue[0] ? `${activeQueue[0].client} (às ${activeQueue[0].time})` : 'Ninguém aguardando'} {activeQueue[0] && ( )}
)}
{kpis.appointmentsToday}
Agendamentos Hoje
{weekChangeLabel}
R$ {kpis.revenueToday.toLocaleString('pt-BR', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
Receita do Dia
Valores confirmados
{kpis.totalClients}
Clientes Cadastrados
Total ativo
{kpis.occupancy}%
Taxa de Ocupação
Hoje

Agendamentos de Hoje

{appointments.map(apt => { const isServing = apt.status === 'in_progress'; const isCompleted = apt.status === 'completed'; const st = statusMap[apt.status] || { label: apt.status, cls: 'badge-secondary' }; return ( ); })} {appointments.length === 0 && ( )}
Horário Cliente Serviço Profissional Status Valor
{apt.time}
{apt.client.split(' ').map((n: string) => n[0]).join('').substring(0, 2)}
{apt.client}
{apt.service} {apt.professional} {st.label} R$ {Number(apt.price).toFixed(2)}
Nenhum agendamento para hoje. Crie um novo na Agenda.

Desempenho Semanal

{weeklyPerformance.length > 0 ? weeklyPerformance.map((d: any) => (
{d.label}
{d.count || 0}
)) : (

Sem dados suficientes

)}

Ações Rápidas

{[ { label: 'Novo Agendamento', desc: 'Agendar um novo cliente', page: 'agenda' }, { label: 'Cadastrar Cliente', desc: 'Adicionar cliente à base', page: 'clients' }, { label: 'Novo Serviço', desc: 'Cadastrar um novo serviço', page: 'services' }, ].map((action, i) => (
{action.label}
{action.desc}
))}
); }