@hed-hog/lms 0.0.331 → 0.0.347
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/class-group/class-group.controller.d.ts +8 -8
- package/dist/class-group/class-group.service.d.ts +8 -8
- package/dist/course/course.controller.d.ts +6 -1
- package/dist/course/course.controller.d.ts.map +1 -1
- package/dist/course/course.controller.js +19 -2
- package/dist/course/course.controller.js.map +1 -1
- package/dist/course/course.service.d.ts +6 -0
- package/dist/course/course.service.d.ts.map +1 -1
- package/dist/course/course.service.js +63 -28
- package/dist/course/course.service.js.map +1 -1
- package/dist/course/dto/create-course.dto.d.ts +1 -0
- package/dist/course/dto/create-course.dto.d.ts.map +1 -1
- package/dist/course/dto/create-course.dto.js +5 -0
- package/dist/course/dto/create-course.dto.js.map +1 -1
- package/dist/enterprise/enterprise.controller.d.ts +84 -12
- package/dist/enterprise/enterprise.controller.d.ts.map +1 -1
- package/dist/enterprise/enterprise.controller.js +10 -0
- package/dist/enterprise/enterprise.controller.js.map +1 -1
- package/dist/enterprise/enterprise.service.d.ts +90 -12
- package/dist/enterprise/enterprise.service.d.ts.map +1 -1
- package/dist/enterprise/enterprise.service.js +413 -40
- package/dist/enterprise/enterprise.service.js.map +1 -1
- package/dist/enterprise/training/training-admin.controller.d.ts +9 -6
- package/dist/enterprise/training/training-admin.controller.d.ts.map +1 -1
- package/dist/enterprise/training/training-admin.controller.js +10 -6
- package/dist/enterprise/training/training-admin.controller.js.map +1 -1
- package/dist/enterprise/training/training-admin.service.d.ts +11 -5
- package/dist/enterprise/training/training-admin.service.d.ts.map +1 -1
- package/dist/enterprise/training/training-admin.service.js +108 -52
- package/dist/enterprise/training/training-admin.service.js.map +1 -1
- package/dist/enterprise/training/training-viewer.controller.d.ts +3 -0
- package/dist/enterprise/training/training-viewer.controller.d.ts.map +1 -1
- package/dist/evaluation/evaluation.controller.d.ts +2 -2
- package/dist/evaluation/evaluation.service.d.ts +2 -2
- package/dist/instructor/dto/create-instructor-skill.dto.d.ts +0 -4
- package/dist/instructor/dto/create-instructor-skill.dto.d.ts.map +1 -1
- package/dist/instructor/dto/create-instructor-skill.dto.js +0 -21
- package/dist/instructor/dto/create-instructor-skill.dto.js.map +1 -1
- package/dist/instructor/dto/update-instructor-skill.dto.d.ts +0 -4
- package/dist/instructor/dto/update-instructor-skill.dto.d.ts.map +1 -1
- package/dist/instructor/dto/update-instructor-skill.dto.js +0 -22
- package/dist/instructor/dto/update-instructor-skill.dto.js.map +1 -1
- package/dist/instructor/instructor-skill.controller.d.ts +4 -4
- package/dist/instructor/instructor-skill.service.d.ts +4 -7
- package/dist/instructor/instructor-skill.service.d.ts.map +1 -1
- package/dist/instructor/instructor-skill.service.js +2 -89
- package/dist/instructor/instructor-skill.service.js.map +1 -1
- package/dist/instructor/instructor.controller.d.ts +21 -0
- package/dist/instructor/instructor.controller.d.ts.map +1 -1
- package/dist/instructor/instructor.controller.js +19 -0
- package/dist/instructor/instructor.controller.js.map +1 -1
- package/dist/instructor/instructor.service.d.ts +27 -0
- package/dist/instructor/instructor.service.d.ts.map +1 -1
- package/dist/instructor/instructor.service.js +79 -25
- package/dist/instructor/instructor.service.js.map +1 -1
- package/dist/lms.module.d.ts.map +1 -1
- package/dist/lms.module.js.map +1 -1
- package/dist/training/dto/create-training.dto.d.ts +1 -0
- package/dist/training/dto/create-training.dto.d.ts.map +1 -1
- package/dist/training/dto/create-training.dto.js +5 -0
- package/dist/training/dto/create-training.dto.js.map +1 -1
- package/dist/training/training.controller.d.ts +4 -0
- package/dist/training/training.controller.d.ts.map +1 -1
- package/dist/training/training.service.d.ts +8 -0
- package/dist/training/training.service.d.ts.map +1 -1
- package/dist/training/training.service.js +71 -6
- package/dist/training/training.service.js.map +1 -1
- package/hedhog/data/route.yaml +23 -1
- package/hedhog/frontend/app/_components/class-form-sheet.tsx.ejs +80 -33
- package/hedhog/frontend/app/_components/course-form-sheet.tsx.ejs +3 -3
- package/hedhog/frontend/app/_components/create-lms-instructor-sheet.tsx.ejs +591 -0
- package/hedhog/frontend/app/certificates/issued/page.tsx.ejs +6 -1
- package/hedhog/frontend/app/certificates/models/page.tsx.ejs +39 -7
- package/hedhog/frontend/app/classes/[id]/page.tsx.ejs +1 -3
- package/hedhog/frontend/app/classes/page.tsx.ejs +34 -7
- package/hedhog/frontend/app/courses/[id]/_components/CourseClassificationCard.tsx.ejs +3 -33
- package/hedhog/frontend/app/courses/[id]/_components/CourseContentCard.tsx.ejs +9 -9
- package/hedhog/frontend/app/courses/[id]/_components/CourseMainInfoCard.tsx.ejs +109 -0
- package/hedhog/frontend/app/courses/[id]/_components/CourseMultiEntityPicker.tsx.ejs +40 -13
- package/hedhog/frontend/app/courses/[id]/_components/CourseRelationsCard.tsx.ejs +76 -81
- package/hedhog/frontend/app/courses/[id]/_components/CourseSummaryCard.tsx.ejs +60 -0
- package/hedhog/frontend/app/courses/[id]/structure/_components/course-scheduled-classes-tab.tsx.ejs +406 -0
- package/hedhog/frontend/app/courses/[id]/structure/_components/course-tree.tsx.ejs +134 -0
- package/hedhog/frontend/app/courses/[id]/structure/_components/detail-course.tsx.ejs +113 -0
- package/hedhog/frontend/app/courses/[id]/structure/_components/detail-lesson.tsx.ejs +314 -0
- package/hedhog/frontend/app/courses/[id]/structure/_components/detail-session.tsx.ejs +174 -0
- package/hedhog/frontend/app/courses/[id]/structure/_components/editor-course.tsx.ejs +243 -34
- package/hedhog/frontend/app/courses/[id]/structure/_components/mock-data.ts.ejs +185 -0
- package/hedhog/frontend/app/courses/page.tsx.ejs +6 -1
- package/hedhog/frontend/app/enterprise/_components/enterprise-activity-timeline.tsx.ejs +87 -0
- package/hedhog/frontend/app/enterprise/_components/enterprise-admin-create-sheet.tsx.ejs +4 -0
- package/hedhog/frontend/app/enterprise/_components/enterprise-administrators-tab.tsx.ejs +31 -5
- package/hedhog/frontend/app/enterprise/_components/enterprise-classes-tab.tsx.ejs +79 -20
- package/hedhog/frontend/app/enterprise/_components/enterprise-company-identity-card.tsx.ejs +11 -2
- package/hedhog/frontend/app/enterprise/_components/enterprise-course-edit-sheet.tsx.ejs +201 -0
- package/hedhog/frontend/app/enterprise/_components/enterprise-courses-tab.tsx.ejs +55 -24
- package/hedhog/frontend/app/enterprise/_components/enterprise-detail-sheet.tsx.ejs +430 -296
- package/hedhog/frontend/app/enterprise/_components/enterprise-mocks.ts.ejs +277 -0
- package/hedhog/frontend/app/enterprise/_components/enterprise-overview-analytics.tsx.ejs +205 -0
- package/hedhog/frontend/app/enterprise/_components/enterprise-person-edit-sheet.tsx.ejs +97 -0
- package/hedhog/frontend/app/enterprise/_components/enterprise-sheet.tsx.ejs +82 -57
- package/hedhog/frontend/app/enterprise/_components/enterprise-student-create-sheet.tsx.ejs +4 -0
- package/hedhog/frontend/app/enterprise/_components/enterprise-students-tab.tsx.ejs +60 -22
- package/hedhog/frontend/app/enterprise/_components/enterprise-types.ts.ejs +54 -0
- package/hedhog/frontend/app/enterprise/_components/enterprise-user-create-sheet.tsx.ejs +211 -0
- package/hedhog/frontend/app/enterprise/page.tsx.ejs +39 -7
- package/hedhog/frontend/app/exams/[id]/questions/page.tsx.ejs +31 -19
- package/hedhog/frontend/app/exams/page.tsx.ejs +6 -1
- package/hedhog/frontend/app/instructor-skills/page.tsx.ejs +51 -104
- package/hedhog/frontend/app/instructors/_components/instructor-form-sheet.tsx.ejs +625 -366
- package/hedhog/frontend/app/instructors/page.tsx.ejs +6 -1
- package/hedhog/frontend/app/paths/page.tsx.ejs +76 -8
- package/hedhog/frontend/app/reports/evaluations/page.tsx.ejs +6 -1
- package/hedhog/frontend/app/training/page.tsx.ejs +78 -9
- package/hedhog/frontend/messages/en.json +101 -10
- package/hedhog/frontend/messages/pt.json +115 -11
- package/hedhog/table/enterprise_student_license_event.yaml +30 -0
- package/hedhog/table/instructor_skill.yaml +0 -11
- package/hedhog/table/learning_path.yaml +4 -0
- package/package.json +6 -6
- package/src/course/course.controller.ts +18 -0
- package/src/course/course.service.ts +85 -26
- package/src/course/dto/create-course.dto.ts +4 -0
- package/src/enterprise/enterprise.controller.ts +5 -0
- package/src/enterprise/enterprise.service.ts +507 -29
- package/src/enterprise/training/training-admin.controller.ts +4 -0
- package/src/enterprise/training/training-admin.service.ts +115 -51
- package/src/instructor/dto/create-instructor-skill.dto.ts +0 -17
- package/src/instructor/dto/update-instructor-skill.dto.ts +0 -18
- package/src/instructor/instructor-skill.service.ts +2 -97
- package/src/instructor/instructor.controller.ts +16 -0
- package/src/instructor/instructor.service.ts +87 -10
- package/src/lms.module.ts +1 -0
- package/src/training/dto/create-training.dto.ts +4 -0
- package/src/training/training.service.ts +104 -5
|
@@ -1544,7 +1544,20 @@
|
|
|
1544
1544
|
"description": {
|
|
1545
1545
|
"label": "Descrição",
|
|
1546
1546
|
"placeholder": "Descreva a formação...",
|
|
1547
|
-
"required":
|
|
1547
|
+
"required": false
|
|
1548
|
+
},
|
|
1549
|
+
"progressionMode": {
|
|
1550
|
+
"label": "Fluxo da Trilha",
|
|
1551
|
+
"placeholder": "Selecione o fluxo",
|
|
1552
|
+
"required": true,
|
|
1553
|
+
"options": {
|
|
1554
|
+
"sequential": "Exigir ordem dos passos",
|
|
1555
|
+
"free": "Liberar navegação entre passos"
|
|
1556
|
+
},
|
|
1557
|
+
"help": {
|
|
1558
|
+
"sequential": "O aluno precisa concluir cada etapa da trilha antes de avançar para a próxima.",
|
|
1559
|
+
"free": "O aluno pode abrir qualquer etapa da trilha a qualquer momento, sem bloqueio de sequência."
|
|
1560
|
+
}
|
|
1548
1561
|
},
|
|
1549
1562
|
"area": {
|
|
1550
1563
|
"label": "Área",
|
|
@@ -2916,6 +2929,11 @@
|
|
|
2916
2929
|
"subFree": "{count} vagas livres",
|
|
2917
2930
|
"subFull": "Lotada"
|
|
2918
2931
|
},
|
|
2932
|
+
"nextClass": "Próxima Aula",
|
|
2933
|
+
"noClass": "Sem aula",
|
|
2934
|
+
"createNext": "Crie a próxima aula",
|
|
2935
|
+
"calendar": "Calendário",
|
|
2936
|
+
"completed": "{count} concluída(s)",
|
|
2919
2937
|
"avgAttendance": {
|
|
2920
2938
|
"label": "Presença Média",
|
|
2921
2939
|
"sub": "frequência geral"
|
|
@@ -3547,10 +3565,92 @@
|
|
|
3547
3565
|
"studentRemoveError": "Falha ao remover aluno."
|
|
3548
3566
|
},
|
|
3549
3567
|
"form": {
|
|
3568
|
+
"title": {
|
|
3569
|
+
"create": "Criar Novo Curso",
|
|
3570
|
+
"edit": "Editar Curso"
|
|
3571
|
+
},
|
|
3572
|
+
"description": {
|
|
3573
|
+
"create": "Preencha os dados para criar um novo curso. Após criar, você será redirecionado para a página do curso.",
|
|
3574
|
+
"edit": "Atualize as informações do curso abaixo."
|
|
3575
|
+
},
|
|
3576
|
+
"fields": {
|
|
3577
|
+
"internalName": {
|
|
3578
|
+
"label": "Nome Interno",
|
|
3579
|
+
"placeholder": "Ex: React Avançado",
|
|
3580
|
+
"description": "Nome interno do curso para uso administrativo"
|
|
3581
|
+
},
|
|
3582
|
+
"slug": {
|
|
3583
|
+
"label": "Slug",
|
|
3584
|
+
"placeholder": "Ex: react-avancado",
|
|
3585
|
+
"description": "Identificador único na URL (letras minúsculas, números e hífens)"
|
|
3586
|
+
},
|
|
3587
|
+
"commercialTitle": {
|
|
3588
|
+
"label": "Título Comercial",
|
|
3589
|
+
"placeholder": "Ex: React Avançado"
|
|
3590
|
+
},
|
|
3591
|
+
"description": {
|
|
3592
|
+
"label": "Descrição",
|
|
3593
|
+
"placeholder": "Descreva o conteúdo e objetivos do curso..."
|
|
3594
|
+
},
|
|
3595
|
+
"level": {
|
|
3596
|
+
"label": "Nível",
|
|
3597
|
+
"placeholder": "Selecione"
|
|
3598
|
+
},
|
|
3599
|
+
"status": {
|
|
3600
|
+
"label": "Status",
|
|
3601
|
+
"placeholder": "Selecione"
|
|
3602
|
+
},
|
|
3603
|
+
"categories": {
|
|
3604
|
+
"label": "Categorias",
|
|
3605
|
+
"description": "Selecione uma ou mais categorias",
|
|
3606
|
+
"createAction": "Criar categoria",
|
|
3607
|
+
"selectPlaceholder": "Selecione uma categoria",
|
|
3608
|
+
"removeAction": "Remover categoria",
|
|
3609
|
+
"searchPlaceholder": "Digite para buscar categoria...",
|
|
3610
|
+
"noResults": "Nenhuma categoria encontrada",
|
|
3611
|
+
"selectedCount": "categoria(s) selecionada(s)"
|
|
3612
|
+
},
|
|
3613
|
+
"primaryColor": {
|
|
3614
|
+
"label": "Cor Primária",
|
|
3615
|
+
"placeholder": "#1D4ED8"
|
|
3616
|
+
},
|
|
3617
|
+
"secondaryColor": {
|
|
3618
|
+
"label": "Cor Secundária",
|
|
3619
|
+
"placeholder": "#111827"
|
|
3620
|
+
},
|
|
3621
|
+
"logo": {
|
|
3622
|
+
"label": "Logo do Curso",
|
|
3623
|
+
"alt": "Logo do curso",
|
|
3624
|
+
"upload": "Carregar logo",
|
|
3625
|
+
"replace": "Substituir logo",
|
|
3626
|
+
"remove": "Remover",
|
|
3627
|
+
"description": "Imagem opcional para identificar o curso"
|
|
3628
|
+
}
|
|
3629
|
+
},
|
|
3630
|
+
"validation": {
|
|
3631
|
+
"internalNameMinLength": "Nome interno deve ter pelo menos 3 caracteres",
|
|
3632
|
+
"slugPattern": "Slug deve conter apenas letras minúsculas, números e hífens"
|
|
3633
|
+
},
|
|
3634
|
+
"actions": {
|
|
3635
|
+
"cancel": "Cancelar",
|
|
3636
|
+
"save": "Salvar Alterações",
|
|
3637
|
+
"create": "Criar Curso"
|
|
3638
|
+
},
|
|
3550
3639
|
"toasts": {
|
|
3551
3640
|
"courseCreated": "Curso criado com sucesso! Redirecionando...",
|
|
3552
3641
|
"courseCreateError": "Não foi possível criar o curso."
|
|
3553
3642
|
}
|
|
3643
|
+
},
|
|
3644
|
+
"levels": {
|
|
3645
|
+
"beginner": "Iniciante",
|
|
3646
|
+
"intermediate": "Intermediário",
|
|
3647
|
+
"advanced": "Avançado"
|
|
3648
|
+
},
|
|
3649
|
+
"status": {
|
|
3650
|
+
"active": "Ativo",
|
|
3651
|
+
"inactive": "Inativo",
|
|
3652
|
+
"draft": "Rascunho",
|
|
3653
|
+
"archived": "Arquivado"
|
|
3554
3654
|
}
|
|
3555
3655
|
},
|
|
3556
3656
|
"InstructorsPage": {
|
|
@@ -3661,9 +3761,17 @@
|
|
|
3661
3761
|
"classes": {
|
|
3662
3762
|
"emptyTitle": "Nenhuma turma encontrada",
|
|
3663
3763
|
"emptyDescription": "Este instrutor ainda não está vinculado a nenhuma turma.",
|
|
3764
|
+
"searchPlaceholder": "Buscar turma por nome, código ou curso...",
|
|
3765
|
+
"statusFilterPlaceholder": "Filtrar por status",
|
|
3766
|
+
"allStatuses": "Todos os status",
|
|
3664
3767
|
"start": "Início:",
|
|
3665
3768
|
"end": "Fim:",
|
|
3666
|
-
"students": "{count} aluno(s)"
|
|
3769
|
+
"students": "{count} aluno(s)",
|
|
3770
|
+
"studentsOfCapacity": "{count} / {total} aluno(s)",
|
|
3771
|
+
"actions": {
|
|
3772
|
+
"editAriaLabel": "Editar turma",
|
|
3773
|
+
"openAriaLabel": "Abrir página da turma"
|
|
3774
|
+
}
|
|
3667
3775
|
},
|
|
3668
3776
|
"evaluations": {
|
|
3669
3777
|
"comingSoonTitle": "Avaliações — funcionalidade em breve",
|
|
@@ -3713,23 +3821,17 @@
|
|
|
3713
3821
|
"current": "Skills de Instrutor"
|
|
3714
3822
|
},
|
|
3715
3823
|
"filters": {
|
|
3716
|
-
"searchPlaceholder": "Buscar por slug
|
|
3824
|
+
"searchPlaceholder": "Buscar por slug..."
|
|
3717
3825
|
},
|
|
3718
3826
|
"table": {
|
|
3719
3827
|
"slug": "Slug",
|
|
3720
|
-
"namePt": "Nome (PT)",
|
|
3721
|
-
"nameEn": "Nome (EN)",
|
|
3722
3828
|
"status": "Status"
|
|
3723
3829
|
},
|
|
3724
3830
|
"form": {
|
|
3725
3831
|
"slug": "Slug",
|
|
3726
3832
|
"slugPlaceholder": "ex.: javascript, react-js",
|
|
3727
|
-
"namePt": "Nome (PT)",
|
|
3728
|
-
"namePtPlaceholder": "Nome em português",
|
|
3729
|
-
"nameEn": "Nome (EN)",
|
|
3730
|
-
"nameEnPlaceholder": "Nome em inglês (opcional)",
|
|
3731
3833
|
"status": "Status",
|
|
3732
|
-
"statusPlaceholder": "Selecione
|
|
3834
|
+
"statusPlaceholder": "Selecione um status",
|
|
3733
3835
|
"validation": {
|
|
3734
3836
|
"required": "Obrigatório",
|
|
3735
3837
|
"max100": "Máximo 100 caracteres",
|
|
@@ -3942,7 +4044,8 @@
|
|
|
3942
4044
|
},
|
|
3943
4045
|
"actions": {
|
|
3944
4046
|
"create": "Criar nova turma",
|
|
3945
|
-
"add": "Adicionar"
|
|
4047
|
+
"add": "Adicionar",
|
|
4048
|
+
"edit": "Editar"
|
|
3946
4049
|
},
|
|
3947
4050
|
"empty": {
|
|
3948
4051
|
"title": "Nenhuma turma encontrada.",
|
|
@@ -3950,6 +4053,7 @@
|
|
|
3950
4053
|
},
|
|
3951
4054
|
"table": {
|
|
3952
4055
|
"class": "Turma",
|
|
4056
|
+
"instructor": "Instrutor",
|
|
3953
4057
|
"status": "Status",
|
|
3954
4058
|
"period": "Período",
|
|
3955
4059
|
"capacity": "Capacidade"
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
columns:
|
|
2
|
+
- type: pk
|
|
3
|
+
- name: enterprise_id
|
|
4
|
+
type: fk
|
|
5
|
+
references:
|
|
6
|
+
table: enterprise
|
|
7
|
+
column: id
|
|
8
|
+
onDelete: CASCADE
|
|
9
|
+
- name: person_id
|
|
10
|
+
type: fk
|
|
11
|
+
references:
|
|
12
|
+
table: person
|
|
13
|
+
column: id
|
|
14
|
+
onDelete: CASCADE
|
|
15
|
+
- name: event_type
|
|
16
|
+
type: enum
|
|
17
|
+
values: [assigned, revoked, status_changed]
|
|
18
|
+
- name: previous_status
|
|
19
|
+
type: varchar
|
|
20
|
+
length: 32
|
|
21
|
+
isNullable: true
|
|
22
|
+
- name: next_status
|
|
23
|
+
type: varchar
|
|
24
|
+
length: 32
|
|
25
|
+
isNullable: true
|
|
26
|
+
- type: created_at
|
|
27
|
+
|
|
28
|
+
indices:
|
|
29
|
+
- columns: [enterprise_id, created_at]
|
|
30
|
+
- columns: [person_id, created_at]
|
|
@@ -2,17 +2,6 @@ columns:
|
|
|
2
2
|
- type: pk
|
|
3
3
|
- name: slug
|
|
4
4
|
isUnique: true
|
|
5
|
-
- name: name
|
|
6
|
-
type: locale_varchar
|
|
7
|
-
locale:
|
|
8
|
-
pt: Nome
|
|
9
|
-
en: Name
|
|
10
|
-
- name: description
|
|
11
|
-
type: locale_text
|
|
12
|
-
isNullable: true
|
|
13
|
-
locale:
|
|
14
|
-
pt: Descrição
|
|
15
|
-
en: Description
|
|
16
5
|
- name: status
|
|
17
6
|
type: enum
|
|
18
7
|
values: [active, inactive]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hed-hog/lms",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.347",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"dependencies": {
|
|
@@ -9,15 +9,15 @@
|
|
|
9
9
|
"@nestjs/core": "^11",
|
|
10
10
|
"@nestjs/jwt": "^11",
|
|
11
11
|
"@nestjs/mapped-types": "*",
|
|
12
|
+
"@hed-hog/api-prisma": "0.0.6",
|
|
12
13
|
"@hed-hog/api-types": "0.0.1",
|
|
13
14
|
"@hed-hog/api-locale": "0.0.14",
|
|
14
15
|
"@hed-hog/api": "0.0.8",
|
|
15
|
-
"@hed-hog/api-prisma": "0.0.6",
|
|
16
|
-
"@hed-hog/contact": "0.0.331",
|
|
17
16
|
"@hed-hog/api-pagination": "0.0.7",
|
|
18
|
-
"@hed-hog/category": "0.0.
|
|
19
|
-
"@hed-hog/
|
|
20
|
-
"@hed-hog/
|
|
17
|
+
"@hed-hog/category": "0.0.347",
|
|
18
|
+
"@hed-hog/contact": "0.0.347",
|
|
19
|
+
"@hed-hog/finance": "0.0.347",
|
|
20
|
+
"@hed-hog/core": "0.0.347"
|
|
21
21
|
},
|
|
22
22
|
"exports": {
|
|
23
23
|
".": {
|
|
@@ -28,6 +28,7 @@ export class CourseController {
|
|
|
28
28
|
@Query('status') status?: string,
|
|
29
29
|
@Query('level') level?: string,
|
|
30
30
|
@Query('category') category?: string,
|
|
31
|
+
@Query('offeringTypes') offeringTypes?: string | string[],
|
|
31
32
|
) {
|
|
32
33
|
return this.courseService.list({
|
|
33
34
|
page: page ? Number(page) : 1,
|
|
@@ -36,9 +37,26 @@ export class CourseController {
|
|
|
36
37
|
status,
|
|
37
38
|
level,
|
|
38
39
|
category,
|
|
40
|
+
offeringTypes: this.toArray(offeringTypes),
|
|
39
41
|
});
|
|
40
42
|
}
|
|
41
43
|
|
|
44
|
+
private toArray(value?: string | string[]) {
|
|
45
|
+
if (Array.isArray(value)) {
|
|
46
|
+
return value
|
|
47
|
+
.flatMap((item) => String(item).split(','))
|
|
48
|
+
.map((item) => item.trim())
|
|
49
|
+
.filter(Boolean);
|
|
50
|
+
}
|
|
51
|
+
if (typeof value === 'string') {
|
|
52
|
+
return value
|
|
53
|
+
.split(',')
|
|
54
|
+
.map((item) => item.trim())
|
|
55
|
+
.filter(Boolean);
|
|
56
|
+
}
|
|
57
|
+
return [];
|
|
58
|
+
}
|
|
59
|
+
|
|
42
60
|
@Get('stats')
|
|
43
61
|
stats() {
|
|
44
62
|
return this.courseService.stats();
|
|
@@ -94,6 +94,35 @@ export class CourseService {
|
|
|
94
94
|
return this.normalizeOptionalText(title) ?? slug;
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
+
private async resolveCertificateTemplateId(value?: string | null) {
|
|
98
|
+
if (value === undefined) {
|
|
99
|
+
return undefined;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const normalized = String(value ?? '').trim();
|
|
103
|
+
|
|
104
|
+
if (!normalized) {
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const numericId = Number(normalized);
|
|
109
|
+
const template = await this.prisma.certificate_template.findFirst({
|
|
110
|
+
where:
|
|
111
|
+
Number.isInteger(numericId) && numericId > 0
|
|
112
|
+
? {
|
|
113
|
+
OR: [{ id: numericId }, { slug: normalized }],
|
|
114
|
+
}
|
|
115
|
+
: { slug: normalized },
|
|
116
|
+
select: { id: true },
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
if (!template) {
|
|
120
|
+
throw new BadRequestException('Certificate template not found');
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return template.id;
|
|
124
|
+
}
|
|
125
|
+
|
|
97
126
|
async list(params: {
|
|
98
127
|
page?: number;
|
|
99
128
|
pageSize?: number;
|
|
@@ -101,6 +130,7 @@ export class CourseService {
|
|
|
101
130
|
status?: string;
|
|
102
131
|
level?: string;
|
|
103
132
|
category?: string;
|
|
133
|
+
offeringTypes?: string[];
|
|
104
134
|
}) {
|
|
105
135
|
const page = Math.max(Number(params.page) || 1, 1);
|
|
106
136
|
const pageSize = Math.max(Number(params.pageSize) || 12, 1);
|
|
@@ -128,6 +158,9 @@ export class CourseService {
|
|
|
128
158
|
some: { category: { slug: params.category } },
|
|
129
159
|
};
|
|
130
160
|
}
|
|
161
|
+
if (params.offeringTypes && params.offeringTypes.length > 0) {
|
|
162
|
+
where.offering_type = { in: params.offeringTypes };
|
|
163
|
+
}
|
|
131
164
|
|
|
132
165
|
const [courses, total] = await Promise.all([
|
|
133
166
|
this.prisma.course.findMany({
|
|
@@ -244,6 +277,9 @@ export class CourseService {
|
|
|
244
277
|
},
|
|
245
278
|
},
|
|
246
279
|
},
|
|
280
|
+
certificate_template: {
|
|
281
|
+
select: { id: true, slug: true },
|
|
282
|
+
},
|
|
247
283
|
_count: {
|
|
248
284
|
select: {
|
|
249
285
|
course_enrollment: true,
|
|
@@ -318,9 +354,18 @@ export class CourseService {
|
|
|
318
354
|
}
|
|
319
355
|
|
|
320
356
|
async create(dto: CreateCourseDto) {
|
|
321
|
-
const {
|
|
357
|
+
const {
|
|
358
|
+
categorySlugs,
|
|
359
|
+
logoFileId,
|
|
360
|
+
bannerFileId,
|
|
361
|
+
instructorIds,
|
|
362
|
+
certificateModel,
|
|
363
|
+
...data
|
|
364
|
+
} = dto;
|
|
322
365
|
const normalizedSlug = data.slug.trim();
|
|
323
366
|
const resolvedTitle = this.resolveCourseTitle(data.title, normalizedSlug);
|
|
367
|
+
const certificateTemplateId =
|
|
368
|
+
await this.resolveCertificateTemplateId(certificateModel);
|
|
324
369
|
|
|
325
370
|
const categories = categorySlugs?.length
|
|
326
371
|
? await this.prisma.category.findMany({
|
|
@@ -365,6 +410,9 @@ export class CourseService {
|
|
|
365
410
|
...(data.certificateWorkload !== undefined && {
|
|
366
411
|
certificate_workload: data.certificateWorkload,
|
|
367
412
|
}),
|
|
413
|
+
...(certificateTemplateId !== undefined && {
|
|
414
|
+
certificate_template_id: certificateTemplateId,
|
|
415
|
+
}),
|
|
368
416
|
...(data.primaryColor !== undefined && {
|
|
369
417
|
primary_color: data.primaryColor,
|
|
370
418
|
}),
|
|
@@ -427,6 +475,9 @@ export class CourseService {
|
|
|
427
475
|
},
|
|
428
476
|
},
|
|
429
477
|
},
|
|
478
|
+
certificate_template: {
|
|
479
|
+
select: { id: true, slug: true },
|
|
480
|
+
},
|
|
430
481
|
_count: { select: { course_enrollment: true } },
|
|
431
482
|
},
|
|
432
483
|
});
|
|
@@ -457,7 +508,14 @@ export class CourseService {
|
|
|
457
508
|
}
|
|
458
509
|
|
|
459
510
|
async update(id: number, dto: UpdateCourseDto) {
|
|
460
|
-
const {
|
|
511
|
+
const {
|
|
512
|
+
categorySlugs,
|
|
513
|
+
logoFileId,
|
|
514
|
+
bannerFileId,
|
|
515
|
+
instructorIds,
|
|
516
|
+
certificateModel,
|
|
517
|
+
...data
|
|
518
|
+
} = dto;
|
|
461
519
|
let existingSlug: string | undefined;
|
|
462
520
|
|
|
463
521
|
if (
|
|
@@ -478,6 +536,8 @@ export class CourseService {
|
|
|
478
536
|
data.title !== undefined
|
|
479
537
|
? this.resolveCourseTitle(data.title, resolvedSlug ?? existingSlug ?? '')
|
|
480
538
|
: undefined;
|
|
539
|
+
const certificateTemplateId =
|
|
540
|
+
await this.resolveCertificateTemplateId(certificateModel);
|
|
481
541
|
|
|
482
542
|
const categories = categorySlugs?.length
|
|
483
543
|
? await this.prisma.category.findMany({
|
|
@@ -535,6 +595,9 @@ export class CourseService {
|
|
|
535
595
|
...(data.certificateWorkload !== undefined && {
|
|
536
596
|
certificate_workload: data.certificateWorkload,
|
|
537
597
|
}),
|
|
598
|
+
...(certificateTemplateId !== undefined && {
|
|
599
|
+
certificate_template_id: certificateTemplateId,
|
|
600
|
+
}),
|
|
538
601
|
...(data.primaryColor !== undefined && {
|
|
539
602
|
primary_color: data.primaryColor,
|
|
540
603
|
}),
|
|
@@ -589,6 +652,9 @@ export class CourseService {
|
|
|
589
652
|
},
|
|
590
653
|
},
|
|
591
654
|
},
|
|
655
|
+
certificate_template: {
|
|
656
|
+
select: { id: true, slug: true },
|
|
657
|
+
},
|
|
592
658
|
_count: { select: { course_enrollment: true } },
|
|
593
659
|
},
|
|
594
660
|
});
|
|
@@ -731,6 +797,11 @@ export class CourseService {
|
|
|
731
797
|
averageCompletion: Math.round(metrics?.averageCompletion ?? 0),
|
|
732
798
|
certificatesIssued:
|
|
733
799
|
metrics?.certificatesIssued ?? c._count?.certificate ?? 0,
|
|
800
|
+
certificateModel:
|
|
801
|
+
c.certificate_template?.slug ??
|
|
802
|
+
(c.certificate_template_id
|
|
803
|
+
? String(c.certificate_template_id)
|
|
804
|
+
: null),
|
|
734
805
|
progressByModule: metrics?.progressByModule ?? [],
|
|
735
806
|
instructors: (c.course_instructor ?? []).map((ci: any) => ({
|
|
736
807
|
id: ci.instructor_id,
|
|
@@ -808,51 +879,39 @@ export class CourseService {
|
|
|
808
879
|
id: number,
|
|
809
880
|
data: PersistCourseExtrasInput,
|
|
810
881
|
) {
|
|
811
|
-
const
|
|
812
|
-
const params: Array<string | boolean | number> = [];
|
|
882
|
+
const updateData: Record<string, string | boolean> = {};
|
|
813
883
|
|
|
814
884
|
if (data.name !== undefined) {
|
|
815
|
-
|
|
816
|
-
sets.push(`name = $${params.length}`);
|
|
885
|
+
updateData.name = data.name;
|
|
817
886
|
}
|
|
818
887
|
|
|
819
888
|
if (data.isFeatured !== undefined) {
|
|
820
|
-
|
|
821
|
-
sets.push(`is_featured = $${params.length}`);
|
|
889
|
+
updateData.is_featured = data.isFeatured;
|
|
822
890
|
}
|
|
823
891
|
|
|
824
892
|
if (data.hasCertificate !== undefined) {
|
|
825
|
-
|
|
826
|
-
sets.push(`has_certificate = $${params.length}`);
|
|
893
|
+
updateData.has_certificate = data.hasCertificate;
|
|
827
894
|
}
|
|
828
895
|
|
|
829
896
|
if (data.isListed !== undefined) {
|
|
830
|
-
|
|
831
|
-
sets.push(`is_listed = $${params.length}`);
|
|
897
|
+
updateData.is_listed = data.isListed;
|
|
832
898
|
}
|
|
833
899
|
|
|
834
900
|
if (data.offeringType !== undefined) {
|
|
835
|
-
|
|
836
|
-
sets.push(`offering_type = $${params.length}`);
|
|
901
|
+
updateData.offering_type = data.offeringType;
|
|
837
902
|
}
|
|
838
903
|
|
|
839
|
-
if (
|
|
904
|
+
if (Object.keys(updateData).length === 0) {
|
|
840
905
|
return;
|
|
841
906
|
}
|
|
842
907
|
|
|
843
|
-
params.push(id);
|
|
844
|
-
|
|
845
908
|
try {
|
|
846
|
-
await this.prisma
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
WHERE id = $${params.length}
|
|
851
|
-
`,
|
|
852
|
-
...params,
|
|
853
|
-
);
|
|
909
|
+
await this.prisma.course.update({
|
|
910
|
+
where: { id },
|
|
911
|
+
data: updateData as any,
|
|
912
|
+
});
|
|
854
913
|
} catch {
|
|
855
|
-
//
|
|
914
|
+
// Some environments may still be behind the current course schema.
|
|
856
915
|
}
|
|
857
916
|
}
|
|
858
917
|
|
|
@@ -126,6 +126,11 @@ export class EnterpriseController {
|
|
|
126
126
|
return { profiles };
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
+
@Get(':id/overview')
|
|
130
|
+
getOverview(@Param('id', ParseIntPipe) id: number) {
|
|
131
|
+
return this.enterpriseService.getOverview(id);
|
|
132
|
+
}
|
|
133
|
+
|
|
129
134
|
@Get(':id')
|
|
130
135
|
getById(@Param('id', ParseIntPipe) id: number) {
|
|
131
136
|
return this.enterpriseService.getById(id);
|