@hed-hog/lms 0.0.330 → 0.0.338

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 (128) hide show
  1. package/dist/class-group/class-group.controller.d.ts +3 -3
  2. package/dist/class-group/class-group.service.d.ts +3 -3
  3. package/dist/course/course.service.d.ts.map +1 -1
  4. package/dist/course/course.service.js +12 -20
  5. package/dist/course/course.service.js.map +1 -1
  6. package/dist/enterprise/enterprise.controller.d.ts +72 -0
  7. package/dist/enterprise/enterprise.controller.d.ts.map +1 -1
  8. package/dist/enterprise/enterprise.controller.js +10 -0
  9. package/dist/enterprise/enterprise.controller.js.map +1 -1
  10. package/dist/enterprise/enterprise.service.d.ts +78 -0
  11. package/dist/enterprise/enterprise.service.d.ts.map +1 -1
  12. package/dist/enterprise/enterprise.service.js +413 -40
  13. package/dist/enterprise/enterprise.service.js.map +1 -1
  14. package/dist/enterprise/training/training-admin.controller.d.ts +6 -3
  15. package/dist/enterprise/training/training-admin.controller.d.ts.map +1 -1
  16. package/dist/enterprise/training/training-admin.controller.js +10 -6
  17. package/dist/enterprise/training/training-admin.controller.js.map +1 -1
  18. package/dist/enterprise/training/training-admin.service.d.ts +8 -2
  19. package/dist/enterprise/training/training-admin.service.d.ts.map +1 -1
  20. package/dist/enterprise/training/training-admin.service.js +108 -52
  21. package/dist/enterprise/training/training-admin.service.js.map +1 -1
  22. package/dist/enterprise/training/training-viewer.controller.d.ts +3 -0
  23. package/dist/enterprise/training/training-viewer.controller.d.ts.map +1 -1
  24. package/dist/evaluation/evaluation.controller.d.ts +4 -4
  25. package/dist/evaluation/evaluation.service.d.ts +4 -4
  26. package/dist/instructor/dto/create-instructor-skill.dto.d.ts +0 -4
  27. package/dist/instructor/dto/create-instructor-skill.dto.d.ts.map +1 -1
  28. package/dist/instructor/dto/create-instructor-skill.dto.js +0 -21
  29. package/dist/instructor/dto/create-instructor-skill.dto.js.map +1 -1
  30. package/dist/instructor/dto/update-instructor-skill.dto.d.ts +0 -4
  31. package/dist/instructor/dto/update-instructor-skill.dto.d.ts.map +1 -1
  32. package/dist/instructor/dto/update-instructor-skill.dto.js +0 -22
  33. package/dist/instructor/dto/update-instructor-skill.dto.js.map +1 -1
  34. package/dist/instructor/instructor-skill.controller.d.ts +4 -4
  35. package/dist/instructor/instructor-skill.service.d.ts +4 -7
  36. package/dist/instructor/instructor-skill.service.d.ts.map +1 -1
  37. package/dist/instructor/instructor-skill.service.js +2 -89
  38. package/dist/instructor/instructor-skill.service.js.map +1 -1
  39. package/dist/instructor/instructor.controller.d.ts +20 -0
  40. package/dist/instructor/instructor.controller.d.ts.map +1 -1
  41. package/dist/instructor/instructor.controller.js +19 -0
  42. package/dist/instructor/instructor.controller.js.map +1 -1
  43. package/dist/instructor/instructor.service.d.ts +25 -0
  44. package/dist/instructor/instructor.service.d.ts.map +1 -1
  45. package/dist/instructor/instructor.service.js +70 -18
  46. package/dist/instructor/instructor.service.js.map +1 -1
  47. package/dist/lms.module.d.ts.map +1 -1
  48. package/dist/lms.module.js.map +1 -1
  49. package/hedhog/data/route.yaml +23 -1
  50. package/hedhog/frontend/app/_components/class-form-sheet.tsx.ejs +42 -24
  51. package/hedhog/frontend/app/_components/create-lms-instructor-sheet.tsx.ejs +591 -0
  52. package/hedhog/frontend/app/certificates/issued/page.tsx.ejs +6 -1
  53. package/hedhog/frontend/app/certificates/models/page.tsx.ejs +7 -2
  54. package/hedhog/frontend/app/classes/[id]/page.tsx.ejs +17 -17
  55. package/hedhog/frontend/app/classes/page.tsx.ejs +6 -1
  56. package/hedhog/frontend/app/courses/[id]/_components/CourseClassificationCard.tsx.ejs +3 -33
  57. package/hedhog/frontend/app/courses/[id]/_components/CourseContentCard.tsx.ejs +9 -9
  58. package/hedhog/frontend/app/courses/[id]/_components/CourseMainInfoCard.tsx.ejs +109 -0
  59. package/hedhog/frontend/app/courses/[id]/_components/CourseMultiEntityPicker.tsx.ejs +42 -15
  60. package/hedhog/frontend/app/courses/[id]/_components/CourseRelationsCard.tsx.ejs +76 -81
  61. package/hedhog/frontend/app/courses/[id]/_components/CourseSummaryCard.tsx.ejs +60 -0
  62. package/hedhog/frontend/app/courses/[id]/page.tsx.ejs +3 -3
  63. package/hedhog/frontend/app/courses/[id]/structure/_components/course-scheduled-classes-tab.tsx.ejs +406 -0
  64. package/hedhog/frontend/app/courses/[id]/structure/_components/course-tree-dnd.tsx.ejs +1 -1
  65. package/hedhog/frontend/app/courses/[id]/structure/_components/course-tree.tsx.ejs +134 -0
  66. package/hedhog/frontend/app/courses/[id]/structure/_components/detail-course.tsx.ejs +113 -0
  67. package/hedhog/frontend/app/courses/[id]/structure/_components/detail-lesson.tsx.ejs +314 -0
  68. package/hedhog/frontend/app/courses/[id]/structure/_components/detail-session.tsx.ejs +174 -0
  69. package/hedhog/frontend/app/courses/[id]/structure/_components/editor-course.tsx.ejs +242 -33
  70. package/hedhog/frontend/app/courses/[id]/structure/_components/editor-lesson.tsx.ejs +228 -152
  71. package/hedhog/frontend/app/courses/[id]/structure/_components/mock-data.ts.ejs +185 -0
  72. package/hedhog/frontend/app/courses/[id]/structure/_components/shortcuts-help.tsx.ejs +71 -31
  73. package/hedhog/frontend/app/courses/page.tsx.ejs +6 -1
  74. package/hedhog/frontend/app/enterprise/[id]/page.tsx.ejs +37 -41
  75. package/hedhog/frontend/app/enterprise/_components/enterprise-activity-timeline.tsx.ejs +87 -0
  76. package/hedhog/frontend/app/enterprise/_components/enterprise-admin-create-sheet.tsx.ejs +4 -0
  77. package/hedhog/frontend/app/enterprise/_components/enterprise-administrators-tab.tsx.ejs +31 -5
  78. package/hedhog/frontend/app/enterprise/_components/enterprise-classes-tab.tsx.ejs +79 -20
  79. package/hedhog/frontend/app/enterprise/_components/enterprise-company-identity-card.tsx.ejs +11 -2
  80. package/hedhog/frontend/app/enterprise/_components/enterprise-course-edit-sheet.tsx.ejs +201 -0
  81. package/hedhog/frontend/app/enterprise/_components/enterprise-courses-tab.tsx.ejs +55 -24
  82. package/hedhog/frontend/app/enterprise/_components/enterprise-detail-sheet.tsx.ejs +430 -296
  83. package/hedhog/frontend/app/enterprise/_components/enterprise-mocks.ts.ejs +277 -0
  84. package/hedhog/frontend/app/enterprise/_components/enterprise-overview-analytics.tsx.ejs +205 -0
  85. package/hedhog/frontend/app/enterprise/_components/enterprise-person-edit-sheet.tsx.ejs +97 -0
  86. package/hedhog/frontend/app/enterprise/_components/enterprise-sheet.tsx.ejs +82 -57
  87. package/hedhog/frontend/app/enterprise/_components/enterprise-student-create-sheet.tsx.ejs +4 -0
  88. package/hedhog/frontend/app/enterprise/_components/enterprise-students-tab.tsx.ejs +60 -22
  89. package/hedhog/frontend/app/enterprise/_components/enterprise-types.ts.ejs +54 -0
  90. package/hedhog/frontend/app/enterprise/_components/enterprise-user-create-sheet.tsx.ejs +211 -0
  91. package/hedhog/frontend/app/enterprise/page.tsx.ejs +39 -7
  92. package/hedhog/frontend/app/evaluations/_components/evaluation-topic-form-sheet.tsx.ejs +1 -1
  93. package/hedhog/frontend/app/exams/[id]/questions/page.tsx.ejs +6 -1
  94. package/hedhog/frontend/app/exams/page.tsx.ejs +12 -3
  95. package/hedhog/frontend/app/instructor-skills/page.tsx.ejs +51 -104
  96. package/hedhog/frontend/app/instructors/_components/instructor-form-sheet.tsx.ejs +712 -427
  97. package/hedhog/frontend/app/instructors/page.tsx.ejs +77 -53
  98. package/hedhog/frontend/app/paths/page.tsx.ejs +14 -5
  99. package/hedhog/frontend/app/reports/courses/page.tsx.ejs +5 -5
  100. package/hedhog/frontend/app/reports/dashboard/page.tsx.ejs +8 -8
  101. package/hedhog/frontend/app/reports/evaluations/page.tsx.ejs +6 -1
  102. package/hedhog/frontend/app/reports/page.tsx.ejs +7 -7
  103. package/hedhog/frontend/app/reports/students/page.tsx.ejs +6 -6
  104. package/hedhog/frontend/app/training/page.tsx.ejs +8 -3
  105. package/hedhog/frontend/messages/en.json +394 -55
  106. package/hedhog/frontend/messages/pt.json +389 -48
  107. package/hedhog/frontend/widgets/active-classes-kpi.tsx.ejs +1 -1
  108. package/hedhog/frontend/widgets/active-courses-kpi.tsx.ejs +1 -1
  109. package/hedhog/frontend/widgets/approval-rate-kpi.tsx.ejs +1 -1
  110. package/hedhog/frontend/widgets/class-calendar.tsx.ejs +2 -2
  111. package/hedhog/frontend/widgets/completion-rate-kpi.tsx.ejs +1 -1
  112. package/hedhog/frontend/widgets/issued-certificates-kpi.tsx.ejs +1 -1
  113. package/hedhog/frontend/widgets/total-students-kpi.tsx.ejs +1 -1
  114. package/hedhog/table/enterprise_student_license_event.yaml +30 -0
  115. package/hedhog/table/instructor_qualification.yaml +1 -1
  116. package/hedhog/table/instructor_skill.yaml +0 -11
  117. package/package.json +8 -8
  118. package/src/course/course.service.ts +12 -24
  119. package/src/enterprise/enterprise.controller.ts +5 -0
  120. package/src/enterprise/enterprise.service.ts +507 -29
  121. package/src/enterprise/training/training-admin.controller.ts +4 -0
  122. package/src/enterprise/training/training-admin.service.ts +115 -51
  123. package/src/instructor/dto/create-instructor-skill.dto.ts +0 -17
  124. package/src/instructor/dto/update-instructor-skill.dto.ts +0 -18
  125. package/src/instructor/instructor-skill.service.ts +2 -97
  126. package/src/instructor/instructor.controller.ts +16 -0
  127. package/src/instructor/instructor.service.ts +85 -10
  128. package/src/lms.module.ts +1 -0
