@hed-hog/lms 0.0.350 → 0.0.351

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 (160) hide show
  1. package/dist/certificate/certificate.controller.d.ts +2 -2
  2. package/dist/certificate/certificate.controller.d.ts.map +1 -1
  3. package/dist/certificate/certificate.controller.js +8 -6
  4. package/dist/certificate/certificate.controller.js.map +1 -1
  5. package/dist/certificate/certificate.service.d.ts +5 -2
  6. package/dist/certificate/certificate.service.d.ts.map +1 -1
  7. package/dist/certificate/certificate.service.js +70 -6
  8. package/dist/certificate/certificate.service.js.map +1 -1
  9. package/dist/course/course-structure.controller.d.ts +24 -10
  10. package/dist/course/course-structure.controller.d.ts.map +1 -1
  11. package/dist/course/course-structure.controller.js +23 -2
  12. package/dist/course/course-structure.controller.js.map +1 -1
  13. package/dist/course/course-structure.service.d.ts +16 -8
  14. package/dist/course/course-structure.service.d.ts.map +1 -1
  15. package/dist/course/course-structure.service.js +61 -30
  16. package/dist/course/course-structure.service.js.map +1 -1
  17. package/dist/course/course-video-conversion.service.d.ts +37 -0
  18. package/dist/course/course-video-conversion.service.d.ts.map +1 -0
  19. package/dist/course/course-video-conversion.service.js +308 -0
  20. package/dist/course/course-video-conversion.service.js.map +1 -0
  21. package/dist/course/course.controller.d.ts +17 -0
  22. package/dist/course/course.controller.d.ts.map +1 -1
  23. package/dist/course/course.controller.js +23 -0
  24. package/dist/course/course.controller.js.map +1 -1
  25. package/dist/course/course.module.d.ts.map +1 -1
  26. package/dist/course/course.module.js +15 -2
  27. package/dist/course/course.module.js.map +1 -1
  28. package/dist/course/course.service.d.ts +15 -0
  29. package/dist/course/course.service.d.ts.map +1 -1
  30. package/dist/course/course.service.js +103 -49
  31. package/dist/course/course.service.js.map +1 -1
  32. package/dist/course/dto/create-course-structure-lesson.dto.d.ts +5 -1
  33. package/dist/course/dto/create-course-structure-lesson.dto.d.ts.map +1 -1
  34. package/dist/course/dto/create-course-structure-lesson.dto.js +16 -2
  35. package/dist/course/dto/create-course-structure-lesson.dto.js.map +1 -1
  36. package/dist/course/dto/create-course.dto.d.ts +1 -0
  37. package/dist/course/dto/create-course.dto.d.ts.map +1 -1
  38. package/dist/course/dto/create-course.dto.js +9 -0
  39. package/dist/course/dto/create-course.dto.js.map +1 -1
  40. package/dist/enterprise/enterprise.controller.d.ts +3 -3
  41. package/dist/enterprise/enterprise.controller.d.ts.map +1 -1
  42. package/dist/enterprise/enterprise.controller.js +0 -1
  43. package/dist/enterprise/enterprise.controller.js.map +1 -1
  44. package/dist/enterprise/enterprise.service.d.ts +3 -3
  45. package/dist/evaluation/evaluation.service.d.ts.map +1 -1
  46. package/dist/evaluation/evaluation.service.js +9 -2
  47. package/dist/evaluation/evaluation.service.js.map +1 -1
  48. package/dist/index.d.ts +1 -0
  49. package/dist/index.d.ts.map +1 -1
  50. package/dist/index.js +1 -0
  51. package/dist/index.js.map +1 -1
  52. package/dist/lms.module.d.ts.map +1 -1
  53. package/dist/lms.module.js +3 -0
  54. package/dist/lms.module.js.map +1 -1
  55. package/dist/video-resolution-profile/dto/create-video-resolution-profile.dto.d.ts +6 -0
  56. package/dist/video-resolution-profile/dto/create-video-resolution-profile.dto.d.ts.map +1 -0
  57. package/dist/video-resolution-profile/dto/create-video-resolution-profile.dto.js +33 -0
  58. package/dist/video-resolution-profile/dto/create-video-resolution-profile.dto.js.map +1 -0
  59. package/dist/video-resolution-profile/dto/update-video-resolution-profile.dto.d.ts +6 -0
  60. package/dist/video-resolution-profile/dto/update-video-resolution-profile.dto.d.ts.map +1 -0
  61. package/dist/video-resolution-profile/dto/update-video-resolution-profile.dto.js +33 -0
  62. package/dist/video-resolution-profile/dto/update-video-resolution-profile.dto.js.map +1 -0
  63. package/dist/video-resolution-profile/video-resolution-profile.controller.d.ts +38 -0
  64. package/dist/video-resolution-profile/video-resolution-profile.controller.d.ts.map +1 -0
  65. package/dist/video-resolution-profile/video-resolution-profile.controller.js +89 -0
  66. package/dist/video-resolution-profile/video-resolution-profile.controller.js.map +1 -0
  67. package/dist/video-resolution-profile/video-resolution-profile.mcp-tools.d.ts +26 -0
  68. package/dist/video-resolution-profile/video-resolution-profile.mcp-tools.d.ts.map +1 -0
  69. package/dist/video-resolution-profile/video-resolution-profile.mcp-tools.js +160 -0
  70. package/dist/video-resolution-profile/video-resolution-profile.mcp-tools.js.map +1 -0
  71. package/dist/video-resolution-profile/video-resolution-profile.module.d.ts +3 -0
  72. package/dist/video-resolution-profile/video-resolution-profile.module.d.ts.map +1 -0
  73. package/dist/video-resolution-profile/video-resolution-profile.module.js +26 -0
  74. package/dist/video-resolution-profile/video-resolution-profile.module.js.map +1 -0
  75. package/dist/video-resolution-profile/video-resolution-profile.service.d.ts +45 -0
  76. package/dist/video-resolution-profile/video-resolution-profile.service.d.ts.map +1 -0
  77. package/dist/video-resolution-profile/video-resolution-profile.service.js +117 -0
  78. package/dist/video-resolution-profile/video-resolution-profile.service.js.map +1 -0
  79. package/hedhog/data/menu.yaml +17 -0
  80. package/hedhog/data/route.yaml +133 -0
  81. package/hedhog/data/video_resolution_profile.yaml +7 -0
  82. package/hedhog/frontend/app/_components/class-form-sheet.tsx.ejs +269 -324
  83. package/hedhog/frontend/app/_components/course-form-sheet.tsx.ejs +124 -70
  84. package/hedhog/frontend/app/_components/create-lms-instructor-sheet.tsx.ejs +7 -4
  85. package/hedhog/frontend/app/_components/create-lms-person-sheet.tsx.ejs +2 -2
  86. package/hedhog/frontend/app/_components/create-lms-student-person-sheet.tsx.ejs +2 -2
  87. package/hedhog/frontend/app/_lib/editor/templateSerializer.ts.ejs +34 -4
  88. package/hedhog/frontend/app/_lib/editor/types.ts.ejs +28 -3
  89. package/hedhog/frontend/app/achievements/page.tsx.ejs +9 -3
  90. package/hedhog/frontend/app/bitcodes/page.tsx.ejs +9 -3
  91. package/hedhog/frontend/app/certificates/issued/page.tsx.ejs +7 -3
  92. package/hedhog/frontend/app/certificates/models/CanvasStage.tsx.ejs +29 -8
  93. package/hedhog/frontend/app/certificates/models/LeftPanel.tsx.ejs +14 -0
  94. package/hedhog/frontend/app/certificates/models/RightPanel.tsx.ejs +194 -9
  95. package/hedhog/frontend/app/certificates/models/page.tsx.ejs +15 -5
  96. package/hedhog/frontend/app/classes/[id]/page.tsx.ejs +9 -5
  97. package/hedhog/frontend/app/classes/page.tsx.ejs +73 -47
  98. package/hedhog/frontend/app/courses/[id]/_components/CourseCertificateCard.tsx.ejs +19 -9
  99. package/hedhog/frontend/app/courses/[id]/_components/CourseClassificationCard.tsx.ejs +24 -1
  100. package/hedhog/frontend/app/courses/[id]/_components/CourseContentCard.tsx.ejs +1 -1
  101. package/hedhog/frontend/app/courses/[id]/_components/CourseMainInfoCard.tsx.ejs +1 -1
  102. package/hedhog/frontend/app/courses/[id]/_components/CourseRelationsCard.tsx.ejs +28 -16
  103. package/hedhog/frontend/app/courses/[id]/_components/CourseSectionCard.tsx.ejs +11 -6
  104. package/hedhog/frontend/app/courses/[id]/_components/CourseSummaryCard.tsx.ejs +7 -4
  105. package/hedhog/frontend/app/courses/[id]/_components/course-edit-types.ts.ejs +1 -0
  106. package/hedhog/frontend/app/courses/[id]/page.tsx.ejs +24 -87
  107. package/hedhog/frontend/app/courses/[id]/structure/_components/editor-course.tsx.ejs +892 -411
  108. package/hedhog/frontend/app/courses/[id]/structure/_components/editor-lesson.tsx.ejs +1004 -293
  109. package/hedhog/frontend/app/courses/[id]/structure/_components/editor-session.tsx.ejs +11 -11
  110. package/hedhog/frontend/app/courses/[id]/structure/_components/shortcuts-help.tsx.ejs +62 -52
  111. package/hedhog/frontend/app/courses/[id]/structure/_components/types.ts.ejs +2 -0
  112. package/hedhog/frontend/app/courses/[id]/structure/_data/adapters/course-structure.adapter.ts.ejs +19 -6
  113. package/hedhog/frontend/app/courses/[id]/structure/_data/services/course-structure.service.ts.ejs +86 -1
  114. package/hedhog/frontend/app/courses/[id]/structure/_data/types/api-course.types.ts.ejs +3 -0
  115. package/hedhog/frontend/app/courses/[id]/structure/_data/use-course-structure-mutations.ts.ejs +1 -0
  116. package/hedhog/frontend/app/courses/page.tsx.ejs +112 -89
  117. package/hedhog/frontend/app/enterprise/[id]/page.tsx.ejs +1 -1
  118. package/hedhog/frontend/app/enterprise/_components/enterprise-admin-create-sheet.tsx.ejs +10 -3
  119. package/hedhog/frontend/app/enterprise/_components/enterprise-detail-sheet.tsx.ejs +8 -4
  120. package/hedhog/frontend/app/enterprise/_components/enterprise-person-edit-sheet.tsx.ejs +2 -2
  121. package/hedhog/frontend/app/enterprise/_components/enterprise-sheet.tsx.ejs +10 -4
  122. package/hedhog/frontend/app/enterprise/_components/enterprise-student-create-sheet.tsx.ejs +10 -3
  123. package/hedhog/frontend/app/enterprise/_components/enterprise-user-create-sheet.tsx.ejs +10 -3
  124. package/hedhog/frontend/app/evaluations/_components/evaluation-topic-form-sheet.tsx.ejs +10 -3
  125. package/hedhog/frontend/app/exams/[id]/questions/page.tsx.ejs +23 -9
  126. package/hedhog/frontend/app/exams/page.tsx.ejs +14 -6
  127. package/hedhog/frontend/app/instructor-skills/page.tsx.ejs +9 -3
  128. package/hedhog/frontend/app/instructors/_components/instructor-form-sheet.tsx.ejs +190 -17
  129. package/hedhog/frontend/app/layout.tsx.ejs +5 -1
  130. package/hedhog/frontend/app/paths/page.tsx.ejs +13 -5
  131. package/hedhog/frontend/app/reports/evaluations/page.tsx.ejs +10 -10
  132. package/hedhog/frontend/app/training/page.tsx.ejs +13 -5
  133. package/hedhog/frontend/app/video-resolution-profiles/page.tsx.ejs +607 -0
  134. package/hedhog/frontend/messages/en.json +250 -9
  135. package/hedhog/frontend/messages/pt.json +250 -9
  136. package/hedhog/table/course.yaml +4 -0
  137. package/hedhog/table/course_lesson_file.yaml +8 -0
  138. package/hedhog/table/course_video_resolution_profile.yaml +22 -0
  139. package/hedhog/table/video_resolution_profile.yaml +18 -0
  140. package/package.json +7 -6
  141. package/src/certificate/certificate.controller.ts +19 -14
  142. package/src/certificate/certificate.service.ts +106 -11
  143. package/src/course/course-structure.controller.ts +24 -2
  144. package/src/course/course-structure.service.ts +21 -4
  145. package/src/course/course-video-conversion.service.ts +415 -0
  146. package/src/course/course.controller.ts +18 -0
  147. package/src/course/course.module.ts +15 -2
  148. package/src/course/course.service.ts +72 -2
  149. package/src/course/dto/create-course-structure-lesson.dto.ts +13 -2
  150. package/src/course/dto/create-course.dto.ts +8 -0
  151. package/src/enterprise/enterprise.controller.ts +0 -1
  152. package/src/evaluation/evaluation.service.ts +9 -2
  153. package/src/index.ts +1 -0
  154. package/src/lms.module.ts +3 -0
  155. package/src/video-resolution-profile/dto/create-video-resolution-profile.dto.ts +16 -0
  156. package/src/video-resolution-profile/dto/update-video-resolution-profile.dto.ts +16 -0
  157. package/src/video-resolution-profile/video-resolution-profile.controller.ts +62 -0
  158. package/src/video-resolution-profile/video-resolution-profile.mcp-tools.ts +128 -0
  159. package/src/video-resolution-profile/video-resolution-profile.module.ts +13 -0
  160. package/src/video-resolution-profile/video-resolution-profile.service.ts +117 -0
