This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
import { Link } from '@inertiajs/react';
|
||||
import { useState } from 'react';
|
||||
import { button, card, input } from '@/pages/investment/shared';
|
||||
|
||||
type Item = {id:number;title:string;slug:string;summary:string|null;province:string|null;district:string|null;chains:string[];stages:string[];maturity_label:string|null};
|
||||
export type CorridorGroup = {id:string;name:string;count:number;locations:string[];opportunities:Item[]};
|
||||
type Props = {groups:CorridorGroup[];selected:number[];onSelect:(id:number,checked:boolean)=>void;onCompare:(ids:number[])=>void;onClear:()=>void};
|
||||
|
||||
function Group({group,selected,onSelect}: {group:CorridorGroup} & Pick<Props,'selected'|'onSelect'>) {
|
||||
const [province,setProvince]=useState('');
|
||||
const [district,setDistrict]=useState('');
|
||||
const [chain,setChain]=useState('');
|
||||
const provinces=[...new Set(group.opportunities.map(r=>r.province).filter((s):s is string=>!!s))].sort();
|
||||
const districts=[...new Set(group.opportunities.filter(r=>!province||r.province===province).map(r=>r.district).filter((s):s is string=>!!s))].sort();
|
||||
const chains=[...new Set(group.opportunities.flatMap(r=>r.chains))].sort();
|
||||
const rows=group.opportunities.filter(r=>(!province||r.province===province)&&(!district||r.district===district)&&(!chain||r.chains.includes(chain)));
|
||||
return <section className={card+' space-y-4'} aria-label={group.name}>
|
||||
<header><h2 className="text-2xl font-bold">{group.name}</h2><p>{group.count} oportunidades publicadas</p>
|
||||
<p>{group.locations.length ? 'Localizações identificadas: '+group.locations.join(' · ') : 'Abrangência territorial por indicar.'}</p></header>
|
||||
<div className="grid gap-3 md:grid-cols-3">
|
||||
<label>Província<select className={input} value={province} onChange={e=>{setProvince(e.target.value);setDistrict('');}}><option value="">Todas as províncias</option>{provinces.map(p=><option key={p}>{p}</option>)}</select></label>
|
||||
<label>Distrito<select className={input} value={district} onChange={e=>setDistrict(e.target.value)}><option value="">Todos os distritos</option>{districts.map(d=><option key={d}>{d}</option>)}</select></label>
|
||||
<label>Cadeia de valor<select className={input} value={chain} onChange={e=>setChain(e.target.value)}><option value="">Todas as cadeias</option>{chains.map(c=><option key={c}>{c}</option>)}</select></label>
|
||||
</div>
|
||||
<p role="status">{rows.length} oportunidades com estes filtros</p>
|
||||
<div className="grid gap-4 md:grid-cols-2 xl:grid-cols-3">{rows.map(r=><article key={r.id} className="space-y-3 rounded-lg border p-4">
|
||||
<h3 className="text-lg font-semibold"><Link href={'/oportunidades/'+r.slug}>{r.title}</Link></h3>
|
||||
<p>{[r.province,r.district].filter(Boolean).join(' / ')||'Localização por escolher'}</p>
|
||||
<p>Cadeia de valor: {r.chains.join(' · ')||'Por indicar'}</p>
|
||||
{r.summary && !r.stages.includes(r.summary) && <p>{r.summary}</p>}
|
||||
<p>Etapas e actividades: {r.stages.join(' · ')||'Por indicar'}</p><p>{r.maturity_label}</p>
|
||||
<label className="flex gap-2"><input type="checkbox" checked={selected.includes(r.id)} onChange={e=>onSelect(r.id,e.target.checked)}/>Escolher para preparar investimento</label>
|
||||
<Link className="underline" href={'/oportunidades/'+r.slug}>Ver ficha</Link>
|
||||
</article>)}</div>
|
||||
</section>;
|
||||
}
|
||||
|
||||
export default function OpportunityCorridorGroups({groups,selected,onSelect,onCompare,onClear}:Props) {
|
||||
return <div className="space-y-6">
|
||||
<section className={card+' space-y-3'} aria-label="Escolhas entre corredores">
|
||||
<h2 className="text-xl font-bold">Explore por corredor e escolha onde investir</h2>
|
||||
<p>Pode escolher oportunidades de vários corredores e confirmar a localização de cada uma durante a preparação.</p>
|
||||
<p>{selected.length} oportunidades escolhidas</p>
|
||||
{!!selected.length&&<div className="flex flex-wrap gap-4"><Link className={button} href={'/investimentos/iniciar?'+selected.map(id=>'opportunities[]='+id).join('&')}>Preparar investimento com as oportunidades escolhidas</Link>
|
||||
<button className={button} disabled={selected.length>4} onClick={()=>onCompare(selected)}>Comparar as escolhidas</button>
|
||||
<button className="underline" onClick={onClear}>Limpar escolha</button>
|
||||
{selected.length>4&&<p>A comparação apresenta até quatro fichas de cada vez. Pode preparar o investimento com todas as escolhidas.</p>}</div>}
|
||||
</section>
|
||||
{groups.map(group=><Group key={group.id} group={group} selected={selected} onSelect={onSelect}/>)}
|
||||
</div>;
|
||||
}
|
||||
Reference in New Issue
Block a user