@@ -23,7 +23,6 @@ import { useForm } from 'react-hook-form';
23
23
  import { toast } from 'sonner';
24
24
  import { z } from 'zod';
25
25
 
26
- import { CreateLmsPersonSheet } from '@/app/(app)/(libraries)/lms/_components/create-lms-person-sheet';
27
26
  import { createDefaultTemplate } from '@/app/(app)/(libraries)/lms/_lib/editor/types';
28
27
  import { RichTextEditor } from '@/components/rich-text-editor';
29
28
  import { Badge } from '@/components/ui/badge';
@@ -48,10 +47,19 @@ import {
48
47
  import { Input } from '@/components/ui/input';
49
48
  import { ScrollArea } from '@/components/ui/scroll-area';
50
49
  import { Separator } from '@/components/ui/separator';
50
+ import {
51
+ Sheet,
52
+ SheetContent,
53
+ SheetDescription,
54
+ SheetFooter,
55
+ SheetHeader,
56
+ SheetTitle,
57
+ } from '@/components/ui/sheet';
51
58
  import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
52
59
  import { useApp, useQuery } from '@hed-hog/next-app-provider';
53
60
  import { useMutation, useQueryClient } from '@tanstack/react-query';
54
61
 
62
+ import { InstructorFormSheet } from '../../../../instructors/_components/instructor-form-sheet';
55
63
  import type {
56
64
  CourseEditFormValues,
57
65
  PickerOption,
@@ -114,6 +122,16 @@ type ApiCourseDetail = {
114
122
  };
115
123
 
116
124
  type ApiCategory = { id: number; slug: string; name: string };
125
+ type ApiCategoryDetail = {
126
+ id: number;
127
+ slug: string;
128
+ name?: string;
129
+ category_id?: number | null;
130
+ color?: string | null;
131
+ icon?: string | null;
132
+ status?: 'active' | 'inactive';
133
+ category_locale?: Array<{ locale_id: number; name: string }>;
134
+ };
117
135
  type ApiCategoryList = {
118
136
  data: ApiCategory[];
119
137
  total: number;
@@ -284,7 +302,27 @@ export function EditorCourse() {
284
302
 
285
303
  // ── UI state ────────────────────────────────────────────────────────────────
286
304
  const [activeTab, setActiveTab] = useState('estrutura');
287
- const [instructorSheetOpen, setInstructorSheetOpen] = useState(false);
305
+ const [instructorEditSheetOpen, setInstructorEditSheetOpen] = useState(false);
306
+ const [editingInstructorId, setEditingInstructorId] = useState<number | null>(
307
+ null
308
+ );
309
+ const [categoryEditSheetOpen, setCategoryEditSheetOpen] = useState(false);
310
+ const [editingCategoryId, setEditingCategoryId] = useState<number | null>(
311
+ null
312
+ );
313
+ const [editingCategoryOriginalSlug, setEditingCategoryOriginalSlug] =
314
+ useState('');
315
+ const [editingCategoryName, setEditingCategoryName] = useState('');
316
+ const [editingCategorySlug, setEditingCategorySlug] = useState('');
317
+ const [editingCategoryColor, setEditingCategoryColor] = useState('#000000');
318
+ const [editingCategoryIcon, setEditingCategoryIcon] = useState('');
319
+ const [editingCategoryParentId, setEditingCategoryParentId] = useState<
320
+ number | null
321
+ >(null);
322
+ const [editingCategoryStatus, setEditingCategoryStatus] = useState<
323
+ 'active' | 'inactive'
324
+ >('active');
325
+ const [savingCategoryEdit, setSavingCategoryEdit] = useState(false);
288
326
  const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
289
327
  const [deleting, setDeleting] = useState(false);
290
328
  const [logoPreview, setLogoPreview] = useState<string | null>(null);
@@ -691,7 +729,7 @@ export function EditorCourse() {
691
729
 
692
730
  async function handleCreateCategory(values: Record<string, string>) {
693
731
  const name = String(values.name ?? '').trim();
694
- const slug = slugify(values.slug || values.name || '');
732
+ const slug = slugify(values.name || values.slug || '');
695
733
  if (!name || !slug) {
696
734
  toast.error('Informe nome e slug para criar a categoria.');
697
735
  return null;
@@ -764,26 +802,112 @@ export function EditorCourse() {
764
802
  }
765
803
  }
766
804
 
767
- const handleInstructorCreated = async (instructor: {
768
- id: number;
769
- personId: number;
770
- name: string;
771
- avatarId?: number | null;
772
- email?: string | null;
773
- phone?: string | null;
774
- qualificationSlugs: string[];
775
- }) => {
776
- const createdId = String(instructor.id);
777
- const current = form.getValues('instrutores') ?? [];
778
- if (!current.includes(createdId)) {
779
- form.setValue('instrutores', [...current, createdId], {
780
- shouldDirty: true,
781
- shouldTouch: true,
782
- shouldValidate: true,
805
+ function handleCreateInstructor() {
806
+ setEditingInstructorId(null);
807
+ setInstructorEditSheetOpen(true);
808
+ }
809
+
810
+ function handleEditInstructor(instructorId: string) {
811
+ const parsed = Number(instructorId);
812
+ if (!Number.isFinite(parsed) || parsed <= 0) {
813
+ toast.error('Instrutor inválido para edição.');
814
+ return;
815
+ }
816
+ setEditingInstructorId(parsed);
817
+ setInstructorEditSheetOpen(true);
818
+ }
819
+
820
+ async function handleEditCategory(categorySlug: string) {
821
+ const category = (categoryListData?.data ?? []).find(
822
+ (item) => item.slug === categorySlug
823
+ );
824
+
825
+ if (!category?.id) {
826
+ toast.error('Categoria não encontrada para edição.');
827
+ return;
828
+ }
829
+
830
+ try {
831
+ const response = await request<ApiCategoryDetail>({
832
+ url: `/category/${category.id}`,
833
+ method: 'GET',
783
834
  });
835
+ const detail = response.data;
836
+ const localeName = detail.category_locale?.[0]?.name ?? detail.name ?? '';
837
+
838
+ setEditingCategoryId(detail.id);
839
+ setEditingCategoryOriginalSlug(detail.slug || categorySlug);
840
+ setEditingCategorySlug(detail.slug || categorySlug);
841
+ setEditingCategoryName(localeName);
842
+ setEditingCategoryColor(detail.color || '#000000');
843
+ setEditingCategoryIcon(detail.icon || '');
844
+ setEditingCategoryParentId(detail.category_id ?? null);
845
+ setEditingCategoryStatus(detail.status || 'active');
846
+ setCategoryEditSheetOpen(true);
847
+ } catch {
848
+ toast.error('Não foi possível carregar a categoria para edição.');
784
849
  }
785
- await refetchInstructorOptions();
786
- };
850
+ }
851
+
852
+ async function handleSaveCategoryEdit() {
853
+ if (!editingCategoryId) return;
854
+
855
+ const name = editingCategoryName.trim();
856
+ const slug = slugify(editingCategorySlug);
857
+
858
+ if (!name || !slug) {
859
+ toast.error('Informe nome e slug válidos para a categoria.');
860
+ return;
861
+ }
862
+
863
+ const localeCode =
864
+ currentLocaleCode ||
865
+ (locales?.[0] as Locale | undefined)?.code ||
866
+ 'pt-BR';
867
+
868
+ setSavingCategoryEdit(true);
869
+ try {
870
+ await request({
871
+ url: `/category/${editingCategoryId}`,
872
+ method: 'PATCH',
873
+ data: {
874
+ locale: {
875
+ [localeCode]: {
876
+ name,
877
+ },
878
+ },
879
+ slug,
880
+ category_id: editingCategoryParentId,
881
+ color: editingCategoryColor,
882
+ icon: editingCategoryIcon,
883
+ status: editingCategoryStatus,
884
+ },
885
+ });
886
+
887
+ const selectedCategories = form.getValues('categorias') ?? [];
888
+ if (editingCategoryOriginalSlug && editingCategoryOriginalSlug !== slug) {
889
+ form.setValue(
890
+ 'categorias',
891
+ selectedCategories.map((item) =>
892
+ item === editingCategoryOriginalSlug ? slug : item
893
+ ),
894
+ {
895
+ shouldDirty: true,
896
+ shouldTouch: true,
897
+ shouldValidate: true,
898
+ }
899
+ );
900
+ }
901
+
902
+ await refetchCategoryOptions();
903
+ setCategoryEditSheetOpen(false);
904
+ toast.success('Categoria atualizada com sucesso.');
905
+ } catch {
906
+ toast.error('Não foi possível atualizar a categoria.');
907
+ } finally {
908
+ setSavingCategoryEdit(false);
909
+ }
910
+ }
787
911
 
788
912
  async function handleDelete() {
789
913
  setDeleting(true);
@@ -1008,7 +1132,9 @@ export function EditorCourse() {
1008
1132
  categoryOptions={categoryOptions}
1009
1133
  instructorOptions={instructorOptions}
1010
1134
  onCreateCategory={handleCreateCategory}
1011
- onCreateInstructor={() => setInstructorSheetOpen(true)}
1135
+ onCreateInstructor={handleCreateInstructor}
1136
+ onEditCategory={handleEditCategory}
1137
+ onEditInstructor={handleEditInstructor}
1012
1138
  />
1013
1139
  <CourseContentCard form={form} />
1014
1140
  </TabsContent>
@@ -1131,19 +1257,102 @@ export function EditorCourse() {
1131
1257
  </div>
1132
1258
  </form>
1133
1259
 
1134
- {/* ── Instructor sheet ─────────────────────────────────────────────── */}
1135
- <CreateLmsPersonSheet
1136
- open={instructorSheetOpen}
1137
- onOpenChange={setInstructorSheetOpen}
1138
- onCreated={handleInstructorCreated}
1139
- title="Cadastrar instrutor"
1140
- description="Cadastre um novo instrutor e adicione-o ao curso."
1141
- submitLabel="Cadastrar instrutor"
1142
- successMessage="Instrutor cadastrado com sucesso."
1143
- errorMessage="Não foi possível cadastrar o instrutor."
1144
- defaultQualificationSlugs={['course-lessons']}
1260
+ <InstructorFormSheet
1261
+ open={instructorEditSheetOpen}
1262
+ onOpenChange={(open) => {
1263
+ setInstructorEditSheetOpen(open);
1264
+ if (!open) {
1265
+ setEditingInstructorId(null);
1266
+ }
1267
+ }}
1268
+ instructorId={editingInstructorId}
1269
+ onSaved={async (instructor) => {
1270
+ if (editingInstructorId === null && instructor?.id) {
1271
+ const createdId = String(instructor.id);
1272
+ const current = form.getValues('instrutores') ?? [];
1273
+ if (!current.includes(createdId)) {
1274
+ form.setValue('instrutores', [...current, createdId], {
1275
+ shouldDirty: true,
1276
+ shouldTouch: true,
1277
+ shouldValidate: true,
1278
+ });
1279
+ }
1280
+ }
1281
+
1282
+ await refetchInstructorOptions();
1283
+ await refetchCourse();
1284
+ }}
1145
1285
  />
1146
1286
 
1287
+ <Sheet
1288
+ open={categoryEditSheetOpen}
1289
+ onOpenChange={(open) => {
1290
+ setCategoryEditSheetOpen(open);
1291
+ if (!open) {
1292
+ setEditingCategoryId(null);
1293
+ setEditingCategoryOriginalSlug('');
1294
+ setEditingCategoryName('');
1295
+ setEditingCategorySlug('');
1296
+ setEditingCategoryColor('#000000');
1297
+ setEditingCategoryIcon('');
1298
+ setEditingCategoryParentId(null);
1299
+ setEditingCategoryStatus('active');
1300
+ }
1301
+ }}
1302
+ >
1303
+ <SheetContent className="sm:max-w-lg">
1304
+ <SheetHeader>
1305
+ <SheetTitle>Editar categoria</SheetTitle>
1306
+ <SheetDescription>
1307
+ Atualize rapidamente os dados da categoria vinculada ao curso.
1308
+ </SheetDescription>
1309
+ </SheetHeader>
1310
+
1311
+ <div className="space-y-3 px-4 pb-4">
1312
+ <div className="space-y-1.5">
1313
+ <FormLabel>Nome</FormLabel>
1314
+ <Input
1315
+ value={editingCategoryName}
1316
+ onChange={(event) => {
1317
+ const nextName = event.target.value;
1318
+ setEditingCategoryName(nextName);
1319
+ setEditingCategorySlug(slugify(nextName));
1320
+ }}
1321
+ placeholder="Nome da categoria"
1322
+ />
1323
+ </div>
1324
+
1325
+ <div className="space-y-1.5">
1326
+ <FormLabel>Slug</FormLabel>
1327
+ <Input
1328
+ value={editingCategorySlug}
1329
+ readOnly
1330
+ placeholder="slug-da-categoria"
1331
+ />
1332
+ </div>
1333
+ </div>
1334
+
1335
+ <SheetFooter>
1336
+ <Button
1337
+ variant="outline"
1338
+ onClick={() => setCategoryEditSheetOpen(false)}
1339
+ disabled={savingCategoryEdit}
1340
+ >
1341
+ Cancelar
1342
+ </Button>
1343
+ <Button
1344
+ onClick={handleSaveCategoryEdit}
1345
+ disabled={savingCategoryEdit}
1346
+ >
1347
+ {savingCategoryEdit ? (
1348
+ <Loader2 className="size-4 animate-spin" />
1349
+ ) : null}
1350
+ Salvar
1351
+ </Button>
1352
+ </SheetFooter>
1353
+ </SheetContent>
1354
+ </Sheet>
1355
+
1147
1356
  {/* ── Delete dialog ────────────────────────────────────────────────── */}
1148
1357
  <Dialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>
1149
1358
  <DialogContent>