// Perfil Supervisor no app do promotor — orcamento 310, item 15. // // Quem esta escalado como Supervisor ou Coordenador ganha, dentro da acao, a // lista de presenca da equipe, os resultados que cada um registrou, e duas // acoes de campo: informar ausencia e registrar substituicao. // // O QUE NAO APARECE AQUI, E DE PROPOSITO // Cache e prazo de pagamento. A migration 040 removeu a policy que expunha a // linha inteira das escalas justamente por causa disso, e a RPC da migration // 044 devolve so as colunas seguras. Esta tela nao tem como mostrar dinheiro // dos colegas nem que alguem queira. // // SUBSTITUICAO NAO TROCA A ESCALA // Quem cobre a vaga quase nunca esta cadastrado, e cache e pagamento sao // decisao da producao. O supervisor registra o fato e a producao formaliza — // por isso a tela pede o nome de quem cobriu e avisa que a producao ajusta // a escala depois. const SUP_ESTADOS = { concluiu: { emoji: '🟢', rotulo: 'Concluiu', cor: '#166534' }, presente: { emoji: '🟢', rotulo: 'Check-in realizado', cor: '#15803D' }, sem_checkin: { emoji: '🟡', rotulo: 'Sem check-in', cor: '#B45309' }, falta: { emoji: '🔴', rotulo: 'Faltou', cor: '#B91C1C' }, recusou: { emoji: '🔴', rotulo: 'Recusou', cor: '#B91C1C' }, }; const supHora = iso => iso ? new Date(iso).toLocaleTimeString('pt-BR', { hour: '2-digit', minute: '2-digit' }) : null; function supEstado(p) { if (p.check_out_em) return 'concluiu'; if (p.check_in_em) return 'presente'; if (p.status === 'Falta') return 'falta'; if (p.status === 'Recusado') return 'recusou'; return 'sem_checkin'; } // Modal unico para ausencia e substituicao: sao o mesmo gesto — "esta pessoa // nao veio" — e a substituicao so acrescenta quem cobriu. Duas telas quase // iguais dariam ao supervisor a chance de escolher a errada com pressa. function SupervisorAusenciaModal({ open, pessoa, modo, onClose, onFeito, showToast }) { const [substituto, setSubstituto] = React.useState(''); const [observacao, setObservacao] = React.useState(''); const [busy, setBusy] = React.useState(false); React.useEffect(() => { if (open) { setSubstituto(''); setObservacao(''); } }, [open, pessoa && pessoa.escala_id, modo]); if (!open || !pessoa) return null; const ehSubstituicao = modo === 'substituicao'; const confirmar = async () => { setBusy(true); const { error } = ehSubstituicao ? await sb.rpc('supervisor_registrar_substituicao', { p_escala_id: pessoa.escala_id, p_substituto: substituto.trim(), p_observacao: observacao.trim() || null, }) : await sb.rpc('supervisor_informar_ausencia', { p_escala_id: pessoa.escala_id, p_observacao: observacao.trim() || null, }); setBusy(false); if (error) { console.error('[SupervisorAusenciaModal] Supabase error:', error); showToast(error.message || 'Não foi possível registrar.', 'danger'); return; } showToast(ehSubstituicao ? 'Substituição registrada. A produção foi avisada.' : 'Ausência informada. A produção foi avisada.'); onFeito(); onClose(); }; const podeConfirmar = !busy && (!ehSubstituicao || substituto.trim().length >= 3); return (
{pessoa.nome} não compareceu?
{ehSubstituicao && ( )}