@hed-hog/finance 0.0.328 → 0.0.330
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.
- package/hedhog/frontend/app/_components/category-picker-field.tsx.ejs +3 -0
- package/hedhog/frontend/app/_components/cost-center-picker-field.tsx.ejs +3 -0
- package/hedhog/frontend/app/_components/finance-entity-field-with-create.tsx.ejs +9 -4
- package/hedhog/frontend/app/_components/finance-picker.tsx.ejs +242 -0
- package/hedhog/frontend/app/accounts-payable/approvals/page.tsx.ejs +18 -15
- package/hedhog/frontend/app/accounts-payable/installments/page.tsx.ejs +13 -19
- package/hedhog/frontend/app/accounts-receivable/collections-default/page.tsx.ejs +4 -8
- package/hedhog/frontend/app/accounts-receivable/installments/page.tsx.ejs +13 -19
- package/hedhog/frontend/app/administration/audit-logs/page.tsx.ejs +10 -4
- package/hedhog/frontend/app/administration/categories/page.tsx.ejs +3 -5
- package/hedhog/frontend/app/administration/cost-centers/page.tsx.ejs +3 -5
- package/hedhog/frontend/app/administration/currencies/page.tsx.ejs +3 -5
- package/hedhog/frontend/app/administration/period-close/page.tsx.ejs +3 -5
- package/hedhog/frontend/app/cash-and-banks/bank-accounts/page.tsx.ejs +48 -72
- package/hedhog/frontend/app/cash-and-banks/bank-reconciliation/page.tsx.ejs +7 -9
- package/hedhog/frontend/app/cash-and-banks/statements/page.tsx.ejs +91 -73
- package/hedhog/frontend/app/cash-and-banks/transfers/page.tsx.ejs +33 -25
- package/hedhog/frontend/app/planning/scenarios/page.tsx.ejs +2 -2
- package/hedhog/frontend/app/reports/actual-vs-forecast/page.tsx.ejs +3 -1
- package/hedhog/frontend/app/reports/aging-default/page.tsx.ejs +3 -1
- package/hedhog/frontend/app/reports/cash-position/page.tsx.ejs +3 -1
- package/hedhog/frontend/app/reports/overview-results/page.tsx.ejs +15 -8
- package/hedhog/frontend/app/reports/top-customers/page.tsx.ejs +9 -5
- package/hedhog/frontend/app/reports/top-operational-expenses/page.tsx.ejs +9 -5
- package/hedhog/frontend/messages/en.json +110 -2
- package/hedhog/frontend/messages/pt.json +92 -2
- package/package.json +4 -4
|
@@ -141,10 +141,8 @@ function CurrencySheet({
|
|
|
141
141
|
getSettingValue,
|
|
142
142
|
currentLocaleCode
|
|
143
143
|
);
|
|
144
|
-
return
|
|
145
|
-
|
|
146
|
-
: `Draft saved ${relativeLabel} • Last saved: ${absoluteLabel}`;
|
|
147
|
-
}, [draftSavedAt, currentLocaleCode, getSettingValue, hasDraft]);
|
|
144
|
+
return t('draftStatus', { relativeLabel, absoluteLabel });
|
|
145
|
+
}, [draftSavedAt, currentLocaleCode, getSettingValue, hasDraft, t]);
|
|
148
146
|
|
|
149
147
|
useEffect(() => {
|
|
150
148
|
if (!open) return;
|
|
@@ -225,7 +223,7 @@ function CurrencySheet({
|
|
|
225
223
|
|
|
226
224
|
return (
|
|
227
225
|
<Sheet open={open} onOpenChange={handleOpenChange}>
|
|
228
|
-
<SheetContent className="w-full overflow-y-auto sm:max-w-lg">
|
|
226
|
+
<SheetContent className="w-full overflow-y-auto sm:max-w-lg">
|
|
229
227
|
<SheetHeader>
|
|
230
228
|
<SheetTitle>
|
|
231
229
|
{editingCurrency ? t('sheet.editTitle') : t('sheet.newTitle')}
|
|
@@ -160,10 +160,8 @@ function ClosePeriodSheet({
|
|
|
160
160
|
currentLocaleCode
|
|
161
161
|
);
|
|
162
162
|
|
|
163
|
-
return
|
|
164
|
-
|
|
165
|
-
: `Draft saved ${relativeLabel} • Last saved: ${absoluteLabel}`;
|
|
166
|
-
}, [draftSavedAt, currentLocaleCode, getSettingValue, hasDraft]);
|
|
163
|
+
return t('draftStatus', { relativeLabel, absoluteLabel });
|
|
164
|
+
}, [draftSavedAt, currentLocaleCode, getSettingValue, hasDraft, t]);
|
|
167
165
|
|
|
168
166
|
useEffect(() => {
|
|
169
167
|
if (!open) {
|
|
@@ -212,7 +210,7 @@ function ClosePeriodSheet({
|
|
|
212
210
|
onOpenChange(nextOpen);
|
|
213
211
|
}}
|
|
214
212
|
>
|
|
215
|
-
<SheetContent className="w-full overflow-y-auto sm:max-w-lg">
|
|
213
|
+
<SheetContent className="w-full overflow-y-auto sm:max-w-lg">
|
|
216
214
|
<SheetHeader>
|
|
217
215
|
<SheetTitle>{t('sheet.title')}</SheetTitle>
|
|
218
216
|
<SheetDescription>{t('sheet.description')}</SheetDescription>
|
|
@@ -82,19 +82,22 @@ import {
|
|
|
82
82
|
FinanceSheetSection,
|
|
83
83
|
} from '../../_components/finance-layout';
|
|
84
84
|
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
85
|
+
const createBankAccountFormSchema = (t: ReturnType<typeof useTranslations>) =>
|
|
86
|
+
z.object({
|
|
87
|
+
banco: z.string().trim().min(1, t('validation.bankRequired')),
|
|
88
|
+
agencia: z.string().optional(),
|
|
89
|
+
conta: z.string().optional(),
|
|
90
|
+
tipo: z.string().min(1, t('validation.typeRequired')),
|
|
91
|
+
descricao: z.string().optional(),
|
|
92
|
+
logoFileId: z.number().int().nullable().optional(),
|
|
93
|
+
currencyId: z.number().int().nullable().optional(),
|
|
94
|
+
dataInicial: z.string().optional(),
|
|
95
|
+
saldoInicial: z.number().min(0, t('validation.initialBalanceInvalid')),
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
type BankAccountFormValues = z.infer<
|
|
99
|
+
ReturnType<typeof createBankAccountFormSchema>
|
|
100
|
+
>;
|
|
98
101
|
|
|
99
102
|
type Currency = {
|
|
100
103
|
id: string;
|
|
@@ -226,36 +229,18 @@ function NovaContaSheet({
|
|
|
226
229
|
});
|
|
227
230
|
const currencies = currenciesData || [];
|
|
228
231
|
|
|
229
|
-
const createSuccessMessage = t
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
const
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
const
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
const updateErrorMessage = t.has('messages.updateError')
|
|
239
|
-
? t('messages.updateError')
|
|
240
|
-
: 'Erro ao atualizar conta bancária';
|
|
241
|
-
const logoUploadSuccessMessage = t.has('messages.logoUploadSuccess')
|
|
242
|
-
? t('messages.logoUploadSuccess')
|
|
243
|
-
: 'Logo enviado com sucesso';
|
|
244
|
-
const logoUploadErrorMessage = t.has('messages.logoUploadError')
|
|
245
|
-
? t('messages.logoUploadError')
|
|
246
|
-
: 'Erro ao enviar logo';
|
|
247
|
-
const logoRemoveSuccessMessage = t.has('messages.logoRemoveSuccess')
|
|
248
|
-
? t('messages.logoRemoveSuccess')
|
|
249
|
-
: 'Logo removido com sucesso';
|
|
250
|
-
const logoInvalidTypeMessage = t.has('messages.logoInvalidType')
|
|
251
|
-
? t('messages.logoInvalidType')
|
|
252
|
-
: 'Selecione um arquivo de imagem válido';
|
|
253
|
-
const logoTooLargeMessage = t.has('messages.logoTooLarge')
|
|
254
|
-
? t('messages.logoTooLarge')
|
|
255
|
-
: 'O logo deve ter no máximo 5 MB';
|
|
232
|
+
const createSuccessMessage = t('messages.createSuccess');
|
|
233
|
+
const createErrorMessage = t('messages.createError');
|
|
234
|
+
const updateSuccessMessage = t('messages.updateSuccess');
|
|
235
|
+
const updateErrorMessage = t('messages.updateError');
|
|
236
|
+
const logoUploadSuccessMessage = t('messages.logoUploadSuccess');
|
|
237
|
+
const logoUploadErrorMessage = t('messages.logoUploadError');
|
|
238
|
+
const logoRemoveSuccessMessage = t('messages.logoRemoveSuccess');
|
|
239
|
+
const logoInvalidTypeMessage = t('messages.logoInvalidType');
|
|
240
|
+
const logoTooLargeMessage = t('messages.logoTooLarge');
|
|
256
241
|
|
|
257
242
|
const form = useForm<BankAccountFormValues>({
|
|
258
|
-
resolver: zodResolver(
|
|
243
|
+
resolver: zodResolver(createBankAccountFormSchema(t)),
|
|
259
244
|
defaultValues: {
|
|
260
245
|
banco: '',
|
|
261
246
|
agencia: '',
|
|
@@ -354,10 +339,11 @@ function NovaContaSheet({
|
|
|
354
339
|
currentLocaleCode
|
|
355
340
|
);
|
|
356
341
|
|
|
357
|
-
return
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
342
|
+
return t('draftStatus', {
|
|
343
|
+
relativeLabel,
|
|
344
|
+
absoluteLabel,
|
|
345
|
+
});
|
|
346
|
+
}, [draftSavedAt, currentLocaleCode, getSettingValue, hasDraft, t]);
|
|
361
347
|
|
|
362
348
|
const getLogoUrl = (fileId?: number | null) => {
|
|
363
349
|
if (typeof fileId !== 'number' || fileId <= 0) {
|
|
@@ -839,35 +825,35 @@ function NovaContaSheet({
|
|
|
839
825
|
<EntityPicker<Currency>
|
|
840
826
|
form={form as never}
|
|
841
827
|
name="currencyId"
|
|
842
|
-
label=
|
|
843
|
-
placeholder=
|
|
844
|
-
searchPlaceholder=
|
|
845
|
-
entityLabel=
|
|
828
|
+
label={t('fields.currency')}
|
|
829
|
+
placeholder={t('fields.currencyPlaceholder')}
|
|
830
|
+
searchPlaceholder={t('fields.currencySearchPlaceholder')}
|
|
831
|
+
entityLabel={t('fields.currencyEntityLabel')}
|
|
846
832
|
valueType="number"
|
|
847
833
|
clearable
|
|
848
834
|
options={currencies}
|
|
849
835
|
getOptionValue={(c) => c.id}
|
|
850
836
|
getOptionLabel={(c) => `${c.symbol} ${c.code} — ${c.name}`}
|
|
851
|
-
createTitle=
|
|
852
|
-
createDescription=
|
|
837
|
+
createTitle={t('fields.currencyCreateTitle')}
|
|
838
|
+
createDescription={t('fields.currencyCreateDescription')}
|
|
853
839
|
mapSearchToCreateValues={(s) => ({ code: s.toUpperCase() })}
|
|
854
840
|
createFields={[
|
|
855
841
|
{
|
|
856
842
|
name: 'code',
|
|
857
|
-
label: '
|
|
858
|
-
placeholder: '
|
|
843
|
+
label: t('fields.currencyCode'),
|
|
844
|
+
placeholder: t('fields.currencyCodePlaceholder'),
|
|
859
845
|
required: true,
|
|
860
846
|
},
|
|
861
847
|
{
|
|
862
848
|
name: 'name',
|
|
863
|
-
label: '
|
|
864
|
-
placeholder: '
|
|
849
|
+
label: t('fields.currencyName'),
|
|
850
|
+
placeholder: t('fields.currencyNamePlaceholder'),
|
|
865
851
|
required: true,
|
|
866
852
|
},
|
|
867
853
|
{
|
|
868
854
|
name: 'symbol',
|
|
869
|
-
label: '
|
|
870
|
-
placeholder: '
|
|
855
|
+
label: t('fields.currencySymbol'),
|
|
856
|
+
placeholder: t('fields.currencySymbolPlaceholder'),
|
|
871
857
|
required: true,
|
|
872
858
|
},
|
|
873
859
|
]}
|
|
@@ -1004,21 +990,11 @@ export default function ContasBancariasPage() {
|
|
|
1004
990
|
const t = useTranslations('finance.BankAccountsPage');
|
|
1005
991
|
const { request, showToastHandler, currentLocaleCode } = useApp();
|
|
1006
992
|
|
|
1007
|
-
const deleteSuccessMessage = t
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
const
|
|
1011
|
-
|
|
1012
|
-
: 'Erro ao inativar conta bancária';
|
|
1013
|
-
const deleteDialogTitle = t.has('deleteDialog.title')
|
|
1014
|
-
? t('deleteDialog.title')
|
|
1015
|
-
: 'Inativar conta bancária';
|
|
1016
|
-
const deleteDialogDescription = t.has('deleteDialog.description')
|
|
1017
|
-
? t('deleteDialog.description')
|
|
1018
|
-
: 'Deseja realmente inativar esta conta bancária?';
|
|
1019
|
-
const deleteDialogConfirm = t.has('deleteDialog.confirm')
|
|
1020
|
-
? t('deleteDialog.confirm')
|
|
1021
|
-
: 'Inativar';
|
|
993
|
+
const deleteSuccessMessage = t('messages.deleteSuccess');
|
|
994
|
+
const deleteErrorMessage = t('messages.deleteError');
|
|
995
|
+
const deleteDialogTitle = t('deleteDialog.title');
|
|
996
|
+
const deleteDialogDescription = t('deleteDialog.description');
|
|
997
|
+
const deleteDialogConfirm = t('deleteDialog.confirm');
|
|
1022
998
|
|
|
1023
999
|
const [sheetOpen, setSheetOpen] = useState(false);
|
|
1024
1000
|
const [editingAccount, setEditingAccount] = useState<BankAccount | null>(
|
|
@@ -201,10 +201,8 @@ function CriarAjusteSheet({
|
|
|
201
201
|
currentLocaleCode
|
|
202
202
|
);
|
|
203
203
|
|
|
204
|
-
return
|
|
205
|
-
|
|
206
|
-
: `Draft saved ${relativeLabel} • Last saved: ${absoluteLabel}`;
|
|
207
|
-
}, [draftSavedAt, currentLocaleCode, getSettingValue, hasDraft]);
|
|
204
|
+
return t('draftStatus', { relativeLabel, absoluteLabel });
|
|
205
|
+
}, [draftSavedAt, currentLocaleCode, getSettingValue, hasDraft, t]);
|
|
208
206
|
|
|
209
207
|
useEffect(() => {
|
|
210
208
|
if (!open) {
|
|
@@ -226,7 +224,7 @@ function CriarAjusteSheet({
|
|
|
226
224
|
|
|
227
225
|
const handleSubmit = async (values: AjusteFormValues) => {
|
|
228
226
|
if (!contaFilter) {
|
|
229
|
-
showToastHandler?.('error', '
|
|
227
|
+
showToastHandler?.('error', t('messages.selectBankAccount'));
|
|
230
228
|
return;
|
|
231
229
|
}
|
|
232
230
|
|
|
@@ -244,10 +242,10 @@ function CriarAjusteSheet({
|
|
|
244
242
|
|
|
245
243
|
clearDraft();
|
|
246
244
|
await onCreated();
|
|
247
|
-
showToastHandler?.('success', '
|
|
245
|
+
showToastHandler?.('success', t('messages.createAdjustmentSuccess'));
|
|
248
246
|
setOpen(false);
|
|
249
247
|
} catch {
|
|
250
|
-
showToastHandler?.('error', '
|
|
248
|
+
showToastHandler?.('error', t('messages.createAdjustmentError'));
|
|
251
249
|
}
|
|
252
250
|
};
|
|
253
251
|
|
|
@@ -677,9 +675,9 @@ export default function ConciliacaoPage() {
|
|
|
677
675
|
setSelectedExtrato(null);
|
|
678
676
|
setSelectedTitulo(null);
|
|
679
677
|
await handleRefreshData();
|
|
680
|
-
showToastHandler?.('success', '
|
|
678
|
+
showToastHandler?.('success', t('messages.reconcileSuccess'));
|
|
681
679
|
} catch {
|
|
682
|
-
showToastHandler?.('error', '
|
|
680
|
+
showToastHandler?.('error', t('messages.reconcileError'));
|
|
683
681
|
}
|
|
684
682
|
};
|
|
685
683
|
|
|
@@ -118,38 +118,46 @@ type PaginatedStatementsResponse = {
|
|
|
118
118
|
};
|
|
119
119
|
};
|
|
120
120
|
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
type StatementEntryFormValues = z.infer<typeof statementEntrySchema>;
|
|
129
|
-
|
|
130
|
-
const bankAccountFormSchema = z.object({
|
|
131
|
-
banco: z.string().trim().min(1, 'Banco é obrigatório'),
|
|
132
|
-
agencia: z.string().optional(),
|
|
133
|
-
conta: z.string().optional(),
|
|
134
|
-
tipo: z.string().min(1, 'Tipo é obrigatório'),
|
|
135
|
-
descricao: z.string().optional(),
|
|
136
|
-
dataInicial: z.string().optional(),
|
|
137
|
-
saldoInicial: z.number().min(0, 'Saldo inicial inválido'),
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
const importStatementSchema = z.object({
|
|
141
|
-
bankAccountId: z.string().trim().min(1, 'Conta bancária é obrigatória'),
|
|
142
|
-
file: z.instanceof(File, { message: 'Arquivo é obrigatório' }).refine(
|
|
143
|
-
(value) => {
|
|
144
|
-
const fileName = value.name.toLowerCase();
|
|
145
|
-
return fileName.endsWith('.csv') || fileName.endsWith('.ofx');
|
|
146
|
-
},
|
|
147
|
-
{ message: 'Apenas arquivos CSV ou OFX são permitidos' }
|
|
148
|
-
),
|
|
149
|
-
});
|
|
121
|
+
const createStatementEntrySchema = (t: ReturnType<typeof useTranslations>) =>
|
|
122
|
+
z.object({
|
|
123
|
+
date: z.string().trim().min(1, t('formErrors.dateRequired')),
|
|
124
|
+
description: z.string().trim().min(1, t('formErrors.descriptionRequired')),
|
|
125
|
+
type: z.enum(['entrada', 'saida']),
|
|
126
|
+
amount: z.number().min(0.01, t('formErrors.amountMustBePositive')),
|
|
127
|
+
});
|
|
150
128
|
|
|
151
|
-
type
|
|
152
|
-
|
|
129
|
+
type StatementEntryFormValues = z.infer<ReturnType<typeof createStatementEntrySchema>>;
|
|
130
|
+
|
|
131
|
+
const createBankAccountFormSchema = (
|
|
132
|
+
tBank: ReturnType<typeof useTranslations>
|
|
133
|
+
) =>
|
|
134
|
+
z.object({
|
|
135
|
+
banco: z.string().trim().min(1, tBank('validation.bankRequired')),
|
|
136
|
+
agencia: z.string().optional(),
|
|
137
|
+
conta: z.string().optional(),
|
|
138
|
+
tipo: z.string().min(1, tBank('validation.typeRequired')),
|
|
139
|
+
descricao: z.string().optional(),
|
|
140
|
+
dataInicial: z.string().optional(),
|
|
141
|
+
saldoInicial: z.number().min(0, tBank('validation.initialBalanceInvalid')),
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
const createImportStatementSchema = (t: ReturnType<typeof useTranslations>) =>
|
|
145
|
+
z.object({
|
|
146
|
+
bankAccountId: z
|
|
147
|
+
.string()
|
|
148
|
+
.trim()
|
|
149
|
+
.min(1, t('formErrors.bankAccountRequired')),
|
|
150
|
+
file: z.instanceof(File, { message: t('formErrors.fileRequired') }).refine(
|
|
151
|
+
(value) => {
|
|
152
|
+
const fileName = value.name.toLowerCase();
|
|
153
|
+
return fileName.endsWith('.csv') || fileName.endsWith('.ofx');
|
|
154
|
+
},
|
|
155
|
+
{ message: t('formErrors.fileTypeNotAllowed') }
|
|
156
|
+
),
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
type ImportStatementFormValues = z.infer<ReturnType<typeof createImportStatementSchema>>;
|
|
160
|
+
type BankAccountFormValues = z.infer<ReturnType<typeof createBankAccountFormSchema>>;
|
|
153
161
|
|
|
154
162
|
type StatementBankAccountDraftPayload = {
|
|
155
163
|
values: BankAccountFormValues;
|
|
@@ -180,7 +188,7 @@ function NovaContaBancariaSheet({
|
|
|
180
188
|
useApp();
|
|
181
189
|
|
|
182
190
|
const form = useForm<BankAccountFormValues>({
|
|
183
|
-
resolver: zodResolver(
|
|
191
|
+
resolver: zodResolver(createBankAccountFormSchema(tBank)),
|
|
184
192
|
defaultValues: {
|
|
185
193
|
banco: '',
|
|
186
194
|
agencia: '',
|
|
@@ -250,10 +258,11 @@ function NovaContaBancariaSheet({
|
|
|
250
258
|
currentLocaleCode
|
|
251
259
|
);
|
|
252
260
|
|
|
253
|
-
return
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
261
|
+
return tBank('draftStatus', {
|
|
262
|
+
relativeLabel,
|
|
263
|
+
absoluteLabel,
|
|
264
|
+
});
|
|
265
|
+
}, [draftSavedAt, currentLocaleCode, getSettingValue, hasDraft, tBank]);
|
|
257
266
|
|
|
258
267
|
useEffect(() => {
|
|
259
268
|
if (!open) {
|
|
@@ -534,7 +543,7 @@ function ImportarExtratoSheet({
|
|
|
534
543
|
};
|
|
535
544
|
|
|
536
545
|
const form = useForm<ImportStatementFormValues>({
|
|
537
|
-
resolver: zodResolver(
|
|
546
|
+
resolver: zodResolver(createImportStatementSchema(t)),
|
|
538
547
|
defaultValues: {
|
|
539
548
|
bankAccountId: defaultBankAccountId || '',
|
|
540
549
|
},
|
|
@@ -585,10 +594,11 @@ function ImportarExtratoSheet({
|
|
|
585
594
|
currentLocaleCode
|
|
586
595
|
);
|
|
587
596
|
|
|
588
|
-
return
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
597
|
+
return t('draftStatus', {
|
|
598
|
+
relativeLabel,
|
|
599
|
+
absoluteLabel,
|
|
600
|
+
});
|
|
601
|
+
}, [draftSavedAt, currentLocaleCode, getSettingValue, hasDraft, t]);
|
|
592
602
|
|
|
593
603
|
useEffect(() => {
|
|
594
604
|
if (!isOpen) {
|
|
@@ -618,10 +628,10 @@ function ImportarExtratoSheet({
|
|
|
618
628
|
|
|
619
629
|
clearDraft();
|
|
620
630
|
await onImported();
|
|
621
|
-
showToastHandler?.('success', '
|
|
631
|
+
showToastHandler?.('success', t('messages.importSuccess'));
|
|
622
632
|
handleOpenChange(false);
|
|
623
633
|
} catch {
|
|
624
|
-
showToastHandler?.('error', '
|
|
634
|
+
showToastHandler?.('error', t('messages.importError'));
|
|
625
635
|
}
|
|
626
636
|
};
|
|
627
637
|
|
|
@@ -676,7 +686,7 @@ function ImportarExtratoSheet({
|
|
|
676
686
|
variant="outline"
|
|
677
687
|
size="icon"
|
|
678
688
|
onClick={() => setOpenNovaContaSheet(true)}
|
|
679
|
-
aria-label=
|
|
689
|
+
aria-label={t('aria.newBankAccount')}
|
|
680
690
|
>
|
|
681
691
|
<Plus className="h-4 w-4" />
|
|
682
692
|
</Button>
|
|
@@ -751,11 +761,13 @@ function ImportarExtratoSheet({
|
|
|
751
761
|
}
|
|
752
762
|
|
|
753
763
|
function NovoLancamentoSheet({
|
|
764
|
+
t,
|
|
754
765
|
open,
|
|
755
766
|
onOpenChange,
|
|
756
767
|
bankAccountId,
|
|
757
768
|
onCreated,
|
|
758
769
|
}: {
|
|
770
|
+
t: ReturnType<typeof useTranslations>;
|
|
759
771
|
open: boolean;
|
|
760
772
|
onOpenChange: (open: boolean) => void;
|
|
761
773
|
bankAccountId?: string;
|
|
@@ -763,7 +775,7 @@ function NovoLancamentoSheet({
|
|
|
763
775
|
}) {
|
|
764
776
|
const { request, showToastHandler } = useApp();
|
|
765
777
|
const form = useForm<StatementEntryFormValues>({
|
|
766
|
-
resolver: zodResolver(
|
|
778
|
+
resolver: zodResolver(createStatementEntrySchema(t)),
|
|
767
779
|
defaultValues: {
|
|
768
780
|
date: new Date().toISOString().slice(0, 10),
|
|
769
781
|
description: '',
|
|
@@ -785,7 +797,7 @@ function NovoLancamentoSheet({
|
|
|
785
797
|
|
|
786
798
|
const handleSubmit = async (values: StatementEntryFormValues) => {
|
|
787
799
|
if (!bankAccountId) {
|
|
788
|
-
showToastHandler?.('error', '
|
|
800
|
+
showToastHandler?.('error', t('messages.selectBankAccount'));
|
|
789
801
|
return;
|
|
790
802
|
}
|
|
791
803
|
|
|
@@ -804,14 +816,14 @@ function NovoLancamentoSheet({
|
|
|
804
816
|
|
|
805
817
|
await onCreated();
|
|
806
818
|
onOpenChange(false);
|
|
807
|
-
showToastHandler?.('success', '
|
|
819
|
+
showToastHandler?.('success', t('messages.createEntrySuccess'));
|
|
808
820
|
} catch (error: any) {
|
|
809
821
|
const message = error?.response?.data?.message;
|
|
810
822
|
showToastHandler?.(
|
|
811
823
|
'error',
|
|
812
824
|
typeof message === 'string' && message.trim()
|
|
813
825
|
? message
|
|
814
|
-
: '
|
|
826
|
+
: t('messages.createEntryError')
|
|
815
827
|
);
|
|
816
828
|
}
|
|
817
829
|
};
|
|
@@ -820,10 +832,8 @@ function NovoLancamentoSheet({
|
|
|
820
832
|
<Sheet open={open} onOpenChange={onOpenChange}>
|
|
821
833
|
<SheetContent className="w-full sm:max-w-lg overflow-y-auto">
|
|
822
834
|
<SheetHeader>
|
|
823
|
-
<SheetTitle>
|
|
824
|
-
<SheetDescription>
|
|
825
|
-
Adicione uma movimentação manual ao extrato da conta bancária.
|
|
826
|
-
</SheetDescription>
|
|
835
|
+
<SheetTitle>{t('newEntry.title')}</SheetTitle>
|
|
836
|
+
<SheetDescription>{t('newEntry.description')}</SheetDescription>
|
|
827
837
|
</SheetHeader>
|
|
828
838
|
|
|
829
839
|
<Form {...form}>
|
|
@@ -837,7 +847,7 @@ function NovoLancamentoSheet({
|
|
|
837
847
|
name="date"
|
|
838
848
|
render={({ field }) => (
|
|
839
849
|
<FormItem>
|
|
840
|
-
<FormLabel>
|
|
850
|
+
<FormLabel>{t('newEntry.fields.date')}</FormLabel>
|
|
841
851
|
<FormControl>
|
|
842
852
|
<Input type="date" {...field} />
|
|
843
853
|
</FormControl>
|
|
@@ -851,7 +861,7 @@ function NovoLancamentoSheet({
|
|
|
851
861
|
name="type"
|
|
852
862
|
render={({ field }) => (
|
|
853
863
|
<FormItem>
|
|
854
|
-
<FormLabel>
|
|
864
|
+
<FormLabel>{t('newEntry.fields.type')}</FormLabel>
|
|
855
865
|
<Select value={field.value} onValueChange={field.onChange}>
|
|
856
866
|
<FormControl>
|
|
857
867
|
<SelectTrigger className="w-full">
|
|
@@ -859,8 +869,12 @@ function NovoLancamentoSheet({
|
|
|
859
869
|
</SelectTrigger>
|
|
860
870
|
</FormControl>
|
|
861
871
|
<SelectContent>
|
|
862
|
-
<SelectItem value="entrada">
|
|
863
|
-
|
|
872
|
+
<SelectItem value="entrada">
|
|
873
|
+
{t('types.inflow')}
|
|
874
|
+
</SelectItem>
|
|
875
|
+
<SelectItem value="saida">
|
|
876
|
+
{t('types.outflow')}
|
|
877
|
+
</SelectItem>
|
|
864
878
|
</SelectContent>
|
|
865
879
|
</Select>
|
|
866
880
|
<FormMessage />
|
|
@@ -874,7 +888,7 @@ function NovoLancamentoSheet({
|
|
|
874
888
|
name="description"
|
|
875
889
|
render={({ field }) => (
|
|
876
890
|
<FormItem>
|
|
877
|
-
<FormLabel>
|
|
891
|
+
<FormLabel>{t('newEntry.fields.description')}</FormLabel>
|
|
878
892
|
<FormControl>
|
|
879
893
|
<Input {...field} />
|
|
880
894
|
</FormControl>
|
|
@@ -888,7 +902,7 @@ function NovoLancamentoSheet({
|
|
|
888
902
|
name="amount"
|
|
889
903
|
render={({ field }) => (
|
|
890
904
|
<FormItem>
|
|
891
|
-
<FormLabel>
|
|
905
|
+
<FormLabel>{t('newEntry.fields.amount')}</FormLabel>
|
|
892
906
|
<FormControl>
|
|
893
907
|
<InputMoney
|
|
894
908
|
ref={field.ref}
|
|
@@ -910,10 +924,10 @@ function NovoLancamentoSheet({
|
|
|
910
924
|
variant="outline"
|
|
911
925
|
onClick={() => onOpenChange(false)}
|
|
912
926
|
>
|
|
913
|
-
|
|
927
|
+
{t('common.cancel')}
|
|
914
928
|
</Button>
|
|
915
929
|
<Button type="submit" disabled={form.formState.isSubmitting}>
|
|
916
|
-
|
|
930
|
+
{t('newEntry.submit')}
|
|
917
931
|
</Button>
|
|
918
932
|
</div>
|
|
919
933
|
</form>
|
|
@@ -1166,7 +1180,7 @@ export default function ExtratosPage() {
|
|
|
1166
1180
|
];
|
|
1167
1181
|
const handleExport = async () => {
|
|
1168
1182
|
if (!activeContaFilter) {
|
|
1169
|
-
showToastHandler?.('error', '
|
|
1183
|
+
showToastHandler?.('error', t('messages.selectBankAccountToExport'));
|
|
1170
1184
|
return;
|
|
1171
1185
|
}
|
|
1172
1186
|
|
|
@@ -1217,7 +1231,7 @@ export default function ExtratosPage() {
|
|
|
1217
1231
|
link.remove();
|
|
1218
1232
|
window.URL.revokeObjectURL(url);
|
|
1219
1233
|
} catch {
|
|
1220
|
-
showToastHandler?.('error', '
|
|
1234
|
+
showToastHandler?.('error', t('messages.exportError'));
|
|
1221
1235
|
}
|
|
1222
1236
|
};
|
|
1223
1237
|
|
|
@@ -1298,7 +1312,7 @@ export default function ExtratosPage() {
|
|
|
1298
1312
|
'error',
|
|
1299
1313
|
typeof message === 'string' && message.trim()
|
|
1300
1314
|
? message
|
|
1301
|
-
: '
|
|
1315
|
+
: t('messages.saveChangesError')
|
|
1302
1316
|
);
|
|
1303
1317
|
} finally {
|
|
1304
1318
|
setIsSavingEdits(false);
|
|
@@ -1310,7 +1324,7 @@ export default function ExtratosPage() {
|
|
|
1310
1324
|
setEditingDescId(null);
|
|
1311
1325
|
setEditingDateId(null);
|
|
1312
1326
|
await Promise.all([refetchExtratos(), refetchContasBancarias()]);
|
|
1313
|
-
showToastHandler?.('success', '
|
|
1327
|
+
showToastHandler?.('success', t('messages.saveChangesSuccess'));
|
|
1314
1328
|
}
|
|
1315
1329
|
};
|
|
1316
1330
|
|
|
@@ -1337,14 +1351,14 @@ export default function ExtratosPage() {
|
|
|
1337
1351
|
|
|
1338
1352
|
setStatementToDelete(null);
|
|
1339
1353
|
await Promise.all([refetchExtratos(), refetchContasBancarias()]);
|
|
1340
|
-
showToastHandler?.('success', '
|
|
1354
|
+
showToastHandler?.('success', t('messages.deleteEntrySuccess'));
|
|
1341
1355
|
} catch (error: any) {
|
|
1342
1356
|
const message = error?.response?.data?.message;
|
|
1343
1357
|
showToastHandler?.(
|
|
1344
1358
|
'error',
|
|
1345
1359
|
typeof message === 'string' && message.trim()
|
|
1346
1360
|
? message
|
|
1347
|
-
: '
|
|
1361
|
+
: t('messages.deleteEntryError')
|
|
1348
1362
|
);
|
|
1349
1363
|
} finally {
|
|
1350
1364
|
setIsDeletingStatement(false);
|
|
@@ -1369,7 +1383,7 @@ export default function ExtratosPage() {
|
|
|
1369
1383
|
</Button>
|
|
1370
1384
|
<Button onClick={() => setIsNewEntrySheetOpen(true)}>
|
|
1371
1385
|
<Plus className="mr-2 h-4 w-4" />
|
|
1372
|
-
|
|
1386
|
+
{t('newEntry.action')}
|
|
1373
1387
|
</Button>
|
|
1374
1388
|
<ImportarExtratoSheet
|
|
1375
1389
|
contasBancarias={contasBancarias}
|
|
@@ -1385,6 +1399,7 @@ export default function ExtratosPage() {
|
|
|
1385
1399
|
/>
|
|
1386
1400
|
|
|
1387
1401
|
<NovoLancamentoSheet
|
|
1402
|
+
t={t}
|
|
1388
1403
|
open={isNewEntrySheetOpen}
|
|
1389
1404
|
onOpenChange={setIsNewEntrySheetOpen}
|
|
1390
1405
|
bankAccountId={activeContaFilter}
|
|
@@ -1773,7 +1788,9 @@ export default function ExtratosPage() {
|
|
|
1773
1788
|
onClick={() => void handleSaveAllPendingEdits()}
|
|
1774
1789
|
disabled={isSavingEdits}
|
|
1775
1790
|
>
|
|
1776
|
-
{isSavingEdits
|
|
1791
|
+
{isSavingEdits
|
|
1792
|
+
? t('actions.savingChanges')
|
|
1793
|
+
: t('actions.saveChanges')}
|
|
1777
1794
|
</Button>
|
|
1778
1795
|
</div>
|
|
1779
1796
|
) : null}
|
|
@@ -1786,10 +1803,9 @@ export default function ExtratosPage() {
|
|
|
1786
1803
|
>
|
|
1787
1804
|
<DialogContent className="sm:max-w-sm">
|
|
1788
1805
|
<DialogHeader>
|
|
1789
|
-
<DialogTitle>
|
|
1806
|
+
<DialogTitle>{t('deleteDialog.title')}</DialogTitle>
|
|
1790
1807
|
<DialogDescription>
|
|
1791
|
-
|
|
1792
|
-
permanentemente do extrato.
|
|
1808
|
+
{t('deleteDialog.description')}
|
|
1793
1809
|
</DialogDescription>
|
|
1794
1810
|
</DialogHeader>
|
|
1795
1811
|
<DialogFooter className="mt-2">
|
|
@@ -1798,14 +1814,16 @@ export default function ExtratosPage() {
|
|
|
1798
1814
|
onClick={() => setStatementToDelete(null)}
|
|
1799
1815
|
disabled={isDeletingStatement}
|
|
1800
1816
|
>
|
|
1801
|
-
|
|
1817
|
+
{t('common.cancel')}
|
|
1802
1818
|
</Button>
|
|
1803
1819
|
<Button
|
|
1804
1820
|
variant="destructive"
|
|
1805
1821
|
onClick={() => void confirmDeleteStatement()}
|
|
1806
1822
|
disabled={isDeletingStatement}
|
|
1807
1823
|
>
|
|
1808
|
-
{isDeletingStatement
|
|
1824
|
+
{isDeletingStatement
|
|
1825
|
+
? t('deleteDialog.deleting')
|
|
1826
|
+
: t('deleteDialog.confirm')}
|
|
1809
1827
|
</Button>
|
|
1810
1828
|
</DialogFooter>
|
|
1811
1829
|
</DialogContent>
|