Files
Investidor-V2/resources/js/components/sector-resource-reference.tsx
T

234 lines
9.8 KiB
TypeScript

import { useState } from "react";
import { Link, usePage } from "@inertiajs/react";
export type SectorResourceArea = {
id: string;
group_ids: string[];
title: string;
locations_text: string;
location_labels: string[];
market_evidence: string;
value_chain: string;
indicative_location: string;
promotion_ready: boolean;
source_row: string;
};
export type SectorResourceSelection = {
sector_slug: string;
key: string;
group_id?: string | null;
group_name?: string | null;
area_id: string;
title: string;
location_label: string | null;
locations_text: string;
value_chain: string;
source_sha256: string;
reference_date: string;
href: string;
};
export type SectorResourceData = {
sector_slug: string;
title: string;
introduction: string;
group_label: string;
resource_heading: string;
resource_notice: string;
background: {title:string;paragraphs:string[]}[];
source_sha256: string;
reference_date: string;
groups: { id: string; name: string; locations_text: string; location_labels: string[] }[];
areas: SectorResourceArea[];
projects: string[];
indicators: { label: string; value: string; source: string }[];
risks: string[];
sources: string[];
source_links?: {title:string;url:string}[];
};
export default function SectorResourceReference({ data }: { data: SectorResourceData }) {
const url = usePage().url,
query = new URL(url, "https://investmoz.invalid").searchParams;
const [location, setLocation] = useState(query.get("resource_location") ?? ""),
[search, setSearch] = useState(""),
[area, setArea] = useState(query.get("resource_area") ?? ""),
[group, setGroup] = useState(query.get("resource_group") ?? "");
const locations = [
...new Set(
data.groups
.flatMap((m) => m.location_labels)
.concat(data.areas.flatMap((m) => m.location_labels)),
),
].sort((a, b) => a.localeCompare(b, "pt"));
const matches = (x: { location_labels: string[] }, text: string) =>
(!location || x.location_labels.includes(location)) &&
(!search || text.toLocaleLowerCase("pt").includes(search.toLocaleLowerCase("pt")));
const groups = data.groups.filter(
(m) => (!group || m.id === group) && matches(m, m.name + " " + m.locations_text),
),
areas = data.areas.filter(
(a) =>
(!area || a.id === area) &&
(!group || a.group_ids.includes(group)) &&
matches(a, a.title + " " + a.value_chain + " " + a.locations_text),
);
return (
<section
aria-label={data.title}
className="space-y-5 rounded border p-4"
>
<h2 className="text-xl font-semibold">{data.title}</h2>
<p>{data.introduction}</p>
<div className="flex flex-wrap gap-3">
<label>
Localização
<select
className="mt-1 block max-w-full rounded border p-2"
aria-label="Localização sectorial"
value={location}
onChange={(e) => {
setLocation(e.target.value);
setArea("");
}}
>
<option value="">Todas as localizações</option>
{locations.map((p) => (
<option key={p} value={p}>
{p === "Maputo" ? "Maputo — província/cidade a precisar" : p}
</option>
))}
</select>
</label>
<label>
{data.group_label}
<select
className="mt-1 block max-w-full rounded border p-2"
aria-label={data.group_label}
value={group}
onChange={(e) => {
setGroup(e.target.value);
setArea("");
}}
>
<option value="">Todos os grupos</option>
{data.groups.map((m) => (
<option key={m.id} value={m.id}>
{m.name}
</option>
))}
</select>
</label>
<label>
Recurso, local ou actividade
<input
className="mt-1 block max-w-full rounded border p-2"
aria-label="Pesquisar recursos e cadeia de valor"
value={search}
onChange={(e) => {
setSearch(e.target.value);
setArea("");
}}
/>
</label>
{area && (
<button type="button" onClick={() => setArea("")}>
Ver todas as áreas
</button>
)}
</div>
<div>
<h3 className="font-semibold">{data.resource_heading}</h3>
{groups.length ? (
<ul className="space-y-3">
{groups.map((m) => (
<li key={m.id}>
<strong>{m.name}</strong>
<p>{m.locations_text}</p>
</li>
))}
</ul>
) : (
<p>Sem referências para esta pesquisa.</p>
)}
<p className="text-sm">{data.resource_notice}</p>
</div>
<div>
<h3 className="font-semibold">Possibilidades na cadeia de valor</h3>
{areas.map((a) => (
<article key={a.id} className="my-3 space-y-2 rounded border p-3">
<h4 className="font-semibold">{a.title}</h4>
<p>{a.locations_text}</p>
<p>{a.value_chain.replace(/\s*\(indicativo\)/, "")}</p>
<details>
<summary>Evidência e âmbito territorial</summary>
<p>{a.market_evidence}</p>
{a.indicative_location !== a.locations_text && <p>{a.indicative_location}</p>}
<p>Referência de {data.reference_date}; preparação da actividade sujeita ao investimento concreto.</p>
</details>
<Link
className="underline"
href={
"/investimentos/a-partir-do-setor/" + data.sector_slug + "?" +
new URLSearchParams({
resource_area: a.id,
resource_source: data.source_sha256,
...(group ? { resource_group: group } : {}),
...(location ? { resource_location: location } : {}),
})
}
>
Preparar uma ideia nesta cadeia de valor
</Link>
</article>
))}
{!areas.length && <p>Sem áreas de investimento para esta selecção.</p>}
</div>
<details>
<summary>Projectos de referência</summary>
<ul>
{data.projects.map((p, i) => (
<li key={i}>{p}</li>
))}
</ul>
</details>
{!!data.indicators.length && (
<details>
<summary>Produção e recursos por período</summary>
{data.indicators.map((s, i) => (
<article key={i}>
<h4>{s.label}</h4>
<p>
{s.value.replace(
"Não encontrei dados de produção das outras gemas.",
"Outras gemas: sem valores apresentados.",
)}
</p>
<p>Fonte: {s.source}</p>
</article>
))}
<p>
Produção, capacidade, recursos e previsões são grandezas distintas. Os valores
conservam os períodos e divergências das fontes.
</p>
</details>
)}
<details>
<summary>Riscos a considerar</summary>
<ul>
{data.risks.map((r, i) => (
<li key={i}>{r}</li>
))}
</ul>
</details>
{data.background.map(section=><details key={section.title}><summary>{section.title}</summary>{section.paragraphs.map((text,i)=><p key={i}>{text}</p>)}{section.title.startsWith("Enquadramento")&&<p>Referência documental; não activa benefícios fiscais, licenças ou direitos no portal.</p>}</details>)}
<details>
<summary>Fontes e data</summary>
<p>Referências reunidas em {data.reference_date}.</p>
<ul>
{data.sources.map((s, i) => (
<li key={i}>{data.source_links?.find(link=>link.title===s)?.url ? <a className="underline" href={data.source_links.find(link=>link.title===s)!.url} target="_blank" rel="noopener noreferrer">{s}</a> : s}</li>
))}
</ul>
</details>
</section>
);
}