Files
Investidor-V2/resources/js/components/investment-roadmap.tsx
T
nala 1106509116
tests / ci (push) Canceled after 0s
vrsao 2
2026-10-08 14:02:01 +02:00

401 lines
18 KiB
TypeScript

import { Link } from '@inertiajs/react';
import { useEffect, useState } from 'react';
import {
correctiveStates,
investmentLocations,
roadmapPhaseIndex,
roadmapPhases,
type RoadmapLink,
} from '@/lib/investment-roadmap';
import { roadmapSource } from '@/lib/investment-roadmap-source';
function Resources({ links }: { links: RoadmapLink[] }) {
return (
<ul className="flex flex-wrap gap-3">
{links.map((link) => (
<li key={`${link.href}-${link.label}`}>
<Link
href={link.href}
className="inline-block rounded-lg border border-emerald-800 px-4 py-2 text-emerald-900 underline underline-offset-4 focus-visible:outline-2"
>
{link.label}
</Link>
</li>
))}
</ul>
);
}
function SourceTable({ index }: { index: number }) {
const table = roadmapSource.tables[index];
const header = table?.[0];
const rows = table?.slice(1) ?? [];
if (!header) {
return (
<p role="alert">
A tabela não está disponível. Rever a transcrição do documento.
</p>
);
}
return (
<div
className="max-w-full overflow-x-auto rounded-lg border"
role="region"
aria-label={header.join(', ')}
tabIndex={0}
>
<table className="w-full min-w-[640px] border-collapse text-left text-sm">
<caption className="p-3 text-left text-slate-600">
Transcrição do roteiro fornecido. Confirmar aplicabilidade e
fontes antes de decisões de execução.
</caption>
<thead className="bg-emerald-900 text-white">
<tr>
{header.map((cell, i) => (
<th
key={i}
scope="col"
className="border border-slate-300 p-3 align-top"
>
{cell}
</th>
))}
</tr>
</thead>
<tbody>
{rows.map((row, i) => (
<tr key={i} className="odd:bg-white even:bg-slate-50">
{row.map((cell, j) => (
<td
key={j}
className="min-w-40 border border-slate-200 p-3 align-top whitespace-pre-line"
>
{cell || '—'}
</td>
))}
</tr>
))}
</tbody>
</table>
</div>
);
}
export function InvestmentRoadmap() {
const [active, setActive] = useState(0);
useEffect(() => {
const sync = () => setActive(roadmapPhaseIndex(window.location.hash));
sync();
window.addEventListener('hashchange', sync);
return () => window.removeEventListener('hashchange', sync);
}, []);
const phase = roadmapPhases[active];
function select(index: number) {
if (index < 0 || index >= roadmapPhases.length) return;
setActive(index);
window.history.replaceState(
window.history.state,
'',
`${window.location.pathname}${window.location.search}#${roadmapPhases[index].id}`,
);
}
return (
<div className="min-w-0 space-y-8">
<header className="space-y-4">
<p className="text-sm font-semibold text-emerald-800">
DA IDEIA À OPERAÇÃO
</p>
<h2 className="text-3xl font-bold">
Roteiro de implementação de ideias em Moçambique
</h2>
<p>
Comece pela fase que corresponde ao seu projecto. Pode
consultar, comparar alternativas e rever o plano em qualquer
momento. A exploração não exige empresa constituída,
documentos carregados ou aprovação prévia.
</p>
<Resources
links={[
{
label: 'Abrir ou continuar o dossier e simulador',
href: '/simulador-fiscal',
},
{
label: 'Explorar oportunidades',
href: '/oportunidades',
},
{ label: 'Pedir apoio', href: '/apoio' },
]}
/>
<p className="text-sm text-slate-600">
No simulador, escolha o percurso de ideia/pequeno negócio ou
de projecto de investimento. O dossier reúne informação,
plano financeiro, riscos e relatório. Os resultados
financeiros e fiscais têm pressupostos distintos; a escolha
de uma zona não confirma automaticamente um incentivo.
</p>
</header>
<nav
aria-label="Fases do roteiro"
className="grid gap-2 sm:grid-cols-2 lg:grid-cols-5"
>
{roadmapPhases.map((item, index) => (
<button
type="button"
key={item.id}
aria-pressed={active === index}
aria-controls="roadmap-phase"
onClick={() => select(index)}
className={`rounded-xl border p-4 text-left focus-visible:outline-2 ${active === index ? 'border-emerald-900 bg-emerald-900 text-white' : 'border-slate-300 bg-white text-slate-900'}`}
>
<span className="mb-1 block text-sm">
Fase {index + 1}
</span>
<span className="font-semibold">{item.title}</span>
</button>
))}
</nav>
<section
id="roadmap-phase"
aria-labelledby="roadmap-phase-title"
className="space-y-5 rounded-xl border bg-white p-5 sm:p-7"
>
<h3 id="roadmap-phase-title" className="text-2xl font-bold">
{active + 1}. {phase.title}
</h3>
<p>{phase.summary}</p>
<ol className="grid gap-4 sm:grid-cols-2">
{phase.steps.map((step) => (
<li
key={step.title}
className="space-y-2 border-l-2 border-emerald-700 pl-4"
>
<h4 className="font-semibold">{step.title}</h4>
<p>{step.description}</p>
<p className="text-sm text-slate-600">
<strong>Resultado:</strong> {step.result}
</p>
</li>
))}
</ol>
<Resources links={phase.links} />
<details className="space-y-3 rounded-lg border p-4">
<summary className="cursor-pointer font-semibold">
PC{active + 1} · Decisão, evidências e acções de revisão
</summary>
<p className="mt-3">
Estes pontos orientam a decisão do promotor e das
entidades competentes. Informação pendente deve ser
investigada; todas as fases do portal continuam
acessíveis. Uma restrição à execução deve identificar a
actividade afectada, a condição aplicável e a respectiva
fonte.
</p>
<dl className="space-y-3">
{roadmapSource.tables[1][0]
.slice(1)
.map((heading, i) => (
<div key={heading}>
<dt className="font-semibold">{heading}</dt>
<dd>
{
roadmapSource.tables[1][active + 1][
i + 1
]
}
</dd>
</div>
))}
</dl>
<h4 className="font-semibold">
Evidência a recolher quando aplicável
</h4>
<p>{roadmapSource.tables[6][active + 1][1]}</p>
<p className="text-sm">
A lista provém do roteiro geral e requer enquadramento
no sector, localização e operação do projecto.
</p>
</details>
<div className="flex flex-wrap justify-between gap-3">
{active > 0 && (
<button
type="button"
onClick={() => select(active - 1)}
className="rounded border px-4 py-2 underline"
>
Fase anterior
</button>
)}
{active < roadmapPhases.length - 1 && (
<button
type="button"
onClick={() => select(active + 1)}
className="rounded bg-emerald-800 px-4 py-2 text-white"
>
Explorar a fase seguinte
</button>
)}
</div>
</section>
<section className="space-y-4" aria-labelledby="roadmap-locations">
<h3 id="roadmap-locations" className="text-2xl font-bold">
Comparar locais e estruturas de investimento
</h3>
<p>
Compare localização, custos, acesso ao mercado, logística,
infra-estruturas, trabalhadores e requisitos. ZEE, ZFI,
parques industriais e clusters são opções territoriais ou
estruturas de investimento; o sector económico da actividade
é registado separadamente.
</p>
<Resources links={investmentLocations} />
<p className="text-sm text-slate-600">
Confirme os dados publicados de cada alternativa. Uma
localização ou proximidade não comprova disponibilidade de
espaço, serviços, elegibilidade ou benefícios fiscais.
</p>
<details className="space-y-3 rounded-lg border p-4">
<summary className="cursor-pointer font-semibold">
Exigências de ZEE, ZFI, parques e clusters referidas no
roteiro
</summary>
<p className="mt-3">
O documento mantém pendentes de confirmação no texto
oficial os artigos, a regra 70/30 e os limiares da ZFI
isolada. Esta tabela permite consultar essas
referências; não activa cálculos ou decisões de
elegibilidade.
</p>
<SourceTable index={5} />
</details>
</section>
<section className="space-y-4" aria-labelledby="roadmap-tools">
<h3 id="roadmap-tools" className="text-2xl font-bold">
Ficha de projecto, conformidade e acompanhamento
</h3>
<p>
Use o dossier existente para desenvolver a ideia, mercado,
localização, equipa, finanças e respostas a riscos. Consulte
os campos complementares do roteiro e registe a informação
aplicável no plano e nos documentos do projecto.
</p>
<details className="space-y-3 rounded-lg border p-4">
<summary className="cursor-pointer font-semibold">
Ficha completa de dados do projecto
</summary>
<p className="mt-3">
Os marcadores de preenchimento do documento representam
dados pendentes. Preencha os campos aplicáveis e
justifique os que não se aplicam; dados desconhecidos
não devem ser substituídos por zero.
</p>
<SourceTable index={3} />
</details>
<details className="space-y-3 rounded-lg border p-4">
<summary className="cursor-pointer font-semibold">
Plano de acções correctivas
</summary>
<p className="mt-3">
Registe identificador, responsável nominal, data de
abertura, prazo acordado, prioridade, estado, bloqueios,
evidência de encerramento e condição de reentrada. Os
prazos abaixo são alvos de gestão sugeridos pelo
roteiro; não são prazos legais confirmados.
</p>
<p>Estados: {correctiveStates.join(' · ')}.</p>
<SourceTable index={2} />
</details>
<details className="space-y-3 rounded-lg border p-4">
<summary className="cursor-pointer font-semibold">
Matriz geral de requisitos por fase
</summary>
<SourceTable index={0} />
</details>
<details className="space-y-3 rounded-lg border p-4">
<summary className="cursor-pointer font-semibold">
Pontos de controlo e matriz de evidências completos
</summary>
<SourceTable index={1} />
<SourceTable index={6} />
</details>
<Resources
links={[
{
label: 'Continuar o dossier',
href: '/simulador-fiscal',
},
{
label: 'Consultar documentos e formulários',
href: '/documentos',
},
{
label: 'Acompanhar o espaço privado',
href: '/investidor',
},
{ label: 'Procurar parceiros', href: '/parcerias' },
]}
/>
<p className="text-sm text-slate-600">
O espaço privado exige autenticação. A consulta deste
roteiro e a exploração pública permanecem disponíveis sem
conta.
</p>
</section>
<section
className="space-y-3 border-t pt-5"
aria-labelledby="roadmap-source"
>
<h3 id="roadmap-source" className="text-xl font-bold">
Origem e validação das referências
</h3>
<p>
Adaptado de{' '}
<cite>
Roteiro de Implementação de Ideias de Negócio em
Moçambique
</cite>
, fornecido pelo proprietário do portal. A matriz é geral e
provisória; a aplicabilidade depende da actividade,
localização, dimensão, origem do investimento e operação.
</p>
<p>
As afirmações de confirmação jurídica pertencem ao documento
de origem. Esta integração não verifica a vigência dos
diplomas nem aprova artigos, requisitos ou parâmetros
fiscais. A obtenção de evidências orienta as decisões de
execução e pode decorrer enquanto o promotor continua a
preparar o projecto.
</p>
<details className="space-y-3 rounded-lg border p-4">
<summary className="cursor-pointer font-semibold">
Estado das fontes e artigos indicado pelo documento
</summary>
<SourceTable index={4} />
</details>
<details className="space-y-3 rounded-lg border p-4">
<summary className="cursor-pointer font-semibold">
Texto completo do roteiro
</summary>
<div className="space-y-3 pt-3">
{roadmapSource.paragraphs.map((paragraph, index) => (
<p key={index} className="whitespace-pre-line">
{paragraph}
</p>
))}
</div>
<p className="text-sm">
As sete tabelas do documento estão disponíveis nas
secções acima. As ilustrações e o original são
preservados no ficheiro de origem.
</p>
</details>
</section>
</div>
);
}