const { useState } = React;
// ─── Status color for env ────────────────────────────────────────────────────
function envColor(s) {
if (s === 'critical') return C.danger;
if (s === 'at_risk') return C.warning;
if (s === 'warning') return '#F97316';
return C.success;
}
function envBg(s) {
if (s === 'critical') return '#FFF5F5';
if (s === 'at_risk') return '#FFFBEB';
if (s === 'warning') return '#FFF7ED';
return '#F0FDF4';
}
// ─── Counter card ─────────────────────────────────────────────────────────────
function EnvCounter({ label, value, color, icon }) {
return (
);
}
// ─── 90-day timeline ─────────────────────────────────────────────────────────
function EnvTimeline({ conditions }) {
// Show next 90 days as weeks
const weeks = Array.from({ length: 13 }, (_, i) => i); // 0 = current week
const weekLabel = i => {
const d = new Date(2026, 4, 23); // May 23
d.setDate(d.getDate() + i * 7);
return `${String(d.getDate()).padStart(2,'0')}/${String(d.getMonth()+1).padStart(2,'0')}`;
};
const dayOfProject = days => Math.floor(days / 7); // which week slot
return (
{/* Week headers */}
{weeks.map(w => (
{weekLabel(w)}{w===0?' (hoje)':''}
))}
{/* Conditions */}
{conditions.filter(c => c.daysLeft <= 90).map(c => {
const weekSlot = Math.min(12, Math.floor(c.daysLeft / 7));
const color = envColor(c.status);
return (
{c.code}
{weeks.map(w => (
))}
{/* Deadline marker */}
{c.daysLeft}d
);
})}
■ Crítico
■ Em risco
■ Atenção
■ OK · Números = dias restantes
);
}
// ─── Risk heatmap ─────────────────────────────────────────────────────────────
function EnvRiskHeatmap() {
const risks = [
{ P:4, I:4, label:'Embargo\nIMASQL' },
{ P:3, I:4, label:'Contaminação\nsolo' },
{ P:3, I:3, label:'Chuvas\nexcessivas' },
{ P:2, I:5, label:'Passivo\nambient.' },
{ P:2, I:3, label:'Ruído\ncomunidade' },
];
const cellBg = (p, i) => {
const s = p * i;
if (s >= 16) return '#FEE2E2';
if (s >= 12) return '#FEF3C7';
if (s >= 6) return '#FEF9C3';
return '#DCFCE7';
};
const cellBorder = (p, i) => {
const s = p * i;
if (s >= 16) return C.danger;
if (s >= 12) return C.warning;
if (s >= 6) return '#FDE047';
return C.success;
};
const riskIn = (prob, imp) => risks.filter(r => r.P === prob && r.I === imp);
return (
PROB ↑
{[1,2,3,4,5].map(i => {i} )}
{[5,4,3,2,1].map(prob => (
{prob}
{[1,2,3,4,5].map(imp => {
const items = riskIn(prob, imp);
return (
{items.map((r, idx) => (
{r.label.replace('\n',' ')}
))}
);
})}
))}
IMPACTO →
);
}
// ─── Screen 5: Painel Ambiental ──────────────────────────────────────────────
function Screen5Ambiental() {
const { envConditions, regulatoryStatus } = window.SIGP_DATA;
const [activeTab, setActiveTab] = useState('lista');
const cumpridas = envConditions.filter(c => c.status === 'ok' && c.docsDone === c.docsReq).length;
const emAndamento = envConditions.filter(c => c.status === 'ok' && c.docsDone < c.docsReq).length + envConditions.filter(c => c.status === 'warning').length;
const emRisco = envConditions.filter(c => c.status === 'at_risk').length;
const criticas = envConditions.filter(c => c.status === 'critical').length;
return (
alert('Gerando Relatório de Conformidade PDF para submissão ao IMASUL...')}>
📄 Gerar Relatório de Conformidade PDF
}
>
{/* ── Counters ── */}
{/* ── Critical highlight ── */}
🚨 CONDICIONANTES CRÍTICAS — PRAZO < 7 DIAS
{envConditions.filter(c => c.daysLeft <= 7).map(c => (
{c.code}
{c.daysLeft}d restante{c.daysLeft !== 1 ? 's' : ''}
{c.desc}
Resp: {c.responsible} · Docs: {c.docsDone}/{c.docsReq} entregues
))}
{/* ── Tabs ── */}
{[{id:'lista',label:'Lista Detalhada'},{id:'timeline',label:'Timeline 90 dias'},{id:'heatmap',label:'Mapa de Risco Ambiental'},{id:'regulatorio',label:'Status Regulatório'}].map(t => (
setActiveTab(t.id)} style={{
padding:'6px 14px', fontSize:11.5, fontWeight:activeTab===t.id?700:500,
background:activeTab===t.id?C.success:'#fff',
color:activeTab===t.id?'#fff':C.textSub,
border:`1px solid ${activeTab===t.id?C.success:C.border}`,
borderRadius:5, cursor:'pointer', fontFamily:'inherit',
}}>{t.label}
))}
{/* ── List Tab ── */}
{activeTab === 'lista' && (
Código
Descrição
Prazo
Dias
Responsável
Status Doc.
Docs
Status
Upload
{envConditions.map((c, i) => {
const col = envColor(c.status);
return (
{c.code}
{c.desc}
{c.deadline}
{c.daysLeft}
{c.responsible}
{c.docStatus}
{c.docsDone}/{c.docsReq}
{c.status==='critical'?'Crítico':c.status==='at_risk'?'Em risco':c.status==='warning'?'Atenção':'OK'}
alert(`Upload para ${c.code}`)}>↑ Upload
);
})}
)}
{/* ── Timeline Tab ── */}
{activeTab === 'timeline' && (
)}
{/* ── Heatmap Tab ── */}
{activeTab === 'heatmap' && (
{[
{ score:'16–25', label:'CRÍTICO', color:C.danger, desc:'Ação imediata requerida — protocolo IMASUL em até 48h' },
{ score:'10–15', label:'ALTO', color:C.warning, desc:'Plano de ação documentado em até 5 dias úteis' },
{ score:'4–9', label:'MÉDIO', color:'#FDE047', desc:'Monitoramento semanal e medidas preventivas' },
{ score:'1–3', label:'BAIXO', color:C.success, desc:'Monitoramento mensal conforme plano ambiental' },
].map(r => (
))}
)}
{/* ── Regulatory Tab ── */}
{activeTab === 'regulatorio' && (
{regulatoryStatus.map((r, i) => {
const col = envColor(r.status);
return (
);
})}
)}
);
}
Object.assign(window, { Screen5Ambiental });