@hed-hog/lms 0.0.279 → 0.0.286
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/README.md +2 -0
- package/hedhog/frontend/app/classes/[id]/page.tsx.ejs +42 -21
- package/hedhog/frontend/app/classes/page.tsx.ejs +28 -99
- package/hedhog/frontend/app/courses/[id]/page.tsx.ejs +152 -109
- package/hedhog/frontend/app/courses/[id]/structure/page.tsx.ejs +22 -34
- package/hedhog/frontend/app/courses/page.tsx.ejs +31 -106
- package/hedhog/frontend/app/exams/[id]/attempt/page.tsx.ejs +25 -3
- package/hedhog/frontend/app/exams/[id]/questions/page.tsx.ejs +43 -17
- package/hedhog/frontend/app/exams/page.tsx.ejs +27 -98
- package/hedhog/frontend/app/page.tsx.ejs +3 -3
- package/hedhog/frontend/app/training/page.tsx.ejs +29 -99
- package/hedhog/frontend/messages/en.json +14 -4
- package/hedhog/frontend/messages/pt.json +14 -4
- package/package.json +6 -6
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
EmptyState,
|
|
5
|
+
Page,
|
|
6
|
+
PageHeader,
|
|
7
|
+
PaginationFooter,
|
|
8
|
+
} from '@/components/entity-list';
|
|
4
9
|
import { Badge } from '@/components/ui/badge';
|
|
5
10
|
import { Button } from '@/components/ui/button';
|
|
6
11
|
import { Card, CardContent } from '@/components/ui/card';
|
|
@@ -46,10 +51,6 @@ import {
|
|
|
46
51
|
AlertTriangle,
|
|
47
52
|
BarChart3,
|
|
48
53
|
BookOpen,
|
|
49
|
-
ChevronLeft,
|
|
50
|
-
ChevronRight,
|
|
51
|
-
ChevronsLeft,
|
|
52
|
-
ChevronsRight,
|
|
53
54
|
Clock,
|
|
54
55
|
Eye,
|
|
55
56
|
FileCheck,
|
|
@@ -604,7 +605,7 @@ export default function TrainingPage() {
|
|
|
604
605
|
</div>
|
|
605
606
|
|
|
606
607
|
{/* Search bar */}
|
|
607
|
-
<form onSubmit={handleSearch} className="-mt-
|
|
608
|
+
<form onSubmit={handleSearch} className="mb-6 mt-0">
|
|
608
609
|
<div className="flex flex-col gap-3 sm:flex-row sm:items-center">
|
|
609
610
|
<div className="relative flex-1">
|
|
610
611
|
<Search className="absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" />
|
|
@@ -689,17 +690,14 @@ export default function TrainingPage() {
|
|
|
689
690
|
))}
|
|
690
691
|
</div>
|
|
691
692
|
) : filteredFormacoes.length === 0 ? (
|
|
692
|
-
<
|
|
693
|
-
<GraduationCap className="
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
<
|
|
699
|
-
|
|
700
|
-
{t('empty.action')}
|
|
701
|
-
</Button>
|
|
702
|
-
</div>
|
|
693
|
+
<EmptyState
|
|
694
|
+
icon={<GraduationCap className="h-12 w-12" />}
|
|
695
|
+
title={t('empty.title')}
|
|
696
|
+
description={t('empty.description')}
|
|
697
|
+
actionLabel={t('empty.action')}
|
|
698
|
+
onAction={openCreateSheet}
|
|
699
|
+
actionIcon={<Plus className="mr-2 h-4 w-4" />}
|
|
700
|
+
/>
|
|
703
701
|
) : (
|
|
704
702
|
<motion.div
|
|
705
703
|
className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3"
|
|
@@ -719,7 +717,7 @@ export default function TrainingPage() {
|
|
|
719
717
|
return (
|
|
720
718
|
<motion.div key={formacao.id} variants={fadeUp}>
|
|
721
719
|
<Card
|
|
722
|
-
className="group relative cursor-pointer overflow-hidden transition-all duration-200 hover
|
|
720
|
+
className="group relative flex min-h-60 max-h-[270px] cursor-pointer flex-col overflow-hidden transition-all duration-200 hover:-translate-y-0.5 hover:shadow-md"
|
|
723
721
|
onClick={() => handleCardClick(formacao)}
|
|
724
722
|
title={t('cards.tooltip')}
|
|
725
723
|
>
|
|
@@ -840,86 +838,18 @@ export default function TrainingPage() {
|
|
|
840
838
|
|
|
841
839
|
{/* Pagination footer */}
|
|
842
840
|
{!loading && filteredFormacoes.length > 0 && (
|
|
843
|
-
<div className="mt-6
|
|
844
|
-
<
|
|
845
|
-
{
|
|
846
|
-
{
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
{
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
size="icon"
|
|
856
|
-
className="size-8"
|
|
857
|
-
onClick={() => setCurrentPage(1)}
|
|
858
|
-
disabled={safePage === 1}
|
|
859
|
-
aria-label={t('pagination.firstPage')}
|
|
860
|
-
>
|
|
861
|
-
<ChevronsLeft className="size-4" />
|
|
862
|
-
</Button>
|
|
863
|
-
<Button
|
|
864
|
-
variant="outline"
|
|
865
|
-
size="icon"
|
|
866
|
-
className="size-8"
|
|
867
|
-
onClick={() => setCurrentPage((p) => p - 1)}
|
|
868
|
-
disabled={safePage === 1}
|
|
869
|
-
aria-label={t('pagination.previousPage')}
|
|
870
|
-
>
|
|
871
|
-
<ChevronLeft className="size-4" />
|
|
872
|
-
</Button>
|
|
873
|
-
<span className="px-3 text-sm">
|
|
874
|
-
{t('pagination.page')}{' '}
|
|
875
|
-
<span className="font-semibold">{safePage}</span>{' '}
|
|
876
|
-
{t('pagination.of')}{' '}
|
|
877
|
-
<span className="font-semibold">{totalPages}</span>
|
|
878
|
-
</span>
|
|
879
|
-
<Button
|
|
880
|
-
variant="outline"
|
|
881
|
-
size="icon"
|
|
882
|
-
className="size-8"
|
|
883
|
-
onClick={() => setCurrentPage((p) => p + 1)}
|
|
884
|
-
disabled={safePage === totalPages}
|
|
885
|
-
aria-label={t('pagination.nextPage')}
|
|
886
|
-
>
|
|
887
|
-
<ChevronRight className="size-4" />
|
|
888
|
-
</Button>
|
|
889
|
-
<Button
|
|
890
|
-
variant="outline"
|
|
891
|
-
size="icon"
|
|
892
|
-
className="size-8"
|
|
893
|
-
onClick={() => setCurrentPage(totalPages)}
|
|
894
|
-
disabled={safePage === totalPages}
|
|
895
|
-
aria-label={t('pagination.lastPage')}
|
|
896
|
-
>
|
|
897
|
-
<ChevronsRight className="size-4" />
|
|
898
|
-
</Button>
|
|
899
|
-
</div>
|
|
900
|
-
<div className="flex items-center gap-2 text-sm">
|
|
901
|
-
<span className="text-muted-foreground">
|
|
902
|
-
{t('pagination.itemsPerPage')}
|
|
903
|
-
</span>
|
|
904
|
-
<Select
|
|
905
|
-
value={String(pageSize)}
|
|
906
|
-
onValueChange={(v) => {
|
|
907
|
-
setPageSize(Number(v));
|
|
908
|
-
setCurrentPage(1);
|
|
909
|
-
}}
|
|
910
|
-
>
|
|
911
|
-
<SelectTrigger className="h-8 w-16 text-sm">
|
|
912
|
-
<SelectValue />
|
|
913
|
-
</SelectTrigger>
|
|
914
|
-
<SelectContent>
|
|
915
|
-
{PAGE_SIZES.map((s) => (
|
|
916
|
-
<SelectItem key={s} value={String(s)}>
|
|
917
|
-
{s}
|
|
918
|
-
</SelectItem>
|
|
919
|
-
))}
|
|
920
|
-
</SelectContent>
|
|
921
|
-
</Select>
|
|
922
|
-
</div>
|
|
841
|
+
<div className="mt-6">
|
|
842
|
+
<PaginationFooter
|
|
843
|
+
currentPage={safePage}
|
|
844
|
+
pageSize={pageSize}
|
|
845
|
+
totalItems={filteredFormacoes.length}
|
|
846
|
+
onPageChange={setCurrentPage}
|
|
847
|
+
onPageSizeChange={(nextSize) => {
|
|
848
|
+
setPageSize(nextSize);
|
|
849
|
+
setCurrentPage(1);
|
|
850
|
+
}}
|
|
851
|
+
pageSizeOptions={PAGE_SIZES}
|
|
852
|
+
/>
|
|
923
853
|
</div>
|
|
924
854
|
)}
|
|
925
855
|
|
|
@@ -1083,7 +1013,7 @@ export default function TrainingPage() {
|
|
|
1083
1013
|
{availableCursos.map((c) => (
|
|
1084
1014
|
<label
|
|
1085
1015
|
key={c.id}
|
|
1086
|
-
className="flex cursor-pointer items-center justify-between border-b p-2.5 last:border-0 hover:bg-muted has-
|
|
1016
|
+
className="flex cursor-pointer items-center justify-between border-b p-2.5 last:border-0 hover:bg-muted has-checked:bg-muted/50"
|
|
1087
1017
|
>
|
|
1088
1018
|
<div className="flex items-center gap-2">
|
|
1089
1019
|
<Checkbox
|
|
@@ -85,13 +85,19 @@
|
|
|
85
85
|
"label": "Course Logo",
|
|
86
86
|
"description": "Square image, max 5MB (PNG, JPG)",
|
|
87
87
|
"change": "Change",
|
|
88
|
-
"
|
|
88
|
+
"remove": "Remove",
|
|
89
|
+
"clickToUpload": "Click to upload",
|
|
90
|
+
"emptyTitle": "No logo uploaded",
|
|
91
|
+
"previewAlt": "Course logo preview"
|
|
89
92
|
},
|
|
90
93
|
"banner": {
|
|
91
94
|
"label": "Course Banner",
|
|
92
95
|
"description": "16:9 image, max 5MB (PNG, JPG)",
|
|
93
96
|
"change": "Change",
|
|
94
|
-
"
|
|
97
|
+
"remove": "Remove",
|
|
98
|
+
"clickToUpload": "Click to upload",
|
|
99
|
+
"emptyTitle": "No banner uploaded",
|
|
100
|
+
"previewAlt": "Course banner preview"
|
|
95
101
|
},
|
|
96
102
|
"certificateModel": {
|
|
97
103
|
"label": "Certificate Model",
|
|
@@ -507,7 +513,8 @@
|
|
|
507
513
|
"merge": "Merge with another session",
|
|
508
514
|
"mergeWith": "Merge lessons with:",
|
|
509
515
|
"delete": "Delete session",
|
|
510
|
-
"noLessons": "No lessons in this session"
|
|
516
|
+
"noLessons": "No lessons in this session",
|
|
517
|
+
"noLessonsDescription": "Create the first lesson to start building this session content."
|
|
511
518
|
},
|
|
512
519
|
"lesson": {
|
|
513
520
|
"dragSession": "Drag session",
|
|
@@ -1377,7 +1384,10 @@
|
|
|
1377
1384
|
},
|
|
1378
1385
|
"empty": {
|
|
1379
1386
|
"notFound": "No student found",
|
|
1380
|
-
"
|
|
1387
|
+
"notFoundDescription": "Try adjusting the search to find students in this class.",
|
|
1388
|
+
"clearSearch": "Clear search",
|
|
1389
|
+
"notEnrolled": "No enrolled students",
|
|
1390
|
+
"notEnrolledDescription": "Add the first student to start managing this class."
|
|
1381
1391
|
},
|
|
1382
1392
|
"menu": {
|
|
1383
1393
|
"viewProfile": "View profile",
|
|
@@ -85,13 +85,19 @@
|
|
|
85
85
|
"label": "Logo do Curso",
|
|
86
86
|
"description": "Imagem quadrada, máx 5MB (PNG, JPG)",
|
|
87
87
|
"change": "Trocar",
|
|
88
|
-
"
|
|
88
|
+
"remove": "Remover",
|
|
89
|
+
"clickToUpload": "Clique para enviar",
|
|
90
|
+
"emptyTitle": "Nenhum logo enviado",
|
|
91
|
+
"previewAlt": "Pré-visualização do logo do curso"
|
|
89
92
|
},
|
|
90
93
|
"banner": {
|
|
91
94
|
"label": "Banner do Curso",
|
|
92
95
|
"description": "Imagem 16:9, máx 5MB (PNG, JPG)",
|
|
93
96
|
"change": "Trocar",
|
|
94
|
-
"
|
|
97
|
+
"remove": "Remover",
|
|
98
|
+
"clickToUpload": "Clique para enviar",
|
|
99
|
+
"emptyTitle": "Nenhum banner enviado",
|
|
100
|
+
"previewAlt": "Pré-visualização do banner do curso"
|
|
95
101
|
},
|
|
96
102
|
"certificateModel": {
|
|
97
103
|
"label": "Modelo de Certificado",
|
|
@@ -507,7 +513,8 @@
|
|
|
507
513
|
"merge": "Mesclar com outra sessão",
|
|
508
514
|
"mergeWith": "Mesclar aulas com:",
|
|
509
515
|
"delete": "Excluir sessão",
|
|
510
|
-
"noLessons": "Nenhuma aula nesta sessão"
|
|
516
|
+
"noLessons": "Nenhuma aula nesta sessão",
|
|
517
|
+
"noLessonsDescription": "Crie a primeira aula para começar a montar o conteúdo desta sessão."
|
|
511
518
|
},
|
|
512
519
|
"lesson": {
|
|
513
520
|
"dragSession": "Arrastar sessão",
|
|
@@ -1377,7 +1384,10 @@
|
|
|
1377
1384
|
},
|
|
1378
1385
|
"empty": {
|
|
1379
1386
|
"notFound": "Nenhum aluno encontrado",
|
|
1380
|
-
"
|
|
1387
|
+
"notFoundDescription": "Tente ajustar a busca para localizar alunos desta turma.",
|
|
1388
|
+
"clearSearch": "Limpar busca",
|
|
1389
|
+
"notEnrolled": "Nenhum aluno matriculado",
|
|
1390
|
+
"notEnrolledDescription": "Adicione o primeiro aluno para começar a gerenciar a turma."
|
|
1381
1391
|
},
|
|
1382
1392
|
"menu": {
|
|
1383
1393
|
"viewProfile": "Ver perfil",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hed-hog/lms",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.286",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"dependencies": {
|
|
@@ -10,14 +10,14 @@
|
|
|
10
10
|
"@nestjs/jwt": "^11",
|
|
11
11
|
"@nestjs/mapped-types": "*",
|
|
12
12
|
"@hed-hog/api": "0.0.4",
|
|
13
|
-
"@hed-hog/
|
|
14
|
-
"@hed-hog/contact": "0.0.
|
|
13
|
+
"@hed-hog/core": "0.0.286",
|
|
14
|
+
"@hed-hog/contact": "0.0.286",
|
|
15
15
|
"@hed-hog/api-pagination": "0.0.6",
|
|
16
16
|
"@hed-hog/api-prisma": "0.0.5",
|
|
17
|
-
"@hed-hog/
|
|
17
|
+
"@hed-hog/finance": "0.0.286",
|
|
18
|
+
"@hed-hog/api-types": "0.0.1",
|
|
18
19
|
"@hed-hog/api-locale": "0.0.13",
|
|
19
|
-
"@hed-hog/
|
|
20
|
-
"@hed-hog/finance": "0.0.279"
|
|
20
|
+
"@hed-hog/category": "0.0.286"
|
|
21
21
|
},
|
|
22
22
|
"exports": {
|
|
23
23
|
".": {
|