@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
|
@@ -56,6 +56,7 @@ import {
|
|
|
56
56
|
} from 'lucide-react';
|
|
57
57
|
import { useTranslations } from 'next-intl';
|
|
58
58
|
import { useEffect, useState } from 'react';
|
|
59
|
+
import { usePersistedPageSize } from '@/hooks/use-persisted-page-size';
|
|
59
60
|
import { toast } from 'sonner';
|
|
60
61
|
import { InstructorFormSheet } from './_components/instructor-form-sheet';
|
|
61
62
|
import type {
|
|
@@ -102,7 +103,11 @@ export default function InstructorsPage() {
|
|
|
102
103
|
const t = useTranslations('lms.InstructorsPage');
|
|
103
104
|
|
|
104
105
|
const [page, setPage] = useState(1);
|
|
105
|
-
const [pageSize, setPageSize] =
|
|
106
|
+
const [pageSize, setPageSize] = usePersistedPageSize({
|
|
107
|
+
storageKey: 'pagination:global:pageSize',
|
|
108
|
+
defaultValue: 12,
|
|
109
|
+
allowedValues: [6, 12, 24, 48],
|
|
110
|
+
});
|
|
106
111
|
const [searchInput, setSearchInput] = useState('');
|
|
107
112
|
const [debouncedSearch, setDebouncedSearch] = useState('');
|
|
108
113
|
const [statusFilter, setStatusFilter] = useState('all');
|
|
@@ -103,6 +103,7 @@ import {
|
|
|
103
103
|
import { useTranslations } from 'next-intl';
|
|
104
104
|
import { useRouter } from 'next/navigation';
|
|
105
105
|
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
106
|
+
import { usePersistedPageSize } from '@/hooks/use-persisted-page-size';
|
|
106
107
|
import { Controller, useForm, useWatch } from 'react-hook-form';
|
|
107
108
|
import { toast } from 'sonner';
|
|
108
109
|
import { z } from 'zod';
|
|
@@ -565,7 +566,11 @@ export default function TrainingPage() {
|
|
|
565
566
|
|
|
566
567
|
// Pagination
|
|
567
568
|
const [currentPage, setCurrentPage] = useState(1);
|
|
568
|
-
const [pageSize, setPageSize] =
|
|
569
|
+
const [pageSize, setPageSize] = usePersistedPageSize({
|
|
570
|
+
storageKey: 'pagination:global:pageSize',
|
|
571
|
+
defaultValue: 12,
|
|
572
|
+
allowedValues: PAGE_SIZES,
|
|
573
|
+
});
|
|
569
574
|
|
|
570
575
|
// Double-click tracking
|
|
571
576
|
const clickTimers = useRef<Map<number, ReturnType<typeof setTimeout>>>(
|
|
@@ -1893,15 +1898,15 @@ export default function TrainingPage() {
|
|
|
1893
1898
|
<FieldError>{form.formState.errors.nome?.message}</FieldError>
|
|
1894
1899
|
</Field>
|
|
1895
1900
|
<Field>
|
|
1896
|
-
<FieldLabel htmlFor="descricao">
|
|
1901
|
+
<FieldLabel htmlFor="descricao">
|
|
1897
1902
|
{t('form.fields.description.label')}{' '}
|
|
1898
1903
|
<span className="text-destructive">*</span>
|
|
1899
1904
|
</FieldLabel>
|
|
1900
1905
|
<Textarea
|
|
1901
|
-
id="descricao"
|
|
1906
|
+
id="descricao"
|
|
1902
1907
|
rows={3}
|
|
1903
1908
|
placeholder={t('form.fields.description.placeholder')}
|
|
1904
|
-
{...form.register('descricao')}
|
|
1909
|
+
{...form.register('descricao')}
|
|
1905
1910
|
/>
|
|
1906
1911
|
<FieldError>
|
|
1907
1912
|
{form.formState.errors.descricao?.message}
|
|
@@ -61,6 +61,7 @@ import {
|
|
|
61
61
|
import { useTranslations } from 'next-intl';
|
|
62
62
|
import { useRouter } from 'next/navigation';
|
|
63
63
|
import { useEffect, useMemo, useRef, useState, type ReactNode } from 'react';
|
|
64
|
+
import { usePersistedPageSize } from '@/hooks/use-persisted-page-size';
|
|
64
65
|
import type { DateRange } from 'react-day-picker';
|
|
65
66
|
|
|
66
67
|
// ── Types ─────────────────────────────────────────────────────────────────────
|
|
@@ -360,7 +361,11 @@ export default function EvaluationsReportPage() {
|
|
|
360
361
|
|
|
361
362
|
// Pagination
|
|
362
363
|
const [currentPage, setCurrentPage] = useState(1);
|
|
363
|
-
const [pageSize, setPageSize] =
|
|
364
|
+
const [pageSize, setPageSize] = usePersistedPageSize({
|
|
365
|
+
storageKey: 'pagination:global:pageSize',
|
|
366
|
+
defaultValue: 12,
|
|
367
|
+
allowedValues: PAGE_SIZES,
|
|
368
|
+
});
|
|
364
369
|
|
|
365
370
|
// Reset page when filters change
|
|
366
371
|
useEffect(() => {
|
|
@@ -102,6 +102,7 @@ import {
|
|
|
102
102
|
import { useTranslations } from 'next-intl';
|
|
103
103
|
import { useRouter } from 'next/navigation';
|
|
104
104
|
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
105
|
+
import { usePersistedPageSize } from '@/hooks/use-persisted-page-size';
|
|
105
106
|
import { Controller, useForm, useWatch } from 'react-hook-form';
|
|
106
107
|
import { toast } from 'sonner';
|
|
107
108
|
import { z } from 'zod';
|
|
@@ -560,7 +561,11 @@ export default function TrainingPage() {
|
|
|
560
561
|
|
|
561
562
|
// Pagination
|
|
562
563
|
const [currentPage, setCurrentPage] = useState(1);
|
|
563
|
-
const [pageSize, setPageSize] =
|
|
564
|
+
const [pageSize, setPageSize] = usePersistedPageSize({
|
|
565
|
+
storageKey: 'pagination:global:pageSize',
|
|
566
|
+
defaultValue: 12,
|
|
567
|
+
allowedValues: PAGE_SIZES,
|
|
568
|
+
});
|
|
564
569
|
|
|
565
570
|
// Double-click tracking
|
|
566
571
|
const clickTimers = useRef<Map<number, ReturnType<typeof setTimeout>>>(
|
|
@@ -1886,15 +1891,15 @@ export default function TrainingPage() {
|
|
|
1886
1891
|
<FieldError>{form.formState.errors.nome?.message}</FieldError>
|
|
1887
1892
|
</Field>
|
|
1888
1893
|
<Field>
|
|
1889
|
-
<FieldLabel htmlFor="descricao">
|
|
1894
|
+
<FieldLabel htmlFor="descricao">
|
|
1890
1895
|
{t('form.fields.description.label')}{' '}
|
|
1891
1896
|
<span className="text-destructive">*</span>
|
|
1892
1897
|
</FieldLabel>
|
|
1893
1898
|
<Textarea
|
|
1894
|
-
id="descricao"
|
|
1899
|
+
id="descricao"
|
|
1895
1900
|
rows={3}
|
|
1896
1901
|
placeholder={t('form.fields.description.placeholder')}
|
|
1897
|
-
{...form.register('descricao')}
|
|
1902
|
+
{...form.register('descricao')}
|
|
1898
1903
|
/>
|
|
1899
1904
|
<FieldError>
|
|
1900
1905
|
{form.formState.errors.descricao?.message}
|
|
@@ -2907,6 +2907,11 @@
|
|
|
2907
2907
|
"subFree": "{count} spots available",
|
|
2908
2908
|
"subFull": "Full"
|
|
2909
2909
|
},
|
|
2910
|
+
"nextClass": "Next Class",
|
|
2911
|
+
"noClass": "No class",
|
|
2912
|
+
"createNext": "Create next class",
|
|
2913
|
+
"calendar": "Calendar",
|
|
2914
|
+
"completed": "{count} completed",
|
|
2910
2915
|
"avgAttendance": {
|
|
2911
2916
|
"label": "Average Attendance",
|
|
2912
2917
|
"sub": "overall attendance"
|
|
@@ -3538,10 +3543,92 @@
|
|
|
3538
3543
|
"studentRemoveError": "Failed to remove student."
|
|
3539
3544
|
},
|
|
3540
3545
|
"form": {
|
|
3546
|
+
"title": {
|
|
3547
|
+
"create": "Create New Course",
|
|
3548
|
+
"edit": "Edit Course"
|
|
3549
|
+
},
|
|
3550
|
+
"description": {
|
|
3551
|
+
"create": "Fill in the details to create a new course. After creating, you will be redirected to the course page.",
|
|
3552
|
+
"edit": "Update the course information below."
|
|
3553
|
+
},
|
|
3554
|
+
"fields": {
|
|
3555
|
+
"internalName": {
|
|
3556
|
+
"label": "Internal Name",
|
|
3557
|
+
"placeholder": "Ex: Advanced React",
|
|
3558
|
+
"description": "Internal course name for administrative use"
|
|
3559
|
+
},
|
|
3560
|
+
"slug": {
|
|
3561
|
+
"label": "Slug",
|
|
3562
|
+
"placeholder": "Ex: advanced-react",
|
|
3563
|
+
"description": "Unique URL identifier (lowercase letters, numbers, and hyphens)"
|
|
3564
|
+
},
|
|
3565
|
+
"commercialTitle": {
|
|
3566
|
+
"label": "Commercial Title",
|
|
3567
|
+
"placeholder": "Ex: Advanced React"
|
|
3568
|
+
},
|
|
3569
|
+
"description": {
|
|
3570
|
+
"label": "Description",
|
|
3571
|
+
"placeholder": "Describe the course content and objectives..."
|
|
3572
|
+
},
|
|
3573
|
+
"level": {
|
|
3574
|
+
"label": "Level",
|
|
3575
|
+
"placeholder": "Select"
|
|
3576
|
+
},
|
|
3577
|
+
"status": {
|
|
3578
|
+
"label": "Status",
|
|
3579
|
+
"placeholder": "Select"
|
|
3580
|
+
},
|
|
3581
|
+
"categories": {
|
|
3582
|
+
"label": "Categories",
|
|
3583
|
+
"description": "Select one or more categories",
|
|
3584
|
+
"createAction": "Create category",
|
|
3585
|
+
"selectPlaceholder": "Select a category",
|
|
3586
|
+
"removeAction": "Remove category",
|
|
3587
|
+
"searchPlaceholder": "Type to search category...",
|
|
3588
|
+
"noResults": "No categories found",
|
|
3589
|
+
"selectedCount": "selected category(ies)"
|
|
3590
|
+
},
|
|
3591
|
+
"primaryColor": {
|
|
3592
|
+
"label": "Primary Color",
|
|
3593
|
+
"placeholder": "#1D4ED8"
|
|
3594
|
+
},
|
|
3595
|
+
"secondaryColor": {
|
|
3596
|
+
"label": "Secondary Color",
|
|
3597
|
+
"placeholder": "#111827"
|
|
3598
|
+
},
|
|
3599
|
+
"logo": {
|
|
3600
|
+
"label": "Course Logo",
|
|
3601
|
+
"alt": "Course logo",
|
|
3602
|
+
"upload": "Upload logo",
|
|
3603
|
+
"replace": "Replace logo",
|
|
3604
|
+
"remove": "Remove",
|
|
3605
|
+
"description": "Optional image to identify the course"
|
|
3606
|
+
}
|
|
3607
|
+
},
|
|
3608
|
+
"validation": {
|
|
3609
|
+
"internalNameMinLength": "Internal name must have at least 3 characters",
|
|
3610
|
+
"slugPattern": "Slug must contain only lowercase letters, numbers and hyphens"
|
|
3611
|
+
},
|
|
3612
|
+
"actions": {
|
|
3613
|
+
"cancel": "Cancel",
|
|
3614
|
+
"save": "Save Changes",
|
|
3615
|
+
"create": "Create Course"
|
|
3616
|
+
},
|
|
3541
3617
|
"toasts": {
|
|
3542
3618
|
"courseCreated": "Course created successfully! Redirecting...",
|
|
3543
3619
|
"courseCreateError": "Failed to create the course."
|
|
3544
3620
|
}
|
|
3621
|
+
},
|
|
3622
|
+
"levels": {
|
|
3623
|
+
"beginner": "Beginner",
|
|
3624
|
+
"intermediate": "Intermediate",
|
|
3625
|
+
"advanced": "Advanced"
|
|
3626
|
+
},
|
|
3627
|
+
"status": {
|
|
3628
|
+
"active": "Active",
|
|
3629
|
+
"inactive": "Inactive",
|
|
3630
|
+
"draft": "Draft",
|
|
3631
|
+
"archived": "Archived"
|
|
3545
3632
|
}
|
|
3546
3633
|
},
|
|
3547
3634
|
"InstructorsPage": {
|
|
@@ -3652,9 +3739,17 @@
|
|
|
3652
3739
|
"classes": {
|
|
3653
3740
|
"emptyTitle": "No classes found",
|
|
3654
3741
|
"emptyDescription": "This instructor is not linked to any classes yet.",
|
|
3742
|
+
"searchPlaceholder": "Search class by name, code or course...",
|
|
3743
|
+
"statusFilterPlaceholder": "Filter by status",
|
|
3744
|
+
"allStatuses": "All statuses",
|
|
3655
3745
|
"start": "Start:",
|
|
3656
3746
|
"end": "End:",
|
|
3657
|
-
"students": "{count} student(s)"
|
|
3747
|
+
"students": "{count} student(s)",
|
|
3748
|
+
"studentsOfCapacity": "{count} / {total} student(s)",
|
|
3749
|
+
"actions": {
|
|
3750
|
+
"editAriaLabel": "Edit class",
|
|
3751
|
+
"openAriaLabel": "Open class page"
|
|
3752
|
+
}
|
|
3658
3753
|
},
|
|
3659
3754
|
"evaluations": {
|
|
3660
3755
|
"comingSoonTitle": "Evaluations — feature coming soon",
|
|
@@ -3704,23 +3799,17 @@
|
|
|
3704
3799
|
"current": "Instructor Skills"
|
|
3705
3800
|
},
|
|
3706
3801
|
"filters": {
|
|
3707
|
-
"searchPlaceholder": "Search by slug
|
|
3802
|
+
"searchPlaceholder": "Search by slug..."
|
|
3708
3803
|
},
|
|
3709
3804
|
"table": {
|
|
3710
3805
|
"slug": "Slug",
|
|
3711
|
-
"namePt": "Name (PT)",
|
|
3712
|
-
"nameEn": "Name (EN)",
|
|
3713
3806
|
"status": "Status"
|
|
3714
3807
|
},
|
|
3715
3808
|
"form": {
|
|
3716
3809
|
"slug": "Slug",
|
|
3717
3810
|
"slugPlaceholder": "e.g. javascript, react-js",
|
|
3718
|
-
"namePt": "Name (PT)",
|
|
3719
|
-
"namePtPlaceholder": "Portuguese name",
|
|
3720
|
-
"nameEn": "Name (EN)",
|
|
3721
|
-
"nameEnPlaceholder": "Name in English (optional)",
|
|
3722
3811
|
"status": "Status",
|
|
3723
|
-
"statusPlaceholder": "Select status",
|
|
3812
|
+
"statusPlaceholder": "Select a status",
|
|
3724
3813
|
"validation": {
|
|
3725
3814
|
"required": "Required",
|
|
3726
3815
|
"max100": "Maximum 100 characters",
|
|
@@ -3933,7 +4022,8 @@
|
|
|
3933
4022
|
},
|
|
3934
4023
|
"actions": {
|
|
3935
4024
|
"create": "Create new class",
|
|
3936
|
-
"add": "Add"
|
|
4025
|
+
"add": "Add",
|
|
4026
|
+
"edit": "Edit"
|
|
3937
4027
|
},
|
|
3938
4028
|
"empty": {
|
|
3939
4029
|
"title": "No classes found.",
|
|
@@ -3941,6 +4031,7 @@
|
|
|
3941
4031
|
},
|
|
3942
4032
|
"table": {
|
|
3943
4033
|
"class": "Class",
|
|
4034
|
+
"instructor": "Instructor",
|
|
3944
4035
|
"status": "Status",
|
|
3945
4036
|
"period": "Period",
|
|
3946
4037
|
"capacity": "Capacity"
|
|
@@ -2916,6 +2916,11 @@
|
|
|
2916
2916
|
"subFree": "{count} vagas livres",
|
|
2917
2917
|
"subFull": "Lotada"
|
|
2918
2918
|
},
|
|
2919
|
+
"nextClass": "Próxima Aula",
|
|
2920
|
+
"noClass": "Sem aula",
|
|
2921
|
+
"createNext": "Crie a próxima aula",
|
|
2922
|
+
"calendar": "Calendário",
|
|
2923
|
+
"completed": "{count} concluída(s)",
|
|
2919
2924
|
"avgAttendance": {
|
|
2920
2925
|
"label": "Presença Média",
|
|
2921
2926
|
"sub": "frequência geral"
|
|
@@ -3547,10 +3552,92 @@
|
|
|
3547
3552
|
"studentRemoveError": "Falha ao remover aluno."
|
|
3548
3553
|
},
|
|
3549
3554
|
"form": {
|
|
3555
|
+
"title": {
|
|
3556
|
+
"create": "Criar Novo Curso",
|
|
3557
|
+
"edit": "Editar Curso"
|
|
3558
|
+
},
|
|
3559
|
+
"description": {
|
|
3560
|
+
"create": "Preencha os dados para criar um novo curso. Após criar, você será redirecionado para a página do curso.",
|
|
3561
|
+
"edit": "Atualize as informações do curso abaixo."
|
|
3562
|
+
},
|
|
3563
|
+
"fields": {
|
|
3564
|
+
"internalName": {
|
|
3565
|
+
"label": "Nome Interno",
|
|
3566
|
+
"placeholder": "Ex: React Avançado",
|
|
3567
|
+
"description": "Nome interno do curso para uso administrativo"
|
|
3568
|
+
},
|
|
3569
|
+
"slug": {
|
|
3570
|
+
"label": "Slug",
|
|
3571
|
+
"placeholder": "Ex: react-avancado",
|
|
3572
|
+
"description": "Identificador único na URL (letras minúsculas, números e hífens)"
|
|
3573
|
+
},
|
|
3574
|
+
"commercialTitle": {
|
|
3575
|
+
"label": "Título Comercial",
|
|
3576
|
+
"placeholder": "Ex: React Avançado"
|
|
3577
|
+
},
|
|
3578
|
+
"description": {
|
|
3579
|
+
"label": "Descrição",
|
|
3580
|
+
"placeholder": "Descreva o conteúdo e objetivos do curso..."
|
|
3581
|
+
},
|
|
3582
|
+
"level": {
|
|
3583
|
+
"label": "Nível",
|
|
3584
|
+
"placeholder": "Selecione"
|
|
3585
|
+
},
|
|
3586
|
+
"status": {
|
|
3587
|
+
"label": "Status",
|
|
3588
|
+
"placeholder": "Selecione"
|
|
3589
|
+
},
|
|
3590
|
+
"categories": {
|
|
3591
|
+
"label": "Categorias",
|
|
3592
|
+
"description": "Selecione uma ou mais categorias",
|
|
3593
|
+
"createAction": "Criar categoria",
|
|
3594
|
+
"selectPlaceholder": "Selecione uma categoria",
|
|
3595
|
+
"removeAction": "Remover categoria",
|
|
3596
|
+
"searchPlaceholder": "Digite para buscar categoria...",
|
|
3597
|
+
"noResults": "Nenhuma categoria encontrada",
|
|
3598
|
+
"selectedCount": "categoria(s) selecionada(s)"
|
|
3599
|
+
},
|
|
3600
|
+
"primaryColor": {
|
|
3601
|
+
"label": "Cor Primária",
|
|
3602
|
+
"placeholder": "#1D4ED8"
|
|
3603
|
+
},
|
|
3604
|
+
"secondaryColor": {
|
|
3605
|
+
"label": "Cor Secundária",
|
|
3606
|
+
"placeholder": "#111827"
|
|
3607
|
+
},
|
|
3608
|
+
"logo": {
|
|
3609
|
+
"label": "Logo do Curso",
|
|
3610
|
+
"alt": "Logo do curso",
|
|
3611
|
+
"upload": "Carregar logo",
|
|
3612
|
+
"replace": "Substituir logo",
|
|
3613
|
+
"remove": "Remover",
|
|
3614
|
+
"description": "Imagem opcional para identificar o curso"
|
|
3615
|
+
}
|
|
3616
|
+
},
|
|
3617
|
+
"validation": {
|
|
3618
|
+
"internalNameMinLength": "Nome interno deve ter pelo menos 3 caracteres",
|
|
3619
|
+
"slugPattern": "Slug deve conter apenas letras minúsculas, números e hífens"
|
|
3620
|
+
},
|
|
3621
|
+
"actions": {
|
|
3622
|
+
"cancel": "Cancelar",
|
|
3623
|
+
"save": "Salvar Alterações",
|
|
3624
|
+
"create": "Criar Curso"
|
|
3625
|
+
},
|
|
3550
3626
|
"toasts": {
|
|
3551
3627
|
"courseCreated": "Curso criado com sucesso! Redirecionando...",
|
|
3552
3628
|
"courseCreateError": "Não foi possível criar o curso."
|
|
3553
3629
|
}
|
|
3630
|
+
},
|
|
3631
|
+
"levels": {
|
|
3632
|
+
"beginner": "Iniciante",
|
|
3633
|
+
"intermediate": "Intermediário",
|
|
3634
|
+
"advanced": "Avançado"
|
|
3635
|
+
},
|
|
3636
|
+
"status": {
|
|
3637
|
+
"active": "Ativo",
|
|
3638
|
+
"inactive": "Inativo",
|
|
3639
|
+
"draft": "Rascunho",
|
|
3640
|
+
"archived": "Arquivado"
|
|
3554
3641
|
}
|
|
3555
3642
|
},
|
|
3556
3643
|
"InstructorsPage": {
|
|
@@ -3661,9 +3748,17 @@
|
|
|
3661
3748
|
"classes": {
|
|
3662
3749
|
"emptyTitle": "Nenhuma turma encontrada",
|
|
3663
3750
|
"emptyDescription": "Este instrutor ainda não está vinculado a nenhuma turma.",
|
|
3751
|
+
"searchPlaceholder": "Buscar turma por nome, código ou curso...",
|
|
3752
|
+
"statusFilterPlaceholder": "Filtrar por status",
|
|
3753
|
+
"allStatuses": "Todos os status",
|
|
3664
3754
|
"start": "Início:",
|
|
3665
3755
|
"end": "Fim:",
|
|
3666
|
-
"students": "{count} aluno(s)"
|
|
3756
|
+
"students": "{count} aluno(s)",
|
|
3757
|
+
"studentsOfCapacity": "{count} / {total} aluno(s)",
|
|
3758
|
+
"actions": {
|
|
3759
|
+
"editAriaLabel": "Editar turma",
|
|
3760
|
+
"openAriaLabel": "Abrir página da turma"
|
|
3761
|
+
}
|
|
3667
3762
|
},
|
|
3668
3763
|
"evaluations": {
|
|
3669
3764
|
"comingSoonTitle": "Avaliações — funcionalidade em breve",
|
|
@@ -3713,23 +3808,17 @@
|
|
|
3713
3808
|
"current": "Skills de Instrutor"
|
|
3714
3809
|
},
|
|
3715
3810
|
"filters": {
|
|
3716
|
-
"searchPlaceholder": "Buscar por slug
|
|
3811
|
+
"searchPlaceholder": "Buscar por slug..."
|
|
3717
3812
|
},
|
|
3718
3813
|
"table": {
|
|
3719
3814
|
"slug": "Slug",
|
|
3720
|
-
"namePt": "Nome (PT)",
|
|
3721
|
-
"nameEn": "Nome (EN)",
|
|
3722
3815
|
"status": "Status"
|
|
3723
3816
|
},
|
|
3724
3817
|
"form": {
|
|
3725
3818
|
"slug": "Slug",
|
|
3726
3819
|
"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
3820
|
"status": "Status",
|
|
3732
|
-
"statusPlaceholder": "Selecione
|
|
3821
|
+
"statusPlaceholder": "Selecione um status",
|
|
3733
3822
|
"validation": {
|
|
3734
3823
|
"required": "Obrigatório",
|
|
3735
3824
|
"max100": "Máximo 100 caracteres",
|
|
@@ -3942,7 +4031,8 @@
|
|
|
3942
4031
|
},
|
|
3943
4032
|
"actions": {
|
|
3944
4033
|
"create": "Criar nova turma",
|
|
3945
|
-
"add": "Adicionar"
|
|
4034
|
+
"add": "Adicionar",
|
|
4035
|
+
"edit": "Editar"
|
|
3946
4036
|
},
|
|
3947
4037
|
"empty": {
|
|
3948
4038
|
"title": "Nenhuma turma encontrada.",
|
|
@@ -3950,6 +4040,7 @@
|
|
|
3950
4040
|
},
|
|
3951
4041
|
"table": {
|
|
3952
4042
|
"class": "Turma",
|
|
4043
|
+
"instructor": "Instrutor",
|
|
3953
4044
|
"status": "Status",
|
|
3954
4045
|
"period": "Período",
|
|
3955
4046
|
"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.338",
|
|
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
|
-
"@hed-hog/api-locale": "0.0.14",
|
|
14
14
|
"@hed-hog/api": "0.0.8",
|
|
15
|
-
"@hed-hog/api-prisma": "0.0.6",
|
|
16
|
-
"@hed-hog/contact": "0.0.331",
|
|
17
15
|
"@hed-hog/api-pagination": "0.0.7",
|
|
18
|
-
"@hed-hog/
|
|
19
|
-
"@hed-hog/
|
|
20
|
-
"@hed-hog/
|
|
16
|
+
"@hed-hog/api-locale": "0.0.14",
|
|
17
|
+
"@hed-hog/contact": "0.0.338",
|
|
18
|
+
"@hed-hog/category": "0.0.338",
|
|
19
|
+
"@hed-hog/core": "0.0.338",
|
|
20
|
+
"@hed-hog/finance": "0.0.338"
|
|
21
21
|
},
|
|
22
22
|
"exports": {
|
|
23
23
|
".": {
|
|
@@ -808,51 +808,39 @@ export class CourseService {
|
|
|
808
808
|
id: number,
|
|
809
809
|
data: PersistCourseExtrasInput,
|
|
810
810
|
) {
|
|
811
|
-
const
|
|
812
|
-
const params: Array<string | boolean | number> = [];
|
|
811
|
+
const updateData: Record<string, string | boolean> = {};
|
|
813
812
|
|
|
814
813
|
if (data.name !== undefined) {
|
|
815
|
-
|
|
816
|
-
sets.push(`name = $${params.length}`);
|
|
814
|
+
updateData.name = data.name;
|
|
817
815
|
}
|
|
818
816
|
|
|
819
817
|
if (data.isFeatured !== undefined) {
|
|
820
|
-
|
|
821
|
-
sets.push(`is_featured = $${params.length}`);
|
|
818
|
+
updateData.is_featured = data.isFeatured;
|
|
822
819
|
}
|
|
823
820
|
|
|
824
821
|
if (data.hasCertificate !== undefined) {
|
|
825
|
-
|
|
826
|
-
sets.push(`has_certificate = $${params.length}`);
|
|
822
|
+
updateData.has_certificate = data.hasCertificate;
|
|
827
823
|
}
|
|
828
824
|
|
|
829
825
|
if (data.isListed !== undefined) {
|
|
830
|
-
|
|
831
|
-
sets.push(`is_listed = $${params.length}`);
|
|
826
|
+
updateData.is_listed = data.isListed;
|
|
832
827
|
}
|
|
833
828
|
|
|
834
829
|
if (data.offeringType !== undefined) {
|
|
835
|
-
|
|
836
|
-
sets.push(`offering_type = $${params.length}`);
|
|
830
|
+
updateData.offering_type = data.offeringType;
|
|
837
831
|
}
|
|
838
832
|
|
|
839
|
-
if (
|
|
833
|
+
if (Object.keys(updateData).length === 0) {
|
|
840
834
|
return;
|
|
841
835
|
}
|
|
842
836
|
|
|
843
|
-
params.push(id);
|
|
844
|
-
|
|
845
837
|
try {
|
|
846
|
-
await this.prisma
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
WHERE id = $${params.length}
|
|
851
|
-
`,
|
|
852
|
-
...params,
|
|
853
|
-
);
|
|
838
|
+
await this.prisma.course.update({
|
|
839
|
+
where: { id },
|
|
840
|
+
data: updateData as any,
|
|
841
|
+
});
|
|
854
842
|
} catch {
|
|
855
|
-
//
|
|
843
|
+
// Some environments may still be behind the current course schema.
|
|
856
844
|
}
|
|
857
845
|
}
|
|
858
846
|
|
|
@@ -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);
|