@hed-hog/contact 0.0.266 → 0.0.270

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 (77) hide show
  1. package/dist/address-type.enum.d.ts +10 -0
  2. package/dist/address-type.enum.d.ts.map +1 -0
  3. package/dist/address-type.enum.js +14 -0
  4. package/dist/address-type.enum.js.map +1 -0
  5. package/dist/contact.module.d.ts.map +1 -1
  6. package/dist/contact.module.js +0 -2
  7. package/dist/contact.module.js.map +1 -1
  8. package/dist/contact.service.d.ts +19 -22
  9. package/dist/contact.service.d.ts.map +1 -1
  10. package/dist/contact.service.js +22 -2
  11. package/dist/contact.service.js.map +1 -1
  12. package/dist/index.d.ts +5 -8
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +1 -4
  15. package/dist/index.js.map +1 -1
  16. package/dist/person/dto/create.dto.d.ts +14 -0
  17. package/dist/person/dto/create.dto.d.ts.map +1 -1
  18. package/dist/person/dto/create.dto.js +52 -1
  19. package/dist/person/dto/create.dto.js.map +1 -1
  20. package/dist/person/dto/update.dto.d.ts +17 -1
  21. package/dist/person/dto/update.dto.d.ts.map +1 -1
  22. package/dist/person/dto/update.dto.js +79 -3
  23. package/dist/person/dto/update.dto.js.map +1 -1
  24. package/dist/person/person.controller.d.ts +33 -8
  25. package/dist/person/person.controller.d.ts.map +1 -1
  26. package/dist/person/person.controller.js +19 -3
  27. package/dist/person/person.controller.js.map +1 -1
  28. package/dist/person/person.service.d.ts +59 -10
  29. package/dist/person/person.service.d.ts.map +1 -1
  30. package/dist/person/person.service.js +710 -107
  31. package/dist/person/person.service.js.map +1 -1
  32. package/dist/person-relation-type/person-relation-type.controller.d.ts +13 -9
  33. package/dist/person-relation-type/person-relation-type.controller.d.ts.map +1 -1
  34. package/dist/person-relation-type/person-relation-type.service.d.ts +16 -20
  35. package/dist/person-relation-type/person-relation-type.service.d.ts.map +1 -1
  36. package/dist/person-relation-type/person-relation-type.service.js +48 -41
  37. package/dist/person-relation-type/person-relation-type.service.js.map +1 -1
  38. package/hedhog/data/menu.yaml +2 -16
  39. package/hedhog/data/route.yaml +2 -21
  40. package/hedhog/data/setting_group.yaml +21 -0
  41. package/hedhog/frontend/app/person/_components/delete-person-dialog.tsx.ejs +59 -0
  42. package/hedhog/frontend/app/person/_components/person-field-with-create.tsx.ejs +831 -0
  43. package/hedhog/frontend/app/person/_components/person-form-sheet.tsx.ejs +1997 -0
  44. package/hedhog/frontend/app/person/_components/person-types.ts.ejs +115 -0
  45. package/hedhog/frontend/app/person/page.tsx.ejs +1209 -1530
  46. package/hedhog/frontend/messages/en.json +114 -4
  47. package/hedhog/frontend/messages/pt.json +114 -4
  48. package/hedhog/table/person.yaml +7 -0
  49. package/hedhog/table/person_address.yaml +18 -0
  50. package/hedhog/table/person_company.yaml +26 -11
  51. package/hedhog/table/person_individual.yaml +17 -13
  52. package/hedhog/table/person_individual_relation.yaml +39 -0
  53. package/package.json +6 -5
  54. package/src/address-type.enum.ts +9 -0
  55. package/src/contact.module.ts +46 -48
  56. package/src/contact.service.ts +28 -13
  57. package/src/index.ts +6 -13
  58. package/src/language/en.json +13 -6
  59. package/src/language/pt.json +14 -6
  60. package/src/person/dto/create.dto.ts +62 -14
  61. package/src/person/dto/update.dto.ts +147 -75
  62. package/src/person/person.controller.ts +39 -27
  63. package/src/person/person.service.ts +1071 -239
  64. package/src/person-relation-type/person-relation-type.service.ts +84 -76
  65. package/hedhog/data/address_type.yaml +0 -28
  66. package/hedhog/frontend/app/address-type/page.tsx.ejs +0 -480
  67. package/hedhog/query/add-unique-address-type-locale.sql +0 -3
  68. package/hedhog/table/address.yaml +0 -28
  69. package/hedhog/table/address_type.yaml +0 -11
  70. package/hedhog/table/person_relation.yaml +0 -20
  71. package/hedhog/table/person_relation_type.yaml +0 -6
  72. package/src/address-type/address-type.controller.ts +0 -55
  73. package/src/address-type/address-type.enum.ts +0 -9
  74. package/src/address-type/address-type.module.ts +0 -18
  75. package/src/address-type/address-type.service.ts +0 -121
  76. package/src/address-type/dto/create.dto.ts +0 -19
  77. package/src/address-type/dto/update.dto.ts +0 -9
