@hed-hog/lms 0.0.364 → 0.0.366
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bitcode-wallet/bitcode-wallet.service.d.ts +1 -0
- package/dist/bitcode-wallet/bitcode-wallet.service.d.ts.map +1 -1
- package/dist/bitcode-wallet/bitcode-wallet.service.js +22 -3
- package/dist/bitcode-wallet/bitcode-wallet.service.js.map +1 -1
- package/dist/class-group/class-group.controller.d.ts +1 -0
- package/dist/class-group/class-group.controller.d.ts.map +1 -1
- package/dist/class-group/class-group.service.d.ts +1 -0
- package/dist/class-group/class-group.service.d.ts.map +1 -1
- package/dist/course/course-export-scorm12-worker.service.d.ts +21 -0
- package/dist/course/course-export-scorm12-worker.service.d.ts.map +1 -0
- package/dist/course/course-export-scorm12-worker.service.js +109 -0
- package/dist/course/course-export-scorm12-worker.service.js.map +1 -0
- package/dist/course/course-export-scorm12.service.d.ts +42 -0
- package/dist/course/course-export-scorm12.service.d.ts.map +1 -0
- package/dist/course/course-export-scorm12.service.js +628 -0
- package/dist/course/course-export-scorm12.service.js.map +1 -0
- package/dist/course/course-export.service.d.ts +84 -0
- package/dist/course/course-export.service.d.ts.map +1 -0
- package/dist/course/course-export.service.js +237 -0
- package/dist/course/course-export.service.js.map +1 -0
- package/dist/course/course-structure.controller.d.ts +20 -10
- package/dist/course/course-structure.controller.d.ts.map +1 -1
- package/dist/course/course-structure.controller.js +20 -4
- package/dist/course/course-structure.controller.js.map +1 -1
- package/dist/course/course-structure.service.d.ts +12 -4
- package/dist/course/course-structure.service.d.ts.map +1 -1
- package/dist/course/course-structure.service.js +98 -23
- package/dist/course/course-structure.service.js.map +1 -1
- package/dist/course/course-video-agent-pipeline.service.d.ts +70 -0
- package/dist/course/course-video-agent-pipeline.service.d.ts.map +1 -0
- package/dist/course/course-video-agent-pipeline.service.js +398 -0
- package/dist/course/course-video-agent-pipeline.service.js.map +1 -0
- package/dist/course/course-video-hls.service.d.ts +71 -0
- package/dist/course/course-video-hls.service.d.ts.map +1 -0
- package/dist/course/course-video-hls.service.js +784 -0
- package/dist/course/course-video-hls.service.js.map +1 -0
- package/dist/course/course.controller.d.ts +47 -13
- package/dist/course/course.controller.d.ts.map +1 -1
- package/dist/course/course.controller.js +40 -26
- package/dist/course/course.controller.js.map +1 -1
- package/dist/course/course.mcp-tools.js +1 -1
- package/dist/course/course.mcp-tools.js.map +1 -1
- package/dist/course/course.module.d.ts.map +1 -1
- package/dist/course/course.module.js +16 -0
- package/dist/course/course.module.js.map +1 -1
- package/dist/course/course.service.d.ts +8 -9
- package/dist/course/course.service.d.ts.map +1 -1
- package/dist/course/course.service.js +93 -50
- package/dist/course/course.service.js.map +1 -1
- package/dist/course/dto/cleanup-course-storage.dto.d.ts +1 -1
- package/dist/course/dto/cleanup-course-storage.dto.d.ts.map +1 -1
- package/dist/course/dto/cleanup-course-storage.dto.js +1 -0
- package/dist/course/dto/cleanup-course-storage.dto.js.map +1 -1
- package/dist/course/dto/cleanup-upload-history.dto.d.ts +1 -1
- package/dist/course/dto/cleanup-upload-history.dto.d.ts.map +1 -1
- package/dist/course/dto/cleanup-upload-history.dto.js +1 -1
- package/dist/course/dto/cleanup-upload-history.dto.js.map +1 -1
- package/dist/course/dto/create-course-bulk-job.dto.d.ts +2 -1
- package/dist/course/dto/create-course-bulk-job.dto.d.ts.map +1 -1
- package/dist/course/dto/create-course-bulk-job.dto.js +6 -1
- package/dist/course/dto/create-course-bulk-job.dto.js.map +1 -1
- package/dist/course/dto/create-course-export.dto.d.ts +14 -0
- package/dist/course/dto/create-course-export.dto.d.ts.map +1 -0
- package/dist/course/dto/create-course-export.dto.js +71 -0
- package/dist/course/dto/create-course-export.dto.js.map +1 -0
- package/dist/course/dto/create-course-structure-lesson.dto.d.ts +2 -2
- package/dist/course/dto/create-course-structure-lesson.dto.d.ts.map +1 -1
- package/dist/course/dto/create-course-structure-lesson.dto.js +3 -2
- package/dist/course/dto/create-course-structure-lesson.dto.js.map +1 -1
- package/dist/course/ffmpeg.util.d.ts +10 -0
- package/dist/course/ffmpeg.util.d.ts.map +1 -0
- package/dist/course/ffmpeg.util.js +79 -0
- package/dist/course/ffmpeg.util.js.map +1 -0
- package/dist/course/lms-bulk-upload-automation.service.d.ts +18 -1
- package/dist/course/lms-bulk-upload-automation.service.d.ts.map +1 -1
- package/dist/course/lms-bulk-upload-automation.service.js +106 -8
- package/dist/course/lms-bulk-upload-automation.service.js.map +1 -1
- package/dist/course/lms-bulk-upload-infra.service.d.ts +1 -0
- package/dist/course/lms-bulk-upload-infra.service.d.ts.map +1 -1
- package/dist/course/lms-bulk-upload-infra.service.js +32 -8
- package/dist/course/lms-bulk-upload-infra.service.js.map +1 -1
- package/dist/course/lms-bulk-upload.controller.d.ts +30 -3
- package/dist/course/lms-bulk-upload.controller.d.ts.map +1 -1
- package/dist/course/lms-bulk-upload.controller.js +43 -2
- package/dist/course/lms-bulk-upload.controller.js.map +1 -1
- package/dist/course/lms-bulk-upload.service.d.ts +11 -0
- package/dist/course/lms-bulk-upload.service.d.ts.map +1 -1
- package/dist/course/lms-bulk-upload.service.js +59 -6
- package/dist/course/lms-bulk-upload.service.js.map +1 -1
- package/dist/course/lms-setting.controller.d.ts +2 -1
- package/dist/course/lms-setting.controller.d.ts.map +1 -1
- package/dist/course/lms-setting.controller.js +4 -2
- package/dist/course/lms-setting.controller.js.map +1 -1
- package/dist/course/scorm12-schemas.d.ts +4 -0
- package/dist/course/scorm12-schemas.d.ts.map +1 -0
- package/dist/course/scorm12-schemas.js +9 -0
- package/dist/course/scorm12-schemas.js.map +1 -0
- package/dist/enterprise/training/training-admin.controller.d.ts +2 -0
- package/dist/enterprise/training/training-admin.controller.d.ts.map +1 -1
- package/dist/enterprise/training/training-admin.service.d.ts +2 -0
- package/dist/enterprise/training/training-admin.service.d.ts.map +1 -1
- package/dist/enterprise/training/training-student.service.d.ts +51 -0
- package/dist/enterprise/training/training-student.service.d.ts.map +1 -1
- package/dist/enterprise/training/training-student.service.js +217 -4
- package/dist/enterprise/training/training-student.service.js.map +1 -1
- package/dist/evaluation/evaluation.service.d.ts +18 -0
- package/dist/evaluation/evaluation.service.d.ts.map +1 -1
- package/dist/evaluation/evaluation.service.js +125 -0
- package/dist/evaluation/evaluation.service.js.map +1 -1
- package/dist/exam/dto/create-standalone-question.dto.d.ts +12 -0
- package/dist/exam/dto/create-standalone-question.dto.d.ts.map +1 -0
- package/dist/exam/dto/create-standalone-question.dto.js +70 -0
- package/dist/exam/dto/create-standalone-question.dto.js.map +1 -0
- package/dist/exam/exam.module.d.ts.map +1 -1
- package/dist/exam/exam.module.js +2 -1
- package/dist/exam/exam.module.js.map +1 -1
- package/dist/exam/exam.service.d.ts +21 -0
- package/dist/exam/exam.service.d.ts.map +1 -1
- package/dist/exam/exam.service.js +80 -0
- package/dist/exam/exam.service.js.map +1 -1
- package/dist/exam/question.controller.d.ts +27 -0
- package/dist/exam/question.controller.d.ts.map +1 -0
- package/dist/exam/question.controller.js +53 -0
- package/dist/exam/question.controller.js.map +1 -0
- package/dist/lesson-xp-map/lesson-xp-ai-calculation.service.d.ts +4 -0
- package/dist/lesson-xp-map/lesson-xp-ai-calculation.service.d.ts.map +1 -1
- package/dist/lesson-xp-map/lesson-xp-ai-calculation.service.js +161 -25
- package/dist/lesson-xp-map/lesson-xp-ai-calculation.service.js.map +1 -1
- package/dist/libraries/lms/tsconfig.tsbuildinfo +1 -1
- package/dist/lms-commerce-access.subscriber.d.ts +11 -0
- package/dist/lms-commerce-access.subscriber.d.ts.map +1 -0
- package/dist/lms-commerce-access.subscriber.js +74 -0
- package/dist/lms-commerce-access.subscriber.js.map +1 -0
- package/dist/lms.module.d.ts.map +1 -1
- package/dist/lms.module.js +16 -5
- package/dist/lms.module.js.map +1 -1
- package/dist/platforma/dto/heartbeat.dto.d.ts +9 -0
- package/dist/platforma/dto/heartbeat.dto.d.ts.map +1 -0
- package/dist/platforma/dto/heartbeat.dto.js +50 -0
- package/dist/platforma/dto/heartbeat.dto.js.map +1 -0
- package/dist/platforma/handlers/emit-certificate.handler.d.ts +27 -0
- package/dist/platforma/handlers/emit-certificate.handler.d.ts.map +1 -0
- package/dist/platforma/handlers/emit-certificate.handler.js +117 -0
- package/dist/platforma/handlers/emit-certificate.handler.js.map +1 -0
- package/dist/platforma/handlers/lesson-heartbeat.handler.d.ts +31 -0
- package/dist/platforma/handlers/lesson-heartbeat.handler.d.ts.map +1 -0
- package/dist/platforma/handlers/lesson-heartbeat.handler.js +281 -0
- package/dist/platforma/handlers/lesson-heartbeat.handler.js.map +1 -0
- package/dist/platforma/platforma-heartbeat.service.d.ts +10 -0
- package/dist/platforma/platforma-heartbeat.service.d.ts.map +1 -0
- package/dist/platforma/platforma-heartbeat.service.js +50 -0
- package/dist/platforma/platforma-heartbeat.service.js.map +1 -0
- package/dist/platforma/platforma-performance.service.d.ts +121 -0
- package/dist/platforma/platforma-performance.service.d.ts.map +1 -0
- package/dist/platforma/platforma-performance.service.js +500 -0
- package/dist/platforma/platforma-performance.service.js.map +1 -0
- package/dist/platforma/platforma-search.service.d.ts +21 -0
- package/dist/platforma/platforma-search.service.d.ts.map +1 -0
- package/dist/platforma/platforma-search.service.js +64 -0
- package/dist/platforma/platforma-search.service.js.map +1 -0
- package/dist/platforma/platforma-video.service.d.ts +39 -0
- package/dist/platforma/platforma-video.service.d.ts.map +1 -0
- package/dist/platforma/platforma-video.service.js +301 -0
- package/dist/platforma/platforma-video.service.js.map +1 -0
- package/dist/platforma/platforma.controller.d.ts +209 -1
- package/dist/platforma/platforma.controller.d.ts.map +1 -1
- package/dist/platforma/platforma.controller.js +208 -2
- package/dist/platforma/platforma.controller.js.map +1 -1
- package/dist/realtime/lms-realtime.controller.d.ts +2 -0
- package/dist/realtime/lms-realtime.controller.d.ts.map +1 -1
- package/dist/realtime/lms-realtime.controller.js +31 -0
- package/dist/realtime/lms-realtime.controller.js.map +1 -1
- package/dist/realtime/lms-realtime.service.d.ts +1 -1
- package/dist/realtime/lms-realtime.service.d.ts.map +1 -1
- package/dist/realtime/lms-realtime.service.js.map +1 -1
- package/dist/student-xp/dto/grant-skill-card-xp.dto.d.ts +5 -0
- package/dist/student-xp/dto/grant-skill-card-xp.dto.d.ts.map +1 -0
- package/dist/student-xp/dto/grant-skill-card-xp.dto.js +26 -0
- package/dist/student-xp/dto/grant-skill-card-xp.dto.js.map +1 -0
- package/dist/student-xp/student-xp.controller.d.ts +15 -0
- package/dist/student-xp/student-xp.controller.d.ts.map +1 -1
- package/dist/student-xp/student-xp.controller.js +24 -0
- package/dist/student-xp/student-xp.controller.js.map +1 -1
- package/dist/student-xp/student-xp.service.d.ts +16 -0
- package/dist/student-xp/student-xp.service.d.ts.map +1 -1
- package/dist/student-xp/student-xp.service.js +51 -1
- package/dist/student-xp/student-xp.service.js.map +1 -1
- package/hedhog/data/evaluation_topic.yaml +17 -0
- package/hedhog/data/menu.yaml +0 -17
- package/hedhog/data/queue_definition.yaml +48 -0
- package/hedhog/data/route.yaml +94 -124
- package/hedhog/data/setting_group.yaml +19 -19
- package/hedhog/frontend/app/bulk-upload-sessions/page.tsx.ejs +337 -41
- package/hedhog/frontend/app/certificates/models/page.tsx.ejs +182 -29
- package/hedhog/frontend/app/classes/_components/classes-calendar-view.tsx.ejs +277 -0
- package/hedhog/frontend/app/classes/page.tsx.ejs +127 -20
- package/hedhog/frontend/app/courses/[id]/page.tsx.ejs +69 -4
- package/hedhog/frontend/app/courses/[id]/structure/_components/course-export-sheet.tsx.ejs +420 -0
- package/hedhog/frontend/app/courses/[id]/structure/_components/course-exports-tab.tsx.ejs +308 -0
- package/hedhog/frontend/app/courses/[id]/structure/_components/course-overview-tab.tsx.ejs +158 -45
- package/hedhog/frontend/app/courses/[id]/structure/_components/course-xp-overview-tab.tsx.ejs +13 -13
- package/hedhog/frontend/app/courses/[id]/structure/_components/detail-lesson-xp-tab.tsx.ejs +11 -23
- package/hedhog/frontend/app/courses/[id]/structure/_components/detail-lesson.tsx.ejs +51 -63
- package/hedhog/frontend/app/courses/[id]/structure/_components/detail-panel.tsx.ejs +8 -3
- package/hedhog/frontend/app/courses/[id]/structure/_components/detail-session.tsx.ejs +31 -8
- package/hedhog/frontend/app/courses/[id]/structure/_components/drag-overlay.tsx.ejs +16 -9
- package/hedhog/frontend/app/courses/[id]/structure/_components/editor-course.tsx.ejs +201 -401
- package/hedhog/frontend/app/courses/[id]/structure/_components/editor-lesson.tsx.ejs +378 -690
- package/hedhog/frontend/app/courses/[id]/structure/_components/mock-data.ts.ejs +1 -2
- package/hedhog/frontend/app/courses/[id]/structure/_components/tree-row-lesson.tsx.ejs +3 -9
- package/hedhog/frontend/app/courses/[id]/structure/_components/types.ts.ejs +1 -1
- package/hedhog/frontend/app/courses/[id]/structure/_components/xp-premium-pills.tsx.ejs +1 -8
- package/hedhog/frontend/app/courses/[id]/structure/_data/adapters/course-structure.adapter.ts.ejs +6 -10
- package/hedhog/frontend/app/courses/[id]/structure/_data/services/course-structure.service.ts.ejs +49 -0
- package/hedhog/frontend/app/courses/[id]/structure/_data/types/api-course.types.ts.ejs +4 -3
- package/hedhog/frontend/app/courses/[id]/structure/_data/use-course-content-overview.ts.ejs +2 -1
- package/hedhog/frontend/app/courses/[id]/structure/_data/use-course-exports.ts.ejs +106 -0
- package/hedhog/frontend/app/courses/[id]/structure/_data/use-course-structure-mutations.ts.ejs +28 -1
- package/hedhog/frontend/app/courses/[id]/structure/_data/use-lms-settings-query.ts.ejs +0 -2
- package/hedhog/frontend/app/courses/page.tsx.ejs +85 -9
- package/hedhog/frontend/app/enterprise/[id]/page.tsx.ejs +6 -0
- package/hedhog/frontend/app/enterprise/_components/enterprise-classes-calendar-tab.tsx.ejs +264 -0
- package/hedhog/frontend/app/enterprise/page.tsx.ejs +104 -47
- package/hedhog/frontend/app/exams/page.tsx.ejs +38 -4
- package/hedhog/frontend/app/instructors/page.tsx.ejs +87 -46
- package/hedhog/frontend/app/paths/page.tsx.ejs +38 -4
- package/hedhog/frontend/app/training/page.tsx.ejs +38 -4
- package/hedhog/frontend/messages/en.json +44 -28
- package/hedhog/frontend/messages/pt.json +47 -29
- package/hedhog/table/course_enrollment.yaml +3 -0
- package/hedhog/table/course_export.yaml +62 -0
- package/hedhog/table/lesson_view_event.yaml +66 -0
- package/package.json +14 -9
- package/src/bitcode-wallet/bitcode-wallet.service.ts +43 -4
- package/src/course/course-export-scorm12-worker.service.ts +124 -0
- package/src/course/course-export-scorm12.service.ts +668 -0
- package/src/course/course-export.service.ts +280 -0
- package/src/course/course-structure.controller.ts +16 -2
- package/src/course/course-structure.service.ts +100 -7
- package/src/course/course-video-agent-pipeline.service.ts +471 -0
- package/src/course/course-video-hls.service.ts +966 -0
- package/src/course/course.controller.ts +33 -19
- package/src/course/course.mcp-tools.ts +1 -1
- package/src/course/course.module.ts +16 -0
- package/src/course/course.service.ts +119 -61
- package/src/course/dto/cleanup-course-storage.dto.ts +1 -0
- package/src/course/dto/cleanup-upload-history.dto.ts +1 -1
- package/src/course/dto/create-course-bulk-job.dto.ts +7 -3
- package/src/course/dto/create-course-export.dto.ts +56 -0
- package/src/course/dto/create-course-structure-lesson.dto.ts +4 -3
- package/src/course/ffmpeg.util.ts +65 -0
- package/src/course/lms-bulk-upload-automation.service.ts +156 -6
- package/src/course/lms-bulk-upload-infra.service.ts +39 -6
- package/src/course/lms-bulk-upload.controller.ts +32 -2
- package/src/course/lms-bulk-upload.service.ts +70 -7
- package/src/course/lms-setting.controller.ts +4 -2
- package/src/course/scorm12-schemas.ts +9 -0
- package/src/enterprise/training/training-student.service.ts +221 -2
- package/src/evaluation/evaluation.service.ts +123 -0
- package/src/exam/dto/create-standalone-question.dto.ts +66 -0
- package/src/exam/exam.module.ts +2 -1
- package/src/exam/exam.service.ts +86 -0
- package/src/exam/question.controller.ts +28 -0
- package/src/lesson-xp-map/lesson-xp-ai-calculation.service.ts +205 -31
- package/src/lms-commerce-access.subscriber.ts +88 -0
- package/src/lms.module.ts +16 -5
- package/src/platforma/dto/heartbeat.dto.ts +30 -0
- package/src/platforma/handlers/emit-certificate.handler.ts +117 -0
- package/src/platforma/handlers/lesson-heartbeat.handler.ts +343 -0
- package/src/platforma/platforma-heartbeat.service.ts +33 -0
- package/src/platforma/platforma-performance.service.ts +606 -0
- package/src/platforma/platforma-search.service.ts +48 -0
- package/src/platforma/platforma-video.service.ts +346 -0
- package/src/platforma/platforma.controller.ts +137 -1
- package/src/platforma/platforma.service.ts +268 -268
- package/src/realtime/lms-realtime.controller.ts +27 -1
- package/src/realtime/lms-realtime.service.ts +2 -1
- package/src/student-xp/dto/grant-skill-card-xp.dto.ts +10 -0
- package/src/student-xp/student-xp.controller.ts +18 -2
- package/src/student-xp/student-xp.service.ts +84 -2
- package/hedhog/data/video_resolution_profile.yaml +0 -7
- package/hedhog/frontend/app/video-resolution-profiles/page.tsx.ejs +0 -607
- package/hedhog/table/course_video_resolution_profile.yaml +0 -22
- package/hedhog/table/video_resolution_profile.yaml +0 -18
- package/src/video-resolution-profile/dto/create-video-resolution-profile.dto.ts +0 -16
- package/src/video-resolution-profile/dto/update-video-resolution-profile.dto.ts +0 -16
- package/src/video-resolution-profile/video-resolution-profile.controller.ts +0 -62
- package/src/video-resolution-profile/video-resolution-profile.mcp-tools.ts +0 -128
- package/src/video-resolution-profile/video-resolution-profile.module.ts +0 -13
- package/src/video-resolution-profile/video-resolution-profile.service.ts +0 -117
|
@@ -72,7 +72,7 @@ const TITLE_PATTERNS = [
|
|
|
72
72
|
'Conceitos fundamentais',
|
|
73
73
|
'Configuracao do ambiente',
|
|
74
74
|
'Pratica guiada passo a passo',
|
|
75
|
-
'
|
|
75
|
+
'Pratica: implementacao',
|
|
76
76
|
'Quiz de revisao',
|
|
77
77
|
'Caso de uso real',
|
|
78
78
|
'Implementacao completa',
|
|
@@ -107,7 +107,6 @@ const LESSON_TYPES: LessonType[] = [
|
|
|
107
107
|
'video',
|
|
108
108
|
'video',
|
|
109
109
|
'questao',
|
|
110
|
-
'exercicio',
|
|
111
110
|
];
|
|
112
111
|
const PROVIDERS: VideoProvider[] = [
|
|
113
112
|
'youtube',
|
|
@@ -7,8 +7,8 @@ import {
|
|
|
7
7
|
TooltipTrigger,
|
|
8
8
|
} from '@/components/ui/tooltip';
|
|
9
9
|
import { cn } from '@/lib/utils';
|
|
10
|
+
import { useApp, useQuery } from '@hed-hog/next-app-provider';
|
|
10
11
|
import {
|
|
11
|
-
ClipboardList,
|
|
12
12
|
Clock3,
|
|
13
13
|
Eye,
|
|
14
14
|
EyeOff,
|
|
@@ -24,19 +24,18 @@ import {
|
|
|
24
24
|
} from 'lucide-react';
|
|
25
25
|
import { useTranslations } from 'next-intl';
|
|
26
26
|
import { useEffect, useRef } from 'react';
|
|
27
|
-
import { useApp, useQuery } from '@hed-hog/next-app-provider';
|
|
28
|
-
import { useUpdateLessonMutation } from '../_data/use-course-structure-mutations';
|
|
29
27
|
import {
|
|
30
28
|
getQueueJob,
|
|
31
29
|
type QueueJobStatus,
|
|
32
30
|
} from '../_data/services/course-structure.service';
|
|
31
|
+
import { useUpdateLessonMutation } from '../_data/use-course-structure-mutations';
|
|
33
32
|
import { HighlightedText } from './highlighted-text';
|
|
34
33
|
import { useStructureStore } from './store';
|
|
35
|
-
import type { Lesson, LessonStatus, LessonType } from './types';
|
|
36
34
|
import {
|
|
37
35
|
getLessonAttachedResourceCount,
|
|
38
36
|
getLessonUploadedVideoCount,
|
|
39
37
|
} from './tree-helpers';
|
|
38
|
+
import type { Lesson, LessonStatus, LessonType } from './types';
|
|
40
39
|
import { useTreeDisplaySettings } from './use-tree-display-settings';
|
|
41
40
|
|
|
42
41
|
// ── Type configs ──────────────────────────────────────────────────────────────
|
|
@@ -48,11 +47,6 @@ const LESSON_TYPE_CONFIG: Record<
|
|
|
48
47
|
video: { icon: Video, color: 'text-violet-500', label: 'Vídeo' },
|
|
49
48
|
post: { icon: FileText, color: 'text-emerald-500', label: 'Post' },
|
|
50
49
|
questao: { icon: HelpCircle, color: 'text-amber-500', label: 'Quiz' },
|
|
51
|
-
exercicio: {
|
|
52
|
-
icon: ClipboardList,
|
|
53
|
-
color: 'text-rose-500',
|
|
54
|
-
label: 'Exercício',
|
|
55
|
-
},
|
|
56
50
|
};
|
|
57
51
|
|
|
58
52
|
const STATUS_CONFIG: Record<LessonStatus, { label: string; dot: string }> = {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Types — LMS Course Structure TreeView
|
|
3
3
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
4
4
|
|
|
5
|
-
export type LessonType = 'video' | 'questao' | 'post'
|
|
5
|
+
export type LessonType = 'video' | 'questao' | 'post';
|
|
6
6
|
export type VideoProvider = 'youtube' | 'vimeo' | 'file_storage';
|
|
7
7
|
export type ItemType = 'course' | 'session' | 'lesson';
|
|
8
8
|
|
|
@@ -11,14 +11,7 @@ export function XpHighlightPill({
|
|
|
11
11
|
value: string;
|
|
12
12
|
tone: 'sky' | 'amber' | 'emerald' | 'violet';
|
|
13
13
|
}) {
|
|
14
|
-
const toneClassName =
|
|
15
|
-
tone === 'sky'
|
|
16
|
-
? 'border-sky-500/15 bg-sky-500/10 text-sky-700 dark:text-sky-300'
|
|
17
|
-
: tone === 'amber'
|
|
18
|
-
? 'border-amber-500/15 bg-amber-500/10 text-amber-700 dark:text-amber-300'
|
|
19
|
-
: tone === 'emerald'
|
|
20
|
-
? 'border-emerald-500/15 bg-emerald-500/10 text-emerald-700 dark:text-emerald-300'
|
|
21
|
-
: 'border-violet-500/15 bg-violet-500/10 text-violet-700 dark:text-violet-300';
|
|
14
|
+
const toneClassName = 'border-border/60 bg-muted/30 text-muted-foreground';
|
|
22
15
|
|
|
23
16
|
return (
|
|
24
17
|
<div
|
package/hedhog/frontend/app/courses/[id]/structure/_data/adapters/course-structure.adapter.ts.ejs
CHANGED
|
@@ -14,9 +14,8 @@
|
|
|
14
14
|
*
|
|
15
15
|
* ⚠️ KNOWN MISMATCHES (documented with inline comments):
|
|
16
16
|
* 1. exameVinculado (number) ↔ linkedExam (string) — converted with String()/Number()
|
|
17
|
-
* 2.
|
|
18
|
-
* 3.
|
|
19
|
-
* 4. Resource.size / url — not returned by API; left as empty string / undefined.
|
|
17
|
+
* 2. Session.order — not returned by API; inferred from sorted array position.
|
|
18
|
+
* 3. Resource.size / url — not returned by API; left as empty string / undefined.
|
|
20
19
|
*/
|
|
21
20
|
|
|
22
21
|
import type {
|
|
@@ -55,7 +54,7 @@ import type {
|
|
|
55
54
|
* Map backend lesson type to the frontend LessonType union.
|
|
56
55
|
*
|
|
57
56
|
* ⚠️ ADAPTER POINT:
|
|
58
|
-
*
|
|
57
|
+
* Keep this helper updated if backend introduces new lesson type aliases.
|
|
59
58
|
*/
|
|
60
59
|
function normalizeLessonType(tipo: ApiLesson['tipo']): LessonType {
|
|
61
60
|
return tipo as LessonType;
|
|
@@ -129,7 +128,7 @@ export function normalizeCourse(raw: ApiCourse): Course {
|
|
|
129
128
|
description: raw.descricao,
|
|
130
129
|
slug: raw.slug,
|
|
131
130
|
offeringType: raw.offeringType,
|
|
132
|
-
published:
|
|
131
|
+
published: raw.status === 'published',
|
|
133
132
|
};
|
|
134
133
|
}
|
|
135
134
|
|
|
@@ -301,9 +300,7 @@ export function toCreateLessonPayload(
|
|
|
301
300
|
): ApiCreateLessonPayload {
|
|
302
301
|
return {
|
|
303
302
|
titulo: data.title,
|
|
304
|
-
|
|
305
|
-
// backend accepts it. Cast is safe as long as LessonType ⊆ ApiLesson['tipo'].
|
|
306
|
-
tipo: data.type as ApiCreateLessonPayload['tipo'],
|
|
303
|
+
tipo: data.type,
|
|
307
304
|
duracao: data.duration,
|
|
308
305
|
published: data.published,
|
|
309
306
|
statusProducao: data.status,
|
|
@@ -361,8 +358,7 @@ export function toUpdateLessonPayload(
|
|
|
361
358
|
): ApiUpdateLessonPayload {
|
|
362
359
|
const payload: ApiUpdateLessonPayload = {};
|
|
363
360
|
if (data.title !== undefined) payload.titulo = data.title;
|
|
364
|
-
if (data.type !== undefined)
|
|
365
|
-
payload.tipo = data.type as ApiCreateLessonPayload['tipo'];
|
|
361
|
+
if (data.type !== undefined) payload.tipo = data.type;
|
|
366
362
|
if (data.duration !== undefined) payload.duracao = data.duration;
|
|
367
363
|
if (data.published !== undefined) payload.published = data.published;
|
|
368
364
|
if (data.status !== undefined) payload.statusProducao = data.status;
|
package/hedhog/frontend/app/courses/[id]/structure/_data/services/course-structure.service.ts.ejs
CHANGED
|
@@ -54,6 +54,7 @@ type RequestFn = (input: {
|
|
|
54
54
|
data?: unknown;
|
|
55
55
|
headers?: Record<string, string>;
|
|
56
56
|
onUploadProgress?: (event: { loaded: number; total?: number }) => void;
|
|
57
|
+
showErrors?: boolean;
|
|
57
58
|
}) => Promise<{ data: unknown }>;
|
|
58
59
|
|
|
59
60
|
export type QueueJobStatus =
|
|
@@ -584,6 +585,7 @@ export async function getQueueJob(
|
|
|
584
585
|
const response = await request({
|
|
585
586
|
url: `/queue/jobs/${jobId}`,
|
|
586
587
|
method: 'GET',
|
|
588
|
+
showErrors: false,
|
|
587
589
|
});
|
|
588
590
|
return extractData<QueueJobResponse>(response);
|
|
589
591
|
}
|
|
@@ -604,3 +606,50 @@ export async function deleteFile(
|
|
|
604
606
|
data: { ids: [fileId] },
|
|
605
607
|
});
|
|
606
608
|
}
|
|
609
|
+
|
|
610
|
+
// ── Questions ─────────────────────────────────────────────────────────────────
|
|
611
|
+
|
|
612
|
+
export interface ApiQuestion {
|
|
613
|
+
id: number;
|
|
614
|
+
questionType: string;
|
|
615
|
+
statement: string;
|
|
616
|
+
points: number;
|
|
617
|
+
subjectId: number | null;
|
|
618
|
+
subjectName: string | null;
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
export interface ApiQuestionListResponse {
|
|
622
|
+
total: number;
|
|
623
|
+
page: number;
|
|
624
|
+
limit: number;
|
|
625
|
+
data: ApiQuestion[];
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
export interface CreateQuestionPayload {
|
|
629
|
+
statement: string;
|
|
630
|
+
questionType?: string;
|
|
631
|
+
points?: number;
|
|
632
|
+
subjectId?: number;
|
|
633
|
+
explanation?: string;
|
|
634
|
+
alternatives?: { text: string; isCorrect: boolean }[];
|
|
635
|
+
fillBlankAnswers?: { answer: string; alternatives?: string[] }[];
|
|
636
|
+
matchingPairs?: { id: string; leftText: string; rightText: string }[];
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
export async function listQuestions(
|
|
640
|
+
request: RequestFn,
|
|
641
|
+
search?: string
|
|
642
|
+
): Promise<ApiQuestionListResponse> {
|
|
643
|
+
const params = new URLSearchParams({ limit: '100' });
|
|
644
|
+
if (search?.trim()) params.set('search', search.trim());
|
|
645
|
+
const response = await request({ url: `/lms/questions?${params}`, method: 'GET' });
|
|
646
|
+
return response.data as ApiQuestionListResponse;
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
export async function createQuestion(
|
|
650
|
+
request: RequestFn,
|
|
651
|
+
dto: CreateQuestionPayload
|
|
652
|
+
): Promise<ApiQuestion> {
|
|
653
|
+
const response = await request({ url: '/lms/questions', method: 'POST', data: dto });
|
|
654
|
+
return response.data as ApiQuestion;
|
|
655
|
+
}
|
|
@@ -65,7 +65,7 @@ export interface ApiLessonInstructor {
|
|
|
65
65
|
* The backend maps DB lesson types to UI types in mapDbTypeToUiType():
|
|
66
66
|
* DB 'video' → UI 'video'
|
|
67
67
|
* DB 'text' → UI 'post'
|
|
68
|
-
* DB 'quiz' → UI 'questao'
|
|
68
|
+
* DB 'quiz' → UI 'questao' (based on content.sourceType)
|
|
69
69
|
*
|
|
70
70
|
* ⚠️ BACKEND NOTE — missing fields:
|
|
71
71
|
* `order` and `visibility` are NOT included in the API response.
|
|
@@ -80,7 +80,7 @@ export interface ApiLesson {
|
|
|
80
80
|
descricaoPrivada: string;
|
|
81
81
|
locale_id?: number | null;
|
|
82
82
|
/** UI-level lesson type resolved by the backend service. */
|
|
83
|
-
tipo: 'video' | 'questao' | 'post'
|
|
83
|
+
tipo: 'video' | 'questao' | 'post';
|
|
84
84
|
/** Duration in minutes. */
|
|
85
85
|
duracao: number;
|
|
86
86
|
published?: boolean;
|
|
@@ -140,6 +140,7 @@ export interface ApiCourse {
|
|
|
140
140
|
titulo: string;
|
|
141
141
|
descricao: string;
|
|
142
142
|
offeringType?: 'scheduled' | 'on_demand' | 'blended';
|
|
143
|
+
status?: 'draft' | 'published' | 'archived';
|
|
143
144
|
recursos?: ApiCourseResource[];
|
|
144
145
|
}
|
|
145
146
|
|
|
@@ -207,7 +208,7 @@ export interface ApiUpdateSessionPayload {
|
|
|
207
208
|
*/
|
|
208
209
|
export interface ApiCreateLessonPayload {
|
|
209
210
|
titulo: string;
|
|
210
|
-
tipo: 'video' | 'questao' | 'post'
|
|
211
|
+
tipo: 'video' | 'questao' | 'post';
|
|
211
212
|
/** Duration in minutes. */
|
|
212
213
|
duracao: number;
|
|
213
214
|
published?: boolean;
|
|
@@ -11,13 +11,14 @@ export type CourseContentOverview = {
|
|
|
11
11
|
video: number;
|
|
12
12
|
questao: number;
|
|
13
13
|
post: number;
|
|
14
|
-
exercicio: number;
|
|
15
14
|
};
|
|
16
15
|
};
|
|
17
16
|
videos: {
|
|
18
17
|
lessonCount: number;
|
|
19
18
|
withTranscription: number;
|
|
20
19
|
withXp: number;
|
|
20
|
+
withVideo: number;
|
|
21
|
+
withProcessedVideo: number;
|
|
21
22
|
};
|
|
22
23
|
media: {
|
|
23
24
|
extractedImageCount: number;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useApp, useQuery } from '@hed-hog/next-app-provider';
|
|
4
|
+
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
|
5
|
+
|
|
6
|
+
export type ScormVisualSettings = {
|
|
7
|
+
primaryColor?: string;
|
|
8
|
+
fontFamily?: string;
|
|
9
|
+
fontSize?: string;
|
|
10
|
+
sidebarWidth?: number;
|
|
11
|
+
sidebarPosition?: string;
|
|
12
|
+
progressStyle?: string;
|
|
13
|
+
sidebarTheme?: string;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export type CourseExportRecord = {
|
|
17
|
+
id: number;
|
|
18
|
+
format: string;
|
|
19
|
+
status: 'pending' | 'processing' | 'completed' | 'failed';
|
|
20
|
+
settings: Record<string, unknown> | null;
|
|
21
|
+
duration_seconds: number | null;
|
|
22
|
+
error_message: string | null;
|
|
23
|
+
created_at: string;
|
|
24
|
+
finished_at: string | null;
|
|
25
|
+
file_id: number | null;
|
|
26
|
+
notification_id: number | null;
|
|
27
|
+
file: {
|
|
28
|
+
id: number;
|
|
29
|
+
path: string;
|
|
30
|
+
filename: string;
|
|
31
|
+
size: number | null;
|
|
32
|
+
} | null;
|
|
33
|
+
user: {
|
|
34
|
+
id: number;
|
|
35
|
+
name: string;
|
|
36
|
+
photo_id: number | null;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export function courseExportsQueryKey(courseId: string) {
|
|
41
|
+
return ['course-exports', courseId] as const;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function useCourseExportsQuery(courseId: string | null) {
|
|
45
|
+
const { request } = useApp();
|
|
46
|
+
|
|
47
|
+
return useQuery<CourseExportRecord[]>({
|
|
48
|
+
queryKey: courseExportsQueryKey(courseId ?? ''),
|
|
49
|
+
enabled: Boolean(courseId),
|
|
50
|
+
queryFn: async () => {
|
|
51
|
+
const res = await request<CourseExportRecord[]>({
|
|
52
|
+
url: `/lms/courses/${courseId}/exports`,
|
|
53
|
+
method: 'GET',
|
|
54
|
+
});
|
|
55
|
+
return res.data ?? [];
|
|
56
|
+
},
|
|
57
|
+
initialData: [],
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function useCreateCourseExportMutation(courseId: string | null) {
|
|
62
|
+
const { request } = useApp();
|
|
63
|
+
const queryClient = useQueryClient();
|
|
64
|
+
|
|
65
|
+
return useMutation({
|
|
66
|
+
mutationFn: async (payload: {
|
|
67
|
+
format: 'scorm_1_2';
|
|
68
|
+
visualSettings?: ScormVisualSettings;
|
|
69
|
+
}) => {
|
|
70
|
+
const res = await request<{
|
|
71
|
+
exportId: number;
|
|
72
|
+
queueJobId: number;
|
|
73
|
+
notificationId: number;
|
|
74
|
+
}>({
|
|
75
|
+
url: `/lms/courses/${courseId}/exports`,
|
|
76
|
+
method: 'POST',
|
|
77
|
+
data: payload,
|
|
78
|
+
});
|
|
79
|
+
return res.data;
|
|
80
|
+
},
|
|
81
|
+
onSuccess: () => {
|
|
82
|
+
queryClient.invalidateQueries({
|
|
83
|
+
queryKey: courseExportsQueryKey(courseId ?? ''),
|
|
84
|
+
});
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export function useDeleteCourseExportMutation(courseId: string | null) {
|
|
90
|
+
const { request } = useApp();
|
|
91
|
+
const queryClient = useQueryClient();
|
|
92
|
+
|
|
93
|
+
return useMutation({
|
|
94
|
+
mutationFn: async (exportId: number) => {
|
|
95
|
+
await request({
|
|
96
|
+
url: `/lms/courses/${courseId}/exports/${exportId}`,
|
|
97
|
+
method: 'DELETE',
|
|
98
|
+
});
|
|
99
|
+
},
|
|
100
|
+
onSuccess: () => {
|
|
101
|
+
queryClient.invalidateQueries({
|
|
102
|
+
queryKey: courseExportsQueryKey(courseId ?? ''),
|
|
103
|
+
});
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
}
|
package/hedhog/frontend/app/courses/[id]/structure/_data/use-course-structure-mutations.ts.ejs
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
* onError: restore cache snapshot + Zustand rollback
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
|
-
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
|
23
|
+
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
|
24
24
|
import { useTranslations } from 'next-intl';
|
|
25
25
|
import { toast } from 'sonner';
|
|
26
26
|
|
|
@@ -54,6 +54,9 @@ import {
|
|
|
54
54
|
updateCourse as apiUpdateCourse,
|
|
55
55
|
updateLesson as apiUpdateLesson,
|
|
56
56
|
updateSession as apiUpdateSession,
|
|
57
|
+
listQuestions as apiListQuestions,
|
|
58
|
+
createQuestion as apiCreateQuestion,
|
|
59
|
+
type CreateQuestionPayload,
|
|
57
60
|
} from './services/course-structure.service';
|
|
58
61
|
import type { CourseStructureCacheData } from './use-course-structure-query';
|
|
59
62
|
import { courseStructureQueryKey } from './use-course-structure-query';
|
|
@@ -1104,3 +1107,27 @@ export function useUpdateResourceTypeMutation() {
|
|
|
1104
1107
|
},
|
|
1105
1108
|
});
|
|
1106
1109
|
}
|
|
1110
|
+
|
|
1111
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
1112
|
+
// useQuestionsQuery / useCreateQuestionMutation
|
|
1113
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
1114
|
+
|
|
1115
|
+
export function useQuestionsQuery(search?: string) {
|
|
1116
|
+
const { request } = useApp();
|
|
1117
|
+
return useQuery({
|
|
1118
|
+
queryKey: ['lms-questions', search ?? ''],
|
|
1119
|
+
queryFn: () => apiListQuestions(request, search),
|
|
1120
|
+
staleTime: 30_000,
|
|
1121
|
+
});
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
export function useCreateQuestionMutation() {
|
|
1125
|
+
const { request } = useApp();
|
|
1126
|
+
const queryClient = useQueryClient();
|
|
1127
|
+
return useMutation({
|
|
1128
|
+
mutationFn: (dto: CreateQuestionPayload) => apiCreateQuestion(request, dto),
|
|
1129
|
+
onSuccess: () => {
|
|
1130
|
+
void queryClient.invalidateQueries({ queryKey: ['lms-questions'] });
|
|
1131
|
+
},
|
|
1132
|
+
});
|
|
1133
|
+
}
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
import { useApp, useQuery } from '@hed-hog/next-app-provider';
|
|
4
4
|
|
|
5
5
|
export interface LmsFeatureFlags {
|
|
6
|
-
videoConversionEnabled: boolean;
|
|
7
6
|
imageExtractionEnabled: boolean;
|
|
8
7
|
transcriptionEnabled: boolean;
|
|
9
8
|
youtubeEnabled: boolean;
|
|
@@ -11,7 +10,6 @@ export interface LmsFeatureFlags {
|
|
|
11
10
|
}
|
|
12
11
|
|
|
13
12
|
const DEFAULT_FLAGS: LmsFeatureFlags = {
|
|
14
|
-
videoConversionEnabled: true,
|
|
15
13
|
imageExtractionEnabled: true,
|
|
16
14
|
transcriptionEnabled: true,
|
|
17
15
|
youtubeEnabled: true,
|
|
@@ -95,6 +95,7 @@ interface Curso {
|
|
|
95
95
|
criadoEm: string;
|
|
96
96
|
logoFileId?: number | null;
|
|
97
97
|
operationsProjectId?: number | null;
|
|
98
|
+
processando?: boolean;
|
|
98
99
|
}
|
|
99
100
|
|
|
100
101
|
type ApiCourse = {
|
|
@@ -122,6 +123,7 @@ type ApiCourse = {
|
|
|
122
123
|
createdAt: string;
|
|
123
124
|
logoFileId?: number | null;
|
|
124
125
|
operationsProjectId?: number | null;
|
|
126
|
+
hasRunningJobs?: boolean;
|
|
125
127
|
};
|
|
126
128
|
|
|
127
129
|
type ApiCourseList = {
|
|
@@ -238,6 +240,7 @@ function mapApiCourse(course: ApiCourse): Curso {
|
|
|
238
240
|
criadoEm: course.createdAt ?? '',
|
|
239
241
|
logoFileId: course.logoFileId ?? null,
|
|
240
242
|
operationsProjectId: course.operationsProjectId ?? null,
|
|
243
|
+
processando: course.hasRunningJobs ?? false,
|
|
241
244
|
};
|
|
242
245
|
}
|
|
243
246
|
|
|
@@ -315,7 +318,7 @@ const OFFERING_TYPE_COLOR: Record<string, string> = {
|
|
|
315
318
|
hibrido: 'bg-teal-50 text-teal-700 border-teal-200',
|
|
316
319
|
};
|
|
317
320
|
|
|
318
|
-
const
|
|
321
|
+
const DEFAULT_PAGE_SIZES = [6, 12, 24, 48, 96] as const;
|
|
319
322
|
|
|
320
323
|
// ── Seed Data ─────────────────────────────────────────────────────────────────
|
|
321
324
|
|
|
@@ -385,10 +388,44 @@ export default function CursosPage() {
|
|
|
385
388
|
|
|
386
389
|
// Pagination
|
|
387
390
|
const [currentPage, setCurrentPage] = useState(1);
|
|
391
|
+
|
|
392
|
+
const { data: generalSettings } = useQuery<{
|
|
393
|
+
data: Array<{ slug: string; value: string }>;
|
|
394
|
+
}>({
|
|
395
|
+
queryKey: ['setting-group-general'],
|
|
396
|
+
queryFn: async () => {
|
|
397
|
+
const response = await request<{
|
|
398
|
+
data: Array<{ slug: string; value: string }>;
|
|
399
|
+
}>({
|
|
400
|
+
url: '/setting/group/general',
|
|
401
|
+
method: 'GET',
|
|
402
|
+
});
|
|
403
|
+
return response.data;
|
|
404
|
+
},
|
|
405
|
+
staleTime: 5 * 60 * 1000,
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
const pageSizeOptions = useMemo(() => {
|
|
409
|
+
const setting = generalSettings?.data?.find(
|
|
410
|
+
(s) => s.slug === 'pagination-page-sizes'
|
|
411
|
+
);
|
|
412
|
+
if (!setting?.value) return DEFAULT_PAGE_SIZES;
|
|
413
|
+
try {
|
|
414
|
+
const parsed = JSON.parse(setting.value) as string[];
|
|
415
|
+
const sizes = parsed
|
|
416
|
+
.map(Number)
|
|
417
|
+
.filter((n) => !isNaN(n) && n > 0)
|
|
418
|
+
.sort((a, b) => a - b);
|
|
419
|
+
return sizes.length > 0 ? sizes : DEFAULT_PAGE_SIZES;
|
|
420
|
+
} catch {
|
|
421
|
+
return DEFAULT_PAGE_SIZES;
|
|
422
|
+
}
|
|
423
|
+
}, [generalSettings]);
|
|
424
|
+
|
|
388
425
|
const [pageSize, setPageSize] = usePersistedPageSize({
|
|
389
426
|
storageKey: 'pagination:global:pageSize',
|
|
390
427
|
defaultValue: 12,
|
|
391
|
-
allowedValues:
|
|
428
|
+
allowedValues: pageSizeOptions,
|
|
392
429
|
});
|
|
393
430
|
|
|
394
431
|
const form = useForm<CourseSheetFormValues>({
|
|
@@ -1088,7 +1125,7 @@ export default function CursosPage() {
|
|
|
1088
1125
|
],
|
|
1089
1126
|
},
|
|
1090
1127
|
]}
|
|
1091
|
-
|
|
1128
|
+
actions={
|
|
1092
1129
|
<ViewModeToggle
|
|
1093
1130
|
viewMode={viewMode}
|
|
1094
1131
|
onViewModeChange={setViewMode}
|
|
@@ -1289,12 +1326,9 @@ export default function CursosPage() {
|
|
|
1289
1326
|
/>
|
|
1290
1327
|
) : (
|
|
1291
1328
|
<div className="relative">
|
|
1292
|
-
{cardsRefreshing && (
|
|
1293
|
-
<div className="absolute inset-0 z-10 rounded-2xl bg-background/55 backdrop-blur-[1px]" />
|
|
1294
|
-
)}
|
|
1295
1329
|
{viewMode === 'cards' ? (
|
|
1296
1330
|
<motion.div
|
|
1297
|
-
className=
|
|
1331
|
+
className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3"
|
|
1298
1332
|
variants={stagger}
|
|
1299
1333
|
initial="hidden"
|
|
1300
1334
|
animate="show"
|
|
@@ -1405,6 +1439,27 @@ export default function CursosPage() {
|
|
|
1405
1439
|
</Badge>
|
|
1406
1440
|
</motion.div>
|
|
1407
1441
|
)}
|
|
1442
|
+
{curso.processando &&
|
|
1443
|
+
!deletingCourseIds.has(curso.id) && (
|
|
1444
|
+
<motion.div
|
|
1445
|
+
initial={{ opacity: 0, scale: 0.8 }}
|
|
1446
|
+
animate={{ opacity: 1, scale: 1 }}
|
|
1447
|
+
exit={{ opacity: 0, scale: 0.8 }}
|
|
1448
|
+
transition={{
|
|
1449
|
+
type: 'spring',
|
|
1450
|
+
stiffness: 300,
|
|
1451
|
+
damping: 30,
|
|
1452
|
+
}}
|
|
1453
|
+
>
|
|
1454
|
+
<Badge
|
|
1455
|
+
variant="secondary"
|
|
1456
|
+
className="gap-1 rounded-full px-2 py-0.5 text-[10px]"
|
|
1457
|
+
>
|
|
1458
|
+
<Loader2 className="size-2.5 animate-spin" />
|
|
1459
|
+
Processando...
|
|
1460
|
+
</Badge>
|
|
1461
|
+
</motion.div>
|
|
1462
|
+
)}
|
|
1408
1463
|
</div>
|
|
1409
1464
|
</div>
|
|
1410
1465
|
</div>
|
|
@@ -1440,7 +1495,7 @@ export default function CursosPage() {
|
|
|
1440
1495
|
</motion.div>
|
|
1441
1496
|
) : (
|
|
1442
1497
|
<div
|
|
1443
|
-
className=
|
|
1498
|
+
className="overflow-hidden rounded-xl border border-border/70"
|
|
1444
1499
|
>
|
|
1445
1500
|
<Table>
|
|
1446
1501
|
<TableHeader>
|
|
@@ -1554,6 +1609,27 @@ export default function CursosPage() {
|
|
|
1554
1609
|
</Badge>
|
|
1555
1610
|
</motion.div>
|
|
1556
1611
|
)}
|
|
1612
|
+
{curso.processando &&
|
|
1613
|
+
!deletingCourseIds.has(curso.id) && (
|
|
1614
|
+
<motion.div
|
|
1615
|
+
initial={{ opacity: 0, scale: 0.8 }}
|
|
1616
|
+
animate={{ opacity: 1, scale: 1 }}
|
|
1617
|
+
exit={{ opacity: 0, scale: 0.8 }}
|
|
1618
|
+
transition={{
|
|
1619
|
+
type: 'spring',
|
|
1620
|
+
stiffness: 300,
|
|
1621
|
+
damping: 30,
|
|
1622
|
+
}}
|
|
1623
|
+
>
|
|
1624
|
+
<Badge
|
|
1625
|
+
variant="secondary"
|
|
1626
|
+
className="gap-1 text-[11px]"
|
|
1627
|
+
>
|
|
1628
|
+
<Loader2 className="size-2.5 animate-spin" />
|
|
1629
|
+
Processando...
|
|
1630
|
+
</Badge>
|
|
1631
|
+
</motion.div>
|
|
1632
|
+
)}
|
|
1557
1633
|
{curso.destaque && (
|
|
1558
1634
|
<span className="inline-flex items-center gap-1 rounded-full border border-amber-200 bg-amber-50 px-2 py-0.5 text-[11px] font-medium text-amber-700">
|
|
1559
1635
|
<Star className="size-3 fill-amber-400 text-amber-400" />
|
|
@@ -1627,7 +1703,7 @@ export default function CursosPage() {
|
|
|
1627
1703
|
setPageSize(nextPageSize);
|
|
1628
1704
|
setCurrentPage(1);
|
|
1629
1705
|
}}
|
|
1630
|
-
pageSizeOptions={
|
|
1706
|
+
pageSizeOptions={pageSizeOptions}
|
|
1631
1707
|
selectedCount={selectedIds.size}
|
|
1632
1708
|
/>
|
|
1633
1709
|
</div>
|
|
@@ -25,6 +25,7 @@ import { notFound, useParams, useRouter } from 'next/navigation';
|
|
|
25
25
|
import { useState } from 'react';
|
|
26
26
|
import { AdministratorsTab } from '../_components/enterprise-administrators-tab';
|
|
27
27
|
import { ClassesTab } from '../_components/enterprise-classes-tab';
|
|
28
|
+
import { ClassesCalendarTab } from '../_components/enterprise-classes-calendar-tab';
|
|
28
29
|
import { CoursesTab } from '../_components/enterprise-courses-tab';
|
|
29
30
|
import { EnterpriseSheet } from '../_components/enterprise-sheet';
|
|
30
31
|
import { StudentsTab } from '../_components/enterprise-students-tab';
|
|
@@ -265,6 +266,7 @@ export default function EnterpriseDetailPage() {
|
|
|
265
266
|
<TabsTrigger value="overview">{t('tabs.overview')}</TabsTrigger>
|
|
266
267
|
<TabsTrigger value="crm">{t('tabs.crm')}</TabsTrigger>
|
|
267
268
|
<TabsTrigger value="classes">{t('tabs.classes')}</TabsTrigger>
|
|
269
|
+
<TabsTrigger value="classesCalendar">{t('tabs.classesCalendar')}</TabsTrigger>
|
|
268
270
|
<TabsTrigger value="courses">{t('tabs.courses')}</TabsTrigger>
|
|
269
271
|
<TabsTrigger value="students">{t('tabs.students')}</TabsTrigger>
|
|
270
272
|
<TabsTrigger value="administrators">
|
|
@@ -288,6 +290,10 @@ export default function EnterpriseDetailPage() {
|
|
|
288
290
|
<ClassesTab enterpriseId={account.id} />
|
|
289
291
|
</TabsContent>
|
|
290
292
|
|
|
293
|
+
<TabsContent value="classesCalendar" className="mt-4 px-1">
|
|
294
|
+
<ClassesCalendarTab enterpriseId={account.id} />
|
|
295
|
+
</TabsContent>
|
|
296
|
+
|
|
291
297
|
<TabsContent value="courses" className="mt-4">
|
|
292
298
|
<CoursesTab enterpriseId={account.id} />
|
|
293
299
|
</TabsContent>
|