@hed-hog/finance 0.0.304 → 0.0.306

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -46,8 +46,12 @@ import {
46
46
  SheetHeader,
47
47
  SheetTitle,
48
48
  } from '@/components/ui/sheet';
49
+ import { useFormDraft } from '@/hooks/use-form-draft';
50
+ import { formatDateTime } from '@/lib/format-date';
49
51
  import { useApp, useQuery } from '@hed-hog/next-app-provider';
50
52
  import { zodResolver } from '@hookform/resolvers/zod';
53
+ import { formatDistanceToNow } from 'date-fns';
54
+ import { enUS, ptBR } from 'date-fns/locale';
51
55
  import {
52
56
  Building2,
53
57
  Eye,
@@ -64,8 +68,8 @@ import {
64
68
  } from 'lucide-react';
65
69
  import { useTranslations } from 'next-intl';
66
70
  import Link from 'next/link';
67
- import { useEffect, useRef, useState, type ChangeEvent } from 'react';
68
- import { useForm } from 'react-hook-form';
71
+ import { useEffect, useMemo, useRef, useState, type ChangeEvent } from 'react';
72
+ import { useForm, useWatch } from 'react-hook-form';
69
73
  import { z } from 'zod';
70
74
  import {
71
75
  FinancePageSection,
@@ -103,6 +107,16 @@ type UploadedFilePayload = {
103
107
  id?: number | string | null;
104
108
  };
105
109
 
110
+ type BankAccountDraftPayload = {
111
+ mode: 'create' | 'edit';
112
+ accountId: string | null;
113
+ values: BankAccountFormValues;
114
+ logoFileId: number | null;
115
+ logoPreviewUrl: string | null;
116
+ };
117
+
118
+ const BANK_ACCOUNT_FORM_DRAFT_STORAGE_KEY = 'finance-bank-account-form-draft';
119
+
106
120
  function BankAccountLogo({
107
121
  account,
108
122
  icon: Icon,
@@ -144,13 +158,14 @@ function NovaContaSheet({
144
158
  onEditingAccountChange,
145
159
  }: {
146
160
  t: ReturnType<typeof useTranslations>;
147
- onCreated: () => Promise<any> | void;
161
+ onCreated: () => Promise<unknown> | void;
148
162
  open: boolean;
149
163
  onOpenChange: (open: boolean) => void;
150
164
  editingAccount: BankAccount | null;
151
165
  onEditingAccountChange: (account: BankAccount | null) => void;
152
166
  }) {
153
- const { request, showToastHandler } = useApp();
167
+ const { request, showToastHandler, currentLocaleCode, getSettingValue } =
168
+ useApp();
154
169
 
155
170
  const createSuccessMessage = t.has('messages.createSuccess')
156
171
  ? t('messages.createSuccess')
@@ -201,6 +216,80 @@ function NovaContaSheet({
201
216
  const [isUploadingLogo, setIsUploadingLogo] = useState(false);
202
217
  const [logoUploadProgress, setLogoUploadProgress] = useState(0);
203
218
  const logoInputRef = useRef<HTMLInputElement | null>(null);
219
+ const watchedFormValues = useWatch({
220
+ control: form.control,
221
+ });
222
+
223
+ const hasDraftContent = useMemo(
224
+ () =>
225
+ Boolean(
226
+ (watchedFormValues.banco ?? '').trim() ||
227
+ (watchedFormValues.agencia ?? '').trim() ||
228
+ (watchedFormValues.conta ?? '').trim() ||
229
+ (watchedFormValues.tipo ?? '').trim() ||
230
+ (watchedFormValues.descricao ?? '').trim() ||
231
+ (watchedFormValues.saldoInicial ?? 0) > 0 ||
232
+ logoFileId != null
233
+ ),
234
+ [watchedFormValues, logoFileId]
235
+ );
236
+
237
+ const draftValue = useMemo<BankAccountDraftPayload>(
238
+ () => ({
239
+ mode: editingAccount ? 'edit' : 'create',
240
+ accountId: editingAccount?.id ?? null,
241
+ values: {
242
+ banco: watchedFormValues.banco ?? '',
243
+ agencia: watchedFormValues.agencia ?? '',
244
+ conta: watchedFormValues.conta ?? '',
245
+ tipo: watchedFormValues.tipo ?? '',
246
+ descricao: watchedFormValues.descricao ?? '',
247
+ logoFileId: logoFileId ?? null,
248
+ saldoInicial: watchedFormValues.saldoInicial ?? 0,
249
+ },
250
+ logoFileId: logoFileId ?? null,
251
+ logoPreviewUrl,
252
+ }),
253
+ [editingAccount, logoFileId, logoPreviewUrl, watchedFormValues]
254
+ );
255
+
256
+ const {
257
+ clearDraft,
258
+ loadDraft,
259
+ hasDraft,
260
+ savedAt: draftSavedAt,
261
+ } = useFormDraft<BankAccountDraftPayload>({
262
+ storageKey: BANK_ACCOUNT_FORM_DRAFT_STORAGE_KEY,
263
+ value: draftValue,
264
+ hasData: hasDraftContent,
265
+ enabled: open,
266
+ });
267
+
268
+ const draftStatusContent = useMemo(() => {
269
+ if (!hasDraft || !draftSavedAt) {
270
+ return null;
271
+ }
272
+
273
+ const savedDate = new Date(draftSavedAt);
274
+ if (Number.isNaN(savedDate.getTime())) {
275
+ return null;
276
+ }
277
+
278
+ const locale = currentLocaleCode.startsWith('pt') ? ptBR : enUS;
279
+ const relativeLabel = formatDistanceToNow(savedDate, {
280
+ addSuffix: true,
281
+ locale,
282
+ });
283
+ const absoluteLabel = formatDateTime(
284
+ savedDate,
285
+ getSettingValue,
286
+ currentLocaleCode
287
+ );
288
+
289
+ return currentLocaleCode.startsWith('pt')
290
+ ? `Rascunho salvo ${relativeLabel} • Último salvamento: ${absoluteLabel}`
291
+ : `Draft saved ${relativeLabel} • Last saved: ${absoluteLabel}`;
292
+ }, [draftSavedAt, currentLocaleCode, getSettingValue, hasDraft]);
204
293
 
205
294
  const getLogoUrl = (fileId?: number | null) => {
206
295
  if (typeof fileId !== 'number' || fileId <= 0) {
@@ -342,45 +431,67 @@ function NovaContaSheet({
342
431
  return;
343
432
  }
344
433
 
434
+ const storedDraft = loadDraft();
435
+
345
436
  if (editingAccount) {
346
- const currentLogoFileId = editingAccount.logoFileId ?? null;
437
+ const shouldRestoreDraft =
438
+ storedDraft?.payload.mode === 'edit' &&
439
+ storedDraft.payload.accountId === editingAccount.id;
440
+ const currentLogoFileId = shouldRestoreDraft
441
+ ? storedDraft.payload.logoFileId
442
+ : (editingAccount.logoFileId ?? null);
347
443
 
348
444
  setLogoFileId(currentLogoFileId);
349
- setPersistedLogoFileId(currentLogoFileId);
445
+ setPersistedLogoFileId(editingAccount.logoFileId ?? null);
350
446
  setLogoPreviewUrl(
351
- currentLogoFileId
352
- ? `${getLogoUrl(currentLogoFileId)}?ts=${Date.now()}`
353
- : null
447
+ shouldRestoreDraft
448
+ ? storedDraft.payload.logoPreviewUrl
449
+ : currentLogoFileId
450
+ ? `${getLogoUrl(currentLogoFileId)}?ts=${Date.now()}`
451
+ : null
354
452
  );
355
453
  setLogoUploadProgress(0);
356
454
 
357
- form.reset({
358
- banco: editingAccount.banco,
359
- agencia: editingAccount.agencia === '-' ? '' : editingAccount.agencia,
360
- conta: editingAccount.conta === '-' ? '' : editingAccount.conta,
361
- tipo: editingAccount.tipo,
362
- descricao: editingAccount.descricao,
363
- logoFileId: currentLogoFileId,
364
- saldoInicial: editingAccount.saldoAtual,
365
- });
455
+ form.reset(
456
+ shouldRestoreDraft
457
+ ? storedDraft.payload.values
458
+ : {
459
+ banco: editingAccount.banco,
460
+ agencia:
461
+ editingAccount.agencia === '-' ? '' : editingAccount.agencia,
462
+ conta: editingAccount.conta === '-' ? '' : editingAccount.conta,
463
+ tipo: editingAccount.tipo,
464
+ descricao: editingAccount.descricao,
465
+ logoFileId: currentLogoFileId,
466
+ saldoInicial: editingAccount.saldoAtual,
467
+ }
468
+ );
366
469
  return;
367
470
  }
368
471
 
369
- setLogoFileId(null);
472
+ const shouldRestoreDraft = storedDraft?.payload.mode === 'create';
473
+
474
+ setLogoFileId(shouldRestoreDraft ? storedDraft.payload.logoFileId : null);
370
475
  setPersistedLogoFileId(null);
371
- setLogoPreviewUrl(null);
476
+ setLogoPreviewUrl(
477
+ shouldRestoreDraft ? storedDraft.payload.logoPreviewUrl : null
478
+ );
372
479
  setLogoUploadProgress(0);
373
480
 
374
- form.reset({
375
- banco: '',
376
- agencia: '',
377
- conta: '',
378
- tipo: '',
379
- descricao: '',
380
- logoFileId: null,
381
- saldoInicial: 0,
382
- });
383
- }, [editingAccount, form, open]);
481
+ form.reset(
482
+ shouldRestoreDraft
483
+ ? storedDraft.payload.values
484
+ : {
485
+ banco: '',
486
+ agencia: '',
487
+ conta: '',
488
+ tipo: '',
489
+ descricao: '',
490
+ logoFileId: null,
491
+ saldoInicial: 0,
492
+ }
493
+ );
494
+ }, [editingAccount, form, loadDraft, open]);
384
495
 
385
496
  const handleSubmit = async (values: BankAccountFormValues) => {
386
497
  const nextLogoFileId = values.logoFileId ?? null;
@@ -425,6 +536,7 @@ function NovaContaSheet({
425
536
  await deleteFileById(previousPersistedLogoId);
426
537
  }
427
538
 
539
+ clearDraft();
428
540
  setPersistedLogoFileId(nextLogoFileId);
429
541
  setLogoFileId(nextLogoFileId);
430
542
  setLogoPreviewUrl(
@@ -455,7 +567,9 @@ function NovaContaSheet({
455
567
  };
456
568
 
457
569
  const handleCancel = () => {
458
- void cleanupUnsavedLogo();
570
+ if (!hasDraftContent) {
571
+ void cleanupUnsavedLogo();
572
+ }
459
573
  form.reset();
460
574
  onEditingAccountChange(null);
461
575
  onOpenChange(false);
@@ -465,7 +579,7 @@ function NovaContaSheet({
465
579
  <Sheet
466
580
  open={open}
467
581
  onOpenChange={(nextOpen) => {
468
- if (!nextOpen) {
582
+ if (!nextOpen && !hasDraftContent) {
469
583
  void cleanupUnsavedLogo();
470
584
  }
471
585
 
@@ -696,16 +810,23 @@ function NovaContaSheet({
696
810
  </FinanceSheetSection>
697
811
  </FinanceSheetBody>
698
812
 
699
- <div className="flex justify-end gap-2 border-t px-4 py-4 sm:px-6">
700
- <Button type="button" variant="outline" onClick={handleCancel}>
701
- {t('common.cancel')}
702
- </Button>
703
- <Button
704
- type="submit"
705
- disabled={form.formState.isSubmitting || isUploadingLogo}
706
- >
707
- {t('common.save')}
708
- </Button>
813
+ <div className="border-t px-4 py-4 sm:px-6">
814
+ {draftStatusContent ? (
815
+ <p className="mb-3 text-xs text-muted-foreground">
816
+ {draftStatusContent}
817
+ </p>
818
+ ) : null}
819
+ <div className="flex justify-end gap-2">
820
+ <Button type="button" variant="outline" onClick={handleCancel}>
821
+ {t('common.cancel')}
822
+ </Button>
823
+ <Button
824
+ type="submit"
825
+ disabled={form.formState.isSubmitting || isUploadingLogo}
826
+ >
827
+ {t('common.save')}
828
+ </Button>
829
+ </div>
709
830
  </div>
710
831
  </form>
711
832
  </Form>
@@ -15,7 +15,6 @@ import {
15
15
  import { Badge } from '@/components/ui/badge';
16
16
  import { Button } from '@/components/ui/button';
17
17
  import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
18
- import { KpiCardsGrid } from '@/components/ui/kpi-cards-grid';
19
18
  import { Checkbox } from '@/components/ui/checkbox';
20
19
  import {
21
20
  Form,
@@ -27,6 +26,7 @@ import {
27
26
  } from '@/components/ui/form';
28
27
  import { Input } from '@/components/ui/input';
29
28
  import { InputMoney } from '@/components/ui/input-money';
29
+ import { KpiCardsGrid } from '@/components/ui/kpi-cards-grid';
30
30
  import { Money } from '@/components/ui/money';
31
31
  import {
32
32
  Select,
@@ -43,13 +43,17 @@ import {
43
43
  SheetTitle,
44
44
  } from '@/components/ui/sheet';
45
45
  import { StatusBadge } from '@/components/ui/status-badge';
46
+ import { useFormDraft } from '@/hooks/use-form-draft';
47
+ import { formatDateTime } from '@/lib/format-date';
46
48
  import { useApp, useQuery } from '@hed-hog/next-app-provider';
47
49
  import { zodResolver } from '@hookform/resolvers/zod';
50
+ import { formatDistanceToNow } from 'date-fns';
51
+ import { enUS, ptBR } from 'date-fns/locale';
48
52
  import { Check, DollarSign, Link2, RefreshCw, Trash2 } from 'lucide-react';
49
53
  import { useTranslations } from 'next-intl';
50
54
  import { usePathname, useRouter, useSearchParams } from 'next/navigation';
51
55
  import { useEffect, useMemo, useState } from 'react';
52
- import { useForm } from 'react-hook-form';
56
+ import { useForm, useWatch } from 'react-hook-form';
53
57
  import { z } from 'zod';
54
58
  import { formatarData, formatarMoeda } from '../../_lib/formatters';
55
59
 
@@ -119,6 +123,14 @@ const ajusteSchema = z.object({
119
123
 
120
124
  type AjusteFormValues = z.infer<typeof ajusteSchema>;
121
125
 
126
+ type ReconciliationAdjustmentDraftPayload = {
127
+ bankAccountId: string;
128
+ values: AjusteFormValues;
129
+ };
130
+
131
+ const RECONCILIATION_ADJUSTMENT_DRAFT_STORAGE_KEY =
132
+ 'finance-bank-reconciliation-adjustment-draft';
133
+
122
134
  function CriarAjusteSheet({
123
135
  t,
124
136
  contaFilter,
@@ -128,7 +140,8 @@ function CriarAjusteSheet({
128
140
  contaFilter: string;
129
141
  onCreated: () => Promise<void> | void;
130
142
  }) {
131
- const { request, showToastHandler } = useApp();
143
+ const { request, showToastHandler, currentLocaleCode, getSettingValue } =
144
+ useApp();
132
145
  const [open, setOpen] = useState(false);
133
146
 
134
147
  const form = useForm<AjusteFormValues>({
@@ -140,17 +153,76 @@ function CriarAjusteSheet({
140
153
  },
141
154
  });
142
155
 
156
+ const watchedValues = useWatch({
157
+ control: form.control,
158
+ });
159
+
160
+ const {
161
+ clearDraft,
162
+ loadDraft,
163
+ hasDraft,
164
+ savedAt: draftSavedAt,
165
+ } = useFormDraft<ReconciliationAdjustmentDraftPayload>({
166
+ storageKey: RECONCILIATION_ADJUSTMENT_DRAFT_STORAGE_KEY,
167
+ value: {
168
+ bankAccountId: contaFilter,
169
+ values: {
170
+ type: watchedValues.type ?? '',
171
+ value: watchedValues.value ?? 0,
172
+ description: watchedValues.description ?? '',
173
+ },
174
+ },
175
+ hasData: Boolean(
176
+ (watchedValues.type ?? '').trim() ||
177
+ (watchedValues.description ?? '').trim() ||
178
+ (watchedValues.value ?? 0) > 0
179
+ ),
180
+ enabled: open,
181
+ });
182
+
183
+ const draftStatusContent = useMemo(() => {
184
+ if (!hasDraft || !draftSavedAt) {
185
+ return null;
186
+ }
187
+
188
+ const savedDate = new Date(draftSavedAt);
189
+ if (Number.isNaN(savedDate.getTime())) {
190
+ return null;
191
+ }
192
+
193
+ const locale = currentLocaleCode.startsWith('pt') ? ptBR : enUS;
194
+ const relativeLabel = formatDistanceToNow(savedDate, {
195
+ addSuffix: true,
196
+ locale,
197
+ });
198
+ const absoluteLabel = formatDateTime(
199
+ savedDate,
200
+ getSettingValue,
201
+ currentLocaleCode
202
+ );
203
+
204
+ return currentLocaleCode.startsWith('pt')
205
+ ? `Rascunho salvo ${relativeLabel} • Último salvamento: ${absoluteLabel}`
206
+ : `Draft saved ${relativeLabel} • Last saved: ${absoluteLabel}`;
207
+ }, [draftSavedAt, currentLocaleCode, getSettingValue, hasDraft]);
208
+
143
209
  useEffect(() => {
144
210
  if (!open) {
145
211
  return;
146
212
  }
147
213
 
148
- form.reset({
149
- type: '',
150
- value: 0,
151
- description: '',
152
- });
153
- }, [form, open]);
214
+ const storedDraft = loadDraft();
215
+
216
+ form.reset(
217
+ storedDraft?.payload.bankAccountId === contaFilter
218
+ ? storedDraft.payload.values
219
+ : {
220
+ type: '',
221
+ value: 0,
222
+ description: '',
223
+ }
224
+ );
225
+ }, [contaFilter, form, loadDraft, open]);
154
226
 
155
227
  const handleSubmit = async (values: AjusteFormValues) => {
156
228
  if (!contaFilter) {
@@ -170,6 +242,7 @@ function CriarAjusteSheet({
170
242
  },
171
243
  });
172
244
 
245
+ clearDraft();
173
246
  await onCreated();
174
247
  showToastHandler?.('success', 'Ajuste criado com sucesso');
175
248
  setOpen(false);
@@ -267,6 +340,12 @@ function CriarAjusteSheet({
267
340
  )}
268
341
  />
269
342
 
343
+ {draftStatusContent ? (
344
+ <p className="text-xs text-muted-foreground">
345
+ {draftStatusContent}
346
+ </p>
347
+ ) : null}
348
+
270
349
  <div className="flex justify-end gap-2 pt-4">
271
350
  <Button
272
351
  type="button"
@@ -294,7 +373,9 @@ export default function ConciliacaoPage() {
294
373
  const searchParams = useSearchParams();
295
374
  const bankAccountIdFromUrl = searchParams.get('bank_account_id');
296
375
 
297
- const [contaFilter, setContaFilter] = useState<string>('');
376
+ const [contaFilter, setContaFilter] = useState<string>(
377
+ () => bankAccountIdFromUrl || ''
378
+ );
298
379
  const [selectedExtrato, setSelectedExtrato] = useState<string | null>(null);
299
380
  const [selectedTitulo, setSelectedTitulo] = useState<string | null>(null);
300
381
  const [reconciliationToUndo, setReconciliationToUndo] = useState<
@@ -313,50 +394,50 @@ export default function ConciliacaoPage() {
313
394
  },
314
395
  });
315
396
 
316
- useEffect(() => {
397
+ const activeContaFilter = useMemo(() => {
317
398
  const firstAccount = contasBancarias[0];
318
399
 
319
400
  if (!firstAccount) {
320
- return;
401
+ return '';
321
402
  }
322
403
 
323
- const hasAccountFromUrl =
324
- !!bankAccountIdFromUrl &&
325
- contasBancarias.some((account) => account.id === bankAccountIdFromUrl);
326
-
327
- const nextAccountId = hasAccountFromUrl
328
- ? (bankAccountIdFromUrl as string)
329
- : firstAccount.id;
404
+ if (
405
+ contaFilter &&
406
+ contasBancarias.some((account) => account.id === contaFilter)
407
+ ) {
408
+ return contaFilter;
409
+ }
330
410
 
331
- if (contaFilter !== nextAccountId) {
332
- setContaFilter(nextAccountId);
411
+ if (
412
+ bankAccountIdFromUrl &&
413
+ contasBancarias.some((account) => account.id === bankAccountIdFromUrl)
414
+ ) {
415
+ return bankAccountIdFromUrl;
333
416
  }
334
417
 
335
- if (bankAccountIdFromUrl !== nextAccountId) {
336
- const params = new URLSearchParams(searchParams.toString());
337
- params.set('bank_account_id', nextAccountId);
338
- router.replace(`${pathname}?${params.toString()}`);
418
+ return firstAccount.id;
419
+ }, [bankAccountIdFromUrl, contaFilter, contasBancarias]);
420
+
421
+ useEffect(() => {
422
+ if (!activeContaFilter || bankAccountIdFromUrl === activeContaFilter) {
423
+ return;
339
424
  }
340
- }, [
341
- bankAccountIdFromUrl,
342
- contaFilter,
343
- contasBancarias,
344
- pathname,
345
- router,
346
- searchParams,
347
- ]);
348
425
 
426
+ const params = new URLSearchParams(searchParams.toString());
427
+ params.set('bank_account_id', activeContaFilter);
428
+ router.replace(`${pathname}?${params.toString()}`);
429
+ }, [activeContaFilter, bankAccountIdFromUrl, pathname, router, searchParams]);
349
430
  const { data: extratos = [], refetch: refetchExtratos } = useQuery<
350
431
  Statement[]
351
432
  >({
352
- queryKey: ['finance-statements', contaFilter],
433
+ queryKey: ['finance-statements', activeContaFilter],
353
434
  queryFn: async () => {
354
- if (!contaFilter) {
435
+ if (!activeContaFilter) {
355
436
  return [];
356
437
  }
357
438
 
358
439
  const response = await request({
359
- url: `/finance/statements?bank_account_id=${contaFilter}`,
440
+ url: `/finance/statements?bank_account_id=${activeContaFilter}`,
360
441
  method: 'GET',
361
442
  });
362
443
 
@@ -366,9 +447,9 @@ export default function ConciliacaoPage() {
366
447
 
367
448
  const { data: reconciliationSummary, refetch: refetchReconciliationSummary } =
368
449
  useQuery<BankReconciliationSummary>({
369
- queryKey: ['finance-bank-reconciliation-summary', contaFilter],
450
+ queryKey: ['finance-bank-reconciliation-summary', activeContaFilter],
370
451
  queryFn: async () => {
371
- if (!contaFilter) {
452
+ if (!activeContaFilter) {
372
453
  return {
373
454
  discrepancies: 0,
374
455
  difference: 0,
@@ -376,7 +457,7 @@ export default function ConciliacaoPage() {
376
457
  }
377
458
 
378
459
  const response = await request<BankReconciliationSummary>({
379
- url: `/finance/bank-reconciliation/summary?bank_account_id=${contaFilter}`,
460
+ url: `/finance/bank-reconciliation/summary?bank_account_id=${activeContaFilter}`,
380
461
  method: 'GET',
381
462
  });
382
463
 
@@ -427,10 +508,10 @@ export default function ConciliacaoPage() {
427
508
  );
428
509
 
429
510
  const extratosFiltered = extratosPendentes.filter(
430
- (e) => e.contaBancariaId === contaFilter
511
+ (e) => e.contaBancariaId === activeContaFilter
431
512
  );
432
513
  const extratosConciliadosFiltered = extratosConciliados.filter(
433
- (e) => e.contaBancariaId === contaFilter
514
+ (e) => e.contaBancariaId === activeContaFilter
434
515
  );
435
516
 
436
517
  const titulosAbertos = useMemo<OpenTitleItem[]>(() => {
@@ -480,24 +561,21 @@ export default function ConciliacaoPage() {
480
561
  (titulo) => titulo.id === selectedTitulo
481
562
  );
482
563
 
483
- const titulosCompativeis = useMemo(() => {
484
- if (!selectedExtratoItem) {
485
- return titulosAbertos;
486
- }
487
-
488
- return titulosAbertos.filter((titulo) =>
489
- selectedExtratoItem.tipo === 'saida'
490
- ? titulo.tipo === 'pagar'
491
- : titulo.tipo === 'receber'
492
- );
493
- }, [selectedExtratoItem, titulosAbertos]);
564
+ const titulosCompativeis = !selectedExtratoItem
565
+ ? titulosAbertos
566
+ : titulosAbertos.filter((titulo) =>
567
+ selectedExtratoItem.tipo === 'saida'
568
+ ? titulo.tipo === 'pagar'
569
+ : titulo.tipo === 'receber'
570
+ );
494
571
 
495
572
  const totalConciliado = extratos.filter(
496
573
  (e) =>
497
- e.contaBancariaId === contaFilter && e.statusConciliacao === 'conciliado'
574
+ e.contaBancariaId === activeContaFilter &&
575
+ e.statusConciliacao === 'conciliado'
498
576
  ).length;
499
577
  const totalExtratoConta = extratos.filter(
500
- (e) => e.contaBancariaId === contaFilter
578
+ (e) => e.contaBancariaId === activeContaFilter
501
579
  ).length;
502
580
  const percentualConciliado =
503
581
  totalExtratoConta > 0
@@ -557,7 +635,7 @@ export default function ConciliacaoPage() {
557
635
  };
558
636
 
559
637
  const handleReconcile = async () => {
560
- if (!selectedExtratoItem || !selectedTituloItem || !contaFilter) {
638
+ if (!selectedExtratoItem || !selectedTituloItem || !activeContaFilter) {
561
639
  return;
562
640
  }
563
641
 
@@ -618,7 +696,7 @@ export default function ConciliacaoPage() {
618
696
 
619
697
  <div className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
620
698
  <Select
621
- value={contaFilter}
699
+ value={activeContaFilter}
622
700
  onValueChange={(value) => {
623
701
  setContaFilter(value);
624
702
  setSelectedExtrato(null);
@@ -644,7 +722,7 @@ export default function ConciliacaoPage() {
644
722
  <div className="flex gap-2">
645
723
  <CriarAjusteSheet
646
724
  t={t}
647
- contaFilter={contaFilter}
725
+ contaFilter={activeContaFilter}
648
726
  onCreated={handleRefreshData}
649
727
  />
650
728
  <Button