|
|
@@ -1,66 +1,291 @@
|
|
|
<script>
|
|
|
import ModalBase from './ModalBase.svelte';
|
|
|
+ import flatpickr from 'flatpickr';
|
|
|
+ import 'flatpickr/dist/flatpickr.min.css';
|
|
|
+ import { Portuguese } from 'flatpickr/dist/l10n/pt.js';
|
|
|
+
|
|
|
export let visible = false;
|
|
|
export let onClose = () => {};
|
|
|
export let state = '';
|
|
|
export let commodity = '';
|
|
|
+ export let prefill = null;
|
|
|
+
|
|
|
let valorSaca = '';
|
|
|
let quantidade = '';
|
|
|
- let referencia = 'BRL : 12';
|
|
|
- let validade = '';
|
|
|
- let calendario = '';
|
|
|
+ let referencia = '';
|
|
|
+ let validade = new Date();
|
|
|
+ let validadeInput = validade.toISOString().slice(0, 10);
|
|
|
+
|
|
|
$: total = (Number(valorSaca) || 0) * (Number(quantidade) || 0);
|
|
|
+
|
|
|
+ $: if (visible && prefill) {
|
|
|
+ if (prefill.valorSaca != null || prefill.valor != null) {
|
|
|
+ valorSaca = String(prefill.valorSaca ?? prefill.valor ?? '');
|
|
|
+ }
|
|
|
+ if (prefill.quantidade != null) {
|
|
|
+ quantidade = String(prefill.quantidade ?? '');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ let calendarEl;
|
|
|
+
|
|
|
+ // Inicializa Flatpickr
|
|
|
+ function initCalendar() {
|
|
|
+ flatpickr(calendarEl, {
|
|
|
+ inline: true,
|
|
|
+ appendTo: calendarEl,
|
|
|
+ defaultDate: validade,
|
|
|
+ locale: Portuguese,
|
|
|
+ dateFormat: 'Y-m-d',
|
|
|
+ onChange: (selectedDates) => {
|
|
|
+ validade = selectedDates[0];
|
|
|
+ validadeInput = validade.toISOString().slice(0, 10);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ function handleValidadeInput(event) {
|
|
|
+ const str = event.target.value;
|
|
|
+ validade = str ? new Date(str) : new Date();
|
|
|
+ if (calendarEl._flatpickr) {
|
|
|
+ calendarEl._flatpickr.setDate(validade);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
function confirmar() {
|
|
|
- const dados = { tipo: 'compra', valorSaca: Number(valorSaca)||0, quantidade: Number(quantidade)||0, referencia, total, validade, calendario, estado: state, commodity };
|
|
|
+ const dados = {
|
|
|
+ tipo: 'compra',
|
|
|
+ valorSaca: Number(valorSaca) || 0,
|
|
|
+ quantidade: Number(quantidade) || 0,
|
|
|
+ referencia,
|
|
|
+ total,
|
|
|
+ validade: validadeInput,
|
|
|
+ estado: state,
|
|
|
+ commodity
|
|
|
+ };
|
|
|
console.log('BoletaCompra confirmada', dados);
|
|
|
try { onClose?.(); } catch {}
|
|
|
}
|
|
|
- function formatBRL(n) { return new Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(Number(n||0)); }
|
|
|
+
|
|
|
+ function formatBRL(n) {
|
|
|
+ return new Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(Number(n || 0));
|
|
|
+ }
|
|
|
</script>
|
|
|
+
|
|
|
<ModalBase title="Boleta de Compra" {visible} {onClose}>
|
|
|
<div class="space-y-4">
|
|
|
+
|
|
|
+ <!-- VALOR E QUANTIDADE -->
|
|
|
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
|
|
<div>
|
|
|
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300">Valor/saca</label>
|
|
|
- <input type="number" min="0" step="0.01" bind:value={valorSaca} class="mt-1 block w-full rounded border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700/70 text-gray-900 dark:text-gray-200 px-3 py-2 focus:outline-none focus:ring-2 focus:ring-green-500" />
|
|
|
+ <input type="number" min="0" step="0.01" bind:value={valorSaca}
|
|
|
+ class="mt-1 block w-full rounded border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700/70 text-gray-900 dark:text-gray-200 px-3 py-2 focus:outline-none focus:ring-2 focus:ring-green-500" />
|
|
|
</div>
|
|
|
<div>
|
|
|
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300">Quantidade em saca</label>
|
|
|
- <input type="number" min="0" step="1" bind:value={quantidade} class="mt-1 block w-full rounded border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700/70 text-gray-900 dark:text-gray-200 px-3 py-2 focus:outline-none focus:ring-2 focus:ring-green-500" />
|
|
|
+ <input type="number" min="0" step="1" bind:value={quantidade}
|
|
|
+ class="mt-1 block w-full rounded border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700/70 text-gray-900 dark:text-gray-200 px-3 py-2 focus:outline-none focus:ring-2 focus:ring-green-500" />
|
|
|
</div>
|
|
|
</div>
|
|
|
+
|
|
|
+ <!-- REFERÊNCIA E TOTAL -->
|
|
|
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
|
|
<div>
|
|
|
- <label class="block text-sm font-medium text-gray-700 dark:text-gray-300">Referência</label>
|
|
|
- <input type="text" bind:value={referencia} class="mt-1 block w-full rounded border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700/70 text-gray-900 dark:text-gray-200 px-3 py-2 focus:outline-none focus:ring-2 focus:ring-green-500" />
|
|
|
+ <label class="block text-sm font-medium text-gray-700 dark:text-gray-300">eBRL: {referencia}</label>
|
|
|
</div>
|
|
|
<div>
|
|
|
- <label class="block text-sm font-medium text-gray-700 dark:text-gray-300">Referência valor total</label>
|
|
|
- <input value={formatBRL(total)} readonly class="mt-1 block w-full rounded border border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-700/40 text-gray-900 dark:text-gray-200 px-3 py-2" />
|
|
|
+ <label class="block text-sm font-medium text-gray-700 dark:text-gray-300">Valor total: {formatBRL(total)}</label>
|
|
|
</div>
|
|
|
</div>
|
|
|
+
|
|
|
+ <!-- VALIDADE E CALENDÁRIO -->
|
|
|
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
|
|
+ <!-- input de validade -->
|
|
|
<div>
|
|
|
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300">Validade</label>
|
|
|
- <input type="date" bind:value={validade} class="mt-1 block w-full rounded border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700/70 text-gray-900 dark:text-gray-200 px-3 py-2 focus:outline-none focus:ring-2 focus:ring-green-500" />
|
|
|
+ <input type="date" bind:value={validadeInput} on:input={handleValidadeInput}
|
|
|
+ class="mt-1 block w-full rounded border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700/70 text-gray-900 dark:text-gray-200 px-3 py-2 focus:outline-none focus:ring-2 focus:ring-green-500" />
|
|
|
+
|
|
|
+ <!-- ESTADO E COMMODITY -->
|
|
|
+ <div class="mt-4">
|
|
|
+ <label class="block text-sm font-medium text-gray-700 dark:text-gray-300">Estado</label>
|
|
|
+ <input value={state} readonly
|
|
|
+ class="mt-1 block w-full rounded border border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-700/40 text-gray-900 dark:text-gray-200 px-3 py-2" />
|
|
|
+ </div>
|
|
|
+ <div class="mt-4">
|
|
|
+ <label class="block text-sm font-medium text-gray-700 dark:text-gray-300">Commodity</label>
|
|
|
+ <input value={commodity} readonly
|
|
|
+ class="mt-1 block w-full rounded border border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-700/40 text-gray-900 dark:text-gray-200 px-3 py-2" />
|
|
|
+ </div>
|
|
|
</div>
|
|
|
+
|
|
|
+ <!-- Calendário inline -->
|
|
|
<div>
|
|
|
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300">Calendário</label>
|
|
|
- <input type="date" bind:value={calendario} class="mt-1 block w-full rounded border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700/70 text-gray-900 dark:text-gray-200 px-3 py-2 focus:outline-none focus:ring-2 focus:ring-green-500" />
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
|
|
- <div>
|
|
|
- <label class="block text-sm font-medium text-gray-700 dark:text-gray-300">Estado</label>
|
|
|
- <input value={state} readonly class="mt-1 block w-full rounded border border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-700/40 text-gray-900 dark:text-gray-200 px-3 py-2" />
|
|
|
- </div>
|
|
|
- <div>
|
|
|
- <label class="block text-sm font-medium text-gray-700 dark:text-gray-300">Commodity</label>
|
|
|
- <input value={commodity} readonly class="mt-1 block w-full rounded border border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-700/40 text-gray-900 dark:text-gray-200 px-3 py-2" />
|
|
|
+ <div bind:this={calendarEl} class="mt-1 w-56 text-sm calendar-override rounded border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700/70 text-gray-900 dark:text-gray-200 p-2" use:initCalendar></div>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <div class="flex justify-end">
|
|
|
- <button class="px-4 py-2 rounded bg-green-600 hover:bg-green-700 text-white focus:outline-none focus:ring-2 focus:ring-green-500" on:click={confirmar}>Confirmar Compra</button>
|
|
|
+
|
|
|
+
|
|
|
+ <!-- BOTÃO CONFIRMAR -->
|
|
|
+ <div class="flex justify-end pt-2">
|
|
|
+ <button class="px-4 py-2 rounded bg-green-600 hover:bg-green-700 text-white focus:outline-none focus:ring-2 focus:ring-green-500"
|
|
|
+ on:click={confirmar}>
|
|
|
+ Confirmar Compra
|
|
|
+ </button>
|
|
|
</div>
|
|
|
</div>
|
|
|
</ModalBase>
|
|
|
+
|
|
|
+<style>
|
|
|
+ :global(.calendar-override .flatpickr-calendar) {
|
|
|
+ position: static !important;
|
|
|
+ background: transparent !important;
|
|
|
+ border: 0 !important;
|
|
|
+ box-shadow: none !important;
|
|
|
+ }
|
|
|
+ :global(.calendar-override .flatpickr-months) {
|
|
|
+ border-bottom: 1px solid #e5e7eb;
|
|
|
+ }
|
|
|
+ :global(.dark .calendar-override .flatpickr-months) {
|
|
|
+ border-color: #374151;
|
|
|
+ }
|
|
|
+ :global(.calendar-override .flatpickr-current-month .cur-month),
|
|
|
+ :global(.calendar-override .flatpickr-current-month .numInputWrapper input) {
|
|
|
+ color: #111827;
|
|
|
+ font-weight: 600;
|
|
|
+ }
|
|
|
+ :global(.dark .calendar-override .flatpickr-current-month .cur-month),
|
|
|
+ :global(.dark .calendar-override .flatpickr-current-month .numInputWrapper input) {
|
|
|
+ color: #e5e7eb;
|
|
|
+ }
|
|
|
+ :global(.calendar-override .flatpickr-weekday) {
|
|
|
+ color: #6b7280;
|
|
|
+ font-weight: 500;
|
|
|
+ }
|
|
|
+ :global(.dark .calendar-override .flatpickr-weekday) {
|
|
|
+ color: #9ca3af;
|
|
|
+ }
|
|
|
+ :global(.calendar-override .flatpickr-day) {
|
|
|
+ color: #111827;
|
|
|
+ border-radius: 0.375rem;
|
|
|
+ }
|
|
|
+ :global(.dark .calendar-override .flatpickr-day) {
|
|
|
+ color: #e5e7eb;
|
|
|
+ }
|
|
|
+ :global(.calendar-override .flatpickr-day:hover) {
|
|
|
+ background: #f3f4f6;
|
|
|
+ }
|
|
|
+ :global(.dark .calendar-override .flatpickr-day:hover) {
|
|
|
+ background: #374151;
|
|
|
+ }
|
|
|
+ :global(.calendar-override .flatpickr-day.selected),
|
|
|
+ :global(.calendar-override .flatpickr-day.startRange),
|
|
|
+ :global(.calendar-override .flatpickr-day.endRange) {
|
|
|
+ background: #16a34a !important; /* green-600 */
|
|
|
+ color: #ffffff !important;
|
|
|
+ border-color: transparent !important;
|
|
|
+ }
|
|
|
+ :global(.calendar-override .flatpickr-day.selected:hover),
|
|
|
+ :global(.calendar-override .flatpickr-day.startRange:hover),
|
|
|
+ :global(.calendar-override .flatpickr-day.endRange:hover) {
|
|
|
+ background: #15803d !important; /* green-700 */
|
|
|
+ }
|
|
|
+ :global(.calendar-override .flatpickr-day.today) {
|
|
|
+ box-shadow: inset 0 -2px 0 #16a34a;
|
|
|
+ }
|
|
|
+ :global(.calendar-override .flatpickr-day.disabled),
|
|
|
+ :global(.calendar-override .flatpickr-day.prevMonthDay),
|
|
|
+ :global(.calendar-override .flatpickr-day.nextMonthDay) {
|
|
|
+ color: #9ca3af;
|
|
|
+ }
|
|
|
+ :global(.dark .calendar-override .flatpickr-day.disabled),
|
|
|
+ :global(.dark .calendar-override .flatpickr-day.prevMonthDay),
|
|
|
+ :global(.dark .calendar-override .flatpickr-day.nextMonthDay) {
|
|
|
+ color: #6b7280;
|
|
|
+ }
|
|
|
+ :global(.calendar-override .flatpickr-prev-month svg),
|
|
|
+ :global(.calendar-override .flatpickr-next-month svg) {
|
|
|
+ fill: #6b7280;
|
|
|
+ }
|
|
|
+ :global(.calendar-override .flatpickr-prev-month:hover svg),
|
|
|
+ :global(.calendar-override .flatpickr-next-month:hover svg) {
|
|
|
+ fill: #111827;
|
|
|
+ }
|
|
|
+ :global(.dark .calendar-override .flatpickr-prev-month svg),
|
|
|
+ :global(.dark .calendar-override .flatpickr-next-month svg) {
|
|
|
+ fill: #9ca3af;
|
|
|
+ }
|
|
|
+ :global(.dark .calendar-override .flatpickr-prev-month:hover svg),
|
|
|
+ :global(.dark .calendar-override .flatpickr-next-month:hover svg) {
|
|
|
+ fill: #e5e7eb;
|
|
|
+ }
|
|
|
+ :global(.calendar-override .flatpickr-calendar) {
|
|
|
+ width: 100% !important;
|
|
|
+ }
|
|
|
+ :global(.calendar-override .flatpickr-months) {
|
|
|
+ padding: 0.25rem 0.25rem;
|
|
|
+ }
|
|
|
+ :global(.calendar-override .flatpickr-current-month) {
|
|
|
+ font-size: 0.875rem; /* text-sm */
|
|
|
+ }
|
|
|
+ :global(.calendar-override .flatpickr-weekday) {
|
|
|
+ font-size: 0.75rem; /* text-xs */
|
|
|
+ }
|
|
|
+ :global(.calendar-override .dayContainer) {
|
|
|
+ padding: 0.25rem !important;
|
|
|
+ }
|
|
|
+ :global(.calendar-override .flatpickr-day) {
|
|
|
+ width: 1.75rem;
|
|
|
+ height: 1.75rem;
|
|
|
+ line-height: 1.75rem;
|
|
|
+ max-width: 1.75rem;
|
|
|
+ font-size: 0.875rem; /* text-sm */
|
|
|
+ margin: 0.125rem;
|
|
|
+ }
|
|
|
+ :global(.calendar-override .flatpickr-prev-month),
|
|
|
+ :global(.calendar-override .flatpickr-next-month) {
|
|
|
+ top: 0.35rem;
|
|
|
+ }
|
|
|
+ :global(.calendar-override .flatpickr-current-month .numInputWrapper input) {
|
|
|
+ max-width: 3.5rem;
|
|
|
+ }
|
|
|
+ /* Ensure smaller footprint and dark-friendly backgrounds */
|
|
|
+ :global(.calendar-override .flatpickr-calendar) {
|
|
|
+ max-width: none !important;
|
|
|
+ min-width: 0 !important;
|
|
|
+ }
|
|
|
+ :global(.calendar-override .flatpickr-innerContainer),
|
|
|
+ :global(.calendar-override .flatpickr-months),
|
|
|
+ :global(.calendar-override .flatpickr-weekdays),
|
|
|
+ :global(.calendar-override .flatpickr-days) {
|
|
|
+ background: transparent !important;
|
|
|
+ }
|
|
|
+ :global(.calendar-override .flatpickr-days),
|
|
|
+ :global(.calendar-override .dayContainer) {
|
|
|
+ width: auto !important;
|
|
|
+ min-width: 0 !important;
|
|
|
+ }
|
|
|
+ :global(.calendar-override .dayContainer) {
|
|
|
+ padding: 0.125rem !important;
|
|
|
+ }
|
|
|
+ :global(.calendar-override .flatpickr-day) {
|
|
|
+ width: 1.5rem;
|
|
|
+ height: 1.5rem;
|
|
|
+ line-height: 1.5rem;
|
|
|
+ max-width: 1.5rem;
|
|
|
+ font-size: 0.875rem; /* text-sm */
|
|
|
+ margin: 0.1rem;
|
|
|
+ }
|
|
|
+ :global(.calendar-override .flatpickr-prev-month svg),
|
|
|
+ :global(.calendar-override .flatpickr-next-month svg) {
|
|
|
+ width: 0.875rem;
|
|
|
+ height: 0.875rem;
|
|
|
+ }
|
|
|
+ /* Hide top navigation arrows */
|
|
|
+ :global(.calendar-override .flatpickr-prev-month),
|
|
|
+ :global(.calendar-override .flatpickr-next-month) {
|
|
|
+ display: none !important;
|
|
|
+ }
|
|
|
+</style>
|