- GeradoresService: cada tipo passa a ser um IGenerator (NIF, NIPC, NISS, CC, passaporte, IBAN, NIB, cartões, referência MB, pessoa, telefone, código postal, email, matrícula, EAN, UUID) registado em GeneratorRegistry; remove DAL/EF - GeradoresWS: minimal APIs em /api/v1 com OpenAPI + Scalar e health check - UnitTest: testes de ida e volta, valores conhecidos, detecção e API - geradoresfe: UI construída a partir dos metadados da API, validador livre, exportação CSV/JSON/TXT, nginx com API_UPSTREAM configurável - Docker, docker-compose e Jenkinsfile actualizados Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
28 lines
1.1 KiB
TypeScript
28 lines
1.1 KiB
TypeScript
import { CopyIcon } from "lucide-react";
|
|
import { copyToClipboard } from "../../lib/clipboard";
|
|
|
|
type ResultDisplayProps = {
|
|
value: string;
|
|
label: string;
|
|
};
|
|
|
|
export function ResultDisplay({ value, label }: ResultDisplayProps) {
|
|
return (
|
|
<div className="flex items-center gap-2 rounded-lg border border-gray-300 bg-gray-50 px-3 py-2 dark:border-zinc-600 dark:bg-zinc-800">
|
|
<output aria-label={`${label} gerado`} className="min-h-5 flex-1 truncate font-mono text-sm text-gray-900 dark:text-gray-100">
|
|
{value || <span className="text-gray-400">—</span>}
|
|
</output>
|
|
<button
|
|
type="button"
|
|
onClick={() => copyToClipboard(value, label)}
|
|
disabled={!value}
|
|
className="rounded p-1 text-gray-500 hover:bg-gray-200 hover:text-blue-600 disabled:opacity-30 dark:hover:bg-zinc-700"
|
|
title="Copiar"
|
|
aria-label="Copiar"
|
|
>
|
|
<CopyIcon className="h-4 w-4" />
|
|
</button>
|
|
</div>
|
|
);
|
|
}
|