import { useState, type FormEvent } from "react"; import { Link } from "react-router"; import { SearchCheckIcon } from "lucide-react"; import { api, type DetectMatch } from "../lib/api"; import { Button } from "./ui/Button"; import { Input } from "./ui/Input"; import { ValidationResultView } from "./ValidationResultView"; /** * Validador livre: o utilizador cola um valor qualquer e a API identifica o tipo * (NIF, IBAN, CC, …) e se é válido, incluindo "quase" correspondências com o dígito errado. */ export function Validator({ autoFocus = false }: { autoFocus?: boolean }) { const [value, setValue] = useState(""); const [matches, setMatches] = useState(null); const [error, setError] = useState(null); const [loading, setLoading] = useState(false); const submit = async (e: FormEvent) => { e.preventDefault(); if (!value.trim()) return; setLoading(true); setError(null); try { setMatches(await api.detect(value)); } catch (err) { setError((err as Error).message); setMatches(null); } finally { setLoading(false); } }; const valid = matches?.filter((m) => m.result.isValid) ?? []; const nearMisses = matches?.filter((m) => !m.result.isValid) ?? []; return (
{ setValue(e.target.value); setMatches(null); }} placeholder="Cole um NIF, NISS, CC, IBAN, cartão, matrícula, EAN…" aria-label="Valor a validar" autoFocus={autoFocus} className="py-3 font-mono text-base" />
{error &&

{error}

} {matches && matches.length === 0 && ( )} {valid.map((m) => ( ))} {valid.length === 0 && nearMisses.map((m) => ( ))} {valid.length > 0 && nearMisses.length > 0 && (

Também tem o formato de: {nearMisses.map((m) => ( {m.generatorName} ))} (mas não é válido como tal).

)}
); }