// Escalas — lado do admin. Orcamento 290.
//
// EscalaEventoModal -> escalar a equipe dentro do evento (funcao, cache,
// prazo de pagamento) + acompanhar presenca/check-in.
// PainelPromotores -> acompanhamento em tempo real de confirmacoes,
// check-ins, fotos e check-outs.
//
// O promotor NAO altera estas linhas direto: ele usa as RPCs da migration 026.
const ESCALA_FUNCOES = [
{ value: 'Promotor', label: 'Promotor' },
{ value: 'Supervisor', label: 'Supervisor' },
{ value: 'Coordenador', label: 'Coordenador' },
{ value: 'Motorista', label: 'Motorista' },
];
const ESCALA_STATUS_VARIANT = {
'Convidado': 'default',
'Confirmado': 'primary',
'Recusado': 'danger',
'Check-in': 'warning',
'Concluído': 'success',
'Falta': 'danger',
};
const fmtEscalaMoney = v => 'R$ ' + (parseFloat(v) || 0).toLocaleString('pt-BR', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
const fmtEscalaHora = iso => iso
? new Date(iso).toLocaleString('pt-BR', { day: '2-digit', month: '2-digit', hour: '2-digit', minute: '2-digit' })
: null;
function EscalaEventoModal({ open, onClose, event }) {
const [freelancers, setFreelancers] = React.useState([]);
const [escalas, setEscalas] = React.useState([]);
const [loading, setLoading] = React.useState(true);
const [saving, setSaving] = React.useState(false);
const [coordenador, setCoordenador] = React.useState('');
const [form, setForm] = React.useState({ freelancer_id: '', funcao: 'Promotor', cache: '', prazo_pagamento: '' });
const [toast, setToast] = React.useState(null);
const showToast = (msg, type = 'success') => { setToast({ msg, type }); setTimeout(() => setToast(null), 3000); };
React.useEffect(() => {
if (!open || !event?.id) return;
setLoading(true);
setCoordenador(event.coordenador_contato || '');
Promise.all([
sb.from('freelancers').select('id, name, role, rate, phone, app_ativo, auth_user_id').order('name'),
sb.from('event_escalas').select('*').eq('event_id', event.id).order('created_at'),
]).then(([{ data: fl }, { data: es }]) => {
setFreelancers(fl || []);
setEscalas(es || []);
setLoading(false);
});
}, [open, event?.id]);
const freelancerPorId = React.useMemo(() => {
const map = {};
freelancers.forEach(f => { map[f.id] = f; });
return map;
}, [freelancers]);
// Ao escolher o freelancer, o cache ja vem preenchido com a diaria dele.
const escolherFreelancer = (id) => {
const f = freelancerPorId[id];
setForm(prev => ({ ...prev, freelancer_id: id, cache: f ? String(f.rate ?? '') : prev.cache }));
};
const jaEscalados = React.useMemo(() => new Set(escalas.map(e => e.freelancer_id)), [escalas]);
const handleEscalar = async () => {
const f = freelancerPorId[form.freelancer_id];
if (!f) { showToast('Escolha um freelancer.', 'danger'); return; }
setSaving(true);
const { data, error } = await sb.from('event_escalas').insert({
event_id: event.id,
freelancer_id: f.id,
funcao: form.funcao,
cache: parseFloat(String(form.cache).replace(',', '.')) || 0,
prazo_pagamento: form.prazo_pagamento || null,
}).select().single();
setSaving(false);
if (error) {
console.error('[EscalaEventoModal.handleEscalar] Supabase error:', error);
showToast(error.code === '23505' ? 'Esse freelancer já está escalado neste evento.' : 'Erro ao escalar: ' + (error.message || 'desconhecido'), 'danger');
return;
}
setEscalas(prev => [...prev, data]);
setForm({ freelancer_id: '', funcao: 'Promotor', cache: '', prazo_pagamento: form.prazo_pagamento });
showToast(`${f.name} escalado!`);
};
const handleRemover = async (escala) => {
const { error } = await sb.from('event_escalas').delete().eq('id', escala.id);
if (error) { console.error('[EscalaEventoModal.handleRemover] Supabase error:', error); showToast('Erro ao remover.', 'danger'); return; }
setEscalas(prev => prev.filter(e => e.id !== escala.id));
showToast('Removido da escala.');
};
const handleSalvarCoordenador = async () => {
setSaving(true);
const { error } = await sb.from('events').update({ coordenador_contato: coordenador || null }).eq('id', event.id);
setSaving(false);
if (error) { console.error('[EscalaEventoModal.handleSalvarCoordenador] Supabase error:', error); showToast('Erro ao salvar o contato.', 'danger'); return; }
if (event) event.coordenador_contato = coordenador;
showToast('Contato do coordenador salvo!');
};
const totalCache = escalas.reduce((s, e) => s + (parseFloat(e.cache) || 0), 0);
return (