// Área de PENDÊNCIAS DO DONO do workspace (só o dono vê). Engloba tudo: // 1) Checklist da clínica — perguntas Sim/Não que o dono responde; // 2) Pendências de configuração — quando a resposta não bate com o banco // (ex.: marcou "mais de um dentista" mas só há 1 cadastrado); // 3) Fila operacional — resumo dos pedidos/dúvidas aguardando a secretária humana. // Consome /api/nw/agenda-config/clinica/:id/{checklist,pendencias}. import React, { useState, useEffect, useCallback } from 'react'; import { X, ClipboardCheck, AlertTriangle, Check, Ban, Loader2, Save, CalendarClock, HelpCircle, ChevronRight } 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; } type Questao = { chave: string; pergunta: string; ajuda?: string; resposta: number | null }; type PendConfig = { chave: string; severidade: string; titulo: string; detalhe: string }; export const PendenciasDono: React.FC<{ isOpen: boolean; onClose: () => void; clinicaId?: string; onOpenFila?: () => void }> = ({ isOpen, onClose, clinicaId, onOpenFila }) => { const [questoes, setQuestoes] = useState([]); const [config, setConfig] = useState([]); const [oper, setOper] = useState<{ horarios: number; duvidas: number; total: number }>({ horarios: 0, duvidas: 0, total: 0 }); const [contagens, setContagens] = useState<{ dentistas: number; pacientes: number }>({ dentistas: 0, pacientes: 0 }); const [loading, setLoading] = useState(false); const [saving, setSaving] = useState(false); const [erro, setErro] = useState(null); const [ok, setOk] = useState(null); const flash = (setter: (v: string | null) => void, m: string) => { setter(m); setTimeout(() => setter(null), 3000); }; const carregar = useCallback(async () => { if (!clinicaId) return; setLoading(true); setErro(null); try { const c = await req(`/clinica/${clinicaId}/checklist`); setQuestoes(c.questoes || []); const p = await req(`/clinica/${clinicaId}/pendencias`); setConfig(p.config || []); setOper(p.operacionais || { horarios: 0, duvidas: 0, total: 0 }); setContagens(p.contagens || { dentistas: 0, pacientes: 0 }); } catch (e: any) { setErro(e.message); } finally { setLoading(false); } }, [clinicaId]); useEffect(() => { if (isOpen) carregar(); }, [isOpen, carregar]); const setResposta = (chave: string, resposta: number | null) => setQuestoes((qs) => qs.map((q) => q.chave === chave ? { ...q, resposta } : q)); const salvar = async () => { setSaving(true); setErro(null); try { const respostas: Record = {}; questoes.forEach((q) => { respostas[q.chave] = q.resposta; }); await req(`/clinica/${clinicaId}/checklist`, { method: 'PUT', body: JSON.stringify({ respostas }) }); flash(setOk, 'Checklist salvo!'); await carregar(); } catch (e: any) { setErro(e.message); } finally { setSaving(false); } }; if (!isOpen) return null; const sevColor = (s: string) => s === 'alta' ? 'border-red-200 bg-red-50' : 'border-amber-200 bg-amber-50'; const sevText = (s: string) => s === 'alta' ? 'text-red-700' : 'text-amber-700'; return (

Pendências do workspace

Config da clínica + o que a Secretária precisa que você resolva

{(erro || ok) &&
{erro || ok}
}
{loading ? (
) : ( <> {/* Fila operacional */}

Aguardando a secretária humana

{/* Pendências de configuração */}

Configuração a resolver

{config.length === 0 ? (

Nenhuma pendência de configuração. 🎉

) : (
{config.map((p, i) => (
{p.severidade === 'alta' ? 'Importante' : 'Atenção'}
{p.titulo}
{p.detalhe}
))}
)}

No sistema: {contagens.dentistas} dentista(s) · {contagens.pacientes} paciente(s) cadastrado(s).

{/* Checklist */}

Checklist da clínica

Responda sobre a clínica. A Secretária usa isto para saber quando pode agendar sozinha — quando algo não bate com o cadastro, ela evita agendar e encaminha ao humano, e aparece aqui em cima como pendência.

{questoes.map((q) => (
{q.pergunta}
{q.ajuda &&
{q.ajuda}
}
))}
)}
); };