@hed-hog/lms 0.0.318 → 0.0.320
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 +65 -2
- package/dist/class-group/class-group.controller.d.ts.map +1 -1
- package/dist/class-group/class-group.controller.js +35 -0
- package/dist/class-group/class-group.controller.js.map +1 -1
- package/dist/class-group/class-group.service.d.ts +67 -2
- package/dist/class-group/class-group.service.d.ts.map +1 -1
- package/dist/class-group/class-group.service.js +164 -13
- package/dist/class-group/class-group.service.js.map +1 -1
- package/dist/class-group/dto/create-class-group.dto.d.ts.map +1 -1
- package/dist/class-group/dto/create-class-group.dto.js +2 -1
- package/dist/class-group/dto/create-class-group.dto.js.map +1 -1
- package/dist/class-group/dto/material.dto.d.ts +18 -0
- package/dist/class-group/dto/material.dto.d.ts.map +1 -0
- package/dist/class-group/dto/material.dto.js +86 -0
- package/dist/class-group/dto/material.dto.js.map +1 -0
- package/dist/course/course.service.d.ts +2 -0
- package/dist/course/course.service.d.ts.map +1 -1
- package/dist/course/course.service.js +27 -2
- package/dist/course/course.service.js.map +1 -1
- package/dist/course/dto/create-course.dto.d.ts +2 -2
- package/dist/course/dto/create-course.dto.d.ts.map +1 -1
- package/dist/course/dto/create-course.dto.js.map +1 -1
- package/dist/enterprise/enterprise.controller.d.ts +7 -1
- package/dist/enterprise/enterprise.controller.d.ts.map +1 -1
- package/dist/enterprise/enterprise.controller.js +72 -2
- package/dist/enterprise/enterprise.controller.js.map +1 -1
- package/dist/enterprise/enterprise.module.d.ts.map +1 -1
- package/dist/enterprise/enterprise.module.js +2 -1
- package/dist/enterprise/enterprise.module.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 +84 -1
- package/dist/enterprise/enterprise.service.js.map +1 -1
- package/dist/enterprise/training/enterprise-training.module.d.ts +3 -0
- package/dist/enterprise/training/enterprise-training.module.d.ts.map +1 -0
- package/dist/enterprise/training/enterprise-training.module.js +40 -0
- package/dist/enterprise/training/enterprise-training.module.js.map +1 -0
- package/dist/enterprise/training/training-admin.controller.d.ts +525 -0
- package/dist/enterprise/training/training-admin.controller.d.ts.map +1 -0
- package/dist/enterprise/training/training-admin.controller.js +385 -0
- package/dist/enterprise/training/training-admin.controller.js.map +1 -0
- package/dist/enterprise/training/training-admin.service.d.ts +582 -0
- package/dist/enterprise/training/training-admin.service.d.ts.map +1 -0
- package/dist/enterprise/training/training-admin.service.js +2283 -0
- package/dist/enterprise/training/training-admin.service.js.map +1 -0
- package/dist/enterprise/training/training-instructor.controller.d.ts +260 -0
- package/dist/enterprise/training/training-instructor.controller.d.ts.map +1 -0
- package/dist/enterprise/training/training-instructor.controller.js +199 -0
- package/dist/enterprise/training/training-instructor.controller.js.map +1 -0
- package/dist/enterprise/training/training-instructor.service.d.ts +280 -0
- package/dist/enterprise/training/training-instructor.service.d.ts.map +1 -0
- package/dist/enterprise/training/training-instructor.service.js +1218 -0
- package/dist/enterprise/training/training-instructor.service.js.map +1 -0
- package/dist/enterprise/training/training-student.controller.d.ts +168 -0
- package/dist/enterprise/training/training-student.controller.d.ts.map +1 -0
- package/dist/enterprise/training/training-student.controller.js +104 -0
- package/dist/enterprise/training/training-student.controller.js.map +1 -0
- package/dist/enterprise/training/training-student.service.d.ts +185 -0
- package/dist/enterprise/training/training-student.service.d.ts.map +1 -0
- package/dist/enterprise/training/training-student.service.js +674 -0
- package/dist/enterprise/training/training-student.service.js.map +1 -0
- package/dist/enterprise/training/training-viewer.controller.d.ts +298 -0
- package/dist/enterprise/training/training-viewer.controller.d.ts.map +1 -0
- package/dist/enterprise/training/training-viewer.controller.js +178 -0
- package/dist/enterprise/training/training-viewer.controller.js.map +1 -0
- package/dist/evaluation/dto/create-evaluation-topic.dto.d.ts +18 -0
- package/dist/evaluation/dto/create-evaluation-topic.dto.d.ts.map +1 -0
- package/dist/evaluation/dto/create-evaluation-topic.dto.js +59 -0
- package/dist/evaluation/dto/create-evaluation-topic.dto.js.map +1 -0
- package/dist/evaluation/dto/update-evaluation-topic.dto.d.ts +6 -0
- package/dist/evaluation/dto/update-evaluation-topic.dto.d.ts.map +1 -0
- package/dist/evaluation/dto/update-evaluation-topic.dto.js +9 -0
- package/dist/evaluation/dto/update-evaluation-topic.dto.js.map +1 -0
- package/dist/evaluation/evaluation.controller.d.ts +66 -0
- package/dist/evaluation/evaluation.controller.d.ts.map +1 -1
- package/dist/evaluation/evaluation.controller.js +73 -0
- package/dist/evaluation/evaluation.controller.js.map +1 -1
- package/dist/evaluation/evaluation.service.d.ts +71 -0
- package/dist/evaluation/evaluation.service.d.ts.map +1 -1
- package/dist/evaluation/evaluation.service.js +121 -0
- package/dist/evaluation/evaluation.service.js.map +1 -1
- package/dist/instructor/instructor.service.js +6 -6
- package/dist/instructor/instructor.service.js.map +1 -1
- package/dist/lms.module.d.ts.map +1 -1
- package/dist/lms.module.js +3 -0
- package/dist/lms.module.js.map +1 -1
- package/hedhog/data/menu.yaml +19 -2
- package/hedhog/data/route.yaml +730 -0
- package/hedhog/frontend/app/_components/class-form-sheet.tsx.ejs +74 -8
- package/hedhog/frontend/app/_components/course-avatar.tsx.ejs +27 -47
- package/hedhog/frontend/app/classes/[id]/_components/event-summary-popover.tsx.ejs +15 -15
- package/hedhog/frontend/app/classes/[id]/_components/quick-create-session-popover.tsx.ejs +5 -5
- package/hedhog/frontend/app/classes/[id]/page.tsx.ejs +2141 -308
- package/hedhog/frontend/app/classes/page.tsx.ejs +8 -7
- package/hedhog/frontend/app/courses/[id]/page.tsx.ejs +21 -8
- package/hedhog/frontend/app/courses/[id]/structure/_components/editor-course.tsx.ejs +10 -6
- package/hedhog/frontend/app/evaluations/_components/evaluation-topic-form-sheet.tsx.ejs +201 -0
- package/hedhog/frontend/app/evaluations/_components/evaluation-topic-types.ts.ejs +49 -0
- package/hedhog/frontend/app/evaluations/page.tsx.ejs +621 -1250
- package/hedhog/frontend/app/instructors/page.tsx.ejs +22 -20
- package/hedhog/frontend/app/reports/evaluations/page.tsx.ejs +1278 -0
- package/hedhog/frontend/messages/en.json +98 -7
- package/hedhog/frontend/messages/pt.json +98 -7
- package/hedhog/table/course_class_group_material.yaml +45 -0
- package/package.json +5 -5
- package/src/class-group/class-group.controller.ts +30 -0
- package/src/class-group/class-group.service.ts +176 -5
- package/src/class-group/dto/create-class-group.dto.ts +8 -8
- package/src/class-group/dto/material.dto.ts +69 -0
- package/src/course/course.service.ts +54 -21
- package/src/course/dto/create-course.dto.ts +8 -8
- package/src/enterprise/enterprise.controller.ts +62 -1
- package/src/enterprise/enterprise.module.ts +2 -1
- package/src/enterprise/enterprise.service.ts +84 -1
- package/src/enterprise/training/enterprise-training.module.ts +27 -0
- package/src/enterprise/training/training-admin.controller.ts +278 -0
- package/src/enterprise/training/training-admin.service.ts +2523 -0
- package/src/enterprise/training/training-instructor.controller.ts +141 -0
- package/src/enterprise/training/training-instructor.service.ts +1303 -0
- package/src/enterprise/training/training-student.controller.ts +65 -0
- package/src/enterprise/training/training-student.service.ts +762 -0
- package/src/enterprise/training/training-viewer.controller.ts +115 -0
- package/src/evaluation/dto/create-evaluation-topic.dto.ts +48 -0
- package/src/evaluation/dto/update-evaluation-topic.dto.ts +6 -0
- package/src/evaluation/evaluation.controller.ts +63 -1
- package/src/evaluation/evaluation.service.ts +150 -1
- package/src/instructor/instructor.service.ts +4 -4
- package/src/lms.module.ts +3 -0
|
@@ -1488,7 +1488,8 @@ export default function TurmasPage() {
|
|
|
1488
1488
|
|
|
1489
1489
|
try {
|
|
1490
1490
|
const payload = {
|
|
1491
|
-
|
|
1491
|
+
name: data.nomeInterno.trim(),
|
|
1492
|
+
slug: data.slug.trim().toLowerCase(),
|
|
1492
1493
|
title: data.tituloComercial,
|
|
1493
1494
|
description: data.descricao,
|
|
1494
1495
|
level: toApiCourseLevel(data.nivel),
|
|
@@ -2628,7 +2629,7 @@ export default function TurmasPage() {
|
|
|
2628
2629
|
<FieldLabel>
|
|
2629
2630
|
{t('form.recurrence.customDialog.repeatOn')}
|
|
2630
2631
|
</FieldLabel>
|
|
2631
|
-
<div className="
|
|
2632
|
+
<div className="grid grid-cols-4 gap-2 sm:grid-cols-7">
|
|
2632
2633
|
{recurrenceDayOptions.map((day) => {
|
|
2633
2634
|
const active = (
|
|
2634
2635
|
watchedFormValues.sessionRecurrenceDaysOfWeek ?? []
|
|
@@ -2639,8 +2640,8 @@ export default function TurmasPage() {
|
|
|
2639
2640
|
key={day.value}
|
|
2640
2641
|
type="button"
|
|
2641
2642
|
variant={active ? 'default' : 'outline'}
|
|
2642
|
-
size="
|
|
2643
|
-
className="
|
|
2643
|
+
size="sm"
|
|
2644
|
+
className="h-9"
|
|
2644
2645
|
onClick={() => toggleCustomRecurrenceDay(day.value)}
|
|
2645
2646
|
>
|
|
2646
2647
|
{day.label}
|
|
@@ -3106,7 +3107,7 @@ export default function TurmasPage() {
|
|
|
3106
3107
|
<FieldLabel>
|
|
3107
3108
|
{t('form.recurrence.customDialog.repeatOn')}
|
|
3108
3109
|
</FieldLabel>
|
|
3109
|
-
<div className="
|
|
3110
|
+
<div className="grid grid-cols-4 gap-2 sm:grid-cols-7">
|
|
3110
3111
|
{recurrenceDayOptions.map((day) => {
|
|
3111
3112
|
const active = (
|
|
3112
3113
|
watchedFormValues.sessionRecurrenceDaysOfWeek ?? []
|
|
@@ -3117,8 +3118,8 @@ export default function TurmasPage() {
|
|
|
3117
3118
|
key={day.value}
|
|
3118
3119
|
type="button"
|
|
3119
3120
|
variant={active ? 'default' : 'outline'}
|
|
3120
|
-
size="
|
|
3121
|
-
className="
|
|
3121
|
+
size="sm"
|
|
3122
|
+
className="h-9"
|
|
3122
3123
|
onClick={() => toggleCustomRecurrenceDay(day.value)}
|
|
3123
3124
|
>
|
|
3124
3125
|
{day.label}
|
|
@@ -40,8 +40,9 @@ import {
|
|
|
40
40
|
ShortcutsHelpTrigger,
|
|
41
41
|
} from './structure/_components/shortcuts-help';
|
|
42
42
|
import { useStructureStore } from './structure/_components/store';
|
|
43
|
-
import { TreeDisplaySettingsPopover } from './structure/_components/tree-display-settings-popover';
|
|
44
|
-
import { useCourseStructureShortcuts } from './structure/_components/use-course-structure-shortcuts';
|
|
43
|
+
import { TreeDisplaySettingsPopover } from './structure/_components/tree-display-settings-popover';
|
|
44
|
+
import { useCourseStructureShortcuts } from './structure/_components/use-course-structure-shortcuts';
|
|
45
|
+
import { CourseAvatar } from '../../_components/course-avatar';
|
|
45
46
|
import {
|
|
46
47
|
useDuplicateLessonMutation,
|
|
47
48
|
useDuplicateSessionMutation,
|
|
@@ -54,11 +55,13 @@ interface Props {
|
|
|
54
55
|
params: Promise<{ id: string }>;
|
|
55
56
|
}
|
|
56
57
|
|
|
57
|
-
type ApiCourseSummary = {
|
|
58
|
-
name?: string;
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
58
|
+
type ApiCourseSummary = {
|
|
59
|
+
name?: string;
|
|
60
|
+
title?: string;
|
|
61
|
+
logoFileId?: number | null;
|
|
62
|
+
enrollmentCount?: number;
|
|
63
|
+
averageCompletion?: number;
|
|
64
|
+
lessonCount?: number;
|
|
62
65
|
sessionCount?: number;
|
|
63
66
|
};
|
|
64
67
|
|
|
@@ -260,7 +263,17 @@ export default function CourseStructurePage({ params }: Props) {
|
|
|
260
263
|
{ label: 'Cursos', href: '/lms/courses' },
|
|
261
264
|
{ label: course.name },
|
|
262
265
|
]}
|
|
263
|
-
title={
|
|
266
|
+
title={
|
|
267
|
+
<span className="flex min-w-0 items-center gap-3">
|
|
268
|
+
<CourseAvatar
|
|
269
|
+
fileId={courseSummary?.logoFileId}
|
|
270
|
+
title={courseSummary?.title ?? course.name}
|
|
271
|
+
className="size-10 rounded-lg"
|
|
272
|
+
iconSize="size-5"
|
|
273
|
+
/>
|
|
274
|
+
<span className="min-w-0 truncate">{course.name}</span>
|
|
275
|
+
</span>
|
|
276
|
+
}
|
|
264
277
|
extraContent={metricsBadges}
|
|
265
278
|
actions={
|
|
266
279
|
<>
|
|
@@ -843,12 +843,16 @@ export function EditorCourse() {
|
|
|
843
843
|
onValueChange={setActiveTab}
|
|
844
844
|
className="flex flex-col flex-1 min-h-0"
|
|
845
845
|
>
|
|
846
|
-
<TabsList>
|
|
847
|
-
{(['estrutura', 'sobre', 'midia', 'extra'] as const).map((tab) => (
|
|
848
|
-
<TabsTrigger
|
|
849
|
-
{tab
|
|
850
|
-
|
|
851
|
-
|
|
846
|
+
<TabsList className="mx-3 mt-3 h-auto shrink-0 grid w-[calc(100%-1.5rem)] grid-cols-4 rounded-lg bg-muted/80 p-1">
|
|
847
|
+
{(['estrutura', 'sobre', 'midia', 'extra'] as const).map((tab) => (
|
|
848
|
+
<TabsTrigger
|
|
849
|
+
key={tab}
|
|
850
|
+
value={tab}
|
|
851
|
+
className="h-8 px-2 text-xs font-medium"
|
|
852
|
+
>
|
|
853
|
+
{tab === 'estrutura'
|
|
854
|
+
? 'Estrutura'
|
|
855
|
+
: tab === 'sobre'
|
|
852
856
|
? 'Sobre'
|
|
853
857
|
: tab === 'midia'
|
|
854
858
|
? 'Mídia'
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { Button } from '@/components/ui/button';
|
|
4
|
+
import { Input } from '@/components/ui/input';
|
|
5
|
+
import { Label } from '@/components/ui/label';
|
|
6
|
+
import {
|
|
7
|
+
Select,
|
|
8
|
+
SelectContent,
|
|
9
|
+
SelectItem,
|
|
10
|
+
SelectTrigger,
|
|
11
|
+
SelectValue,
|
|
12
|
+
} from '@/components/ui/select';
|
|
13
|
+
import {
|
|
14
|
+
Sheet,
|
|
15
|
+
SheetContent,
|
|
16
|
+
SheetFooter,
|
|
17
|
+
SheetHeader,
|
|
18
|
+
SheetTitle,
|
|
19
|
+
} from '@/components/ui/sheet';
|
|
20
|
+
import { Switch } from '@/components/ui/switch';
|
|
21
|
+
import { Textarea } from '@/components/ui/textarea';
|
|
22
|
+
import { useApp } from '@hed-hog/next-app-provider';
|
|
23
|
+
import { useTranslations } from 'next-intl';
|
|
24
|
+
import { useEffect, useState } from 'react';
|
|
25
|
+
import { toast } from 'sonner';
|
|
26
|
+
import type {
|
|
27
|
+
EvaluationTargetType,
|
|
28
|
+
EvaluationTopicItem,
|
|
29
|
+
} from './evaluation-topic-types';
|
|
30
|
+
import { TARGET_TYPE_OPTIONS } from './evaluation-topic-types';
|
|
31
|
+
|
|
32
|
+
interface EvaluationTopicFormSheetProps {
|
|
33
|
+
open: boolean;
|
|
34
|
+
onOpenChange: (open: boolean) => void;
|
|
35
|
+
editingItem: EvaluationTopicItem | null;
|
|
36
|
+
onSuccess: () => void;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function EvaluationTopicFormSheet({
|
|
40
|
+
open,
|
|
41
|
+
onOpenChange,
|
|
42
|
+
editingItem,
|
|
43
|
+
onSuccess,
|
|
44
|
+
}: EvaluationTopicFormSheetProps) {
|
|
45
|
+
const t = useTranslations('lms.EvaluationTopicsPage');
|
|
46
|
+
const { request } = useApp();
|
|
47
|
+
|
|
48
|
+
const [name, setName] = useState('');
|
|
49
|
+
const [description, setDescription] = useState('');
|
|
50
|
+
const [targetType, setTargetType] = useState<EvaluationTargetType>('course');
|
|
51
|
+
const [isActive, setIsActive] = useState(true);
|
|
52
|
+
const [saving, setSaving] = useState(false);
|
|
53
|
+
|
|
54
|
+
useEffect(() => {
|
|
55
|
+
if (open) {
|
|
56
|
+
if (editingItem) {
|
|
57
|
+
setName(editingItem.name);
|
|
58
|
+
setDescription(editingItem.description ?? '');
|
|
59
|
+
setTargetType(editingItem.targetType);
|
|
60
|
+
setIsActive(editingItem.isActive);
|
|
61
|
+
} else {
|
|
62
|
+
setName('');
|
|
63
|
+
setDescription('');
|
|
64
|
+
setTargetType('course');
|
|
65
|
+
setIsActive(true);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}, [open, editingItem]);
|
|
69
|
+
|
|
70
|
+
async function handleSubmit(e: React.FormEvent) {
|
|
71
|
+
e.preventDefault();
|
|
72
|
+
if (!name.trim()) return;
|
|
73
|
+
|
|
74
|
+
setSaving(true);
|
|
75
|
+
try {
|
|
76
|
+
const body: Record<string, unknown> = {
|
|
77
|
+
name: name.trim(),
|
|
78
|
+
description: description.trim() || null,
|
|
79
|
+
targetType,
|
|
80
|
+
isActive,
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
if (editingItem) {
|
|
84
|
+
await request({
|
|
85
|
+
url: `/lms/evaluations/topics/${editingItem.id}`,
|
|
86
|
+
method: 'PATCH',
|
|
87
|
+
data: body,
|
|
88
|
+
});
|
|
89
|
+
toast.success(t('form.updatedSuccess'));
|
|
90
|
+
} else {
|
|
91
|
+
await request({
|
|
92
|
+
url: '/lms/evaluations/topics',
|
|
93
|
+
method: 'POST',
|
|
94
|
+
data: body,
|
|
95
|
+
});
|
|
96
|
+
toast.success(t('form.createdSuccess'));
|
|
97
|
+
}
|
|
98
|
+
onSuccess();
|
|
99
|
+
onOpenChange(false);
|
|
100
|
+
} catch {
|
|
101
|
+
toast.error(t('form.saveError'));
|
|
102
|
+
} finally {
|
|
103
|
+
setSaving(false);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return (
|
|
108
|
+
<Sheet open={open} onOpenChange={onOpenChange}>
|
|
109
|
+
<SheetContent side="right" className="w-full sm:max-w-md">
|
|
110
|
+
<SheetHeader>
|
|
111
|
+
<SheetTitle>
|
|
112
|
+
{editingItem ? t('form.editTitle') : t('form.createTitle')}
|
|
113
|
+
</SheetTitle>
|
|
114
|
+
</SheetHeader>
|
|
115
|
+
|
|
116
|
+
<form onSubmit={handleSubmit} className="mt-6 flex flex-col gap-5 px-2">
|
|
117
|
+
{/* Name */}
|
|
118
|
+
<div className="flex flex-col gap-1.5">
|
|
119
|
+
<Label htmlFor="topic-name">{t('form.name')}</Label>
|
|
120
|
+
<Input
|
|
121
|
+
id="topic-name"
|
|
122
|
+
value={name}
|
|
123
|
+
onChange={(e) => setName(e.target.value)}
|
|
124
|
+
placeholder={t('form.namePlaceholder')}
|
|
125
|
+
required
|
|
126
|
+
maxLength={255}
|
|
127
|
+
/>
|
|
128
|
+
</div>
|
|
129
|
+
|
|
130
|
+
{/* Description */}
|
|
131
|
+
<div className="flex flex-col gap-1.5">
|
|
132
|
+
<Label htmlFor="topic-description">{t('form.description')}</Label>
|
|
133
|
+
<Textarea
|
|
134
|
+
id="topic-description"
|
|
135
|
+
value={description}
|
|
136
|
+
onChange={(e) => setDescription(e.target.value)}
|
|
137
|
+
placeholder={t('form.descriptionPlaceholder')}
|
|
138
|
+
rows={3}
|
|
139
|
+
className="resize-none"
|
|
140
|
+
/>
|
|
141
|
+
</div>
|
|
142
|
+
|
|
143
|
+
{/* Target Type */}
|
|
144
|
+
<div className="flex flex-col gap-1.5">
|
|
145
|
+
<Label>{t('form.targetType')}</Label>
|
|
146
|
+
<Select
|
|
147
|
+
value={targetType}
|
|
148
|
+
onValueChange={(v) => setTargetType(v as EvaluationTargetType)}
|
|
149
|
+
disabled={!!editingItem}
|
|
150
|
+
>
|
|
151
|
+
<SelectTrigger className="w-full">
|
|
152
|
+
<SelectValue />
|
|
153
|
+
</SelectTrigger>
|
|
154
|
+
<SelectContent>
|
|
155
|
+
{TARGET_TYPE_OPTIONS.map((opt) => (
|
|
156
|
+
<SelectItem key={opt.value} value={opt.value}>
|
|
157
|
+
{t(`targetType.${opt.labelKey}`)}
|
|
158
|
+
</SelectItem>
|
|
159
|
+
))}
|
|
160
|
+
</SelectContent>
|
|
161
|
+
</Select>
|
|
162
|
+
{editingItem && (
|
|
163
|
+
<p className="text-xs text-muted-foreground">
|
|
164
|
+
{t('form.targetTypeReadonly')}
|
|
165
|
+
</p>
|
|
166
|
+
)}
|
|
167
|
+
</div>
|
|
168
|
+
|
|
169
|
+
{/* Is Active */}
|
|
170
|
+
<div className="flex items-center justify-between rounded-lg border border-border/50 px-4 py-3">
|
|
171
|
+
<div>
|
|
172
|
+
<p className="text-sm font-medium">{t('form.isActive')}</p>
|
|
173
|
+
<p className="text-xs text-muted-foreground">
|
|
174
|
+
{t('form.isActiveDesc')}
|
|
175
|
+
</p>
|
|
176
|
+
</div>
|
|
177
|
+
<Switch checked={isActive} onCheckedChange={setIsActive} />
|
|
178
|
+
</div>
|
|
179
|
+
|
|
180
|
+
<SheetFooter className="mt-2 flex gap-2">
|
|
181
|
+
<Button
|
|
182
|
+
type="button"
|
|
183
|
+
variant="outline"
|
|
184
|
+
onClick={() => onOpenChange(false)}
|
|
185
|
+
disabled={saving}
|
|
186
|
+
>
|
|
187
|
+
{t('form.cancel')}
|
|
188
|
+
</Button>
|
|
189
|
+
<Button type="submit" disabled={saving || !name.trim()}>
|
|
190
|
+
{saving
|
|
191
|
+
? t('form.saving')
|
|
192
|
+
: editingItem
|
|
193
|
+
? t('form.save')
|
|
194
|
+
: t('form.create')}
|
|
195
|
+
</Button>
|
|
196
|
+
</SheetFooter>
|
|
197
|
+
</form>
|
|
198
|
+
</SheetContent>
|
|
199
|
+
</Sheet>
|
|
200
|
+
);
|
|
201
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export type EvaluationTargetType =
|
|
2
|
+
| 'course'
|
|
3
|
+
| 'course_lesson'
|
|
4
|
+
| 'course_class_session'
|
|
5
|
+
| 'question'
|
|
6
|
+
| 'exam';
|
|
7
|
+
|
|
8
|
+
export interface EvaluationTopicItem {
|
|
9
|
+
id: number;
|
|
10
|
+
name: string;
|
|
11
|
+
description: string | null;
|
|
12
|
+
targetType: EvaluationTargetType;
|
|
13
|
+
order: number | null;
|
|
14
|
+
isActive: boolean;
|
|
15
|
+
ratingCount: number;
|
|
16
|
+
createdAt: string;
|
|
17
|
+
updatedAt: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export type ApiEvaluationTopicList = {
|
|
21
|
+
data: EvaluationTopicItem[];
|
|
22
|
+
total: number;
|
|
23
|
+
page: number;
|
|
24
|
+
pageSize: number;
|
|
25
|
+
lastPage: number;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export const TARGET_TYPE_OPTIONS: {
|
|
29
|
+
value: EvaluationTargetType;
|
|
30
|
+
labelKey: string;
|
|
31
|
+
}[] = [
|
|
32
|
+
{ value: 'course', labelKey: 'course' },
|
|
33
|
+
{ value: 'course_lesson', labelKey: 'course_lesson' },
|
|
34
|
+
{ value: 'course_class_session', labelKey: 'course_class_session' },
|
|
35
|
+
{ value: 'question', labelKey: 'question' },
|
|
36
|
+
{ value: 'exam', labelKey: 'exam' },
|
|
37
|
+
];
|
|
38
|
+
|
|
39
|
+
export const TARGET_TYPE_COLORS: Record<EvaluationTargetType, string> = {
|
|
40
|
+
course:
|
|
41
|
+
'bg-blue-100 text-blue-700 border-blue-200 dark:bg-blue-950 dark:text-blue-300 dark:border-blue-800',
|
|
42
|
+
course_lesson:
|
|
43
|
+
'bg-green-100 text-green-700 border-green-200 dark:bg-green-950 dark:text-green-300 dark:border-green-800',
|
|
44
|
+
course_class_session:
|
|
45
|
+
'bg-purple-100 text-purple-700 border-purple-200 dark:bg-purple-950 dark:text-purple-300 dark:border-purple-800',
|
|
46
|
+
question:
|
|
47
|
+
'bg-orange-100 text-orange-700 border-orange-200 dark:bg-orange-950 dark:text-orange-300 dark:border-orange-800',
|
|
48
|
+
exam: 'bg-red-100 text-red-700 border-red-200 dark:bg-red-950 dark:text-red-300 dark:border-red-800',
|
|
49
|
+
};
|