@hed-hog/lms 0.0.328 → 0.0.330
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/instructor/instructor.service.d.ts.map +1 -1
- package/dist/instructor/instructor.service.js +22 -16
- package/dist/instructor/instructor.service.js.map +1 -1
- package/hedhog/frontend/app/_components/class-form-sheet.tsx.ejs +18 -8
- package/hedhog/frontend/app/_components/course-form-sheet.tsx.ejs +7 -5
- package/hedhog/frontend/app/_components/create-lms-person-sheet.tsx.ejs +5 -9
- package/hedhog/frontend/app/_components/create-lms-student-person-sheet.tsx.ejs +5 -9
- package/hedhog/frontend/app/certificates/models/LeftPanel.tsx.ejs +15 -14
- package/hedhog/frontend/app/certificates/models/RightPanel.tsx.ejs +66 -29
- package/hedhog/frontend/app/certificates/models/TemplateEditorPage.tsx.ejs +4 -2
- package/hedhog/frontend/app/certificates/models/TopBar.tsx.ejs +44 -34
- package/hedhog/frontend/app/classes/[id]/page.tsx.ejs +10 -10
- package/hedhog/frontend/app/classes/page.tsx.ejs +23 -15
- package/hedhog/frontend/app/courses/[id]/page.tsx.ejs +5 -3
- package/hedhog/frontend/app/courses/[id]/structure/_components/confirm-dialog.tsx.ejs +5 -3
- package/hedhog/frontend/app/courses/[id]/structure/_components/course-tree-panel.tsx.ejs +9 -7
- package/hedhog/frontend/app/courses/[id]/structure/_components/course-tree-skeleton.tsx.ejs +3 -1
- package/hedhog/frontend/app/courses/[id]/structure/_components/drag-handle.tsx.ejs +4 -2
- package/hedhog/frontend/app/courses/[id]/structure/_components/editor-bulk.tsx.ejs +24 -23
- package/hedhog/frontend/app/courses/[id]/structure/_components/multi-select-bar.tsx.ejs +21 -19
- package/hedhog/frontend/app/courses/[id]/structure/_components/shortcuts-help.tsx.ejs +7 -5
- package/hedhog/frontend/app/courses/[id]/structure/_components/tree-display-settings-popover.tsx.ejs +18 -16
- package/hedhog/frontend/app/courses/[id]/structure/_components/tree-row-lesson.tsx.ejs +13 -11
- package/hedhog/frontend/app/courses/[id]/structure/_components/tree-row-session.tsx.ejs +5 -3
- package/hedhog/frontend/app/courses/[id]/structure/_components/use-course-structure-shortcuts.ts.ejs +14 -9
- package/hedhog/frontend/app/courses/[id]/structure/_data/use-course-structure-mutations.ts.ejs +42 -25
- package/hedhog/frontend/app/enterprise/_components/enterprise-admin-create-sheet.tsx.ejs +3 -1
- package/hedhog/frontend/app/enterprise/_components/enterprise-administrators-tab.tsx.ejs +10 -8
- package/hedhog/frontend/app/enterprise/_components/enterprise-classes-tab.tsx.ejs +22 -20
- package/hedhog/frontend/app/enterprise/_components/enterprise-course-create-sheet.tsx.ejs +3 -3
- package/hedhog/frontend/app/enterprise/_components/enterprise-courses-tab.tsx.ejs +21 -19
- package/hedhog/frontend/app/enterprise/_components/enterprise-sheet.tsx.ejs +34 -36
- package/hedhog/frontend/app/enterprise/_components/enterprise-student-create-sheet.tsx.ejs +3 -1
- package/hedhog/frontend/app/enterprise/_components/enterprise-students-tab.tsx.ejs +7 -5
- package/hedhog/frontend/app/enterprise/page.tsx.ejs +106 -54
- package/hedhog/frontend/app/instructor-skills/page.tsx.ejs +79 -59
- package/hedhog/frontend/app/instructors/_components/instructor-form-sheet.tsx.ejs +92 -26
- package/hedhog/frontend/app/instructors/page.tsx.ejs +4 -2
- package/hedhog/frontend/messages/en.json +619 -13
- package/hedhog/frontend/messages/pt.json +619 -13
- package/package.json +7 -7
- package/src/instructor/instructor.service.ts +22 -19
- package/hedhog/frontend/app/_components/create-lms-instructor-sheet.tsx.ejs +0 -591
- package/hedhog/frontend/app/courses/[id]/_components/CourseMainInfoCard.tsx.ejs +0 -109
- package/hedhog/frontend/app/courses/[id]/_components/CourseSummaryCard.tsx.ejs +0 -60
- package/hedhog/frontend/app/courses/[id]/structure/_components/course-tree.tsx.ejs +0 -134
- package/hedhog/frontend/app/courses/[id]/structure/_components/detail-course.tsx.ejs +0 -113
- package/hedhog/frontend/app/courses/[id]/structure/_components/detail-lesson.tsx.ejs +0 -314
- package/hedhog/frontend/app/courses/[id]/structure/_components/detail-session.tsx.ejs +0 -174
- package/hedhog/frontend/app/courses/[id]/structure/_components/mock-data.ts.ejs +0 -185
- package/hedhog/frontend/app/enterprise/_components/enterprise-mocks.ts.ejs +0 -277
- package/hedhog/frontend/app/enterprise/_components/enterprise-user-create-sheet.tsx.ejs +0 -207
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
} from '@/components/ui/table';
|
|
22
22
|
import { useApp, useQuery } from '@hed-hog/next-app-provider';
|
|
23
23
|
import { Trash2 } from 'lucide-react';
|
|
24
|
+
import { useTranslations } from 'next-intl';
|
|
24
25
|
import { useCallback, useState } from 'react';
|
|
25
26
|
import { toast } from 'sonner';
|
|
26
27
|
import { EnterpriseAdminCreateSheet } from './enterprise-admin-create-sheet';
|
|
@@ -52,6 +53,7 @@ export function AdministratorsTab({
|
|
|
52
53
|
enterpriseId: number;
|
|
53
54
|
onMutate?: () => void;
|
|
54
55
|
}) {
|
|
56
|
+
const t = useTranslations('lms.EnterprisePage');
|
|
55
57
|
const { request } = useApp();
|
|
56
58
|
const [search, setSearch] = useState('');
|
|
57
59
|
const [page, setPage] = useState(1);
|
|
@@ -104,9 +106,9 @@ export function AdministratorsTab({
|
|
|
104
106
|
data: { role },
|
|
105
107
|
}).then(() => refetch());
|
|
106
108
|
toast.promise(promise, {
|
|
107
|
-
loading: '
|
|
108
|
-
success: '
|
|
109
|
-
error: '
|
|
109
|
+
loading: t('sheet.adminRoleUpdating'),
|
|
110
|
+
success: t('sheet.adminRoleUpdated'),
|
|
111
|
+
error: t('sheet.adminRoleUpdateError'),
|
|
110
112
|
});
|
|
111
113
|
try {
|
|
112
114
|
await promise;
|
|
@@ -127,9 +129,9 @@ export function AdministratorsTab({
|
|
|
127
129
|
onMutate?.();
|
|
128
130
|
});
|
|
129
131
|
toast.promise(promise, {
|
|
130
|
-
loading: '
|
|
131
|
-
success: '
|
|
132
|
-
error: '
|
|
132
|
+
loading: t('sheet.adminRemoving'),
|
|
133
|
+
success: t('sheet.adminRemoved'),
|
|
134
|
+
error: t('sheet.adminRemoveError'),
|
|
133
135
|
});
|
|
134
136
|
try {
|
|
135
137
|
await promise;
|
|
@@ -153,7 +155,7 @@ export function AdministratorsTab({
|
|
|
153
155
|
refetch();
|
|
154
156
|
onMutate?.();
|
|
155
157
|
} catch {
|
|
156
|
-
toast.error('
|
|
158
|
+
toast.error(t('sheet.adminAddError'));
|
|
157
159
|
}
|
|
158
160
|
}
|
|
159
161
|
|
|
@@ -320,7 +322,7 @@ export function AdministratorsTab({
|
|
|
320
322
|
data: { user_id: user.userId, role: user.role },
|
|
321
323
|
});
|
|
322
324
|
} catch {
|
|
323
|
-
toast.error('
|
|
325
|
+
toast.error(t('sheet.adminLinkError'));
|
|
324
326
|
}
|
|
325
327
|
setCreateSheetOpen(false);
|
|
326
328
|
refetch();
|
|
@@ -22,6 +22,7 @@ import { formatDate } from '@/lib/format-date';
|
|
|
22
22
|
import { useApp, useQuery } from '@hed-hog/next-app-provider';
|
|
23
23
|
import { CalendarDays, SquareArrowOutUpRight, Trash2 } from 'lucide-react';
|
|
24
24
|
import { useRouter } from 'next/navigation';
|
|
25
|
+
import { useTranslations } from 'next-intl';
|
|
25
26
|
import { useCallback, useState } from 'react';
|
|
26
27
|
import { toast } from 'sonner';
|
|
27
28
|
import { EnterpriseClassCreateSheet } from './enterprise-class-create-sheet';
|
|
@@ -93,6 +94,7 @@ export function ClassesTab({
|
|
|
93
94
|
}) {
|
|
94
95
|
const router = useRouter();
|
|
95
96
|
const { request, currentLocaleCode, getSettingValue } = useApp();
|
|
97
|
+
const t = useTranslations('lms.EnterpriseDetailPage.relatedClasses');
|
|
96
98
|
|
|
97
99
|
const [search, setSearch] = useState('');
|
|
98
100
|
const [statusFilter, setStatusFilter] = useState<
|
|
@@ -144,11 +146,11 @@ export function ClassesTab({
|
|
|
144
146
|
url: `/lms/enterprise/${enterpriseId}/classes/${classGroupId}`,
|
|
145
147
|
method: 'DELETE',
|
|
146
148
|
});
|
|
147
|
-
toast.success('
|
|
149
|
+
toast.success(t('messages.removeSuccess'));
|
|
148
150
|
refetch();
|
|
149
151
|
onMutate?.();
|
|
150
152
|
} catch {
|
|
151
|
-
toast.error('
|
|
153
|
+
toast.error(t('messages.removeError'));
|
|
152
154
|
}
|
|
153
155
|
}
|
|
154
156
|
|
|
@@ -168,7 +170,7 @@ export function ClassesTab({
|
|
|
168
170
|
refetch();
|
|
169
171
|
onMutate?.();
|
|
170
172
|
} catch {
|
|
171
|
-
toast.error('
|
|
173
|
+
toast.error(t('messages.addError'));
|
|
172
174
|
}
|
|
173
175
|
}
|
|
174
176
|
|
|
@@ -180,7 +182,7 @@ export function ClassesTab({
|
|
|
180
182
|
setSearch(v);
|
|
181
183
|
setPage(1);
|
|
182
184
|
}}
|
|
183
|
-
searchPlaceholder=
|
|
185
|
+
searchPlaceholder={t('searchPlaceholder')}
|
|
184
186
|
filters={
|
|
185
187
|
<Select
|
|
186
188
|
value={statusFilter}
|
|
@@ -190,19 +192,19 @@ export function ClassesTab({
|
|
|
190
192
|
}}
|
|
191
193
|
>
|
|
192
194
|
<SelectTrigger className="w-44">
|
|
193
|
-
<SelectValue placeholder=
|
|
195
|
+
<SelectValue placeholder={t('filters.allStatuses')} />
|
|
194
196
|
</SelectTrigger>
|
|
195
197
|
<SelectContent>
|
|
196
|
-
<SelectItem value="all">
|
|
197
|
-
<SelectItem value="open">
|
|
198
|
-
<SelectItem value="ongoing">
|
|
199
|
-
<SelectItem value="completed">
|
|
200
|
-
<SelectItem value="cancelled">
|
|
198
|
+
<SelectItem value="all">{t('filters.allStatuses')}</SelectItem>
|
|
199
|
+
<SelectItem value="open">{t('status.open')}</SelectItem>
|
|
200
|
+
<SelectItem value="ongoing">{t('status.ongoing')}</SelectItem>
|
|
201
|
+
<SelectItem value="completed">{t('status.completed')}</SelectItem>
|
|
202
|
+
<SelectItem value="cancelled">{t('status.cancelled')}</SelectItem>
|
|
201
203
|
</SelectContent>
|
|
202
204
|
</Select>
|
|
203
205
|
}
|
|
204
|
-
pickerPlaceholder=
|
|
205
|
-
pickerEntityLabel=
|
|
206
|
+
pickerPlaceholder={t('pickerPlaceholder')}
|
|
207
|
+
pickerEntityLabel={t('pickerEntityLabel')}
|
|
206
208
|
pickerValue={pickerValue}
|
|
207
209
|
onPickerChange={(value, option) => {
|
|
208
210
|
setPickerValue(value);
|
|
@@ -236,9 +238,9 @@ export function ClassesTab({
|
|
|
236
238
|
</div>
|
|
237
239
|
)}
|
|
238
240
|
onCreateNew={() => setCreateSheetOpen(true)}
|
|
239
|
-
createLabel=
|
|
241
|
+
createLabel={t('actions.create')}
|
|
240
242
|
onAdd={handleAdd}
|
|
241
|
-
addLabel=
|
|
243
|
+
addLabel={t('actions.add')}
|
|
242
244
|
addDisabled={!pickerClass}
|
|
243
245
|
currentPage={page}
|
|
244
246
|
pageSize={pageSize}
|
|
@@ -253,10 +255,10 @@ export function ClassesTab({
|
|
|
253
255
|
<div className="flex flex-col items-center justify-center py-16 text-center">
|
|
254
256
|
<CalendarDays className="mb-4 h-10 w-10 text-muted-foreground/30" />
|
|
255
257
|
<p className="text-sm font-medium text-muted-foreground">
|
|
256
|
-
|
|
258
|
+
{t('empty.title')}
|
|
257
259
|
</p>
|
|
258
260
|
<p className="mt-1 text-xs text-muted-foreground/60">
|
|
259
|
-
|
|
261
|
+
{t('empty.description')}
|
|
260
262
|
</p>
|
|
261
263
|
</div>
|
|
262
264
|
) : (
|
|
@@ -264,10 +266,10 @@ export function ClassesTab({
|
|
|
264
266
|
<Table>
|
|
265
267
|
<TableHeader>
|
|
266
268
|
<TableRow>
|
|
267
|
-
<TableHead>
|
|
268
|
-
<TableHead>
|
|
269
|
-
<TableHead>
|
|
270
|
-
<TableHead className="text-center">
|
|
269
|
+
<TableHead>{t('table.class')}</TableHead>
|
|
270
|
+
<TableHead>{t('table.status')}</TableHead>
|
|
271
|
+
<TableHead>{t('table.period')}</TableHead>
|
|
272
|
+
<TableHead className="text-center">{t('table.capacity')}</TableHead>
|
|
271
273
|
<TableHead className="w-10" />
|
|
272
274
|
</TableRow>
|
|
273
275
|
</TableHeader>
|
|
@@ -77,7 +77,7 @@ export function EnterpriseCourseCreateSheet({
|
|
|
77
77
|
enterpriseId,
|
|
78
78
|
onCreated,
|
|
79
79
|
}: EnterpriseCourseCreateSheetProps) {
|
|
80
|
-
const t = useTranslations('lms.
|
|
80
|
+
const t = useTranslations('lms.EnterprisePage');
|
|
81
81
|
const { request } = useApp();
|
|
82
82
|
const [saving, setSaving] = useState(false);
|
|
83
83
|
|
|
@@ -159,11 +159,11 @@ export function EnterpriseCourseCreateSheet({
|
|
|
159
159
|
data: { course_id: created.id },
|
|
160
160
|
});
|
|
161
161
|
|
|
162
|
-
toast.success(t('toasts.courseCreated'));
|
|
162
|
+
toast.success(t('form.toasts.courseCreated'));
|
|
163
163
|
onCreated?.();
|
|
164
164
|
onOpenChange(false);
|
|
165
165
|
} catch {
|
|
166
|
-
toast.error('
|
|
166
|
+
toast.error(t('form.toasts.courseCreateError'));
|
|
167
167
|
} finally {
|
|
168
168
|
setSaving(false);
|
|
169
169
|
}
|
|
@@ -22,6 +22,7 @@ import { formatDate } from '@/lib/format-date';
|
|
|
22
22
|
import { useApp, useQuery } from '@hed-hog/next-app-provider';
|
|
23
23
|
import { BookOpen, SquareArrowOutUpRight, Trash2 } from 'lucide-react';
|
|
24
24
|
import { useRouter } from 'next/navigation';
|
|
25
|
+
import { useTranslations } from 'next-intl';
|
|
25
26
|
import { useCallback, useState } from 'react';
|
|
26
27
|
import { toast } from 'sonner';
|
|
27
28
|
import { EnterpriseCourseCreateSheet } from './enterprise-course-create-sheet';
|
|
@@ -89,6 +90,7 @@ export function CoursesTab({
|
|
|
89
90
|
}) {
|
|
90
91
|
const router = useRouter();
|
|
91
92
|
const { request, getSettingValue, currentLocaleCode } = useApp();
|
|
93
|
+
const t = useTranslations('lms.EnterpriseDetailPage.relatedCourses');
|
|
92
94
|
|
|
93
95
|
const [search, setSearch] = useState('');
|
|
94
96
|
const [statusFilter, setStatusFilter] = useState<
|
|
@@ -142,11 +144,11 @@ export function CoursesTab({
|
|
|
142
144
|
url: `/lms/enterprise/${enterpriseId}/courses/${courseId}`,
|
|
143
145
|
method: 'DELETE',
|
|
144
146
|
});
|
|
145
|
-
toast.success('
|
|
147
|
+
toast.success(t('messages.removeSuccess'));
|
|
146
148
|
refetch();
|
|
147
149
|
onMutate?.();
|
|
148
150
|
} catch {
|
|
149
|
-
toast.error('
|
|
151
|
+
toast.error(t('messages.removeError'));
|
|
150
152
|
}
|
|
151
153
|
}
|
|
152
154
|
|
|
@@ -163,7 +165,7 @@ export function CoursesTab({
|
|
|
163
165
|
refetch();
|
|
164
166
|
onMutate?.();
|
|
165
167
|
} catch {
|
|
166
|
-
toast.error('
|
|
168
|
+
toast.error(t('messages.addError'));
|
|
167
169
|
}
|
|
168
170
|
}
|
|
169
171
|
|
|
@@ -175,7 +177,7 @@ export function CoursesTab({
|
|
|
175
177
|
setSearch(v);
|
|
176
178
|
setPage(1);
|
|
177
179
|
}}
|
|
178
|
-
searchPlaceholder=
|
|
180
|
+
searchPlaceholder={t('searchPlaceholder')}
|
|
179
181
|
filters={
|
|
180
182
|
<Select
|
|
181
183
|
value={statusFilter}
|
|
@@ -185,18 +187,18 @@ export function CoursesTab({
|
|
|
185
187
|
}}
|
|
186
188
|
>
|
|
187
189
|
<SelectTrigger className="w-40">
|
|
188
|
-
<SelectValue placeholder=
|
|
190
|
+
<SelectValue placeholder={t('filters.allStatuses')} />
|
|
189
191
|
</SelectTrigger>
|
|
190
192
|
<SelectContent>
|
|
191
|
-
<SelectItem value="all">
|
|
192
|
-
<SelectItem value="published">
|
|
193
|
-
<SelectItem value="draft">
|
|
194
|
-
<SelectItem value="archived">
|
|
193
|
+
<SelectItem value="all">{t('filters.allStatuses')}</SelectItem>
|
|
194
|
+
<SelectItem value="published">{t('status.published')}</SelectItem>
|
|
195
|
+
<SelectItem value="draft">{t('status.draft')}</SelectItem>
|
|
196
|
+
<SelectItem value="archived">{t('status.archived')}</SelectItem>
|
|
195
197
|
</SelectContent>
|
|
196
198
|
</Select>
|
|
197
199
|
}
|
|
198
|
-
pickerPlaceholder=
|
|
199
|
-
pickerEntityLabel=
|
|
200
|
+
pickerPlaceholder={t('pickerPlaceholder')}
|
|
201
|
+
pickerEntityLabel={t('pickerEntityLabel')}
|
|
200
202
|
pickerValue={pickerValue}
|
|
201
203
|
onPickerChange={(value, option) => {
|
|
202
204
|
setPickerValue(value);
|
|
@@ -228,9 +230,9 @@ export function CoursesTab({
|
|
|
228
230
|
</div>
|
|
229
231
|
)}
|
|
230
232
|
onCreateNew={() => setCreateSheetOpen(true)}
|
|
231
|
-
createLabel=
|
|
233
|
+
createLabel={t('actions.create')}
|
|
232
234
|
onAdd={handleAdd}
|
|
233
|
-
addLabel=
|
|
235
|
+
addLabel={t('actions.add')}
|
|
234
236
|
addDisabled={!pickerCourse}
|
|
235
237
|
currentPage={page}
|
|
236
238
|
pageSize={pageSize}
|
|
@@ -245,10 +247,10 @@ export function CoursesTab({
|
|
|
245
247
|
<div className="flex flex-col items-center justify-center py-16 text-center">
|
|
246
248
|
<BookOpen className="mb-4 h-10 w-10 text-muted-foreground/30" />
|
|
247
249
|
<p className="text-sm font-medium text-muted-foreground">
|
|
248
|
-
|
|
250
|
+
{t('empty.title')}
|
|
249
251
|
</p>
|
|
250
252
|
<p className="mt-1 text-xs text-muted-foreground/60">
|
|
251
|
-
|
|
253
|
+
{t('empty.description')}
|
|
252
254
|
</p>
|
|
253
255
|
</div>
|
|
254
256
|
) : (
|
|
@@ -256,10 +258,10 @@ export function CoursesTab({
|
|
|
256
258
|
<Table>
|
|
257
259
|
<TableHeader>
|
|
258
260
|
<TableRow>
|
|
259
|
-
<TableHead>
|
|
260
|
-
<TableHead>
|
|
261
|
-
<TableHead>
|
|
262
|
-
<TableHead>
|
|
261
|
+
<TableHead>{t('table.course')}</TableHead>
|
|
262
|
+
<TableHead>{t('table.modality')}</TableHead>
|
|
263
|
+
<TableHead>{t('table.status')}</TableHead>
|
|
264
|
+
<TableHead>{t('table.contracted')}</TableHead>
|
|
263
265
|
<TableHead className="w-10" />
|
|
264
266
|
</TableRow>
|
|
265
267
|
</TableHeader>
|
|
@@ -30,6 +30,7 @@ import { Switch } from '@/components/ui/switch';
|
|
|
30
30
|
import { Textarea } from '@/components/ui/textarea';
|
|
31
31
|
import { useApp } from '@hed-hog/next-app-provider';
|
|
32
32
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
33
|
+
import { useTranslations } from 'next-intl';
|
|
33
34
|
import { useEffect } from 'react';
|
|
34
35
|
import { useForm } from 'react-hook-form';
|
|
35
36
|
import { toast } from 'sonner';
|
|
@@ -86,6 +87,7 @@ export function EnterpriseSheet({
|
|
|
86
87
|
}: EnterpriseSheetProps) {
|
|
87
88
|
const isEditing = Boolean(editingAccount);
|
|
88
89
|
const { request } = useApp();
|
|
90
|
+
const t = useTranslations('lms.EnterprisePage.sheet');
|
|
89
91
|
|
|
90
92
|
const form = useForm<EnterpriseFormValues>({
|
|
91
93
|
resolver: zodResolver(enterpriseSchema),
|
|
@@ -163,14 +165,12 @@ export function EnterpriseSheet({
|
|
|
163
165
|
|
|
164
166
|
onSave?.(values, isEditing);
|
|
165
167
|
toast.success(
|
|
166
|
-
isEditing
|
|
167
|
-
? 'Account updated successfully.'
|
|
168
|
-
: 'Account created successfully.'
|
|
168
|
+
isEditing ? t('messages.updateSuccess') : t('messages.createSuccess')
|
|
169
169
|
);
|
|
170
170
|
onOpenChange(false);
|
|
171
171
|
} catch {
|
|
172
172
|
toast.error(
|
|
173
|
-
isEditing ? '
|
|
173
|
+
isEditing ? t('messages.updateError') : t('messages.createError')
|
|
174
174
|
);
|
|
175
175
|
}
|
|
176
176
|
}
|
|
@@ -180,12 +180,10 @@ export function EnterpriseSheet({
|
|
|
180
180
|
<SheetContent className="w-full overflow-y-auto sm:max-w-lg">
|
|
181
181
|
<SheetHeader>
|
|
182
182
|
<SheetTitle>
|
|
183
|
-
{isEditing ? '
|
|
183
|
+
{isEditing ? t('editTitle') : t('createTitle')}
|
|
184
184
|
</SheetTitle>
|
|
185
185
|
<SheetDescription>
|
|
186
|
-
{isEditing
|
|
187
|
-
? 'Update the corporate account details below.'
|
|
188
|
-
: 'Register a new corporate account in the LMS platform.'}
|
|
186
|
+
{isEditing ? t('editDescription') : t('createDescription')}
|
|
189
187
|
</SheetDescription>
|
|
190
188
|
</SheetHeader>
|
|
191
189
|
|
|
@@ -200,9 +198,9 @@ export function EnterpriseSheet({
|
|
|
200
198
|
name="name"
|
|
201
199
|
render={({ field }) => (
|
|
202
200
|
<FormItem>
|
|
203
|
-
<FormLabel>
|
|
201
|
+
<FormLabel>{t('fields.name')}</FormLabel>
|
|
204
202
|
<FormControl>
|
|
205
|
-
<Input placeholder=
|
|
203
|
+
<Input placeholder={t('fields.namePlaceholder')} {...field} />
|
|
206
204
|
</FormControl>
|
|
207
205
|
<FormMessage />
|
|
208
206
|
</FormItem>
|
|
@@ -215,13 +213,12 @@ export function EnterpriseSheet({
|
|
|
215
213
|
name="slug"
|
|
216
214
|
render={({ field }) => (
|
|
217
215
|
<FormItem>
|
|
218
|
-
<FormLabel>
|
|
216
|
+
<FormLabel>{t('fields.slug')}</FormLabel>
|
|
219
217
|
<FormControl>
|
|
220
|
-
<Input placeholder=
|
|
218
|
+
<Input placeholder={t('fields.slugPlaceholder')} {...field} />
|
|
221
219
|
</FormControl>
|
|
222
220
|
<FormDescription>
|
|
223
|
-
|
|
224
|
-
from the name when creating.
|
|
221
|
+
{t('fields.slugDescription')}
|
|
225
222
|
</FormDescription>
|
|
226
223
|
<FormMessage />
|
|
227
224
|
</FormItem>
|
|
@@ -234,17 +231,17 @@ export function EnterpriseSheet({
|
|
|
234
231
|
name="status"
|
|
235
232
|
render={({ field }) => (
|
|
236
233
|
<FormItem>
|
|
237
|
-
<FormLabel>
|
|
234
|
+
<FormLabel>{t('fields.status')}</FormLabel>
|
|
238
235
|
<FormControl>
|
|
239
236
|
<Select value={field.value} onValueChange={field.onChange}>
|
|
240
237
|
<SelectTrigger className="w-full">
|
|
241
238
|
<SelectValue />
|
|
242
239
|
</SelectTrigger>
|
|
243
240
|
<SelectContent>
|
|
244
|
-
<SelectItem value="active">
|
|
245
|
-
<SelectItem value="trial">
|
|
246
|
-
<SelectItem value="inactive">
|
|
247
|
-
<SelectItem value="suspended">
|
|
241
|
+
<SelectItem value="active">{t('status.active')}</SelectItem>
|
|
242
|
+
<SelectItem value="trial">{t('status.trial')}</SelectItem>
|
|
243
|
+
<SelectItem value="inactive">{t('status.inactive')}</SelectItem>
|
|
244
|
+
<SelectItem value="suspended">{t('status.suspended')}</SelectItem>
|
|
248
245
|
</SelectContent>
|
|
249
246
|
</Select>
|
|
250
247
|
</FormControl>
|
|
@@ -262,11 +259,11 @@ export function EnterpriseSheet({
|
|
|
262
259
|
shouldValidate: true,
|
|
263
260
|
})
|
|
264
261
|
}
|
|
265
|
-
label=
|
|
266
|
-
placeholder=
|
|
267
|
-
searchPlaceholder=
|
|
268
|
-
emptyLabel=
|
|
269
|
-
entityLabel=
|
|
262
|
+
label={t('fields.company')}
|
|
263
|
+
placeholder={t('fields.companyPlaceholder')}
|
|
264
|
+
searchPlaceholder={t('fields.companySearchPlaceholder')}
|
|
265
|
+
emptyLabel={t('fields.companyEmpty')}
|
|
266
|
+
entityLabel={t('fields.companyEntity')}
|
|
270
267
|
clearable
|
|
271
268
|
valueType="number"
|
|
272
269
|
loadOptions={async ({ page, pageSize, search }) => {
|
|
@@ -290,8 +287,8 @@ export function EnterpriseSheet({
|
|
|
290
287
|
createFields={[
|
|
291
288
|
{
|
|
292
289
|
name: 'name',
|
|
293
|
-
label: '
|
|
294
|
-
placeholder: '
|
|
290
|
+
label: t('fields.companyCreateName'),
|
|
291
|
+
placeholder: t('fields.companyCreateNamePlaceholder'),
|
|
295
292
|
required: true,
|
|
296
293
|
},
|
|
297
294
|
]}
|
|
@@ -317,11 +314,10 @@ export function EnterpriseSheet({
|
|
|
317
314
|
<FormItem className="flex items-center justify-between rounded-lg border px-4 py-3">
|
|
318
315
|
<div className="space-y-0.5">
|
|
319
316
|
<FormLabel className="text-sm font-medium">
|
|
320
|
-
|
|
317
|
+
{t('fields.portalEnabled')}
|
|
321
318
|
</FormLabel>
|
|
322
319
|
<FormDescription className="text-xs">
|
|
323
|
-
|
|
324
|
-
portal.
|
|
320
|
+
{t('fields.portalEnabledDescription')}
|
|
325
321
|
</FormDescription>
|
|
326
322
|
</div>
|
|
327
323
|
<FormControl>
|
|
@@ -340,12 +336,12 @@ export function EnterpriseSheet({
|
|
|
340
336
|
name="licenseLimit"
|
|
341
337
|
render={({ field }) => (
|
|
342
338
|
<FormItem>
|
|
343
|
-
<FormLabel>
|
|
339
|
+
<FormLabel>{t('fields.licenseLimit')}</FormLabel>
|
|
344
340
|
<FormControl>
|
|
345
341
|
<Input
|
|
346
342
|
type="number"
|
|
347
343
|
min={1}
|
|
348
|
-
placeholder=
|
|
344
|
+
placeholder={t('fields.licenseLimitPlaceholder')}
|
|
349
345
|
value={field.value ?? ''}
|
|
350
346
|
onChange={(e) =>
|
|
351
347
|
field.onChange(
|
|
@@ -355,7 +351,7 @@ export function EnterpriseSheet({
|
|
|
355
351
|
/>
|
|
356
352
|
</FormControl>
|
|
357
353
|
<FormDescription>
|
|
358
|
-
|
|
354
|
+
{t('fields.licenseLimitDescription')}
|
|
359
355
|
</FormDescription>
|
|
360
356
|
<FormMessage />
|
|
361
357
|
</FormItem>
|
|
@@ -368,10 +364,10 @@ export function EnterpriseSheet({
|
|
|
368
364
|
name="notes"
|
|
369
365
|
render={({ field }) => (
|
|
370
366
|
<FormItem>
|
|
371
|
-
<FormLabel>
|
|
367
|
+
<FormLabel>{t('fields.notes')}</FormLabel>
|
|
372
368
|
<FormControl>
|
|
373
369
|
<Textarea
|
|
374
|
-
placeholder=
|
|
370
|
+
placeholder={t('fields.notesPlaceholder')}
|
|
375
371
|
rows={3}
|
|
376
372
|
{...field}
|
|
377
373
|
value={field.value ?? ''}
|
|
@@ -384,9 +380,11 @@ export function EnterpriseSheet({
|
|
|
384
380
|
|
|
385
381
|
<FormActions
|
|
386
382
|
sheet
|
|
387
|
-
cancelLabel=
|
|
383
|
+
cancelLabel={t('actions.cancel')}
|
|
388
384
|
onCancel={() => onOpenChange(false)}
|
|
389
|
-
submitLabel={
|
|
385
|
+
submitLabel={
|
|
386
|
+
isEditing ? t('actions.saveChanges') : t('actions.create')
|
|
387
|
+
}
|
|
390
388
|
submitType="submit"
|
|
391
389
|
/>
|
|
392
390
|
</form>
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
import { useApp } from '@hed-hog/next-app-provider';
|
|
22
22
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
23
23
|
import { Loader2 } from 'lucide-react';
|
|
24
|
+
import { useTranslations } from 'next-intl';
|
|
24
25
|
import { useEffect, useState } from 'react';
|
|
25
26
|
import { useForm } from 'react-hook-form';
|
|
26
27
|
import { toast } from 'sonner';
|
|
@@ -57,6 +58,7 @@ export function EnterpriseStudentCreateSheet({
|
|
|
57
58
|
onOpenChange,
|
|
58
59
|
onCreated,
|
|
59
60
|
}: EnterpriseStudentCreateSheetProps) {
|
|
61
|
+
const t = useTranslations('lms.EnterprisePage');
|
|
60
62
|
const { request } = useApp();
|
|
61
63
|
const [saving, setSaving] = useState(false);
|
|
62
64
|
|
|
@@ -90,7 +92,7 @@ export function EnterpriseStudentCreateSheet({
|
|
|
90
92
|
onCreated?.(personId);
|
|
91
93
|
handleOpenChange(false);
|
|
92
94
|
} catch {
|
|
93
|
-
toast.error('
|
|
95
|
+
toast.error(t('sheet.studentCreated'));
|
|
94
96
|
} finally {
|
|
95
97
|
setSaving(false);
|
|
96
98
|
}
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
import { formatDate } from '@/lib/format-date';
|
|
16
16
|
import { useApp, useQuery } from '@hed-hog/next-app-provider';
|
|
17
17
|
import { Trash2 } from 'lucide-react';
|
|
18
|
+
import { useTranslations } from 'next-intl';
|
|
18
19
|
import { useCallback, useState } from 'react';
|
|
19
20
|
import { toast } from 'sonner';
|
|
20
21
|
import {
|
|
@@ -39,6 +40,7 @@ export function StudentsTab({
|
|
|
39
40
|
enterpriseId: number;
|
|
40
41
|
onMutate?: () => void;
|
|
41
42
|
}) {
|
|
43
|
+
const t = useTranslations('lms.EnterprisePage');
|
|
42
44
|
const { request, getSettingValue, currentLocaleCode } = useApp();
|
|
43
45
|
const [search, setSearch] = useState('');
|
|
44
46
|
const [page, setPage] = useState(1);
|
|
@@ -93,7 +95,7 @@ export function StudentsTab({
|
|
|
93
95
|
refetch();
|
|
94
96
|
onMutate?.();
|
|
95
97
|
} catch {
|
|
96
|
-
toast.error('
|
|
98
|
+
toast.error(t('sheet.studentAddError'));
|
|
97
99
|
}
|
|
98
100
|
}
|
|
99
101
|
|
|
@@ -107,9 +109,9 @@ export function StudentsTab({
|
|
|
107
109
|
onMutate?.();
|
|
108
110
|
});
|
|
109
111
|
toast.promise(promise, {
|
|
110
|
-
loading: '
|
|
111
|
-
success: '
|
|
112
|
-
error: '
|
|
112
|
+
loading: t('sheet.studentRemoving'),
|
|
113
|
+
success: t('sheet.studentRemoved'),
|
|
114
|
+
error: t('sheet.studentRemoveError'),
|
|
113
115
|
});
|
|
114
116
|
try {
|
|
115
117
|
await promise;
|
|
@@ -255,7 +257,7 @@ export function StudentsTab({
|
|
|
255
257
|
data: { person_id: personId, status: 'active' },
|
|
256
258
|
});
|
|
257
259
|
} catch {
|
|
258
|
-
toast.error('
|
|
260
|
+
toast.error(t('sheet.studentLinkError'));
|
|
259
261
|
}
|
|
260
262
|
setCreateSheetOpen(false);
|
|
261
263
|
refetch();
|