Files
Investidor-V2/resources/js/components/profile-proof-picker.tsx
T

113 lines
4.2 KiB
TypeScript

import { useState } from 'react';
export default function ProfileProofPicker({
documents,
value,
onChange,
disabled = false,
}: {
documents: { id: string; file_name: string }[];
value: string[];
onChange: (ids: string[]) => void;
disabled?: boolean;
}) {
const [query, setQuery] = useState('');
const [showAll, setShowAll] = useState(false);
const [limit, setLimit] = useState(10);
const normalize = (text: string) =>
text
.normalize('NFD')
.replace(/\p{Diacritic}/gu, '')
.toLocaleLowerCase();
const matches = documents.filter((document) =>
normalize(document.file_name).includes(normalize(query)),
);
const toggle = (id: string) =>
onChange(
value.includes(id)
? value.filter((item) => item !== id)
: [...value, id],
);
return (
<fieldset disabled={disabled} className="space-y-3 rounded border p-4">
<legend>Escolher comprovativos</legend>
<p className="text-sm">
Escolha os seus documentos que sustentam este pedido. A lista
contém ficheiros próprios com análise antimalware concluída; não
confirma a sua adequação como comprovativo.
</p>
<p role="status">{value.length} comprovativos escolhidos</p>
{value.map((id) => (
<div
key={id}
className="flex items-start justify-between gap-3 rounded border p-2"
>
<span className="min-w-0 break-words">
{documents.find((document) => document.id === id)
?.file_name ??
'Ficheiro seleccionado indisponível nesta consulta'}
</span>
<button
type="button"
className="underline"
onClick={() => toggle(id)}
>
Retirar
</button>
</div>
))}
<label className="block">
Pesquisar nos meus ficheiros
<input
type="search"
className="mt-1 w-full rounded border p-2"
value={query}
onChange={(event) => {
setQuery(event.target.value);
setLimit(10);
}}
/>
</label>
<button
type="button"
className="underline"
onClick={() => setShowAll(!showAll)}
>
{showAll ? 'Fechar lista' : 'Ver ficheiros disponíveis'}
</button>
{(query || showAll) && (
<div className="space-y-2">
<p role="status">
{matches.length} ficheiros encontrados · a mostrar até{' '}
{Math.min(limit, matches.length)}
</p>
{matches.slice(0, limit).map((document) => (
<label
key={document.id}
className="flex gap-2 rounded border p-2"
>
<input
type="checkbox"
checked={value.includes(document.id)}
onChange={() => toggle(document.id)}
/>
<span className="min-w-0 break-words">
{document.file_name}
</span>
</label>
))}
{matches.length > limit && (
<button
type="button"
className="underline"
onClick={() => setLimit(limit + 10)}
>
Mostrar mais ficheiros
</button>
)}
</div>
)}
</fieldset>
);
}