@hed-hog/lms 0.0.314 → 0.0.316
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/enterprise/dto/enterprise-profile.dto.d.ts +13 -0
- package/dist/enterprise/dto/enterprise-profile.dto.d.ts.map +1 -0
- package/dist/enterprise/dto/enterprise-profile.dto.js +3 -0
- package/dist/enterprise/dto/enterprise-profile.dto.js.map +1 -0
- package/dist/enterprise/enterprise.controller.d.ts +3 -0
- package/dist/enterprise/enterprise.controller.d.ts.map +1 -1
- package/dist/enterprise/enterprise.controller.js +14 -0
- package/dist/enterprise/enterprise.controller.js.map +1 -1
- package/dist/enterprise/enterprise.service.d.ts +3 -0
- package/dist/enterprise/enterprise.service.d.ts.map +1 -1
- package/dist/enterprise/enterprise.service.js +128 -1
- package/dist/enterprise/enterprise.service.js.map +1 -1
- package/dist/instructor/instructor.controller.d.ts +23 -0
- package/dist/instructor/instructor.controller.d.ts.map +1 -1
- package/dist/instructor/instructor.controller.js +41 -0
- package/dist/instructor/instructor.controller.js.map +1 -1
- package/dist/instructor/instructor.service.d.ts +25 -0
- package/dist/instructor/instructor.service.d.ts.map +1 -1
- package/dist/instructor/instructor.service.js +126 -8
- package/dist/instructor/instructor.service.js.map +1 -1
- package/hedhog/data/menu.yaml +23 -7
- package/hedhog/data/role.yaml +17 -1
- package/hedhog/data/route.yaml +48 -0
- package/hedhog/frontend/app/_components/class-form-sheet.tsx.ejs +2 -1
- package/hedhog/frontend/app/courses/[id]/structure/_components/confirm-dialog.tsx.ejs +44 -44
- package/hedhog/frontend/app/courses/[id]/structure/_components/course-tree-dnd.tsx.ejs +362 -362
- package/hedhog/frontend/app/courses/[id]/structure/_components/course-tree-panel.tsx.ejs +111 -111
- package/hedhog/frontend/app/courses/[id]/structure/_components/course-tree.tsx.ejs +134 -134
- package/hedhog/frontend/app/courses/[id]/structure/_components/detail-course.tsx.ejs +113 -113
- package/hedhog/frontend/app/courses/[id]/structure/_components/detail-lesson.tsx.ejs +314 -314
- package/hedhog/frontend/app/courses/[id]/structure/_components/detail-panel.tsx.ejs +62 -62
- package/hedhog/frontend/app/courses/[id]/structure/_components/detail-session.tsx.ejs +173 -173
- package/hedhog/frontend/app/courses/[id]/structure/_components/drag-handle.tsx.ejs +58 -58
- package/hedhog/frontend/app/courses/[id]/structure/_components/drag-overlay.tsx.ejs +51 -51
- package/hedhog/frontend/app/courses/[id]/structure/_components/editor-bulk.tsx.ejs +276 -276
- package/hedhog/frontend/app/courses/[id]/structure/_components/editor-course.tsx.ejs +1216 -1216
- package/hedhog/frontend/app/courses/[id]/structure/_components/editor-lesson.tsx.ejs +1824 -1824
- package/hedhog/frontend/app/courses/[id]/structure/_components/editor-session.tsx.ejs +443 -443
- package/hedhog/frontend/app/courses/[id]/structure/_components/highlighted-text.tsx.ejs +40 -40
- package/hedhog/frontend/app/courses/[id]/structure/_components/mock-data.ts.ejs +185 -185
- package/hedhog/frontend/app/courses/[id]/structure/_components/multi-select-bar.tsx.ejs +264 -264
- package/hedhog/frontend/app/courses/[id]/structure/_components/search-filter.tsx.ejs +95 -95
- package/hedhog/frontend/app/courses/[id]/structure/_components/session-picker-dialog.tsx.ejs +73 -73
- package/hedhog/frontend/app/courses/[id]/structure/_components/shortcuts-help.tsx.ejs +136 -136
- package/hedhog/frontend/app/courses/[id]/structure/_components/sortable-tree-row.tsx.ejs +80 -80
- package/hedhog/frontend/app/courses/[id]/structure/_components/store.ts.ejs +949 -949
- package/hedhog/frontend/app/courses/[id]/structure/_components/tree-context-menu.tsx.ejs +525 -525
- package/hedhog/frontend/app/courses/[id]/structure/_components/tree-helpers.ts.ejs +181 -181
- package/hedhog/frontend/app/courses/[id]/structure/_components/tree-row-course.tsx.ejs +51 -51
- package/hedhog/frontend/app/courses/[id]/structure/_components/tree-row-lesson.tsx.ejs +271 -271
- package/hedhog/frontend/app/courses/[id]/structure/_components/tree-row-session.tsx.ejs +167 -167
- package/hedhog/frontend/app/courses/[id]/structure/_components/tree-row.tsx.ejs +108 -108
- package/hedhog/frontend/app/courses/[id]/structure/_components/use-course-structure-shortcuts.ts.ejs +318 -318
- package/hedhog/frontend/app/courses/[id]/structure/page.tsx.ejs +10 -10
- package/hedhog/frontend/app/enterprise/_components/enterprise-course-create-sheet.tsx.ejs +2 -1
- package/hedhog/frontend/app/instructors/_components/instructor-form-sheet.tsx.ejs +438 -0
- package/hedhog/frontend/app/instructors/_components/instructor-types.ts.ejs +40 -0
- package/hedhog/frontend/app/instructors/page.tsx.ejs +696 -0
- package/hedhog/frontend/app/training/page.tsx.ejs +2339 -0
- package/hedhog/query/add_route_role.sql +15 -0
- package/hedhog/table/enterprise_user.yaml +1 -1
- package/package.json +6 -6
- package/src/enterprise/dto/enterprise-profile.dto.ts +17 -0
- package/src/enterprise/enterprise.controller.ts +9 -1
- package/src/enterprise/enterprise.service.ts +147 -4
- package/src/instructor/instructor.controller.ts +36 -9
- package/src/instructor/instructor.service.ts +140 -10
|
@@ -1,113 +1,113 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import { Badge } from '@/components/ui/badge';
|
|
4
|
-
import { Separator } from '@/components/ui/separator';
|
|
5
|
-
import { BookOpen, Globe, Hash, Tag } from 'lucide-react';
|
|
6
|
-
import { useStructureStore } from './store';
|
|
7
|
-
|
|
8
|
-
export function DetailCourse() {
|
|
9
|
-
const course = useStructureStore((s) => s.course);
|
|
10
|
-
const sessions = useStructureStore((s) => s.sessions);
|
|
11
|
-
const lessons = useStructureStore((s) => s.lessons);
|
|
12
|
-
|
|
13
|
-
const totalMinutes = lessons.reduce((sum, l) => sum + l.duration, 0);
|
|
14
|
-
const hours = Math.floor(totalMinutes / 60);
|
|
15
|
-
const minutes = totalMinutes % 60;
|
|
16
|
-
|
|
17
|
-
return (
|
|
18
|
-
<div className="flex flex-col overflow-y-auto h-full">
|
|
19
|
-
{/* Header */}
|
|
20
|
-
<div className="flex items-center gap-3 px-4 py-4 border-b bg-muted/30 shrink-0">
|
|
21
|
-
<div className="flex size-10 items-center justify-center rounded-lg bg-primary/10 shrink-0">
|
|
22
|
-
<BookOpen className="size-5 text-primary" />
|
|
23
|
-
</div>
|
|
24
|
-
<div className="min-w-0 flex-1">
|
|
25
|
-
<h2 className="text-base font-semibold truncate">{course.title}</h2>
|
|
26
|
-
<p className="text-xs text-muted-foreground">{course.slug}</p>
|
|
27
|
-
</div>
|
|
28
|
-
<Badge
|
|
29
|
-
variant={course.published ? 'default' : 'secondary'}
|
|
30
|
-
className="shrink-0"
|
|
31
|
-
>
|
|
32
|
-
{course.published ? 'Publicado' : 'Rascunho'}
|
|
33
|
-
</Badge>
|
|
34
|
-
</div>
|
|
35
|
-
|
|
36
|
-
<div className="flex flex-col gap-5 p-4">
|
|
37
|
-
{/* Stats */}
|
|
38
|
-
<div className="grid grid-cols-3 gap-3">
|
|
39
|
-
<StatCard label="Sessões" value={sessions.length} />
|
|
40
|
-
<StatCard label="Aulas" value={lessons.length} />
|
|
41
|
-
<StatCard
|
|
42
|
-
label="Duração"
|
|
43
|
-
value={hours > 0 ? `${hours}h ${minutes}m` : `${minutes}m`}
|
|
44
|
-
/>
|
|
45
|
-
</div>
|
|
46
|
-
|
|
47
|
-
<Separator />
|
|
48
|
-
|
|
49
|
-
{/* Info */}
|
|
50
|
-
<div className="flex flex-col gap-2.5">
|
|
51
|
-
<InfoRow
|
|
52
|
-
icon={<Hash className="size-3.5" />}
|
|
53
|
-
label="Slug"
|
|
54
|
-
value={course.slug}
|
|
55
|
-
/>
|
|
56
|
-
<InfoRow
|
|
57
|
-
icon={<Tag className="size-3.5" />}
|
|
58
|
-
label="Slug"
|
|
59
|
-
value={course.slug}
|
|
60
|
-
/>
|
|
61
|
-
<InfoRow
|
|
62
|
-
icon={<Globe className="size-3.5" />}
|
|
63
|
-
label="Status"
|
|
64
|
-
value={course.published ? 'Publicado' : 'Rascunho'}
|
|
65
|
-
/>
|
|
66
|
-
</div>
|
|
67
|
-
|
|
68
|
-
{course.description && (
|
|
69
|
-
<>
|
|
70
|
-
<Separator />
|
|
71
|
-
<div>
|
|
72
|
-
<p className="text-xs font-medium text-muted-foreground mb-1.5">
|
|
73
|
-
Descrição
|
|
74
|
-
</p>
|
|
75
|
-
<p className="text-sm leading-relaxed text-foreground/90">
|
|
76
|
-
{course.description}
|
|
77
|
-
</p>
|
|
78
|
-
</div>
|
|
79
|
-
</>
|
|
80
|
-
)}
|
|
81
|
-
</div>
|
|
82
|
-
</div>
|
|
83
|
-
);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
function StatCard({ label, value }: { label: string; value: string | number }) {
|
|
87
|
-
return (
|
|
88
|
-
<div className="flex flex-col items-center rounded-lg border bg-muted/30 py-3 gap-0.5">
|
|
89
|
-
<span className="text-lg font-bold tabular-nums">{value}</span>
|
|
90
|
-
<span className="text-[0.65rem] text-muted-foreground">{label}</span>
|
|
91
|
-
</div>
|
|
92
|
-
);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
function InfoRow({
|
|
96
|
-
icon,
|
|
97
|
-
label,
|
|
98
|
-
value,
|
|
99
|
-
}: {
|
|
100
|
-
icon: React.ReactNode;
|
|
101
|
-
label: string;
|
|
102
|
-
value: string;
|
|
103
|
-
}) {
|
|
104
|
-
return (
|
|
105
|
-
<div className="flex items-center gap-2">
|
|
106
|
-
<span className="text-muted-foreground shrink-0">{icon}</span>
|
|
107
|
-
<span className="text-xs text-muted-foreground w-14 shrink-0">
|
|
108
|
-
{label}
|
|
109
|
-
</span>
|
|
110
|
-
<span className="text-sm truncate">{value}</span>
|
|
111
|
-
</div>
|
|
112
|
-
);
|
|
113
|
-
}
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { Badge } from '@/components/ui/badge';
|
|
4
|
+
import { Separator } from '@/components/ui/separator';
|
|
5
|
+
import { BookOpen, Globe, Hash, Tag } from 'lucide-react';
|
|
6
|
+
import { useStructureStore } from './store';
|
|
7
|
+
|
|
8
|
+
export function DetailCourse() {
|
|
9
|
+
const course = useStructureStore((s) => s.course);
|
|
10
|
+
const sessions = useStructureStore((s) => s.sessions);
|
|
11
|
+
const lessons = useStructureStore((s) => s.lessons);
|
|
12
|
+
|
|
13
|
+
const totalMinutes = lessons.reduce((sum, l) => sum + l.duration, 0);
|
|
14
|
+
const hours = Math.floor(totalMinutes / 60);
|
|
15
|
+
const minutes = totalMinutes % 60;
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<div className="flex flex-col overflow-y-auto h-full">
|
|
19
|
+
{/* Header */}
|
|
20
|
+
<div className="flex items-center gap-3 px-4 py-4 border-b bg-muted/30 shrink-0">
|
|
21
|
+
<div className="flex size-10 items-center justify-center rounded-lg bg-primary/10 shrink-0">
|
|
22
|
+
<BookOpen className="size-5 text-primary" />
|
|
23
|
+
</div>
|
|
24
|
+
<div className="min-w-0 flex-1">
|
|
25
|
+
<h2 className="text-base font-semibold truncate">{course.title}</h2>
|
|
26
|
+
<p className="text-xs text-muted-foreground">{course.slug}</p>
|
|
27
|
+
</div>
|
|
28
|
+
<Badge
|
|
29
|
+
variant={course.published ? 'default' : 'secondary'}
|
|
30
|
+
className="shrink-0"
|
|
31
|
+
>
|
|
32
|
+
{course.published ? 'Publicado' : 'Rascunho'}
|
|
33
|
+
</Badge>
|
|
34
|
+
</div>
|
|
35
|
+
|
|
36
|
+
<div className="flex flex-col gap-5 p-4">
|
|
37
|
+
{/* Stats */}
|
|
38
|
+
<div className="grid grid-cols-3 gap-3">
|
|
39
|
+
<StatCard label="Sessões" value={sessions.length} />
|
|
40
|
+
<StatCard label="Aulas" value={lessons.length} />
|
|
41
|
+
<StatCard
|
|
42
|
+
label="Duração"
|
|
43
|
+
value={hours > 0 ? `${hours}h ${minutes}m` : `${minutes}m`}
|
|
44
|
+
/>
|
|
45
|
+
</div>
|
|
46
|
+
|
|
47
|
+
<Separator />
|
|
48
|
+
|
|
49
|
+
{/* Info */}
|
|
50
|
+
<div className="flex flex-col gap-2.5">
|
|
51
|
+
<InfoRow
|
|
52
|
+
icon={<Hash className="size-3.5" />}
|
|
53
|
+
label="Slug"
|
|
54
|
+
value={course.slug}
|
|
55
|
+
/>
|
|
56
|
+
<InfoRow
|
|
57
|
+
icon={<Tag className="size-3.5" />}
|
|
58
|
+
label="Slug"
|
|
59
|
+
value={course.slug}
|
|
60
|
+
/>
|
|
61
|
+
<InfoRow
|
|
62
|
+
icon={<Globe className="size-3.5" />}
|
|
63
|
+
label="Status"
|
|
64
|
+
value={course.published ? 'Publicado' : 'Rascunho'}
|
|
65
|
+
/>
|
|
66
|
+
</div>
|
|
67
|
+
|
|
68
|
+
{course.description && (
|
|
69
|
+
<>
|
|
70
|
+
<Separator />
|
|
71
|
+
<div>
|
|
72
|
+
<p className="text-xs font-medium text-muted-foreground mb-1.5">
|
|
73
|
+
Descrição
|
|
74
|
+
</p>
|
|
75
|
+
<p className="text-sm leading-relaxed text-foreground/90">
|
|
76
|
+
{course.description}
|
|
77
|
+
</p>
|
|
78
|
+
</div>
|
|
79
|
+
</>
|
|
80
|
+
)}
|
|
81
|
+
</div>
|
|
82
|
+
</div>
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function StatCard({ label, value }: { label: string; value: string | number }) {
|
|
87
|
+
return (
|
|
88
|
+
<div className="flex flex-col items-center rounded-lg border bg-muted/30 py-3 gap-0.5">
|
|
89
|
+
<span className="text-lg font-bold tabular-nums">{value}</span>
|
|
90
|
+
<span className="text-[0.65rem] text-muted-foreground">{label}</span>
|
|
91
|
+
</div>
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function InfoRow({
|
|
96
|
+
icon,
|
|
97
|
+
label,
|
|
98
|
+
value,
|
|
99
|
+
}: {
|
|
100
|
+
icon: React.ReactNode;
|
|
101
|
+
label: string;
|
|
102
|
+
value: string;
|
|
103
|
+
}) {
|
|
104
|
+
return (
|
|
105
|
+
<div className="flex items-center gap-2">
|
|
106
|
+
<span className="text-muted-foreground shrink-0">{icon}</span>
|
|
107
|
+
<span className="text-xs text-muted-foreground w-14 shrink-0">
|
|
108
|
+
{label}
|
|
109
|
+
</span>
|
|
110
|
+
<span className="text-sm truncate">{value}</span>
|
|
111
|
+
</div>
|
|
112
|
+
);
|
|
113
|
+
}
|