@@ -1,76 +1,84 @@
1
- import { DeleteDTO } from '@hed-hog/api';
2
- import { LocaleService, getLocaleText } from '@hed-hog/api-locale';
3
- import { PaginationDTO, PaginationService } from '@hed-hog/api-pagination';
4
- import { PrismaService } from '@hed-hog/api-prisma';
5
- import {
6
- BadRequestException,
7
- Inject,
8
- Injectable,
9
- forwardRef
10
- } from '@nestjs/common';
11
- import { CreateDTO } from './dto/create.dto';
12
- import { UpdateDTO } from './dto/update.dto';
13
-
14
- @Injectable()
15
- export class PersonRelationTypeService {
16
- private readonly modelName = 'person_relation_type';
17
- private readonly foreignKey = 'relation_type_id';
18
-
19
- constructor(
20
- @Inject(forwardRef(() => PrismaService))
21
- private readonly prismaService: PrismaService,
22
- @Inject(forwardRef(() => PaginationService))
23
- private readonly paginationService: PaginationService,
24
- @Inject(forwardRef(() => LocaleService))
25
- private readonly localeService: LocaleService
26
- ) {}
27
-
28
- async list(locale: string, paginationParams: PaginationDTO) {
29
- return this.localeService.listModelWithLocale(
30
- locale,
31
- this.modelName,
32
- paginationParams
33
- );
34
- }
35
-
36
- async get(id: number) {
37
- return this.localeService.getModelWithLocale(this.modelName, id);
38
- }
39
-
40
- async create(data: CreateDTO) {
41
- return this.localeService.createModelWithLocale(
42
- this.modelName,
43
- this.foreignKey,
44
- data
45
- );
46
- }
47
-
48
- async update({ id, data }: { id: number; data: UpdateDTO }) {
49
- return this.localeService.updateModelWithLocale(
50
- this.modelName,
51
- this.foreignKey,
52
- id,
53
- data
54
- );
55
- }
56
-
57
- async delete({ ids }: DeleteDTO, locale: string = 'en') {
58
- if (ids == undefined || ids == null) {
59
- throw new BadRequestException(
60
- getLocaleText(
61
- 'deleteItemsRequired',
62
- locale,
63
- 'You must select at least one item to delete.',
64
- ),
65
- );
66
- }
67
-
68
- return this.prismaService.person_relation_type.deleteMany({
69
- where: {
70
- id: {
71
- in: ids
72
- }
73
- }
74
- });
75
- }
76
- }
1
+ import { DeleteDTO } from '@hed-hog/api';
2
+ import { getLocaleText } from '@hed-hog/api-locale';
3
+ import { PaginationDTO } from '@hed-hog/api-pagination';
4
+ import { BadRequestException, Injectable, NotFoundException } from '@nestjs/common';
5
+ import { CreateDTO } from './dto/create.dto';
6
+ import { UpdateDTO } from './dto/update.dto';
7
+
8
+ const RELATION_TYPES = [
9
+ 'parent',
10
+ 'child',
11
+ 'spouse',
12
+ 'sibling',
13
+ 'guardian',
14
+ 'dependent',
15
+ 'partner',
16
+ 'responsible',
17
+ 'emergency_contact',
18
+ 'other',
19
+ ] as const;
20
+
21
+ @Injectable()
22
+ export class PersonRelationTypeService {
23
+ async list(_locale: string, paginationParams: PaginationDTO) {
24
+ const search = String(paginationParams.search || '').trim().toLowerCase();
25
+ const page = Math.max(1, Number(paginationParams.page) || 1);
26
+ const pageSize = Math.max(1, Number(paginationParams.pageSize) || 10);
27
+
28
+ const allItems = RELATION_TYPES.map((code, index) => ({
29
+ id: index + 1,
30
+ code,
31
+ }));
32
+
33
+ const filtered = search
34
+ ? allItems.filter((item) => item.code.includes(search))
35
+ : allItems;
36
+
37
+ const start = (page - 1) * pageSize;
38
+ const data = filtered.slice(start, start + pageSize);
39
+
40
+ return {
41
+ data,
42
+ total: filtered.length,
43
+ page,
44
+ pageSize,
45
+ pageCount: Math.max(1, Math.ceil(filtered.length / pageSize)),
46
+ };
47
+ }
48
+
49
+ async get(id: number, locale: string = 'en') {
50
+ const item = RELATION_TYPES[id - 1];
51
+ if (!item) {
52
+ throw new NotFoundException(
53
+ getLocaleText(
54
+ 'personRelationTypeNotFound',
55
+ locale,
56
+ `Person relation type with ID ${id} not found`,
57
+ ),
58
+ );
59
+ }
60
+
61
+ return {
62
+ id,
63
+ code: item,
64
+ };
65
+ }
66
+
67
+ async create(_data: CreateDTO) {
68
+ throw new BadRequestException(
69
+ 'Person relation types are now fixed by schema and cannot be created dynamically.',
70
+ );
71
+ }
72
+
73
+ async update(_args: { id: number; data: UpdateDTO }) {
74
+ throw new BadRequestException(
75
+ 'Person relation types are now fixed by schema and cannot be updated.',
76
+ );
77
+ }
78
+
79
+ async delete(_data: DeleteDTO) {
80
+ throw new BadRequestException(
81
+ 'Person relation types are now fixed by schema and cannot be deleted.',
82
+ );
83
+ }
84
+ }
@@ -1,28 +0,0 @@
1
- - name:
2
- en: Residential
3
- pt: Residencial
4
- code: RESIDENTIAL
5
- - name:
6
- en: Commercial
7
- pt: Comercial
8
- code: COMMERCIAL
9
- - name:
10
- en: Correspondence
11
- pt: Correspondência
12
- code: CORRESPONDENCE
13
- - name:
14
- en: Alternative
15
- pt: Alternativo
16
- code: ALTERNATIVE
17
- - name:
18
- en: Work
19
- pt: Trabalho
20
- code: WORK
21
- - name:
22
- en: Billing
23
- pt: Cobrança
24
- code: BILLING
25
- - name:
26
- en: Shipping
27
- pt: Entrega
28
- code: SHIPPING
@@ -1,480 +0,0 @@
1
- 'use client';
2
-
3
- import {
4
- PageHeader,
5
- PaginationFooter,
6
- SearchBar,
7
- } from '@/components/entity-list';
8
- import { Button } from '@/components/ui/button';
9
- import {
10
- Dialog,
11
- DialogContent,
12
- DialogDescription,
13
- DialogHeader,
14
- DialogTitle,
15
- } from '@/components/ui/dialog';
16
- import {
17
- DropdownMenu,
18
- DropdownMenuContent,
19
- DropdownMenuItem,
20
- DropdownMenuLabel,
21
- DropdownMenuSeparator,
22
- DropdownMenuTrigger,
23
- } from '@/components/ui/dropdown-menu';
24
- import {
25
- Form,
26
- FormControl,
27
- FormField,
28
- FormItem,
29
- FormLabel,
30
- FormMessage,
31
- } from '@/components/ui/form';
32
- import { Input } from '@/components/ui/input';
33
- import {
34
- Table,
35
- TableBody,
36
- TableCell,
37
- TableHead,
38
- TableHeader,
39
- TableRow,
40
- } from '@/components/ui/table';
41
- import { formatDate } from '@/lib/format-date';
42
- import { useApp, useQuery } from '@hed-hog/next-app-provider';
43
- import { zodResolver } from '@hookform/resolvers/zod';
44
- import { MoreHorizontal, Pencil, Plus, Trash2 } from 'lucide-react';
45
- import { useTranslations } from 'next-intl';
46
- import { useState } from 'react';
47
- import { useForm } from 'react-hook-form';
48
- import { toast } from 'sonner';
49
- import { z } from 'zod';
50
-
51
- type PaginatedResult<T> = {
52
- data: T[];
53
- total: number;
54
- page: number;
55
- pageSize: number;
56
- };
57
-
58
- type AddressType = {
59
- address_type_id?: number;
60
- id: number;
61
- code: string;
62
- name: string;
63
- created_at: string;
64
- };
65
-
66
- export default function AddressTypePage() {
67
- const t = useTranslations('contact.AddressType');
68
-
69
- const addressTypeSchema = z.object({
70
- code: z.string().min(2, t('errorCode')),
71
- name: z.string().min(2, t('errorName')),
72
- });
73
- const { request, currentLocaleCode, getSettingValue } = useApp();
74
-
75
- const [searchQuery, setSearchQuery] = useState('');
76
- const [isDialogOpen, setIsDialogOpen] = useState(false);
77
- const [isEditDialogOpen, setIsEditDialogOpen] = useState(false);
78
- const [editingAddressType, setEditingAddressType] =
79
- useState<AddressType | null>(null);
80
-
81
- const [page, setPage] = useState(1);
82
- const [pageSize, setPageSize] = useState(12);
83
- const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
84
- const [deletingId, setDeletingId] = useState<number | null>(null);
85
-
86
- const {
87
- data: paginate = { data: [], total: 0, page: 1, pageSize: 12 },
88
- isLoading,
89
- refetch,
90
- } = useQuery<PaginatedResult<AddressType>>({
91
- queryKey: ['address-types', page, pageSize, searchQuery, currentLocaleCode],
92
- queryFn: async () => {
93
- const params = new URLSearchParams();
94
- params.set('page', String(page));
95
- params.set('pageSize', String(pageSize));
96
- if (searchQuery) params.set('search', searchQuery);
97
-
98
- const response = await request<PaginatedResult<AddressType>>({
99
- url: `/person-address-type?${params.toString()}`,
100
- method: 'GET',
101
- });
102
-
103
- return response.data;
104
- },
105
- });
106
-
107
- const form = useForm<z.infer<typeof addressTypeSchema>>({
108
- resolver: zodResolver(addressTypeSchema),
109
- defaultValues: {
110
- code: '',
111
- name: '',
112
- },
113
- });
114
-
115
- const editForm = useForm<z.infer<typeof addressTypeSchema>>({
116
- resolver: zodResolver(addressTypeSchema),
117
- });
118
-
119
- const onSubmit = async (values: z.infer<typeof addressTypeSchema>) => {
120
- try {
121
- const payload = {
122
- code: values.code,
123
- locale: {
124
- [currentLocaleCode]: {
125
- name: values.name,
126
- },
127
- },
128
- };
129
-
130
- await request({
131
- url: '/person-address-type',
132
- method: 'POST',
133
- data: payload,
134
- });
135
-
136
- toast.success(t('successCreate'));
137
- setIsDialogOpen(false);
138
- form.reset();
139
- refetch();
140
- } catch (error: any) {
141
- toast.error(error?.message || t('errorCreate'));
142
- }
143
- };
144
-
145
- const onEditSubmit = async (values: z.infer<typeof addressTypeSchema>) => {
146
- if (!editingAddressType) return;
147
-
148
- try {
149
- const payload = {
150
- code: values.code,
151
- locale: {
152
- [currentLocaleCode]: {
153
- name: values.name,
154
- },
155
- },
156
- };
157
-
158
- await request({
159
- url: `/person-address-type/${editingAddressType.address_type_id || editingAddressType.id}`,
160
- method: 'PATCH',
161
- data: payload,
162
- });
163
-
164
- toast.success(t('successUpdate'));
165
- setIsEditDialogOpen(false);
166
- setEditingAddressType(null);
167
- editForm.reset();
168
- refetch();
169
- } catch (error: any) {
170
- toast.error(error?.message || t('errorUpdate'));
171
- }
172
- };
173
-
174
- const handleDelete = async () => {
175
- if (deletingId === null) return;
176
- try {
177
- await request({
178
- url: '/person-address-type',
179
- method: 'DELETE',
180
- data: { ids: [deletingId] },
181
- });
182
- toast.success(t('successDelete'));
183
- setDeleteDialogOpen(false);
184
- setDeletingId(null);
185
- refetch();
186
- } catch (error: any) {
187
- toast.error(error?.message || t('errorDelete'));
188
- }
189
- };
190
-
191
- const handleEdit = (addressType: AddressType) => {
192
- (async () => {
193
- setEditingAddressType(addressType);
194
- try {
195
- const { data } = await request<any>({
196
- url: `/person-address-type/${addressType.address_type_id || addressType.id}?locale=${currentLocaleCode}`,
197
- method: 'GET',
198
- });
199
- editForm.reset({
200
- code: data.code || addressType.code,
201
- name: data.name || addressType.name || '',
202
- });
203
- } catch {
204
- editForm.reset({
205
- code: addressType.code,
206
- name: addressType.name || '',
207
- });
208
- }
209
- setIsEditDialogOpen(true);
210
- })();
211
- };
212
-
213
- return (
214
- <div className="flex flex-col h-screen px-4">
215
- <PageHeader
216
- breadcrumbs={[
217
- { label: t('breadcrumbContact'), href: '/contact' },
218
- { label: t('breadcrumbTitle') },
219
- ]}
220
- title={t('pageTitle')}
221
- description={t('pageDescription')}
222
- actions={[
223
- {
224
- label: t('buttonNewType'),
225
- onClick: () => setIsDialogOpen(true),
226
- variant: 'default',
227
- icon: <Plus />,
228
- },
229
- ]}
230
- />
231
-
232
- <div className="mb-4">
233
- <SearchBar
234
- searchQuery={searchQuery}
235
- onSearchChange={setSearchQuery}
236
- onSearch={() => refetch()}
237
- placeholder={t('searchPlaceholder')}
238
- />
239
- </div>
240
-
241
- <div className="rounded-md border mb-4">
242
- <Table>
243
- <TableHeader>
244
- <TableRow>
245
- <TableHead>{t('tableSlug')}</TableHead>
246
- <TableHead>{t('tableName')}</TableHead>
247
- <TableHead>{t('tableCreatedAt')}</TableHead>
248
- <TableHead className="w-[70px]"></TableHead>
249
- </TableRow>
250
- </TableHeader>
251
- <TableBody>
252
- {isLoading ? (
253
- <TableRow>
254
- <TableCell colSpan={5} className="text-center">
255
- {t('loading')}
256
- </TableCell>
257
- </TableRow>
258
- ) : paginate.data.length === 0 ? (
259
- <TableRow>
260
- <TableCell colSpan={5} className="text-center">
261
- {t('noResults')}
262
- </TableCell>
263
- </TableRow>
264
- ) : (
265
- paginate.data.map((addressType) => (
266
- <TableRow
267
- key={addressType.id}
268
- onDoubleClick={() => handleEdit(addressType)}
269
- className="cursor-pointer"
270
- >
271
- <TableCell className="font-medium">
272
- {addressType.code}
273
- </TableCell>
274
- <TableCell>{addressType.name}</TableCell>
275
- <TableCell>
276
- {addressType.created_at
277
- ? formatDate(
278
- addressType.created_at,
279
- getSettingValue,
280
- currentLocaleCode
281
- )
282
- : null}
283
- </TableCell>
284
- <TableCell>
285
- <DropdownMenu>
286
- <DropdownMenuTrigger asChild>
287
- <Button variant="ghost" className="size-8 p-0">
288
- <span className="sr-only">{t('menuOpen')}</span>
289
- <MoreHorizontal className="size-4" />
290
- </Button>
291
- </DropdownMenuTrigger>
292
- <DropdownMenuContent align="end">
293
- <DropdownMenuLabel>
294
- {t('menuActions')}
295
- </DropdownMenuLabel>
296
- <DropdownMenuSeparator />
297
- <DropdownMenuItem
298
- onClick={() => handleEdit(addressType)}
299
- >
300
- <Pencil className="mr-2 size-4" />
301
- {t('menuEdit')}
302
- </DropdownMenuItem>
303
- <DropdownMenuItem
304
- onClick={() => {
305
- setDeletingId(
306
- addressType.address_type_id || addressType.id
307
- );
308
- setDeleteDialogOpen(true);
309
- }}
310
- className="text-red-600"
311
- >
312
- <Trash2 className="mr-2 size-4" />
313
- {t('menuDelete')}
314
- </DropdownMenuItem>
315
- </DropdownMenuContent>
316
- </DropdownMenu>
317
- </TableCell>
318
- </TableRow>
319
- ))
320
- )}
321
- </TableBody>
322
- </Table>
323
- </div>
324
-
325
- <PaginationFooter
326
- currentPage={page}
327
- pageSize={pageSize}
328
- totalItems={paginate.total}
329
- onPageChange={setPage}
330
- onPageSizeChange={setPageSize}
331
- pageSizeOptions={[10, 20, 30, 40, 50]}
332
- />
333
-
334
- <Dialog open={isDialogOpen} onOpenChange={setIsDialogOpen}>
335
- <DialogContent className="max-w-md">
336
- <DialogHeader>
337
- <DialogTitle>{t('dialogNewTitle')}</DialogTitle>
338
- <DialogDescription>{t('dialogNewDescription')}</DialogDescription>
339
- </DialogHeader>
340
-
341
- <Form {...form}>
342
- <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
343
- <FormField
344
- control={form.control}
345
- name="code"
346
- render={({ field }) => (
347
- <FormItem>
348
- <FormLabel>{t('formSlugLabel')}</FormLabel>
349
- <FormControl>
350
- <Input
351
- placeholder={t('formSlugPlaceholder')}
352
- {...field}
353
- />
354
- </FormControl>
355
- <FormMessage />
356
- </FormItem>
357
- )}
358
- />
359
-
360
- <FormField
361
- control={form.control}
362
- name="name"
363
- render={({ field }) => (
364
- <FormItem>
365
- <FormLabel>{t('formNameLabel')}</FormLabel>
366
- <FormControl>
367
- <Input
368
- placeholder={t('formNamePlaceholderNew')}
369
- {...field}
370
- />
371
- </FormControl>
372
- <FormMessage />
373
- </FormItem>
374
- )}
375
- />
376
-
377
- <div className="flex justify-end gap-2">
378
- <Button
379
- type="button"
380
- variant="outline"
381
- onClick={() => setIsDialogOpen(false)}
382
- >
383
- {t('buttonCancel')}
384
- </Button>
385
- <Button type="submit">{t('buttonCreate')}</Button>
386
- </div>
387
- </form>
388
- </Form>
389
- </DialogContent>
390
- </Dialog>
391
-
392
- <Dialog open={isEditDialogOpen} onOpenChange={setIsEditDialogOpen}>
393
- <DialogContent className="max-w-md">
394
- <DialogHeader>
395
- <DialogTitle>{t('dialogEditTitle')}</DialogTitle>
396
- <DialogDescription>{t('dialogEditDescription')}</DialogDescription>
397
- </DialogHeader>
398
-
399
- <Form {...editForm}>
400
- <form
401
- onSubmit={editForm.handleSubmit(onEditSubmit)}
402
- className="space-y-4"
403
- >
404
- <FormField
405
- control={editForm.control}
406
- name="code"
407
- render={({ field }) => (
408
- <FormItem>
409
- <FormLabel>{t('formSlugLabel')}</FormLabel>
410
- <FormControl>
411
- <Input
412
- placeholder={t('formSlugPlaceholder')}
413
- {...field}
414
- />
415
- </FormControl>
416
- <FormMessage />
417
- </FormItem>
418
- )}
419
- />
420
-
421
- <FormField
422
- control={editForm.control}
423
- name="name"
424
- render={({ field }) => (
425
- <FormItem>
426
- <FormLabel>{t('formNameLabel')}</FormLabel>
427
- <FormControl>
428
- <Input
429
- placeholder={t('formNamePlaceholderEdit')}
430
- {...field}
431
- />
432
- </FormControl>
433
- <FormMessage />
434
- </FormItem>
435
- )}
436
- />
437
-
438
- <div className="flex justify-end gap-2">
439
- <Button
440
- type="button"
441
- variant="outline"
442
- onClick={() => setIsEditDialogOpen(false)}
443
- >
444
- {t('buttonCancel')}
445
- </Button>
446
- <Button type="submit">{t('buttonUpdate')}</Button>
447
- </div>
448
- </form>
449
- </Form>
450
- </DialogContent>
451
- </Dialog>
452
-
453
- <Dialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>
454
- <DialogContent className="max-w-md">
455
- <DialogHeader>
456
- <DialogTitle>{t('dialogDeleteTitle')}</DialogTitle>
457
- <DialogDescription>
458
- {t('dialogDeleteDescription')}
459
- </DialogDescription>
460
- </DialogHeader>
461
- <div className="flex justify-end gap-2 mt-4">
462
- <Button
463
- type="button"
464
- variant="outline"
465
- onClick={() => {
466
- setDeleteDialogOpen(false);
467
- setDeletingId(null);
468
- }}
469
- >
470
- {t('buttonCancel')}
471
- </Button>
472
- <Button type="button" variant="destructive" onClick={handleDelete}>
473
- {t('buttonDelete')}
474
- </Button>
475
- </div>
476
- </DialogContent>
477
- </Dialog>
478
- </div>
479
- );
480
- }
@@ -1,3 +0,0 @@
1
- -- Adiciona constraint UNIQUE composta para address_type_id e locale_id
2
- ALTER TABLE address_type_locale
3
- ADD CONSTRAINT address_type_locale_unique UNIQUE (address_type_id, locale_id);