@hed-hog/finance 0.0.224 → 0.0.225

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.
Files changed (43) hide show
  1. package/dist/dto/create-financial-title.dto.d.ts +19 -0
  2. package/dist/dto/create-financial-title.dto.d.ts.map +1 -0
  3. package/dist/dto/create-financial-title.dto.js +128 -0
  4. package/dist/dto/create-financial-title.dto.js.map +1 -0
  5. package/dist/finance.controller.d.ts +276 -0
  6. package/dist/finance.controller.d.ts.map +1 -0
  7. package/dist/finance.controller.js +110 -0
  8. package/dist/finance.controller.js.map +1 -0
  9. package/dist/finance.module.d.ts.map +1 -1
  10. package/dist/finance.module.js +8 -3
  11. package/dist/finance.module.js.map +1 -1
  12. package/dist/finance.service.d.ts +295 -0
  13. package/dist/finance.service.d.ts.map +1 -0
  14. package/dist/finance.service.js +416 -0
  15. package/dist/finance.service.js.map +1 -0
  16. package/dist/index.d.ts +3 -0
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +3 -0
  19. package/dist/index.js.map +1 -1
  20. package/hedhog/data/menu.yaml +72 -25
  21. package/hedhog/data/route.yaml +55 -1
  22. package/hedhog/frontend/app/accounts-payable/approvals/page.tsx.ejs +69 -44
  23. package/hedhog/frontend/app/accounts-payable/installments/[id]/page.tsx.ejs +68 -46
  24. package/hedhog/frontend/app/accounts-payable/installments/page.tsx.ejs +87 -63
  25. package/hedhog/frontend/app/accounts-receivable/collections-default/page.tsx.ejs +94 -59
  26. package/hedhog/frontend/app/accounts-receivable/installments/[id]/page.tsx.ejs +78 -52
  27. package/hedhog/frontend/app/accounts-receivable/installments/page.tsx.ejs +89 -68
  28. package/hedhog/frontend/app/cash-and-banks/bank-accounts/page.tsx.ejs +69 -47
  29. package/hedhog/frontend/app/cash-and-banks/bank-reconciliation/page.tsx.ejs +79 -53
  30. package/hedhog/frontend/app/cash-and-banks/statements/page.tsx.ejs +43 -36
  31. package/hedhog/frontend/app/cash-and-banks/transfers/page.tsx.ejs +47 -38
  32. package/hedhog/frontend/app/page.tsx.ejs +54 -31
  33. package/hedhog/frontend/app/planning/cash-flow-forecast/page.tsx.ejs +51 -38
  34. package/hedhog/frontend/app/planning/receivables-calendar/page.tsx.ejs +63 -33
  35. package/hedhog/frontend/app/planning/scenarios/page.tsx.ejs +50 -33
  36. package/hedhog/frontend/messages/en.json +776 -0
  37. package/hedhog/frontend/messages/pt.json +776 -0
  38. package/package.json +3 -3
  39. package/src/dto/create-financial-title.dto.ts +142 -0
  40. package/src/finance.controller.ts +89 -0
  41. package/src/finance.module.ts +8 -3
  42. package/src/finance.service.ts +529 -0
  43. package/src/index.ts +4 -0
@@ -1,5 +1,59 @@
1
- - url: /finance
1
+ - url: /finance/data
2
2
  method: GET
3
+ relations:
4
+ role:
5
+ - where:
6
+ slug: admin
7
+ - where:
8
+ slug: admin-finance
9
+
10
+ - url: /finance/accounts-payable/installments
11
+ method: GET
12
+ relations:
13
+ role:
14
+ - where:
15
+ slug: admin
16
+ - where:
17
+ slug: admin-finance
18
+
19
+ - url: /finance/accounts-payable/installments/:id
20
+ method: GET
21
+ relations:
22
+ role:
23
+ - where:
24
+ slug: admin
25
+ - where:
26
+ slug: admin-finance
27
+
28
+ - url: /finance/accounts-payable/installments
29
+ method: POST
30
+ relations:
31
+ role:
32
+ - where:
33
+ slug: admin
34
+ - where:
35
+ slug: admin-finance
36
+
37
+ - url: /finance/accounts-receivable/installments
38
+ method: GET
39
+ relations:
40
+ role:
41
+ - where:
42
+ slug: admin
43
+ - where:
44
+ slug: admin-finance
45
+
46
+ - url: /finance/accounts-receivable/installments/:id
47
+ method: GET
48
+ relations:
49
+ role:
50
+ - where:
51
+ slug: admin
52
+ - where:
53
+ slug: admin-finance
54
+
55
+ - url: /finance/accounts-receivable/installments
56
+ method: POST
3
57
  relations:
