@hed-hog/lms 0.0.331 → 0.0.338
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 +3 -3
- package/dist/class-group/class-group.service.d.ts +3 -3
- package/dist/course/course.service.d.ts.map +1 -1
- package/dist/course/course.service.js +12 -20
- package/dist/course/course.service.js.map +1 -1
- package/dist/enterprise/enterprise.controller.d.ts +72 -0
- 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 +78 -0
- 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 +6 -3
- 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 +8 -2
- 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 +4 -4
- package/dist/evaluation/evaluation.service.d.ts +4 -4
- 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 +20 -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 +25 -0
- package/dist/instructor/instructor.service.d.ts.map +1 -1
- package/dist/instructor/instructor.service.js +70 -18
- 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/hedhog/data/route.yaml +23 -1
- package/hedhog/frontend/app/_components/class-form-sheet.tsx.ejs +42 -24
- 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 +6 -1
- package/hedhog/frontend/app/classes/page.tsx.ejs +6 -1
- 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 +242 -33
- 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 +6 -1
- 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 +9 -4
- package/hedhog/frontend/app/reports/evaluations/page.tsx.ejs +6 -1
- package/hedhog/frontend/app/training/page.tsx.ejs +9 -4
- package/hedhog/frontend/messages/en.json +101 -10
- package/hedhog/frontend/messages/pt.json +101 -10
- package/hedhog/table/enterprise_student_license_event.yaml +30 -0
- package/hedhog/table/instructor_skill.yaml +0 -11
- package/package.json +7 -7
- package/src/course/course.service.ts +12 -24
- 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 +85 -10
- package/src/lms.module.ts +1 -0
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
SearchBar,
|
|
9
9
|
type SearchBarControl,
|
|
10
10
|
} from '@/components/entity-list';
|
|
11
|
+
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
|
|
11
12
|
import { Badge } from '@/components/ui/badge';
|
|
12
13
|
import { Button } from '@/components/ui/button';
|
|
13
14
|
import { Card, CardContent } from '@/components/ui/card';
|
|
@@ -246,6 +247,21 @@ export default function EnterprisePage() {
|
|
|
246
247
|
const accounts = enterpriseList?.data ?? [];
|
|
247
248
|
const totalItems = enterpriseList?.total ?? 0;
|
|
248
249
|
|
|
250
|
+
function getPersonAvatarUrl(avatarId?: number | null) {
|
|
251
|
+
return typeof avatarId === 'number' && avatarId > 0
|
|
252
|
+
? `${process.env.NEXT_PUBLIC_API_BASE_URL}/person/avatar/${avatarId}`
|
|
253
|
+
: undefined;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
function getInitials(name: string) {
|
|
257
|
+
const parts = name.trim().split(/\s+/).filter(Boolean);
|
|
258
|
+
if (parts.length === 0) return '?';
|
|
259
|
+
if (parts.length === 1) return (parts[0] ?? '').slice(0, 2).toUpperCase();
|
|
260
|
+
return (
|
|
261
|
+
((parts[0] ?? '')[0] ?? '') + ((parts[1] ?? '')[0] ?? '')
|
|
262
|
+
).toUpperCase();
|
|
263
|
+
}
|
|
264
|
+
|
|
249
265
|
function handleSearch(v: string) {
|
|
250
266
|
setSearch(v);
|
|
251
267
|
setPage(1);
|
|
@@ -386,9 +402,7 @@ export default function EnterprisePage() {
|
|
|
386
402
|
<TableHead>{t('table.name')}</TableHead>
|
|
387
403
|
<TableHead>{t('table.status')}</TableHead>
|
|
388
404
|
<TableHead>
|
|
389
|
-
{t.has('table.
|
|
390
|
-
? t('table.crmAccount')
|
|
391
|
-
: 'CRM Account'}
|
|
405
|
+
{t.has('table.client') ? t('table.client') : 'Cliente'}
|
|
392
406
|
</TableHead>
|
|
393
407
|
<TableHead className="text-center">
|
|
394
408
|
{t.has('table.classes') ? t('table.classes') : 'Classes'}
|
|
@@ -410,7 +424,7 @@ export default function EnterprisePage() {
|
|
|
410
424
|
<TableRow
|
|
411
425
|
key={account.id}
|
|
412
426
|
className="cursor-pointer"
|
|
413
|
-
|
|
427
|
+
onDoubleClick={() => handleViewDetails(account)}
|
|
414
428
|
>
|
|
415
429
|
<TableCell>
|
|
416
430
|
<p className="font-medium">{account.name}</p>
|
|
@@ -437,7 +451,25 @@ export default function EnterprisePage() {
|
|
|
437
451
|
</Badge>
|
|
438
452
|
</TableCell>
|
|
439
453
|
<TableCell className="text-sm text-muted-foreground">
|
|
440
|
-
{account.crmAccountName
|
|
454
|
+
{account.crmAccountName ? (
|
|
455
|
+
<div className="flex items-center gap-2">
|
|
456
|
+
<Avatar className="h-7 w-7">
|
|
457
|
+
<AvatarImage
|
|
458
|
+
src={getPersonAvatarUrl(
|
|
459
|
+
account.crmAccount?.avatarId ?? null
|
|
460
|
+
)}
|
|
461
|
+
/>
|
|
462
|
+
<AvatarFallback className="text-[10px] font-semibold">
|
|
463
|
+
{getInitials(account.crmAccountName)}
|
|
464
|
+
</AvatarFallback>
|
|
465
|
+
</Avatar>
|
|
466
|
+
<span className="truncate text-sm text-foreground">
|
|
467
|
+
{account.crmAccountName}
|
|
468
|
+
</span>
|
|
469
|
+
</div>
|
|
470
|
+
) : (
|
|
471
|
+
'—'
|
|
472
|
+
)}
|
|
441
473
|
</TableCell>
|
|
442
474
|
<TableCell className="text-center text-sm tabular-nums">
|
|
443
475
|
{account.classesCount}
|
|
@@ -490,7 +522,7 @@ export default function EnterprisePage() {
|
|
|
490
522
|
<Card
|
|
491
523
|
key={account.id}
|
|
492
524
|
className="group cursor-pointer overflow-hidden border-border/70 py-0 transition-colors hover:border-border hover:shadow-md"
|
|
493
|
-
|
|
525
|
+
onDoubleClick={() => handleViewDetails(account)}
|
|
494
526
|
>
|
|
495
527
|
<CardContent className="flex flex-col gap-3 p-4">
|
|
496
528
|
{/* Header */}
|
|
@@ -616,7 +648,7 @@ export default function EnterprisePage() {
|
|
|
616
648
|
pageSize={PAGE_SIZE}
|
|
617
649
|
totalItems={totalItems}
|
|
618
650
|
onPageChange={setPage}
|
|
619
|
-
onPageSizeChange={function (
|
|
651
|
+
onPageSizeChange={function (): void {
|
|
620
652
|
throw new Error('Function not implemented.');
|
|
621
653
|
}}
|
|
622
654
|
/>
|
|
@@ -104,6 +104,7 @@ import {
|
|
|
104
104
|
import { useTranslations } from 'next-intl';
|
|
105
105
|
import { useParams, useRouter } from 'next/navigation';
|
|
106
106
|
import { useEffect, useMemo, useState } from 'react';
|
|
107
|
+
import { usePersistedPageSize } from '@/hooks/use-persisted-page-size';
|
|
107
108
|
import { useForm } from 'react-hook-form';
|
|
108
109
|
import { toast } from 'sonner';
|
|
109
110
|
import { z } from 'zod';
|
|
@@ -599,7 +600,11 @@ export default function QuestoesPage() {
|
|
|
599
600
|
allowedValues: ['cards', 'list'],
|
|
600
601
|
});
|
|
601
602
|
const [currentPage, setCurrentPage] = useState(1);
|
|
602
|
-
const [pageSize, setPageSize] =
|
|
603
|
+
const [pageSize, setPageSize] = usePersistedPageSize({
|
|
604
|
+
storageKey: 'pagination:global:pageSize',
|
|
605
|
+
defaultValue: 12,
|
|
606
|
+
allowedValues: PAGE_SIZE_OPTIONS,
|
|
607
|
+
});
|
|
603
608
|
|
|
604
609
|
const questaoSchema = z.object({
|
|
605
610
|
enunciado: z.string().min(5, t('sheet.validation.statementMin')),
|
|
@@ -83,6 +83,7 @@ import {
|
|
|
83
83
|
import { useTranslations } from 'next-intl';
|
|
84
84
|
import { useRouter } from 'next/navigation';
|
|
85
85
|
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
86
|
+
import { usePersistedPageSize } from '@/hooks/use-persisted-page-size';
|
|
86
87
|
import { Controller, useForm, useWatch } from 'react-hook-form';
|
|
87
88
|
import { toast } from 'sonner';
|
|
88
89
|
import { z } from 'zod';
|
|
@@ -261,7 +262,11 @@ export default function ExamesPage() {
|
|
|
261
262
|
|
|
262
263
|
// Pagination
|
|
263
264
|
const [currentPage, setCurrentPage] = useState(1);
|
|
264
|
-
const [pageSize, setPageSize] =
|
|
265
|
+
const [pageSize, setPageSize] = usePersistedPageSize({
|
|
266
|
+
storageKey: 'pagination:global:pageSize',
|
|
267
|
+
defaultValue: 12,
|
|
268
|
+
allowedValues: PAGE_SIZES,
|
|
269
|
+
});
|
|
265
270
|
|
|
266
271
|
// Double-click tracking
|
|
267
272
|
const clickTimers = useRef<Map<number, ReturnType<typeof setTimeout>>>(
|
|
@@ -56,6 +56,7 @@ import {
|
|
|
56
56
|
TableHeader,
|
|
57
57
|
TableRow,
|
|
58
58
|
} from '@/components/ui/table';
|
|
59
|
+
import { usePersistedPageSize } from '@/hooks/use-persisted-page-size';
|
|
59
60
|
import { cn } from '@/lib/utils';
|
|
60
61
|
import { useApp, useQuery } from '@hed-hog/next-app-provider';
|
|
61
62
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
@@ -71,8 +72,6 @@ import * as z from 'zod';
|
|
|
71
72
|
type InstructorSkill = {
|
|
72
73
|
id: number;
|
|
73
74
|
slug: string;
|
|
74
|
-
namePt: string;
|
|
75
|
-
nameEn?: string | null;
|
|
76
75
|
status: 'active' | 'inactive';
|
|
77
76
|
};
|
|
78
77
|
|
|
@@ -93,16 +92,7 @@ const createSkillSchema = (t: ReturnType<typeof useTranslations>) =>
|
|
|
93
92
|
.min(1, t('form.validation.required'))
|
|
94
93
|
.max(100, t('form.validation.max100'))
|
|
95
94
|
.regex(/^[a-z0-9-]+$/, t('form.validation.slugPattern')),
|
|
96
|
-
|
|
97
|
-
.string()
|
|
98
|
-
.min(1, t('form.validation.required'))
|
|
99
|
-
.max(255, t('form.validation.max255')),
|
|
100
|
-
nameEn: z
|
|
101
|
-
.string()
|
|
102
|
-
.max(255, t('form.validation.max255'))
|
|
103
|
-
.optional()
|
|
104
|
-
.or(z.literal('')),
|
|
105
|
-
status: z.enum(['active', 'inactive']).default('active'),
|
|
95
|
+
status: z.enum(['active', 'inactive']),
|
|
106
96
|
});
|
|
107
97
|
|
|
108
98
|
type SkillFormValues = z.infer<ReturnType<typeof createSkillSchema>>;
|
|
@@ -130,8 +120,6 @@ function SkillFormSheet({
|
|
|
130
120
|
resolver: zodResolver(createSkillSchema(t)),
|
|
131
121
|
defaultValues: {
|
|
132
122
|
slug: '',
|
|
133
|
-
namePt: '',
|
|
134
|
-
nameEn: '',
|
|
135
123
|
status: 'active',
|
|
136
124
|
},
|
|
137
125
|
});
|
|
@@ -142,15 +130,11 @@ function SkillFormSheet({
|
|
|
142
130
|
if (skillToEdit) {
|
|
143
131
|
form.reset({
|
|
144
132
|
slug: skillToEdit.slug,
|
|
145
|
-
namePt: skillToEdit.namePt,
|
|
146
|
-
nameEn: skillToEdit.nameEn ?? '',
|
|
147
133
|
status: skillToEdit.status,
|
|
148
134
|
});
|
|
149
135
|
} else {
|
|
150
136
|
form.reset({
|
|
151
137
|
slug: '',
|
|
152
|
-
namePt: '',
|
|
153
|
-
nameEn: '',
|
|
154
138
|
status: 'active',
|
|
155
139
|
});
|
|
156
140
|
}
|
|
@@ -162,8 +146,6 @@ function SkillFormSheet({
|
|
|
162
146
|
setIsSaving(true);
|
|
163
147
|
const payload = {
|
|
164
148
|
slug: values.slug,
|
|
165
|
-
namePt: values.namePt,
|
|
166
|
-
nameEn: values.nameEn || undefined,
|
|
167
149
|
status: values.status,
|
|
168
150
|
};
|
|
169
151
|
|
|
@@ -206,81 +188,52 @@ function SkillFormSheet({
|
|
|
206
188
|
onSubmit={form.handleSubmit(onSubmit)}
|
|
207
189
|
className="flex flex-col gap-4 px-4 py-4"
|
|
208
190
|
>
|
|
209
|
-
<
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
<
|
|
215
|
-
|
|
216
|
-
<Input placeholder={t('form.slugPlaceholder')} {...field} />
|
|
217
|
-
</FormControl>
|
|
218
|
-
<FormMessage />
|
|
219
|
-
</FormItem>
|
|
220
|
-
)}
|
|
221
|
-
/>
|
|
222
|
-
|
|
223
|
-
<FormField
|
|
224
|
-
control={form.control}
|
|
225
|
-
name="namePt"
|
|
226
|
-
render={({ field }) => (
|
|
227
|
-
<FormItem>
|
|
228
|
-
<FormLabel>{t('form.namePt')}</FormLabel>
|
|
229
|
-
<FormControl>
|
|
230
|
-
<Input
|
|
231
|
-
placeholder={t('form.namePtPlaceholder')}
|
|
232
|
-
{...field}
|
|
233
|
-
/>
|
|
234
|
-
</FormControl>
|
|
235
|
-
<FormMessage />
|
|
236
|
-
</FormItem>
|
|
237
|
-
)}
|
|
238
|
-
/>
|
|
239
|
-
|
|
240
|
-
<FormField
|
|
241
|
-
control={form.control}
|
|
242
|
-
name="nameEn"
|
|
243
|
-
render={({ field }) => (
|
|
244
|
-
<FormItem>
|
|
245
|
-
<FormLabel>{t('form.nameEn')}</FormLabel>
|
|
246
|
-
<FormControl>
|
|
247
|
-
<Input
|
|
248
|
-
placeholder={t('form.nameEnPlaceholder')}
|
|
249
|
-
{...field}
|
|
250
|
-
/>
|
|
251
|
-
</FormControl>
|
|
252
|
-
<FormMessage />
|
|
253
|
-
</FormItem>
|
|
254
|
-
)}
|
|
255
|
-
/>
|
|
256
|
-
|
|
257
|
-
<FormField
|
|
258
|
-
control={form.control}
|
|
259
|
-
name="status"
|
|
260
|
-
render={({ field }) => (
|
|
261
|
-
<FormItem>
|
|
262
|
-
<FormLabel>{t('form.status')}</FormLabel>
|
|
263
|
-
<Select onValueChange={field.onChange} value={field.value}>
|
|
191
|
+
<div className="grid grid-cols-2 gap-4">
|
|
192
|
+
<FormField
|
|
193
|
+
control={form.control}
|
|
194
|
+
name="slug"
|
|
195
|
+
render={({ field }) => (
|
|
196
|
+
<FormItem>
|
|
197
|
+
<FormLabel>{t('form.slug')}</FormLabel>
|
|
264
198
|
<FormControl>
|
|
265
|
-
<
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
</SelectTrigger>
|
|
199
|
+
<Input
|
|
200
|
+
placeholder={t('form.slugPlaceholder')}
|
|
201
|
+
{...field}
|
|
202
|
+
/>
|
|
270
203
|
</FormControl>
|
|
271
|
-
<
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
<
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
204
|
+
<FormMessage />
|
|
205
|
+
</FormItem>
|
|
206
|
+
)}
|
|
207
|
+
/>
|
|
208
|
+
|
|
209
|
+
<FormField
|
|
210
|
+
control={form.control}
|
|
211
|
+
name="status"
|
|
212
|
+
render={({ field }) => (
|
|
213
|
+
<FormItem>
|
|
214
|
+
<FormLabel>{t('form.status')}</FormLabel>
|
|
215
|
+
<Select onValueChange={field.onChange} value={field.value}>
|
|
216
|
+
<FormControl>
|
|
217
|
+
<SelectTrigger className="w-full">
|
|
218
|
+
<SelectValue
|
|
219
|
+
placeholder={t('form.statusPlaceholder')}
|
|
220
|
+
/>
|
|
221
|
+
</SelectTrigger>
|
|
222
|
+
</FormControl>
|
|
223
|
+
<SelectContent>
|
|
224
|
+
<SelectItem value="active">
|
|
225
|
+
{t('status.active')}
|
|
226
|
+
</SelectItem>
|
|
227
|
+
<SelectItem value="inactive">
|
|
228
|
+
{t('status.inactive')}
|
|
229
|
+
</SelectItem>
|
|
230
|
+
</SelectContent>
|
|
231
|
+
</Select>
|
|
232
|
+
<FormMessage />
|
|
233
|
+
</FormItem>
|
|
234
|
+
)}
|
|
235
|
+
/>
|
|
236
|
+
</div>
|
|
284
237
|
|
|
285
238
|
<div className="flex justify-end gap-2 pt-2">
|
|
286
239
|
<Button
|
|
@@ -309,7 +262,11 @@ export default function InstructorSkillsPage() {
|
|
|
309
262
|
const t = useTranslations('lms.InstructorSkillsPage');
|
|
310
263
|
|
|
311
264
|
const [page, setPage] = useState(1);
|
|
312
|
-
const [pageSize, setPageSize] =
|
|
265
|
+
const [pageSize, setPageSize] = usePersistedPageSize({
|
|
266
|
+
storageKey: 'pagination:global:pageSize',
|
|
267
|
+
defaultValue: 6,
|
|
268
|
+
allowedValues: [6, 12, 24, 48],
|
|
269
|
+
});
|
|
313
270
|
const [searchInput, setSearchInput] = useState('');
|
|
314
271
|
const [debouncedSearch, setDebouncedSearch] = useState('');
|
|
315
272
|
const [sheetOpen, setSheetOpen] = useState(false);
|
|
@@ -448,8 +405,6 @@ export default function InstructorSkillsPage() {
|
|
|
448
405
|
<TableHeader>
|
|
449
406
|
<TableRow>
|
|
450
407
|
<TableHead>{t('table.slug')}</TableHead>
|
|
451
|
-
<TableHead>{t('table.namePt')}</TableHead>
|
|
452
|
-
<TableHead>{t('table.nameEn')}</TableHead>
|
|
453
408
|
<TableHead>{t('table.status')}</TableHead>
|
|
454
409
|
<TableHead className="w-10" />
|
|
455
410
|
</TableRow>
|
|
@@ -464,14 +419,6 @@ export default function InstructorSkillsPage() {
|
|
|
464
419
|
<TableCell>
|
|
465
420
|
<span className="font-mono text-sm">{skill.slug}</span>
|
|
466
421
|
</TableCell>
|
|
467
|
-
<TableCell>
|
|
468
|
-
<span className="font-medium">{skill.namePt}</span>
|
|
469
|
-
</TableCell>
|
|
470
|
-
<TableCell>
|
|
471
|
-
<span className="text-sm text-muted-foreground">
|
|
472
|
-
{skill.nameEn ?? '—'}
|
|
473
|
-
</span>
|
|
474
|
-
</TableCell>
|
|
475
422
|
<TableCell>
|
|
476
423
|
<Badge
|
|
477
424
|
variant="outline"
|