Files
Investidor-V2/resources/js/components/investment-zone-installation.tsx
T

113 lines
3.8 KiB
TypeScript

import { useState } from 'react';
import { api } from '@/pages/investment/shared';
export type ParkInstallationPlan = {
installed: boolean;
ready: boolean;
hash: string;
migration: string;
reasons: string[];
target: { database: string; port: number };
};
export default function InvestmentZoneInstallation({
initial,
endpoint = '/management/investment/zones/profile-install',
title = 'Preparação privada da ficha de parques',
summary = 'Uma coluna privada; sem importação ou publicação de dados.',
}: {
initial: ParkInstallationPlan;
endpoint?: string;
title?: string;
summary?: string;
}) {
const [plan, setPlan] = useState(initial);
const [busy, setBusy] = useState(false);
const [message, setMessage] = useState('');
async function refresh() {
const response = await fetch(endpoint, {
headers: { Accept: 'application/json' },
});
if (!response.ok)
throw new Error(
'Não foi possível carregar a prévia da instalação.',
);
const value = await response.json();
setPlan(value.plan);
return value.plan as ParkInstallationPlan;
}
return (
<section
className="space-y-3 rounded border p-4"
aria-label="Instalação da ficha de parques"
>
<h2 className="font-semibold">{title}</h2>
<p>
{plan.installed
? 'Esquema instalado. Não importa nem publica fichas.'
: summary}
</p>
<p>
Alvo: {plan.target.database}:{plan.target.port} ·{' '}
{plan.migration}
</p>
{plan.reasons.map((reason) => (
<p key={reason} role="status">
{reason}
</p>
))}
<button
type="button"
className="rounded border p-2"
disabled={busy}
onClick={async () => {
setBusy(true);
try {
await refresh();
setMessage('Prévia atualizada, sem escrita.');
} catch (e) {
setMessage(
e instanceof Error
? e.message
: 'Falha ao carregar.',
);
} finally {
setBusy(false);
}
}}
>
Atualizar prévia
</button>
<button
type="button"
className="rounded border p-2"
disabled={busy || !plan.ready || plan.installed}
onClick={async () => {
setBusy(true);
try {
await api(endpoint, {
hash: plan.hash,
idempotency_key: crypto.randomUUID(),
confirm: true,
});
await refresh();
setMessage(
'Instalação nominal verificada; nenhuma ficha publicada.',
);
} catch (e) {
setMessage(
e instanceof Error
? e.message
: 'Falha ao instalar.',
);
} finally {
setBusy(false);
}
}}
>
Instalar apenas o esquema indicado
</button>
{message && <p role="alert">{message}</p>}
</section>
);
}