@@ -12,12 +12,7 @@ import {
12
12
  DialogTitle,
13
13
  } from '@/components/ui/dialog';
14
14
  import { EntityPicker } from '@/components/ui/entity-picker';
15
- import {
16
- Field,
17
- FieldDescription,
18
- FieldError,
19
- FieldLabel,
20
- } from '@/components/ui/field';
15
+ import { Field, FieldError, FieldLabel } from '@/components/ui/field';
21
16
  import { Input } from '@/components/ui/input';
22
17
  import {
23
18
  Popover,
@@ -33,12 +28,12 @@ import {
33
28
  } from '@/components/ui/select';
34
29
  import {
35
30
  Sheet,
36
- SheetContent,
37
31
  SheetDescription,
38
32
  SheetFooter,
39
33
  SheetHeader,
40
34
  SheetTitle,
41
35
  } from '@/components/ui/sheet';
36
+ import { ResizableSheetContent } from '@/components/ui/resizable-sheet-content';
42
37
  import { useApp, useQuery } from '@hed-hog/next-app-provider';
43
38
  import { zodResolver } from '@hookform/resolvers/zod';
44
39
  import { format } from 'date-fns';
@@ -771,11 +766,6 @@ export function ClassFormSheet({
771
766
  )
772
767
  ? t('form.fields.sessionAccess.placeholder')
773
768
  : 'Sala 201 ou https://meet.google.com/...';
774
- const sessionAccessDescription = t.has(
775
- 'form.fields.sessionAccess.description'
776
- )
777
- ? t('form.fields.sessionAccess.description')
778
- : 'Opcional. Quando preenchido, será aplicado a todas as aulas geradas para esta turma.';
779
769
 
780
770
  const filteredEndTimeOptions = useMemo(() => {
781
771
  const startTime = watchedFormValues.horarioInicio ?? '';
@@ -815,20 +805,6 @@ export function ClassFormSheet({
815
805
  [t]
816
806
  );
817
807
 
818
- const recurrenceSummaryText = useMemo(() => {
819
- const until = watchedFormValues.sessionRecurrenceUntil
820
- ? formatDate(watchedFormValues.sessionRecurrenceUntil)
821
- : '--';
822
- return t(
823
- `form.recurrence.summary.${watchedFormValues.sessionRecurrenceMode}`,
824
- { until }
825
- );
826
- }, [
827
- t,
828
- watchedFormValues.sessionRecurrenceMode,
829
- watchedFormValues.sessionRecurrenceUntil,
830
- ]);
831
-
832
808
  const customRecurrenceFrequency =
833
809
  watchedFormValues.sessionRecurrenceMode === 'custom'
834
810
  ? watchedFormValues.sessionRecurrenceCustomFrequency
@@ -1197,9 +1173,13 @@ export function ClassFormSheet({
1197
1173
  return (
1198
1174
  <>
1199
1175
  <Sheet open={open} onOpenChange={onOpenChange}>
1200
- <SheetContent
1176
+ <ResizableSheetContent
1177
+ sheetId="lms-class-form-sheet"
1178
+ defaultWidth={672}
1179
+ minWidth={460}
1180
+ maxWidth={1100}
1201
1181
  side="right"
1202
- className="flex w-full flex-col overflow-y-auto sm:max-w-2xl"
1182
+ className="flex w-full flex-col overflow-y-auto"
1203
1183
  >
1204
1184
  <SheetHeader className="shrink-0">
1205
1185
  <SheetTitle>
@@ -1218,9 +1198,9 @@ export function ClassFormSheet({
1218
1198
  ) : (
1219
1199
  <form
1220
1200
  onSubmit={form.handleSubmit(onSubmit)}
1221
- className="flex flex-1 flex-col gap-5 px-4 py-6"
1201
+ className="flex flex-1 flex-col gap-4 px-4 py-6"
1222
1202
  >
1223
- <div className="grid gap-4 md:grid-cols-[minmax(0,0.8fr)_minmax(0,1.2fr)]">
1203
+ <div className="grid grid-cols-1 gap-3 md:grid-cols-2">
1224
1204
  <Field>
1225
1205
  <FieldLabel htmlFor="codigo">
1226
1206
  {t('form.fields.code.label')}
@@ -1231,9 +1211,6 @@ export function ClassFormSheet({
1231
1211
  readOnly
1232
1212
  className="uppercase"
1233
1213
  />
1234
- <FieldDescription>
1235
- Codigo gerado automaticamente pelo sistema.
1236
- </FieldDescription>
1237
1214
  <FieldError>
1238
1215
  {form.formState.errors.codigo?.message}
1239
1216
  </FieldError>
@@ -1262,12 +1239,9 @@ export function ClassFormSheet({
1262
1239
  showEditButton={!lockCourse}
1263
1240
  searchEndpoint="/lms/courses"
1264
1241
  searchExtraParams={{
1265
- offeringTypes: 'scheduled,blended,on_demand',
1242
+ offeringTypes: 'scheduled,blended',
1266
1243
  }}
1267
1244
  refreshToken={coursePickerRefreshToken}
1268
- isOptionDisabled={(option) =>
1269
- option.offeringType === 'on_demand'
1270
- }
1271
1245
  onSelectionChange={(value, option) => {
1272
1246
  const cId = typeof value === 'number' ? value : undefined;
1273
1247
  const cTitle =
@@ -1321,164 +1295,149 @@ export function ClassFormSheet({
1321
1295
  </Field>
1322
1296
  </div>
1323
1297
 
1324
- <div className="rounded-lg border border-border/70 p-4">
1325
- <div className="grid gap-4">
1298
+ <div className="space-y-3">
1299
+ <Field>
1300
+ <FieldLabel>
1301
+ {t('form.fields.startDate.label')} /{' '}
1302
+ {t('form.fields.endDate.label')}{' '}
1303
+ <span className="text-destructive">*</span>
1304
+ </FieldLabel>
1305
+ <Popover open={dateRangeOpen} onOpenChange={setDateRangeOpen}>
1306
+ <PopoverTrigger asChild>
1307
+ <Button
1308
+ type="button"
1309
+ variant="outline"
1310
+ className={`w-full justify-start text-left font-normal ${
1311
+ !watchedFormValues.dataInicio ||
1312
+ !watchedFormValues.dataFim
1313
+ ? 'text-muted-foreground'
1314
+ : ''
1315
+ }`}
1316
+ >
1317
+ <CalendarIcon className="mr-2 size-4" />
1318
+ {formatDateRangeLabel(
1319
+ watchedFormValues.dataInicio,
1320
+ watchedFormValues.dataFim
1321
+ ) || t('form.fields.startDate.placeholder')}
1322
+ </Button>
1323
+ </PopoverTrigger>
1324
+ <PopoverContent className="w-auto p-0" align="start">
1325
+ <Calendar
1326
+ mode="range"
1327
+ numberOfMonths={2}
1328
+ selected={dateRangeDraft}
1329
+ onSelect={(range) => {
1330
+ setDateRangeDraft(range);
1331
+ if (!range?.from || !range?.to) {
1332
+ form.setValue('dataInicio', '', {
1333
+ shouldDirty: true,
1334
+ shouldTouch: true,
1335
+ shouldValidate: true,
1336
+ });
1337
+ form.setValue('dataFim', '', {
1338
+ shouldDirty: true,
1339
+ shouldTouch: true,
1340
+ shouldValidate: true,
1341
+ });
1342
+ return;
1343
+ }
1344
+ form.setValue(
1345
+ 'dataInicio',
1346
+ format(range.from, 'yyyy-MM-dd'),
1347
+ {
1348
+ shouldDirty: true,
1349
+ shouldTouch: true,
1350
+ shouldValidate: true,
1351
+ }
1352
+ );
1353
+ form.setValue(
1354
+ 'dataFim',
1355
+ format(range.to, 'yyyy-MM-dd'),
1356
+ {
1357
+ shouldDirty: true,
1358
+ shouldTouch: true,
1359
+ shouldValidate: true,
1360
+ }
1361
+ );
1362
+ }}
1363
+ initialFocus
1364
+ />
1365
+ </PopoverContent>
1366
+ </Popover>
1367
+ <FieldError>
1368
+ {form.formState.errors.dataInicio?.message ||
1369
+ form.formState.errors.dataFim?.message}
1370
+ </FieldError>
1371
+ </Field>
1372
+
1373
+ <div className="grid grid-cols-1 gap-3 md:grid-cols-2">
1326
1374
  <Field>
1327
- <FieldLabel>
1328
- {t('form.fields.startDate.label')} /{' '}
1329
- {t('form.fields.endDate.label')}{' '}
1375
+ <FieldLabel htmlFor="horarioInicio">
1376
+ {t('form.fields.startTime.label')}{' '}
1330
1377
  <span className="text-destructive">*</span>
1331
1378
  </FieldLabel>
1332
- <Popover
1333
- open={dateRangeOpen}
1334
- onOpenChange={setDateRangeOpen}
1335
- >
1336
- <PopoverTrigger asChild>
1337
- <Button
1338
- type="button"
1339
- variant="outline"
1340
- className={`w-full justify-start text-left font-normal ${
1341
- !watchedFormValues.dataInicio ||
1342
- !watchedFormValues.dataFim
1343
- ? 'text-muted-foreground'
1344
- : ''
1345
- }`}
1379
+ <Controller
1380
+ name="horarioInicio"
1381
+ control={form.control}
1382
+ render={({ field }) => (
1383
+ <Select
1384
+ onValueChange={field.onChange}
1385
+ value={field.value}
1346
1386
  >
1347
- <CalendarIcon className="mr-2 size-4" />
1348
- {formatDateRangeLabel(
1349
- watchedFormValues.dataInicio,
1350
- watchedFormValues.dataFim
1351
- ) || t('form.fields.startDate.placeholder')}
1352
- </Button>
1353
- </PopoverTrigger>
1354
- <PopoverContent className="w-auto p-0" align="start">
1355
- <Calendar
1356
- mode="range"
1357
- numberOfMonths={2}
1358
- selected={dateRangeDraft}
1359
- onSelect={(range) => {
1360
- setDateRangeDraft(range);
1361
- if (!range?.from || !range?.to) {
1362
- form.setValue('dataInicio', '', {
1363
- shouldDirty: true,
1364
- shouldTouch: true,
1365
- shouldValidate: true,
1366
- });
1367
- form.setValue('dataFim', '', {
1368
- shouldDirty: true,
1369
- shouldTouch: true,
1370
- shouldValidate: true,
1371
- });
1372
- return;
1373
- }
1374
- form.setValue(
1375
- 'dataInicio',
1376
- format(range.from, 'yyyy-MM-dd'),
1377
- {
1378
- shouldDirty: true,
1379
- shouldTouch: true,
1380
- shouldValidate: true,
1381
- }
1382
- );
1383
- form.setValue(
1384
- 'dataFim',
1385
- format(range.to, 'yyyy-MM-dd'),
1386
- {
1387
- shouldDirty: true,
1388
- shouldTouch: true,
1389
- shouldValidate: true,
1390
- }
1391
- );
1392
- }}
1393
- initialFocus
1394
- />
1395
- </PopoverContent>
1396
- </Popover>
1387
+ <SelectTrigger id="horarioInicio">
1388
+ <SelectValue
1389
+ placeholder={t(
1390
+ 'form.fields.startTime.placeholder'
1391
+ )}
1392
+ />
1393
+ </SelectTrigger>
1394
+ <SelectContent>
1395
+ {TIME_OPTIONS.map((time) => (
1396
+ <SelectItem key={time} value={time}>
1397
+ {time}
1398
+ </SelectItem>
1399
+ ))}
1400
+ </SelectContent>
1401
+ </Select>
1402
+ )}
1403
+ />
1397
1404
  <FieldError>
1398
- {form.formState.errors.dataInicio?.message ||
1399
- form.formState.errors.dataFim?.message}
1405
+ {form.formState.errors.horarioInicio?.message}
1400
1406
  </FieldError>
1401
1407
  </Field>
1402
1408
 
1403
- <div className="grid gap-4 md:grid-cols-2">
1404
- <Field>
1405
- <FieldLabel htmlFor="horarioInicio">
1406
- {t('form.fields.startTime.label')}{' '}
1407
- <span className="text-destructive">*</span>
1408
- </FieldLabel>
1409
- <Controller
1410
- name="horarioInicio"
1411
- control={form.control}
1412
- render={({ field }) => (
1413
- <Select
1414
- onValueChange={field.onChange}
1415
- value={field.value}
1416
- >
1417
- <SelectTrigger id="horarioInicio">
1418
- <SelectValue
1419
- placeholder={t(
1420
- 'form.fields.startTime.placeholder'
1421
- )}
1422
- />
1423
- </SelectTrigger>
1424
- <SelectContent>
1425
- {TIME_OPTIONS.map((time) => (
1426
- <SelectItem key={time} value={time}>
1427
- {time}
1428
- </SelectItem>
1429
- ))}
1430
- </SelectContent>
1431
- </Select>
1432
- )}
1433
- />
1434
- <FieldDescription>
1435
- Escolha o horario de inicio na lista para preencher mais
1436
- rapido.
1437
- </FieldDescription>
1438
- <FieldError>
1439
- {form.formState.errors.horarioInicio?.message}
1440
- </FieldError>
1441
- </Field>
1442
-
1443
- <Field>
1444
- <FieldLabel htmlFor="horarioFim">
1445
- {t('form.fields.endTime.label')}{' '}
1446
- <span className="text-destructive">*</span>
1447
- </FieldLabel>
1448
- <Controller
1449
- name="horarioFim"
1450
- control={form.control}
1451
- render={({ field }) => (
1452
- <Select
1453
- onValueChange={field.onChange}
1454
- value={field.value}
1455
- >
1456
- <SelectTrigger id="horarioFim">
1457
- <SelectValue
1458
- placeholder={t(
1459
- 'form.fields.endTime.placeholder'
1460
- )}
1461
- />
1462
- </SelectTrigger>
1463
- <SelectContent>
1464
- {filteredEndTimeOptions.map((time) => (
1465
- <SelectItem key={time} value={time}>
1466
- {time}
1467
- </SelectItem>
1468
- ))}
1469
- </SelectContent>
1470
- </Select>
1471
- )}
1472
- />
1473
- <FieldDescription>
1474
- O termino mostra apenas horarios iguais ou depois do
1475
- inicio.
1476
- </FieldDescription>
1477
- <FieldError>
1478
- {form.formState.errors.horarioFim?.message}
1479
- </FieldError>
1480
- </Field>
1481
- </div>
1409
+ <Field>
1410
+ <FieldLabel htmlFor="horarioFim">
1411
+ {t('form.fields.endTime.label')}{' '}
1412
+ <span className="text-destructive">*</span>
1413
+ </FieldLabel>
1414
+ <Controller
1415
+ name="horarioFim"
1416
+ control={form.control}
1417
+ render={({ field }) => (
1418
+ <Select
1419
+ onValueChange={field.onChange}
1420
+ value={field.value}
1421
+ >
1422
+ <SelectTrigger id="horarioFim">
1423
+ <SelectValue
1424
+ placeholder={t('form.fields.endTime.placeholder')}
1425
+ />
1426
+ </SelectTrigger>
1427
+ <SelectContent>
1428
+ {filteredEndTimeOptions.map((time) => (
1429
+ <SelectItem key={time} value={time}>
1430
+ {time}
1431
+ </SelectItem>
1432
+ ))}
1433
+ </SelectContent>
1434
+ </Select>
1435
+ )}
1436
+ />
1437
+ <FieldError>
1438
+ {form.formState.errors.horarioFim?.message}
1439
+ </FieldError>
1440
+ </Field>
1482
1441
 
1483
1442
  <Field>
1484
1443
  <FieldLabel htmlFor="sessionAccess">
@@ -1496,9 +1455,6 @@ export function ClassFormSheet({
1496
1455
  })
1497
1456
  }
1498
1457
  />
1499
- <FieldDescription>
1500
- {sessionAccessDescription}
1501
- </FieldDescription>
1502
1458
  <FieldError>
1503
1459
  {form.formState.errors.sessionAccess?.message}
1504
1460
  </FieldError>
@@ -1506,17 +1462,17 @@ export function ClassFormSheet({
1506
1462
  </div>
1507
1463
  </div>
1508
1464
 
1509
- <div className="rounded-lg border border-border/70 p-4">
1510
- <div className="space-y-4">
1511
- <div className="space-y-1">
1512
- <h3 className="text-sm font-semibold">
1513
- {t('form.recurrence.sectionTitle')}
1514
- </h3>
1515
- <p className="text-sm text-muted-foreground">
1516
- {t('form.recurrence.sectionDescription')}
1517
- </p>
1518
- </div>
1465
+ <div className="space-y-3">
1466
+ <div className="space-y-1">
1467
+ <h3 className="text-sm font-semibold">
1468
+ {t('form.recurrence.sectionTitle')}
1469
+ </h3>
1470
+ <p className="text-sm text-muted-foreground">
1471
+ {t('form.recurrence.sectionDescription')}
1472
+ </p>
1473
+ </div>
1519
1474
 
1475
+ <div className="grid grid-cols-1 gap-3 md:grid-cols-2">
1520
1476
  <Field>
1521
1477
  <FieldLabel>{t('form.recurrence.label')}</FieldLabel>
1522
1478
  <Select
@@ -1527,7 +1483,7 @@ export function ClassFormSheet({
1527
1483
  )
1528
1484
  }
1529
1485
  >
1530
- <SelectTrigger className="w-full md:w-56">
1486
+ <SelectTrigger>
1531
1487
  <SelectValue />
1532
1488
  </SelectTrigger>
1533
1489
  <SelectContent>
@@ -1559,133 +1515,122 @@ export function ClassFormSheet({
1559
1515
  </FieldError>
1560
1516
  </Field>
1561
1517
 
1562
- {(watchedFormValues.sessionRecurrenceMode === 'weekly' ||
1563
- watchedFormValues.sessionRecurrenceMode === 'weekdays' ||
1564
- (watchedFormValues.sessionRecurrenceMode === 'custom' &&
1565
- customRecurrenceFrequency === 'weekly')) && (
1566
- <Field>
1567
- <FieldLabel>
1568
- {t('form.recurrence.customDialog.repeatOn')}
1569
- </FieldLabel>
1570
- <div className="grid grid-cols-4 gap-2 sm:grid-cols-7">
1571
- {recurrenceDayOptions.map((day) => {
1572
- const active = (
1573
- watchedFormValues.sessionRecurrenceDaysOfWeek ?? []
1574
- ).includes(day.value);
1575
- const isWeekdays =
1576
- watchedFormValues.sessionRecurrenceMode ===
1577
- 'weekdays';
1578
- return (
1579
- <Button
1580
- key={day.value}
1581
- type="button"
1582
- variant={active ? 'default' : 'outline'}
1583
- size="sm"
1584
- className="h-9"
1585
- disabled={isWeekdays}
1586
- title={day.label}
1587
- aria-label={day.label}
1588
- onClick={() =>
1589
- toggleCustomRecurrenceDay(day.value)
1590
- }
1591
- >
1592
- {day.shortLabel}
1593
- </Button>
1594
- );
1595
- })}
1596
- </div>
1597
- <FieldError>
1598
- {
1599
- form.formState.errors.sessionRecurrenceDaysOfWeek
1600
- ?.message
1601
- }
1602
- </FieldError>
1603
- </Field>
1604
- )}
1518
+ <Field>
1519
+ <FieldLabel>
1520
+ {t('form.recurrence.titleMode.label')}
1521
+ </FieldLabel>
1522
+ <Controller
1523
+ name="sessionTitleMode"
1524
+ control={form.control}
1525
+ render={({ field }) => (
1526
+ <Select
1527
+ value={field.value}
1528
+ onValueChange={(value) => {
1529
+ field.onChange(value);
1530
+ if (value === 'default-course-code') {
1531
+ form.setValue(
1532
+ 'sessionTitle',
1533
+ defaultSessionTitle,
1534
+ {
1535
+ shouldDirty: true,
1536
+ shouldTouch: false,
1537
+ shouldValidate: false,
1538
+ }
1539
+ );
1540
+ }
1541
+ }}
1542
+ >
1543
+ <SelectTrigger>
1544
+ <SelectValue />
1545
+ </SelectTrigger>
1546
+ <SelectContent>
1547
+ <SelectItem value="default-course-code">
1548
+ {t('form.recurrence.titleMode.default')}
1549
+ </SelectItem>
1550
+ <SelectItem value="custom">
1551
+ {t('form.recurrence.titleMode.custom')}
1552
+ </SelectItem>
1553
+ </SelectContent>
1554
+ </Select>
1555
+ )}
1556
+ />
1557
+ </Field>
1605
1558
 
1606
- <div className="grid gap-4 md:grid-cols-[minmax(0,0.55fr)_minmax(0,1fr)]">
1607
- <Field>
1608
- <FieldLabel>
1609
- {t('form.recurrence.titleMode.label')}
1610
- </FieldLabel>
1611
- <Controller
1612
- name="sessionTitleMode"
1613
- control={form.control}
1614
- render={({ field }) => (
1615
- <Select
1616
- value={field.value}
1617
- onValueChange={(value) => {
1618
- field.onChange(value);
1619
- if (value === 'default-course-code') {
1620
- form.setValue(
1621
- 'sessionTitle',
1622
- defaultSessionTitle,
1623
- {
1624
- shouldDirty: true,
1625
- shouldTouch: false,
1626
- shouldValidate: false,
1627
- }
1628
- );
1629
- }
1630
- }}
1631
- >
1632
- <SelectTrigger>
1633
- <SelectValue />
1634
- </SelectTrigger>
1635
- <SelectContent>
1636
- <SelectItem value="default-course-code">
1637
- {t('form.recurrence.titleMode.default')}
1638
- </SelectItem>
1639
- <SelectItem value="custom">
1640
- {t('form.recurrence.titleMode.custom')}
1641
- </SelectItem>
1642
- </SelectContent>
1643
- </Select>
1644
- )}
1645
- />
1646
- </Field>
1647
-
1648
- <Field>
1649
- <FieldLabel htmlFor="sessionTitle">
1650
- {t('form.fields.sessionTitle.label')}
1651
- </FieldLabel>
1652
- <Input
1653
- id="sessionTitle"
1654
- value={
1655
- watchedFormValues.sessionTitleMode ===
1656
- 'default-course-code'
1657
- ? defaultSessionTitle
1658
- : (watchedFormValues.sessionTitle ?? '')
1659
- }
1660
- placeholder={t('form.fields.sessionTitle.placeholder')}
1661
- disabled={
1662
- watchedFormValues.sessionTitleMode ===
1663
- 'default-course-code'
1664
- }
1665
- onChange={(event) =>
1666
- form.setValue('sessionTitle', event.target.value, {
1667
- shouldDirty: true,
1668
- shouldTouch: true,
1669
- shouldValidate: false,
1670
- })
1671
- }
1672
- />
1673
- <FieldDescription>
1674
- {watchedFormValues.sessionTitleMode ===
1559
+ <Field>
1560
+ <FieldLabel htmlFor="sessionTitle">
1561
+ {t('form.fields.sessionTitle.label')}
1562
+ </FieldLabel>
1563
+ <Input
1564
+ id="sessionTitle"
1565
+ value={
1566
+ watchedFormValues.sessionTitleMode ===
1675
1567
  'default-course-code'
1676
- ? defaultSessionTitle ||
1677
- t('form.fields.sessionTitle.placeholder')
1678
- : recurrenceSummaryText}
1679
- </FieldDescription>
1680
- <FieldError>
1681
- {form.formState.errors.sessionTitle?.message}
1682
- </FieldError>
1683
- </Field>
1684
- </div>
1568
+ ? defaultSessionTitle
1569
+ : (watchedFormValues.sessionTitle ?? '')
1570
+ }
1571
+ placeholder={t('form.fields.sessionTitle.placeholder')}
1572
+ disabled={
1573
+ watchedFormValues.sessionTitleMode ===
1574
+ 'default-course-code'
1575
+ }
1576
+ onChange={(event) =>
1577
+ form.setValue('sessionTitle', event.target.value, {
1578
+ shouldDirty: true,
1579
+ shouldTouch: true,
1580
+ shouldValidate: false,
1581
+ })
1582
+ }
1583
+ />
1584
+ <FieldError>
1585
+ {form.formState.errors.sessionTitle?.message}
1586
+ </FieldError>
1587
+ </Field>
1685
1588
  </div>
1589
+
1590
+ {(watchedFormValues.sessionRecurrenceMode === 'weekly' ||
1591
+ watchedFormValues.sessionRecurrenceMode === 'weekdays' ||
1592
+ (watchedFormValues.sessionRecurrenceMode === 'custom' &&
1593
+ customRecurrenceFrequency === 'weekly')) && (
1594
+ <Field>
1595
+ <FieldLabel>
1596
+ {t('form.recurrence.customDialog.repeatOn')}
1597
+ </FieldLabel>
1598
+ <div className="grid grid-cols-4 gap-2 sm:grid-cols-7">
1599
+ {recurrenceDayOptions.map((day) => {
1600
+ const active = (
1601
+ watchedFormValues.sessionRecurrenceDaysOfWeek ?? []
1602
+ ).includes(day.value);
1603
+ const isWeekdays =
1604
+ watchedFormValues.sessionRecurrenceMode ===
1605
+ 'weekdays';
1606
+ return (
1607
+ <Button
1608
+ key={day.value}
1609
+ type="button"
1610
+ variant={active ? 'default' : 'outline'}
1611
+ size="sm"
1612
+ className="h-9"
1613
+ disabled={isWeekdays}
1614
+ title={day.label}
1615
+ aria-label={day.label}
1616
+ onClick={() => toggleCustomRecurrenceDay(day.value)}
1617
+ >
1618
+ {day.shortLabel}
1619
+ </Button>
1620
+ );
1621
+ })}
1622
+ </div>
1623
+ <FieldError>
1624
+ {
1625
+ form.formState.errors.sessionRecurrenceDaysOfWeek
1626
+ ?.message
1627
+ }
1628
+ </FieldError>
1629
+ </Field>
1630
+ )}
1686
1631
  </div>
1687
1632
 
1688
- <div className="grid gap-4 md:grid-cols-3">
1633
+ <div className="grid grid-cols-1 gap-3 md:grid-cols-2">
1689
1634
  <Field>
1690
1635
  <FieldLabel>
1691
1636
  {t('form.fields.type.label')}{' '}
@@ -1947,7 +1892,7 @@ export function ClassFormSheet({
1947
1892
  </SheetFooter>
1948
1893
  </form>
1949
1894
  )}
1950
- </SheetContent>
1895
+ </ResizableSheetContent>
1951
1896
  </Sheet>
1952
1897
 
1953
1898
  {/* Custom Recurrence Dialog */}