4
58
  role:
5
59
  - where:
@@ -20,7 +20,8 @@ import {
20
20
  } from '@/components/ui/dialog';
21
21
  import { Label } from '@/components/ui/label';
22
22
  import { Money } from '@/components/ui/money';
23
- import { PageHeader } from '@/components/ui/page-header';
23
+
24
+ import { Page, PageHeader } from '@/components/entity-list';
24
25
  import {
25
26
  Table,
26
27
  TableBody,
@@ -31,23 +32,19 @@ import {
31
32
  } from '@/components/ui/table';
32
33
  import { Textarea } from '@/components/ui/textarea';
33
34
  import { AlertTriangle, CheckCircle, Clock, XCircle } from 'lucide-react';
35
+ import { useTranslations } from 'next-intl';
34
36
  import { useEffect, useState } from 'react';
35
37
  import { formatarData } from '../../_lib/formatters';
36
38
  import { useFinanceData } from '../../_lib/use-finance-data';
37
39
 
38
- const urgenciaConfig = {
39
- baixa: { label: 'Baixa', className: 'bg-slate-100 text-slate-700' },
40
- media: { label: 'Média', className: 'bg-blue-100 text-blue-700' },
41
- alta: { label: 'Alta', className: 'bg-orange-100 text-orange-700' },
42
- critica: { label: 'Crítica', className: 'bg-red-100 text-red-700' },
43
- };
44
-
45
40
  function AprovacaoDialog({
46
41
  tipo,
47
42
  onConfirm,
43
+ t,
48
44
  }: {
49
45
  tipo: 'aprovar' | 'reprovar';
50
46
  onConfirm: () => void;
47
+ t: ReturnType<typeof useTranslations>;
51
48
  }) {
52
49
  const isAprovar = tipo === 'aprovar';
53
50
 
@@ -58,12 +55,12 @@ function AprovacaoDialog({
58
55
  {isAprovar ? (
59
56
  <>
60
57
  <CheckCircle className="mr-2 h-4 w-4" />
61
- Aprovar
58
+ {t('dialog.approveAction')}
62
59
  </>
63
60
  ) : (
64
61
  <>
65
62
  <XCircle className="mr-2 h-4 w-4" />
66
- Reprovar
63
+ {t('dialog.rejectAction')}
67
64
  </>
68
65
  )}
69
66
  </Button>
@@ -71,34 +68,34 @@ function AprovacaoDialog({
71
68
  <DialogContent>
72
69
  <DialogHeader>
73
70
  <DialogTitle>
74
- {isAprovar ? 'Aprovar Título' : 'Reprovar Título'}
71
+ {isAprovar ? t('dialog.approveTitle') : t('dialog.rejectTitle')}
75
72
  </DialogTitle>
76
73
  <DialogDescription>
77
74
  {isAprovar
78
- ? 'Confirme a aprovação deste título para pagamento.'
79
- : 'Informe o motivo da reprovação.'}
75
+ ? t('dialog.approveDescription')
76
+ : t('dialog.rejectDescription')}
80
77
  </DialogDescription>
81
78
  </DialogHeader>
82
79
  <div className="space-y-4">
83
80
  <div className="space-y-2">
84
- <Label htmlFor="comentario">Comentário</Label>
81
+ <Label htmlFor="comentario">{t('dialog.comment')}</Label>
85
82
  <Textarea
86
83
  id="comentario"
87
84
  placeholder={
88
85
  isAprovar
89
- ? 'Comentário opcional...'
90
- : 'Informe o motivo da reprovação...'
86
+ ? t('dialog.optionalCommentPlaceholder')
87
+ : t('dialog.rejectReasonPlaceholder')
91
88
  }
92
89
  />
93
90
  </div>
94
91
  </div>
95
92
  <DialogFooter>
96
- <Button variant="outline">Cancelar</Button>
93
+ <Button variant="outline">{t('dialog.cancel')}</Button>
97
94
  <Button
98
95
  variant={isAprovar ? 'default' : 'destructive'}
99
96
  onClick={onConfirm}
100
97
  >
101
- {isAprovar ? 'Confirmar Aprovação' : 'Confirmar Reprovação'}
98
+ {isAprovar ? t('dialog.confirmApprove') : t('dialog.confirmReject')}
102
99
  </Button>
103
100
  </DialogFooter>
104
101
  </DialogContent>
@@ -107,6 +104,7 @@ function AprovacaoDialog({
107
104
  }
108
105
 
109
106
  export default function AprovacoesPage() {
107
+ const t = useTranslations('finance.PayableApprovalsPage');
110
108
  const { data } = useFinanceData();
111
109
  const { aprovacoesPendentes, titulosPagar, pessoas } = data;
112
110
 
@@ -122,26 +120,45 @@ export default function AprovacoesPage() {
122
120
  setAprovacoes(aprovacoes.filter((a) => a.id !== id));
123
121
  };
124
122
 
123
+ const urgenciaConfig = {
124
+ baixa: {
125
+ label: t('urgency.low'),
126
+ className: 'bg-slate-100 text-slate-700',
127
+ },
128
+ media: {
129
+ label: t('urgency.medium'),
130
+ className: 'bg-blue-100 text-blue-700',
131
+ },
132
+ alta: {
133
+ label: t('urgency.high'),
134
+ className: 'bg-orange-100 text-orange-700',
135
+ },
136
+ critica: {
137
+ label: t('urgency.critical'),
138
+ className: 'bg-red-100 text-red-700',
139
+ },
140
+ };
141
+
125
142
  const totalPendente = aprovacoes.reduce((acc, a) => acc + a.valor, 0);
126
143
 
127
144
  return (
128
- <div className="flex flex-col h-screen px-4">
145
+ <Page>
129
146
  <PageHeader
130
- title="Aprovações"
131
- description="Gerencie as aprovações de títulos"
147
+ title={t('header.title')}
148
+ description={t('header.description')}
132
149
  breadcrumbs={[
133
- {
134
- label: 'Contas a Pagar',
135
- href: '/finance/accounts-payable/installments',
136
- },
137
- { label: 'Aprovações' },
150
+ { label: t('breadcrumbs.home'), href: '/' },
151
+ { label: t('breadcrumbs.finance'), href: '/finance' },
152
+ { label: t('breadcrumbs.current') },
138
153
  ]}
139
154
  />
140
155
 
141
156
  <div className="grid gap-4 md:grid-cols-3">
142
157
  <Card>
143
158
  <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
144
- <CardTitle className="text-sm font-medium">Pendentes</CardTitle>
159
+ <CardTitle className="text-sm font-medium">
160
+ {t('cards.pending')}
161
+ </CardTitle>
145
162
  <Clock className="h-4 w-4 text-muted-foreground" />
146
163
  </CardHeader>
147
164
  <CardContent>
@@ -150,7 +167,9 @@ export default function AprovacoesPage() {
150
167
  </Card>
151
168
  <Card>
152
169
  <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
153
- <CardTitle className="text-sm font-medium">Valor Total</CardTitle>
170
+ <CardTitle className="text-sm font-medium">
171
+ {t('cards.totalValue')}
172
+ </CardTitle>
154
173
  <AlertTriangle className="h-4 w-4 text-muted-foreground" />
155
174
  </CardHeader>
156
175
  <CardContent>
@@ -161,7 +180,9 @@ export default function AprovacoesPage() {
161
180
  </Card>
162
181
  <Card>
163
182
  <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
164
- <CardTitle className="text-sm font-medium">Urgentes</CardTitle>
183
+ <CardTitle className="text-sm font-medium">
184
+ {t('cards.urgent')}
185
+ </CardTitle>
165
186
  <AlertTriangle className="h-4 w-4 text-orange-500" />
166
187
  </CardHeader>
167
188
  <CardContent>
@@ -178,22 +199,26 @@ export default function AprovacoesPage() {
178
199
 
179
200
  <Card>
180
201
  <CardHeader>
181
- <CardTitle>Aprovações Pendentes</CardTitle>
182
- <CardDescription>Títulos aguardando sua aprovação</CardDescription>
202
+ <CardTitle>{t('table.title')}</CardTitle>
203
+ <CardDescription>{t('table.description')}</CardDescription>
183
204
  </CardHeader>
184
205
  <CardContent>
185
206
  {aprovacoes.length > 0 ? (
186
207
  <Table>
187
208
  <TableHeader>
188
209
  <TableRow>
189
- <TableHead>Documento</TableHead>
190
- <TableHead>Fornecedor</TableHead>
191
- <TableHead>Solicitante</TableHead>
192
- <TableHead className="text-right">Valor</TableHead>
193
- <TableHead>Política</TableHead>
194
- <TableHead>Urgência</TableHead>
195
- <TableHead>Data</TableHead>
196
- <TableHead className="text-right">Ações</TableHead>
210
+ <TableHead>{t('table.headers.document')}</TableHead>
211
+ <TableHead>{t('table.headers.supplier')}</TableHead>
212
+ <TableHead>{t('table.headers.requester')}</TableHead>
213
+ <TableHead className="text-right">
214
+ {t('table.headers.value')}
215
+ </TableHead>
216
+ <TableHead>{t('table.headers.policy')}</TableHead>
217
+ <TableHead>{t('table.headers.urgency')}</TableHead>
218
+ <TableHead>{t('table.headers.date')}</TableHead>
219
+ <TableHead className="text-right">
220
+ {t('table.headers.actions')}
221
+ </TableHead>
197
222
  </TableRow>
198
223
  </TableHeader>
199
224
  <TableBody>
@@ -236,10 +261,12 @@ export default function AprovacoesPage() {
236
261
  <div className="flex justify-end gap-2">
237
262
  <AprovacaoDialog
238
263
  tipo="aprovar"
264
+ t={t}
239
265
  onConfirm={() => handleAprovacao(aprovacao.id)}
240
266
  />
241
267
  <AprovacaoDialog
242
268
  tipo="reprovar"
269
+ t={t}
243
270
  onConfirm={() => handleAprovacao(aprovacao.id)}
244
271
  />
245
272
  </div>
@@ -252,14 +279,12 @@ export default function AprovacoesPage() {
252
279
  ) : (
253
280
  <div className="flex flex-col items-center justify-center py-12 text-center">
254
281
  <CheckCircle className="h-12 w-12 text-green-500" />
255
- <h3 className="mt-4 text-lg font-semibold">Tudo em dia!</h3>
256
- <p className="text-muted-foreground">
257
- Não há aprovações pendentes.
258
- </p>
282
+ <h3 className="mt-4 text-lg font-semibold">{t('empty.title')}</h3>
283
+ <p className="text-muted-foreground">{t('empty.description')}</p>
259
284
  </div>
260
285
  )}
261
286
  </CardContent>
262
287
  </Card>
263
- </div>
288
+ </Page>
264
289
  );
265
290
  }
@@ -1,5 +1,6 @@
1
1
  'use client';
2
2
 
3
+ import { Page, PageHeader } from '@/components/entity-list';
3
4
  import { AuditTimeline } from '@/components/ui/audit-timeline';
4
5
  import { Badge } from '@/components/ui/badge';
5
6
  import { Button } from '@/components/ui/button';
@@ -18,7 +19,6 @@ import {
18
19
  DropdownMenuTrigger,
19
20
  } from '@/components/ui/dropdown-menu';
20
21
  import { Money } from '@/components/ui/money';
21
- import { PageHeader } from '@/components/ui/page-header';
22
22
  import { StatusBadge } from '@/components/ui/status-badge';
23
23
  import {
24
24
  Table,
@@ -39,12 +39,14 @@ import {
39
39
  Undo,
40
40
  XCircle,
41
41
  } from 'lucide-react';
42
+ import { useTranslations } from 'next-intl';
42
43
  import Link from 'next/link';
43
44
  import { useParams } from 'next/navigation';
44
45
  import { formatarData } from '../../../_lib/formatters';
45
46
  import { useFinanceData } from '../../../_lib/use-finance-data';
46
47
 
47
48
  export default function TituloDetalhePage() {
49
+ const t = useTranslations('finance.PayableInstallmentDetailPage');
48
50
  const params = useParams<{ id: string }>();
49
51
  const id = params?.id;
50
52
  const { data } = useFinanceData();
@@ -64,11 +66,17 @@ export default function TituloDetalhePage() {
64
66
  return (
65
67
  <div className="space-y-6">
66
68
  <PageHeader
67
- title="Título não encontrado"
68
- description="Não foi possível carregar os dados do título."
69
+ title={t('notFound.title')}
70
+ description={t('notFound.description')}
69
71
  breadcrumbs={[
70
- { label: 'Contas a Pagar', href: '/finance/accounts-payable/installments' },
71
- { label: 'Títulos e Parcelas', href: '/finance/accounts-payable/installments' },
72
+ {
73
+ label: t('notFound.breadcrumbPayables'),
74
+ href: '/finance/accounts-payable/installments',
75
+ },
76
+ {
77
+ label: t('notFound.breadcrumbInstallments'),
78
+ href: '/finance/accounts-payable/installments',
79
+ },
72
80
  ]}
73
81
  />
74
82
  </div>
@@ -106,7 +114,7 @@ export default function TituloDetalhePage() {
106
114
  }));
107
115
 
108
116
  return (
109
- <div className="space-y-6">
117
+ <Page>
110
118
  <div className="flex items-center gap-4">
111
119
  <Button variant="ghost" size="icon" asChild>
112
120
  <Link href="/finance/accounts-payable/installments">
@@ -117,8 +125,12 @@ export default function TituloDetalhePage() {
117
125
  title={titulo.documento}
118
126
  description={titulo.descricao}
119
127
  breadcrumbs={[
120
- { label: 'Contas a Pagar', href: '/finance/accounts-payable/installments' },
121
- { label: 'Títulos e Parcelas', href: '/finance/accounts-payable/installments' },
128
+ { label: t('breadcrumbs.home'), href: '/' },
129
+ { label: t('breadcrumbs.finance'), href: '/finance' },
130
+ {
131
+ label: t('breadcrumbs.payables'),
132
+ href: '/finance/accounts-payable/installments',
133
+ },
122
134
  { label: titulo.documento },
123
135
  ]}
124
136
  actions={
@@ -128,30 +140,30 @@ export default function TituloDetalhePage() {
128
140
  <DropdownMenuTrigger asChild>
129
141
  <Button variant="outline">
130
142
  <MoreHorizontal className="mr-2 h-4 w-4" />
131
- Ações
143
+ {t('actions.title')}
132
144
  </Button>
133
145
  </DropdownMenuTrigger>
134
146
  <DropdownMenuContent align="end">
135
147
  <DropdownMenuItem>
136
148
  <Edit className="mr-2 h-4 w-4" />
137
- Editar
149
+ {t('actions.edit')}
138
150
  </DropdownMenuItem>
139
151
  <DropdownMenuItem>
140
152
  <CheckCircle className="mr-2 h-4 w-4" />
141
- Aprovar
153
+ {t('actions.approve')}
142
154
  </DropdownMenuItem>
143
155
  <DropdownMenuItem>
144
156
  <Download className="mr-2 h-4 w-4" />
145
- Baixar
157
+ {t('actions.settle')}
146
158
  </DropdownMenuItem>
147
159
  <DropdownMenuItem>
148
160
  <Undo className="mr-2 h-4 w-4" />
149
- Estornar
161
+ {t('actions.reverse')}
150
162
  </DropdownMenuItem>
151
163
  <DropdownMenuSeparator />
152
164
  <DropdownMenuItem className="text-destructive">
153
165
  <XCircle className="mr-2 h-4 w-4" />
154
- Cancelar
166
+ {t('actions.cancel')}
155
167
  </DropdownMenuItem>
156
168
  </DropdownMenuContent>
157
169
  </DropdownMenu>
@@ -163,13 +175,13 @@ export default function TituloDetalhePage() {
163
175
  <div className="grid gap-6 lg:grid-cols-3">
164
176
  <Card className="lg:col-span-2">
165
177
  <CardHeader>
166
- <CardTitle>Dados do Documento</CardTitle>
178
+ <CardTitle>{t('documentData.title')}</CardTitle>
167
179
  </CardHeader>
168
180
  <CardContent>
169
181
  <dl className="grid gap-4 sm:grid-cols-2">
170
182
  <div>
171
183
  <dt className="text-sm font-medium text-muted-foreground">
172
- Fornecedor
184
+ {t('documentData.supplier')}
173
185
  </dt>
174
186
  <dd className="mt-1">
175
187
  <Link
@@ -182,19 +194,19 @@ export default function TituloDetalhePage() {
182
194
  </div>
183
195
  <div>
184
196
  <dt className="text-sm font-medium text-muted-foreground">
185
- CNPJ/CPF
197
+ {t('documentData.cnpjCpf')}
186
198
  </dt>
187
199
  <dd className="mt-1">{fornecedor?.documento}</dd>
188
200
  </div>
189
201
  <div>
190
202
  <dt className="text-sm font-medium text-muted-foreground">
191
- Competência
203
+ {t('documentData.competency')}
192
204
  </dt>
193
205
  <dd className="mt-1">{titulo.competencia}</dd>
194
206
  </div>
195
207
  <div>
196
208
  <dt className="text-sm font-medium text-muted-foreground">
197
- Valor Total
209
+ {t('documentData.totalValue')}
198
210
  </dt>
199
211
  <dd className="mt-1 text-lg font-semibold">
200
212
  <Money value={titulo.valorTotal} />
@@ -202,25 +214,25 @@ export default function TituloDetalhePage() {
202
214
  </div>
203
215
  <div>
204
216
  <dt className="text-sm font-medium text-muted-foreground">
205
- Categoria
217
+ {t('documentData.category')}
206
218
  </dt>
207
219
  <dd className="mt-1">{categoria?.nome}</dd>
208
220
  </div>
209
221
  <div>
210
222
  <dt className="text-sm font-medium text-muted-foreground">
211
- Centro de Custo
223
+ {t('documentData.costCenter')}
212
224
  </dt>
213
225
  <dd className="mt-1">{centroCusto?.nome}</dd>
214
226
  </div>
215
227
  <div>
216
228
  <dt className="text-sm font-medium text-muted-foreground">
217
- Data de Criação
229
+ {t('documentData.createdAt')}
218
230
  </dt>
219
231
  <dd className="mt-1">{formatarData(titulo.criadoEm)}</dd>
220
232
  </div>
221
233
  <div>
222
234
  <dt className="text-sm font-medium text-muted-foreground">
223
- Tags
235
+ {t('documentData.tags')}
224
236
  </dt>
225
237
  <dd className="mt-1 flex gap-1">
226
238
  {tituloTags.length > 0 ? (
@@ -244,8 +256,8 @@ export default function TituloDetalhePage() {
244
256
 
245
257
  <Card>
246
258
  <CardHeader>
247
- <CardTitle>Anexos</CardTitle>
248
- <CardDescription>Documentos relacionados</CardDescription>
259
+ <CardTitle>{t('attachments.title')}</CardTitle>
260
+ <CardDescription>{t('attachments.description')}</CardDescription>
249
261
  </CardHeader>
250
262
  <CardContent>
251
263
  {titulo.anexos.length > 0 ? (
@@ -263,7 +275,9 @@ export default function TituloDetalhePage() {
263
275
  ))}
264
276
  </ul>
265
277
  ) : (
266
- <p className="text-sm text-muted-foreground">Nenhum anexo</p>
278
+ <p className="text-sm text-muted-foreground">
279
+ {t('attachments.none')}
280
+ </p>
267
281
  )}
268
282
  </CardContent>
269
283
  </Card>
@@ -271,9 +285,9 @@ export default function TituloDetalhePage() {
271
285
 
272
286
  <Tabs defaultValue="parcelas">
273
287
  <TabsList>
274
- <TabsTrigger value="parcelas">Parcelas</TabsTrigger>
275
- <TabsTrigger value="liquidacoes">Liquidações</TabsTrigger>
276
- <TabsTrigger value="auditoria">Auditoria</TabsTrigger>
288
+ <TabsTrigger value="parcelas">{t('tabs.installments')}</TabsTrigger>
289
+ <TabsTrigger value="liquidacoes">{t('tabs.settlements')}</TabsTrigger>
290
+ <TabsTrigger value="auditoria">{t('tabs.audit')}</TabsTrigger>
277
291
  </TabsList>
278
292
 
279
293
  <TabsContent value="parcelas" className="mt-4">
@@ -282,11 +296,13 @@ export default function TituloDetalhePage() {
282
296
  <Table>
283
297
  <TableHeader>
284
298
  <TableRow>
285
- <TableHead>Parcela</TableHead>
286
- <TableHead>Vencimento</TableHead>
287
- <TableHead className="text-right">Valor</TableHead>
288
- <TableHead>Método</TableHead>
289
- <TableHead>Status</TableHead>
299
+ <TableHead>{t('installmentsTable.installment')}</TableHead>
300
+ <TableHead>{t('installmentsTable.dueDate')}</TableHead>
301
+ <TableHead className="text-right">
302
+ {t('installmentsTable.value')}
303
+ </TableHead>
304
+ <TableHead>{t('installmentsTable.method')}</TableHead>
305
+ <TableHead>{t('installmentsTable.status')}</TableHead>
290
306
  </TableRow>
291
307
  </TableHeader>
292
308
  <TableBody>
@@ -320,13 +336,21 @@ export default function TituloDetalhePage() {
320
336
  <Table>
321
337
  <TableHeader>
322
338
  <TableRow>
323
- <TableHead>Data</TableHead>
324
- <TableHead className="text-right">Valor</TableHead>
325
- <TableHead className="text-right">Juros</TableHead>
326
- <TableHead className="text-right">Desconto</TableHead>
327
- <TableHead className="text-right">Multa</TableHead>
328
- <TableHead>Conta</TableHead>
329
- <TableHead>Método</TableHead>
339
+ <TableHead>{t('settlementsTable.date')}</TableHead>
340
+ <TableHead className="text-right">
341
+ {t('settlementsTable.value')}
342
+ </TableHead>
343
+ <TableHead className="text-right">
344
+ {t('settlementsTable.interest')}
345
+ </TableHead>
346
+ <TableHead className="text-right">
347
+ {t('settlementsTable.discount')}
348
+ </TableHead>
349
+ <TableHead className="text-right">
350
+ {t('settlementsTable.fine')}
351
+ </TableHead>
352
+ <TableHead>{t('settlementsTable.account')}</TableHead>
353
+ <TableHead>{t('settlementsTable.method')}</TableHead>
330
354
  </TableRow>
331
355
  </TableHeader>
332
356
  <TableBody>
@@ -360,7 +384,7 @@ export default function TituloDetalhePage() {
360
384
  </Table>
361
385
  ) : (
362
386
  <p className="text-center text-muted-foreground py-8">
363
- Nenhuma liquidação registrada
387
+ {t('settlementsTable.none')}
364
388
  </p>
365
389
  )}
366
390
  </CardContent>
@@ -374,15 +398,13 @@ export default function TituloDetalhePage() {
374
398
  <AuditTimeline events={auditEvents} />
375
399
  ) : (
376
400
  <p className="text-center text-muted-foreground py-8">
377
- Nenhum evento de auditoria
401
+ {t('audit.none')}
378
402
  </p>
379
403
  )}
380
404
  </CardContent>
381
405
  </Card>
382
406
  </TabsContent>
383
407
  </Tabs>
384
- </div>
408
+ </Page>
385
409
  );
386
410
  }
387
-
388
-