// Fila da secretária humana: pedidos de horário da ZONA CINZA que a Secretária IA // registrou ("vou confirmar e retorno"). A humana confirma (vira agendamento) ou // recusa. Consome /api/nw/agenda-config/clinica/:id/pedidos*. import React, { useState, useEffect, useCallback } from 'react'; import { X, CalendarClock, Check, Ban, Loader2, Phone, User, HelpCircle } from 'lucide-react'; const API = (import.meta as any).env?.VITE_API_URL || '/api'; const BASE = `${API}/nw/agenda-config`; async function req(path: string, opts: RequestInit = {}) { const token = localStorage.getItem('SCOREODONTO_AUTH_TOKEN'); const res = await fetch(`${BASE}${path}`, { ...opts, headers: { 'Content-Type': 'application/json', ...(token ? { Authorization: `Bearer ${token}` } : {}), ...(opts.headers || {}) } }); const t = await res.text(); const d = t ? JSON.parse(t) : {}; if (!res.ok) throw new Error(d.error || `Erro ${res.status}`); return d; } const dm = (s: string) => s ? s.split('-').reverse().join('/') : s; export const PedidosPendentes: React.FC<{ isOpen: boolean; onClose: () => void; clinicaId?: string; onChange?: () => void }> = ({ isOpen, onClose, clinicaId, onChange }) => { const [pedidos, setPedidos] = useState([]); const [dentistas, setDentistas] = useState([]); const [sel, setSel] = useState>({}); // pedido_id → dentista_id escolhido const [busy, setBusy] = useState(null); const [erro, setErro] = useState(null); const [loading, setLoading] = useState(false); const carregar = useCallback(async () => { if (!clinicaId) return; setLoading(true); setErro(null); try { const p = await req(`/clinica/${clinicaId}/pedidos?status=pendente`); setPedidos(p.pedidos || []); const d = await req(`/clinica/${clinicaId}/dentistas`); setDentistas(d.dentistas || []); } catch (e: any) { setErro(e.message); } finally { setLoading(false); } }, [clinicaId]); useEffect(() => { if (isOpen) carregar(); }, [isOpen, carregar]); const confirmar = async (p: any) => { const dentistaId = p.dentista_id || sel[p.id]; if (!dentistaId) { setErro('Escolha o dentista para confirmar.'); return; } setBusy(p.id); setErro(null); try { await req(`/clinica/${clinicaId}/pedidos/${p.id}/confirmar`, { method: 'POST', body: JSON.stringify({ dentista_id: dentistaId }) }); await carregar(); onChange?.(); } catch (e: any) { setErro(e.message); } finally { setBusy(null); } }; const recusar = async (p: any) => { setBusy(p.id); setErro(null); try { await req(`/clinica/${clinicaId}/pedidos/${p.id}/recusar`, { method: 'POST' }); await carregar(); onChange?.(); } catch (e: any) { setErro(e.message); } finally { setBusy(null); } }; const resolver = async (p: any) => { setBusy(p.id); setErro(null); try { await req(`/clinica/${clinicaId}/pedidos/${p.id}/resolver`, { method: 'POST' }); await carregar(); onChange?.(); } catch (e: any) { setErro(e.message); } finally { setBusy(null); } }; if (!isOpen) return null; return (

Pedidos aguardando confirmação

Horários fora do padrão que a Secretária IA encaminhou

{erro &&
{erro}
}
{loading ? (
) : pedidos.length === 0 ? (

Nenhum pedido pendente. 🎉

) : pedidos.map((p) => p.tipo === 'duvida' ? (
Dúvida p/ decidir
{p.resumo}
{p.paciente_nome || 'Cliente'} {p.paciente_telefone && {p.paciente_telefone}}
) : (
{dm(p.data)} às {p.hora_inicio}{p.hora_fim ? `–${p.hora_fim}` : ''}
{p.paciente_nome || 'Cliente'} {p.paciente_telefone && {p.paciente_telefone}}
{p.procedimento &&
{p.procedimento}
}
{p.dentista_id ? ( {p.dentista_nome} ) : ( )}
))}
); };