|
@@ -7,6 +7,195 @@
|
|
|
import EmissionCpr from '$lib/components/commodities/cpr/EmissionCpr.svelte';
|
|
import EmissionCpr from '$lib/components/commodities/cpr/EmissionCpr.svelte';
|
|
|
import CprEditModal from '$lib/components/commodities/cpr/CprEditModal.svelte';
|
|
import CprEditModal from '$lib/components/commodities/cpr/CprEditModal.svelte';
|
|
|
import ConfirmModal from '$lib/components/ui/PopUpDelete.svelte';
|
|
import ConfirmModal from '$lib/components/ui/PopUpDelete.svelte';
|
|
|
|
|
+ import { authToken } from '$lib/utils/stores';
|
|
|
|
|
+
|
|
|
|
|
+ const apiUrl = import.meta.env.VITE_API_URL;
|
|
|
|
|
+
|
|
|
|
|
+ const fieldKeys = [
|
|
|
|
|
+ 'cpr_contract_code',
|
|
|
|
|
+ 'cpr_contract_number',
|
|
|
|
|
+ 'cpr_number',
|
|
|
|
|
+ 'cpr_self_number',
|
|
|
|
|
+ 'cpr_ipoc_code',
|
|
|
|
|
+ 'cpr_calculation_type_code',
|
|
|
|
|
+ 'cpr_initial_exchange_value',
|
|
|
|
|
+ 'cpr_fixing_type_code',
|
|
|
|
|
+ 'cpr_data_source_type_code',
|
|
|
|
|
+ 'cpr_adjustment_frequency_type_code',
|
|
|
|
|
+ 'cpr_adjustment_pro_rata_type_code',
|
|
|
|
|
+ 'cpr_adjustment_type_code',
|
|
|
|
|
+ 'cpr_issue_date',
|
|
|
|
|
+ 'cpr_maturity_date',
|
|
|
|
|
+ 'cpr_reference_date',
|
|
|
|
|
+ 'cpr_profitability_start_date',
|
|
|
|
|
+ 'cpr_payment_start_date',
|
|
|
|
|
+ 'cpr_amortization_start_date',
|
|
|
|
|
+ 'cpr_interest_payment_date',
|
|
|
|
|
+ 'cpr_issue_quantity',
|
|
|
|
|
+ 'cpr_issue_value',
|
|
|
|
|
+ 'cpr_issue_financial_value',
|
|
|
|
|
+ 'cpr_unit_value',
|
|
|
|
|
+ 'cpr_unit_price_value',
|
|
|
|
|
+ 'cpr_interest_unit_price_value',
|
|
|
|
|
+ 'cpr_residual_value',
|
|
|
|
|
+ 'cpr_amortization_percentage',
|
|
|
|
|
+ 'cpr_event_quantity',
|
|
|
|
|
+ 'cpr_creditor_name',
|
|
|
|
|
+ 'cpr_creditor_document_number',
|
|
|
|
|
+ 'cpr_payment_method_code',
|
|
|
|
|
+ 'cpr_index_code',
|
|
|
|
|
+ 'cpr_index_short_name',
|
|
|
|
|
+ 'cpr_vcp_indicator_type_code',
|
|
|
|
|
+ 'cpr_indexador_percentage_value',
|
|
|
|
|
+ 'cpr_interest_rate_spread_percentage',
|
|
|
|
|
+ 'cpr_interest_rate_criteria_type_code',
|
|
|
|
|
+ 'cpr_interest_payment_value',
|
|
|
|
|
+ 'cpr_interest_payment_frequency_code',
|
|
|
|
|
+ 'cpr_interest_months_quantity',
|
|
|
|
|
+ 'cpr_interestPaymentFlow_time_unit_type_code',
|
|
|
|
|
+ 'cpr_interestPaymentFlow_deadline_type_code',
|
|
|
|
|
+ 'cpr_amortization_type_code',
|
|
|
|
|
+ 'cpr_amortization_months_quantity',
|
|
|
|
|
+ 'cpr_amortizationPaymentFlow_time_unit_type_code',
|
|
|
|
|
+ 'cpr_amortizationPaymentFlow_deadline_type_code',
|
|
|
|
|
+ 'cpr_additional_text',
|
|
|
|
|
+ 'cpr_type_code',
|
|
|
|
|
+ 'cpr_internal_control_number',
|
|
|
|
|
+ 'cpr_isin_code',
|
|
|
|
|
+ 'cpr_electronic_emission_indicator',
|
|
|
|
|
+ 'cpr_automatic_expiration_indicator',
|
|
|
|
|
+ 'cpr_otc_register_account_code',
|
|
|
|
|
+ 'cpr_otc_payment_agent_account_code',
|
|
|
|
|
+ 'cpr_otc_custodian_account_code',
|
|
|
|
|
+ 'cpr_otc_favored_account_code',
|
|
|
|
|
+ 'cpr_settlement_modality_type_code',
|
|
|
|
|
+ 'cpr_otc_settlement_bank_account_code',
|
|
|
|
|
+ 'cpr_ballast_type_code',
|
|
|
|
|
+ 'cpr_lot_number',
|
|
|
|
|
+ 'cpr_ballast_quantity',
|
|
|
|
|
+ 'cpr_currency_code',
|
|
|
|
|
+ 'cpr_transaction_identification',
|
|
|
|
|
+ 'cpr_guarantee_limit_type_code',
|
|
|
|
|
+ 'cpr_mother_code',
|
|
|
|
|
+ 'cpr_deposit_quantity',
|
|
|
|
|
+ 'cpr_deposit_unit_price_value',
|
|
|
|
|
+ 'cpr_deposit_person_type_acronym',
|
|
|
|
|
+ 'cpr_deposit_document_number',
|
|
|
|
|
+ 'cpr_event_type_code',
|
|
|
|
|
+ 'cpr_event_original_date',
|
|
|
|
|
+ 'cpr_operation_modality_type_code',
|
|
|
|
|
+ 'cpr_bacen_reference_code',
|
|
|
|
|
+ 'cpr_children_codes',
|
|
|
|
|
+ 'cpr_scr_type_code',
|
|
|
|
|
+ 'cpr_finality_code',
|
|
|
|
|
+ 'cpr_scr_customer_detail',
|
|
|
|
|
+ 'cpr_scr_person_type_acronym',
|
|
|
|
|
+ 'cpr_scr_document_number',
|
|
|
|
|
+ 'cpr_issuer_name',
|
|
|
|
|
+ 'cpr_place_name',
|
|
|
|
|
+ 'cpr_document_deadline_days_number',
|
|
|
|
|
+ 'cpr_deliveryPlace_state_acronym',
|
|
|
|
|
+ 'cpr_deliveryPlace_city_name',
|
|
|
|
|
+ 'cpr_deliveryPlace_ibge_code',
|
|
|
|
|
+ 'cpr_issuer_legal_nature_code',
|
|
|
|
|
+ 'cpr_issuers_person_type_acronym',
|
|
|
|
|
+ 'cpr_issuers_document_number',
|
|
|
|
|
+ 'cpr_issuers_state_acronym',
|
|
|
|
|
+ 'cpr_issuers_city_name',
|
|
|
|
|
+ 'cpr_issuers_ibge_code',
|
|
|
|
|
+ 'cpr_collateral_type_code',
|
|
|
|
|
+ 'cpr_collateral_type_name',
|
|
|
|
|
+ 'cpr_constitution_process_indicator',
|
|
|
|
|
+ 'cpr_otc_bondsman_account_code',
|
|
|
|
|
+ 'cpr_collaterals_document_number',
|
|
|
|
|
+ 'cpr_product_name',
|
|
|
|
|
+ 'cpr_product_class_name',
|
|
|
|
|
+ 'cpr_product_harvest',
|
|
|
|
|
+ 'cpr_product_quantity',
|
|
|
|
|
+ 'cpr_measure_unit_name',
|
|
|
|
|
+ 'cpr_packaging_way_name',
|
|
|
|
|
+ 'cpr_product_status_code',
|
|
|
|
|
+ 'cpr_production_type_code',
|
|
|
|
|
+ 'cpr_product_description',
|
|
|
|
|
+ 'cpr_production_place_name',
|
|
|
|
|
+ 'cpr_property_registration_number',
|
|
|
|
|
+ 'cpr_notary_name',
|
|
|
|
|
+ 'cpr_total_production_area_in_hectares_number',
|
|
|
|
|
+ 'cpr_total_area_in_hectares_number',
|
|
|
|
|
+ 'cpr_car_code',
|
|
|
|
|
+ 'cpr_latitude_code',
|
|
|
|
|
+ 'cpr_longitude_code',
|
|
|
|
|
+ 'cpr_zip_code',
|
|
|
|
|
+ 'cpr_green_cpr_indicator',
|
|
|
|
|
+ 'cpr_green_cpr_certificate_name',
|
|
|
|
|
+ 'cpr_green_cpr_certificate_cnpj_number',
|
|
|
|
|
+ 'cpr_green_cpr_declaration_indicator',
|
|
|
|
|
+ 'cpr_green_cpr_georeferencing_description'
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+ const allFieldKeys = Array.from(new Set(fieldKeys));
|
|
|
|
|
+
|
|
|
|
|
+ const requiredFields = new Set([
|
|
|
|
|
+ 'cpr_type_code',
|
|
|
|
|
+ 'cpr_otc_register_account_code',
|
|
|
|
|
+ 'cpr_otc_custodian_account_code',
|
|
|
|
|
+ 'cpr_electronic_emission_indicator',
|
|
|
|
|
+ 'cpr_issue_date',
|
|
|
|
|
+ 'cpr_maturity_date',
|
|
|
|
|
+ 'cpr_issue_quantity',
|
|
|
|
|
+ 'cpr_issue_value',
|
|
|
|
|
+ 'cpr_issue_financial_value',
|
|
|
|
|
+ 'cpr_profitability_start_date',
|
|
|
|
|
+ 'cpr_automatic_expiration_indicator',
|
|
|
|
|
+ 'cpr_collateral_type_code',
|
|
|
|
|
+ 'cpr_collateral_type_name',
|
|
|
|
|
+ 'cpr_constitution_process_indicator',
|
|
|
|
|
+ 'cpr_otc_bondsman_account_code',
|
|
|
|
|
+ 'cpr_product_name',
|
|
|
|
|
+ 'cpr_product_class_name',
|
|
|
|
|
+ 'cpr_product_harvest',
|
|
|
|
|
+ 'cpr_product_description',
|
|
|
|
|
+ 'cpr_product_quantity',
|
|
|
|
|
+ 'cpr_measure_unit_name',
|
|
|
|
|
+ 'cpr_packaging_way_name',
|
|
|
|
|
+ 'cpr_product_status_code',
|
|
|
|
|
+ 'cpr_production_type_code',
|
|
|
|
|
+ 'cpr_document_deadline_days_number',
|
|
|
|
|
+ 'cpr_place_name',
|
|
|
|
|
+ 'cpr_deliveryPlace_state_acronym',
|
|
|
|
|
+ 'cpr_deliveryPlace_city_name',
|
|
|
|
|
+ 'cpr_issuer_name',
|
|
|
|
|
+ 'cpr_issuers_document_number',
|
|
|
|
|
+ 'cpr_issuers_person_type_acronym',
|
|
|
|
|
+ 'cpr_issuer_legal_nature_code',
|
|
|
|
|
+ 'cpr_issuers_state_acronym',
|
|
|
|
|
+ 'cpr_issuers_city_name',
|
|
|
|
|
+ 'cpr_scr_type_code',
|
|
|
|
|
+ 'cpr_finality_code',
|
|
|
|
|
+ 'cpr_contract_code',
|
|
|
|
|
+ 'cpr_creditor_name',
|
|
|
|
|
+ 'cpr_creditor_document_number',
|
|
|
|
|
+ 'cpr_production_place_name',
|
|
|
|
|
+ 'cpr_property_registration_number',
|
|
|
|
|
+ 'cpr_notary_name',
|
|
|
|
|
+ 'cpr_total_production_area_in_hectares_number',
|
|
|
|
|
+ 'cpr_total_area_in_hectares_number',
|
|
|
|
|
+ 'cpr_car_code',
|
|
|
|
|
+ 'cpr_latitude_code',
|
|
|
|
|
+ 'cpr_longitude_code',
|
|
|
|
|
+ 'cpr_zip_code'
|
|
|
|
|
+ ]);
|
|
|
|
|
+
|
|
|
|
|
+ const createInitialForm = () =>
|
|
|
|
|
+ allFieldKeys.reduce((acc, key) => {
|
|
|
|
|
+ acc[key] = '';
|
|
|
|
|
+ return acc;
|
|
|
|
|
+ }, {});
|
|
|
|
|
+
|
|
|
|
|
+ let cprForm = createInitialForm();
|
|
|
|
|
+ let submitError = '';
|
|
|
|
|
+ let submitSuccess = '';
|
|
|
|
|
+ let isSubmitting = false;
|
|
|
|
|
|
|
|
// EditModal
|
|
// EditModal
|
|
|
let showCprEdit = false;
|
|
let showCprEdit = false;
|
|
@@ -31,7 +220,16 @@
|
|
|
{ nome: "CPR B", status: "Indisponível" }
|
|
{ nome: "CPR B", status: "Indisponível" }
|
|
|
];
|
|
];
|
|
|
|
|
|
|
|
|
|
+ function handleFieldChange(key, value) {
|
|
|
|
|
+ submitError = '';
|
|
|
|
|
+ submitSuccess = '';
|
|
|
|
|
+ cprForm = { ...cprForm, [key]: value ?? '' };
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
function handleAddTop() {
|
|
function handleAddTop() {
|
|
|
|
|
+ cprForm = createInitialForm();
|
|
|
|
|
+ submitError = '';
|
|
|
|
|
+ submitSuccess = '';
|
|
|
activeTab = 0;
|
|
activeTab = 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -44,7 +242,7 @@
|
|
|
function handleEditRow(e) {
|
|
function handleEditRow(e) {
|
|
|
const { row } = e.detail;
|
|
const { row } = e.detail;
|
|
|
selectedRow = row;
|
|
selectedRow = row;
|
|
|
- editValue = { ...row };
|
|
|
|
|
|
|
+ editValue = { ...row };
|
|
|
showCprEdit = true;
|
|
showCprEdit = true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -62,13 +260,9 @@
|
|
|
editValue = {};
|
|
editValue = {};
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- function handleFinalize() {
|
|
|
|
|
- alert('CPR finalizado com sucesso!');
|
|
|
|
|
- activeTab = 4;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
function handleCancel() {
|
|
function handleCancel() {
|
|
|
activeTab = 4;
|
|
activeTab = 4;
|
|
|
|
|
+ submitError = '';
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function confirmDelete() {
|
|
function confirmDelete() {
|
|
@@ -81,6 +275,87 @@
|
|
|
showDeleteConfirm = false;
|
|
showDeleteConfirm = false;
|
|
|
rowToDelete = null;
|
|
rowToDelete = null;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ function getMissingRequiredFields() {
|
|
|
|
|
+ const missing = [];
|
|
|
|
|
+ requiredFields.forEach((key) => {
|
|
|
|
|
+ const raw = cprForm[key];
|
|
|
|
|
+ if (!raw || String(raw).trim() === '') {
|
|
|
|
|
+ missing.push(key);
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ return missing;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function buildPayload() {
|
|
|
|
|
+ const payload = {};
|
|
|
|
|
+ for (const key of allFieldKeys) {
|
|
|
|
|
+ const raw = cprForm[key];
|
|
|
|
|
+ const trimmed = typeof raw === 'string' ? raw.trim() : raw;
|
|
|
|
|
+ if (trimmed === '' || trimmed === undefined || trimmed === null) {
|
|
|
|
|
+ payload[key] = requiredFields.has(key) ? '' : 'NA';
|
|
|
|
|
+ } else {
|
|
|
|
|
+ payload[key] = raw;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return payload;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ async function handleFinalize(event) {
|
|
|
|
|
+ event?.preventDefault();
|
|
|
|
|
+ submitError = '';
|
|
|
|
|
+ submitSuccess = '';
|
|
|
|
|
+
|
|
|
|
|
+ const missing = getMissingRequiredFields();
|
|
|
|
|
+ if (missing.length) {
|
|
|
|
|
+ submitError = `Preencha os campos obrigatórios: ${missing.join(', ')}`;
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const token = $authToken;
|
|
|
|
|
+ if (!token) {
|
|
|
|
|
+ submitError = 'Sessão expirada. Faça login novamente.';
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const payload = buildPayload();
|
|
|
|
|
+ isSubmitting = true;
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res = await fetch(`${apiUrl}/b3/cpr/register`, {
|
|
|
|
|
+ method: 'POST',
|
|
|
|
|
+ headers: {
|
|
|
|
|
+ 'content-type': 'application/json',
|
|
|
|
|
+ Authorization: `Bearer ${token}`
|
|
|
|
|
+ },
|
|
|
|
|
+ body: JSON.stringify(payload)
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ const raw = await res.text();
|
|
|
|
|
+ let response = null;
|
|
|
|
|
+ if (raw) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ response = JSON.parse(raw);
|
|
|
|
|
+ } catch (err) {
|
|
|
|
|
+ console.error('Resposta inválida ao registrar CPR:', err, raw);
|
|
|
|
|
+ throw new Error('Resposta inválida do servidor ao registrar CPR.');
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const serverStatus = response?.status?.toLowerCase?.() ?? '';
|
|
|
|
|
+ if (!res.ok || (response?.status && serverStatus !== 'ok')) {
|
|
|
|
|
+ throw new Error(response?.msg ?? 'Falha ao registrar CPR.');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ submitSuccess = response?.msg ?? 'CPR registrada com sucesso.';
|
|
|
|
|
+ cprForm = createInitialForm();
|
|
|
|
|
+ activeTab = 4;
|
|
|
|
|
+ } catch (err) {
|
|
|
|
|
+ submitError = err?.message ?? 'Falha ao registrar CPR.';
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ isSubmitting = false;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<div>
|
|
<div>
|
|
@@ -88,6 +363,13 @@
|
|
|
<div class="p-4">
|
|
<div class="p-4">
|
|
|
<div class="max-w-6xl mx-auto mt-4">
|
|
<div class="max-w-6xl mx-auto mt-4">
|
|
|
|
|
|
|
|
|
|
+ {#if submitError}
|
|
|
|
|
+ <div class="mb-4 rounded border border-red-300 bg-red-50 text-red-700 px-3 py-2 text-sm">{submitError}</div>
|
|
|
|
|
+ {/if}
|
|
|
|
|
+ {#if submitSuccess}
|
|
|
|
|
+ <div class="mb-4 rounded border border-green-300 bg-green-50 text-green-700 px-3 py-2 text-sm">{submitSuccess}</div>
|
|
|
|
|
+ {/if}
|
|
|
|
|
+
|
|
|
{#if activeTab === 4}
|
|
{#if activeTab === 4}
|
|
|
<Tables
|
|
<Tables
|
|
|
title="CPRs"
|
|
title="CPRs"
|
|
@@ -108,17 +390,19 @@
|
|
|
{:else if activeTab === 0}
|
|
{:else if activeTab === 0}
|
|
|
<Tabs {tabs} bind:active={activeTab} showCloseIcon={true} on:close={handleCancel} />
|
|
<Tabs {tabs} bind:active={activeTab} showCloseIcon={true} on:close={handleCancel} />
|
|
|
<div class="mt-4">
|
|
<div class="mt-4">
|
|
|
- <ContractCpr />
|
|
|
|
|
|
|
+ <ContractCpr formData={cprForm} onFieldChange={handleFieldChange} {requiredFields} />
|
|
|
</div>
|
|
</div>
|
|
|
<!-- Navigation Controls -->
|
|
<!-- Navigation Controls -->
|
|
|
<div class="flex justify-between mt-6">
|
|
<div class="flex justify-between mt-6">
|
|
|
<button
|
|
<button
|
|
|
|
|
+ type="button"
|
|
|
class="px-4 py-2 bg-gray-300 text-gray-700 rounded-lg cursor-not-allowed"
|
|
class="px-4 py-2 bg-gray-300 text-gray-700 rounded-lg cursor-not-allowed"
|
|
|
disabled
|
|
disabled
|
|
|
>
|
|
>
|
|
|
Anterior
|
|
Anterior
|
|
|
</button>
|
|
</button>
|
|
|
<button
|
|
<button
|
|
|
|
|
+ type="button"
|
|
|
class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700"
|
|
class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700"
|
|
|
on:click={() => activeTab = 1}
|
|
on:click={() => activeTab = 1}
|
|
|
>
|
|
>
|
|
@@ -128,17 +412,19 @@
|
|
|
{:else if activeTab === 1}
|
|
{:else if activeTab === 1}
|
|
|
<Tabs {tabs} bind:active={activeTab} showCloseIcon={true} on:close={handleCancel} />
|
|
<Tabs {tabs} bind:active={activeTab} showCloseIcon={true} on:close={handleCancel} />
|
|
|
<div class="mt-4">
|
|
<div class="mt-4">
|
|
|
- <RegisterCpr />
|
|
|
|
|
|
|
+ <RegisterCpr formData={cprForm} onFieldChange={handleFieldChange} {requiredFields} />
|
|
|
</div>
|
|
</div>
|
|
|
<!-- Navigation Controls -->
|
|
<!-- Navigation Controls -->
|
|
|
<div class="flex justify-between mt-6">
|
|
<div class="flex justify-between mt-6">
|
|
|
<button
|
|
<button
|
|
|
|
|
+ type="button"
|
|
|
class="px-4 py-2 bg-gray-500 text-white rounded-lg hover:bg-gray-600"
|
|
class="px-4 py-2 bg-gray-500 text-white rounded-lg hover:bg-gray-600"
|
|
|
on:click={() => activeTab = 0}
|
|
on:click={() => activeTab = 0}
|
|
|
>
|
|
>
|
|
|
Anterior
|
|
Anterior
|
|
|
</button>
|
|
</button>
|
|
|
<button
|
|
<button
|
|
|
|
|
+ type="button"
|
|
|
class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700"
|
|
class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700"
|
|
|
on:click={() => activeTab = 2}
|
|
on:click={() => activeTab = 2}
|
|
|
>
|
|
>
|
|
@@ -148,21 +434,24 @@
|
|
|
{:else if activeTab === 2}
|
|
{:else if activeTab === 2}
|
|
|
<Tabs {tabs} bind:active={activeTab} showCloseIcon={true} on:close={handleCancel} />
|
|
<Tabs {tabs} bind:active={activeTab} showCloseIcon={true} on:close={handleCancel} />
|
|
|
<div class="mt-4">
|
|
<div class="mt-4">
|
|
|
- <EmissionCpr />
|
|
|
|
|
|
|
+ <EmissionCpr formData={cprForm} onFieldChange={handleFieldChange} {requiredFields} />
|
|
|
</div>
|
|
</div>
|
|
|
<!-- Navigation Controls -->
|
|
<!-- Navigation Controls -->
|
|
|
<div class="flex justify-between mt-6">
|
|
<div class="flex justify-between mt-6">
|
|
|
<button
|
|
<button
|
|
|
|
|
+ type="button"
|
|
|
class="px-4 py-2 bg-gray-500 text-white rounded-lg hover:bg-gray-600"
|
|
class="px-4 py-2 bg-gray-500 text-white rounded-lg hover:bg-gray-600"
|
|
|
on:click={() => activeTab = 1}
|
|
on:click={() => activeTab = 1}
|
|
|
>
|
|
>
|
|
|
Anterior
|
|
Anterior
|
|
|
</button>
|
|
</button>
|
|
|
<button
|
|
<button
|
|
|
|
|
+ type="button"
|
|
|
class="px-6 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 font-semibold"
|
|
class="px-6 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 font-semibold"
|
|
|
- on:click={handleFinalize}
|
|
|
|
|
|
|
+ on:click|preventDefault={handleFinalize}
|
|
|
|
|
+ disabled={isSubmitting}
|
|
|
>
|
|
>
|
|
|
- Finalizar CPR
|
|
|
|
|
|
|
+ {isSubmitting ? 'Enviando...' : 'Finalizar CPR'}
|
|
|
</button>
|
|
</button>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|