// Historico e ranking do profissional — orcamento 310, itens 26 e 28.
//
// Nenhum numero daqui e guardado. Tudo e conta feita na hora sobre as escalas
// e as avaliacoes que ja existem (migration 047). Uma tabela de estatisticas
// do freelancer seria um segundo lugar para a mesma verdade, e bastaria um
// gatilho falhar para o ranking passar a mentir sobre a operacao.
//
// "USO APENAS INTERNO" (item 28)
// As duas funcoes do banco so devolvem linha para quem e da equipe. O
// promotor nao descobre a propria posicao nem a dos colegas, e o cliente
// nao tem caminho nenhum ate aqui.
const FD_DATA_BR = iso => iso ? String(iso).split('-').reverse().join('/') : '—';
function FDNumero({ valor, rotulo, cor, dica }) {
return (
{valor}
{rotulo}
);
}
// =================================================
// ITEM 26 — historico dentro do cadastro do freelancer
// =================================================
function HistoricoProfissionalCard({ freelancerId }) {
const [h, setH] = React.useState(null);
const [carregando, setCarregando] = React.useState(true);
React.useEffect(() => {
if (!freelancerId) return;
let vivo = true;
sb.rpc('historico_do_profissional', { p_freelancer_id: freelancerId }).then(({ data, error }) => {
if (!vivo) return;
if (error) console.error('[HistoricoProfissionalCard] Supabase error:', error);
setH((data && data[0]) || null);
setCarregando(false);
});
return () => { vivo = false; };
}, [freelancerId]);
if (carregando || !h) return null;
const pct = v => (v === null || v === undefined ? '—' : Number(v) + '%');
return (
Histórico de ações
0 ? '#B91C1C' : undefined} />
0 ? '#B45309' : undefined}
dica="Check-in mais de 15 minutos depois do horário da ação" />
0 ? h.avaliacoes + (h.avaliacoes === 1 ? ' avaliação' : ' avaliações') : 'sem avaliação'} />