@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
|
@@ -1,277 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
EnterpriseAccount,
|
|
3
|
-
EnterpriseClass,
|
|
4
|
-
EnterpriseCourse,
|
|
5
|
-
EnterpriseUser,
|
|
6
|
-
} from './enterprise-types';
|
|
7
|
-
|
|
8
|
-
// ── CRM Accounts (picker options) ─────────────────────────────────────────────
|
|
9
|
-
|
|
10
|
-
export const MOCK_CRM_ACCOUNTS = [
|
|
11
|
-
{ id: 101, name: 'Techcorp Brasil Ltda' },
|
|
12
|
-
{ id: 102, name: 'Grupo Atlas S.A.' },
|
|
13
|
-
{ id: 103, name: 'Horizonte Engenharia Ltda' },
|
|
14
|
-
{ id: 104, name: 'MedPlus Saúde S.A.' },
|
|
15
|
-
{ id: 105, name: 'Agro Prime Comércio Ltda' },
|
|
16
|
-
{ id: 106, name: 'LogTech Transportes Ltda' },
|
|
17
|
-
{ id: 107, name: 'Inova Tech S.A.' },
|
|
18
|
-
{ id: 108, name: 'Dinâmica Consultoria Ltda' },
|
|
19
|
-
];
|
|
20
|
-
|
|
21
|
-
// ── Accounts ───────────────────────────────────────────────────────────────────
|
|
22
|
-
|
|
23
|
-
export const MOCK_ENTERPRISE_ACCOUNTS: EnterpriseAccount[] = [
|
|
24
|
-
{
|
|
25
|
-
id: 1,
|
|
26
|
-
name: 'Techcorp Brasil',
|
|
27
|
-
slug: 'techcorp-brasil',
|
|
28
|
-
status: 'active',
|
|
29
|
-
crmAccountId: 101,
|
|
30
|
-
crmAccountName: 'Techcorp Brasil Ltda',
|
|
31
|
-
portalEnabled: true,
|
|
32
|
-
usersCount: 120,
|
|
33
|
-
studentsCount: 104,
|
|
34
|
-
managersCount: 14,
|
|
35
|
-
adminsCount: 2,
|
|
36
|
-
coursesCount: 8,
|
|
37
|
-
classesCount: 3,
|
|
38
|
-
licenseLimit: 150,
|
|
39
|
-
notes: null,
|
|
40
|
-
createdAt: '2026-01-01T10:00:00Z',
|
|
41
|
-
updatedAt: '2026-04-10T08:30:00Z',
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
id: 2,
|
|
45
|
-
name: 'Grupo Financeiro Atlas',
|
|
46
|
-
slug: 'grupo-financeiro-atlas',
|
|
47
|
-
status: 'active',
|
|
48
|
-
crmAccountId: 102,
|
|
49
|
-
crmAccountName: 'Grupo Atlas S.A.',
|
|
50
|
-
portalEnabled: true,
|
|
51
|
-
usersCount: 250,
|
|
52
|
-
studentsCount: 220,
|
|
53
|
-
managersCount: 28,
|
|
54
|
-
adminsCount: 2,
|
|
55
|
-
coursesCount: 14,
|
|
56
|
-
classesCount: 5,
|
|
57
|
-
licenseLimit: 300,
|
|
58
|
-
notes: null,
|
|
59
|
-
createdAt: '2026-02-01T09:00:00Z',
|
|
60
|
-
updatedAt: '2026-04-15T11:00:00Z',
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
id: 3,
|
|
64
|
-
name: 'Construtora Horizonte',
|
|
65
|
-
slug: 'construtora-horizonte',
|
|
66
|
-
status: 'active',
|
|
67
|
-
crmAccountId: null,
|
|
68
|
-
crmAccountName: null,
|
|
69
|
-
portalEnabled: false,
|
|
70
|
-
usersCount: 60,
|
|
71
|
-
studentsCount: 52,
|
|
72
|
-
managersCount: 6,
|
|
73
|
-
adminsCount: 1,
|
|
74
|
-
coursesCount: 4,
|
|
75
|
-
classesCount: 2,
|
|
76
|
-
licenseLimit: 80,
|
|
77
|
-
notes: null,
|
|
78
|
-
createdAt: '2026-03-01T08:00:00Z',
|
|
79
|
-
updatedAt: '2026-04-01T09:00:00Z',
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
id: 4,
|
|
83
|
-
name: 'MedPlus Saúde',
|
|
84
|
-
slug: 'medplus-saude',
|
|
85
|
-
status: 'trial',
|
|
86
|
-
crmAccountId: 104,
|
|
87
|
-
crmAccountName: 'MedPlus Saúde S.A.',
|
|
88
|
-
portalEnabled: true,
|
|
89
|
-
usersCount: 30,
|
|
90
|
-
studentsCount: 28,
|
|
91
|
-
managersCount: 2,
|
|
92
|
-
adminsCount: 1,
|
|
93
|
-
coursesCount: 3,
|
|
94
|
-
classesCount: 1,
|
|
95
|
-
licenseLimit: 50,
|
|
96
|
-
notes: null,
|
|
97
|
-
createdAt: '2026-04-01T11:00:00Z',
|
|
98
|
-
updatedAt: '2026-04-18T14:00:00Z',
|
|
99
|
-
},
|
|
100
|
-
{
|
|
101
|
-
id: 5,
|
|
102
|
-
name: 'Agro Prime',
|
|
103
|
-
slug: 'agro-prime',
|
|
104
|
-
status: 'inactive',
|
|
105
|
-
crmAccountId: null,
|
|
106
|
-
crmAccountName: null,
|
|
107
|
-
portalEnabled: false,
|
|
108
|
-
usersCount: 0,
|
|
109
|
-
studentsCount: 0,
|
|
110
|
-
managersCount: 0,
|
|
111
|
-
adminsCount: 0,
|
|
112
|
-
coursesCount: 0,
|
|
113
|
-
classesCount: 0,
|
|
114
|
-
licenseLimit: null,
|
|
115
|
-
notes: null,
|
|
116
|
-
createdAt: '2025-09-01T14:00:00Z',
|
|
117
|
-
updatedAt: '2026-02-28T18:00:00Z',
|
|
118
|
-
},
|
|
119
|
-
{
|
|
120
|
-
id: 6,
|
|
121
|
-
name: 'LogTech Transportes',
|
|
122
|
-
slug: 'logtech-transportes',
|
|
123
|
-
status: 'active',
|
|
124
|
-
crmAccountId: 106,
|
|
125
|
-
crmAccountName: 'LogTech Transportes Ltda',
|
|
126
|
-
portalEnabled: true,
|
|
127
|
-
usersCount: 100,
|
|
128
|
-
studentsCount: 88,
|
|
129
|
-
managersCount: 10,
|
|
130
|
-
adminsCount: 2,
|
|
131
|
-
coursesCount: 6,
|
|
132
|
-
classesCount: 2,
|
|
133
|
-
licenseLimit: 120,
|
|
134
|
-
notes: null,
|
|
135
|
-
createdAt: '2026-01-15T09:30:00Z',
|
|
136
|
-
updatedAt: '2026-04-12T10:00:00Z',
|
|
137
|
-
},
|
|
138
|
-
];
|
|
139
|
-
|
|
140
|
-
// ── Users (linked to account id=1) ─────────────────────────────────────────────
|
|
141
|
-
|
|
142
|
-
export const MOCK_ENTERPRISE_USERS: EnterpriseUser[] = [
|
|
143
|
-
{
|
|
144
|
-
id: 1,
|
|
145
|
-
userId: 201,
|
|
146
|
-
name: 'Ana Beatriz Souza',
|
|
147
|
-
email: 'ana.souza@techcorp.com.br',
|
|
148
|
-
role: 'enterprise_admin',
|
|
149
|
-
status: 'active',
|
|
150
|
-
lastAccessAt: '2026-04-20T14:32:00Z',
|
|
151
|
-
},
|
|
152
|
-
{
|
|
153
|
-
id: 2,
|
|
154
|
-
userId: 202,
|
|
155
|
-
name: 'Carlos Eduardo Lima',
|
|
156
|
-
email: 'carlos.lima@techcorp.com.br',
|
|
157
|
-
role: 'hr_manager',
|
|
158
|
-
status: 'active',
|
|
159
|
-
lastAccessAt: '2026-04-19T09:15:00Z',
|
|
160
|
-
},
|
|
161
|
-
{
|
|
162
|
-
id: 3,
|
|
163
|
-
userId: 203,
|
|
164
|
-
name: 'Fernanda Oliveira',
|
|
165
|
-
email: 'fernanda.oliveira@techcorp.com.br',
|
|
166
|
-
role: 'student',
|
|
167
|
-
status: 'active',
|
|
168
|
-
lastAccessAt: '2026-04-18T16:00:00Z',
|
|
169
|
-
},
|
|
170
|
-
{
|
|
171
|
-
id: 4,
|
|
172
|
-
userId: 204,
|
|
173
|
-
name: 'Ricardo Mendes',
|
|
174
|
-
email: 'ricardo.mendes@techcorp.com.br',
|
|
175
|
-
role: 'student',
|
|
176
|
-
status: 'active',
|
|
177
|
-
lastAccessAt: '2026-04-17T11:45:00Z',
|
|
178
|
-
},
|
|
179
|
-
{
|
|
180
|
-
id: 5,
|
|
181
|
-
userId: 205,
|
|
182
|
-
name: 'Juliana Castro',
|
|
183
|
-
email: 'juliana.castro@techcorp.com.br',
|
|
184
|
-
role: 'viewer',
|
|
185
|
-
status: 'inactive',
|
|
186
|
-
lastAccessAt: null,
|
|
187
|
-
},
|
|
188
|
-
{
|
|
189
|
-
id: 6,
|
|
190
|
-
userId: 206,
|
|
191
|
-
name: 'Marcos Vinicius Santos',
|
|
192
|
-
email: 'marcos.santos@techcorp.com.br',
|
|
193
|
-
role: 'student',
|
|
194
|
-
status: 'pending',
|
|
195
|
-
lastAccessAt: null,
|
|
196
|
-
},
|
|
197
|
-
];
|
|
198
|
-
|
|
199
|
-
// ── Courses (linked to account id=1) ──────────────────────────────────────────
|
|
200
|
-
|
|
201
|
-
export const MOCK_ENTERPRISE_COURSES: EnterpriseCourse[] = [
|
|
202
|
-
{
|
|
203
|
-
id: 10,
|
|
204
|
-
title: 'Liderança e Gestão de Equipes',
|
|
205
|
-
slug: 'lideranca-gestao-equipes',
|
|
206
|
-
status: 'published',
|
|
207
|
-
modality: 'Online',
|
|
208
|
-
enrolledCount: 45,
|
|
209
|
-
completionRate: 72,
|
|
210
|
-
contractedAt: '2026-01-05T00:00:00Z',
|
|
211
|
-
},
|
|
212
|
-
{
|
|
213
|
-
id: 11,
|
|
214
|
-
title: 'Compliance e Ética Corporativa',
|
|
215
|
-
slug: 'compliance-etica-corporativa',
|
|
216
|
-
status: 'published',
|
|
217
|
-
modality: 'Híbrido',
|
|
218
|
-
enrolledCount: 104,
|
|
219
|
-
completionRate: 88,
|
|
220
|
-
contractedAt: '2026-01-05T00:00:00Z',
|
|
221
|
-
},
|
|
222
|
-
{
|
|
223
|
-
id: 12,
|
|
224
|
-
title: 'Segurança da Informação',
|
|
225
|
-
slug: 'seguranca-informacao',
|
|
226
|
-
status: 'published',
|
|
227
|
-
modality: 'Online',
|
|
228
|
-
enrolledCount: 98,
|
|
229
|
-
completionRate: 61,
|
|
230
|
-
contractedAt: '2026-02-01T00:00:00Z',
|
|
231
|
-
},
|
|
232
|
-
{
|
|
233
|
-
id: 13,
|
|
234
|
-
title: 'Agile & Scrum na Prática',
|
|
235
|
-
slug: 'agile-scrum-pratica',
|
|
236
|
-
status: 'draft',
|
|
237
|
-
modality: 'Presencial',
|
|
238
|
-
enrolledCount: 0,
|
|
239
|
-
completionRate: 0,
|
|
240
|
-
contractedAt: '2026-03-10T00:00:00Z',
|
|
241
|
-
},
|
|
242
|
-
];
|
|
243
|
-
|
|
244
|
-
// ── Classes / Turmas (linked to account id=1) ──────────────────────────────────
|
|
245
|
-
|
|
246
|
-
export const MOCK_ENTERPRISE_CLASSES: EnterpriseClass[] = [
|
|
247
|
-
{
|
|
248
|
-
id: 20,
|
|
249
|
-
code: 'T2026-LG-01',
|
|
250
|
-
courseTitle: 'Liderança e Gestão de Equipes',
|
|
251
|
-
startDate: '2026-03-01',
|
|
252
|
-
endDate: '2026-06-30',
|
|
253
|
-
enrolledCount: 45,
|
|
254
|
-
capacity: 50,
|
|
255
|
-
status: 'ongoing',
|
|
256
|
-
},
|
|
257
|
-
{
|
|
258
|
-
id: 21,
|
|
259
|
-
code: 'T2026-CE-01',
|
|
260
|
-
courseTitle: 'Compliance e Ética Corporativa',
|
|
261
|
-
startDate: '2026-01-10',
|
|
262
|
-
endDate: '2026-04-10',
|
|
263
|
-
enrolledCount: 104,
|
|
264
|
-
capacity: 120,
|
|
265
|
-
status: 'completed',
|
|
266
|
-
},
|
|
267
|
-
{
|
|
268
|
-
id: 22,
|
|
269
|
-
code: 'T2026-SI-01',
|
|
270
|
-
courseTitle: 'Segurança da Informação',
|
|
271
|
-
startDate: '2026-04-15',
|
|
272
|
-
endDate: null,
|
|
273
|
-
enrolledCount: 98,
|
|
274
|
-
capacity: 100,
|
|
275
|
-
status: 'open',
|
|
276
|
-
},
|
|
277
|
-
];
|
|
@@ -1,207 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import { Button } from '@/components/ui/button';
|
|
4
|
-
import {
|
|
5
|
-
Form,
|
|
6
|
-
FormControl,
|
|
7
|
-
FormDescription,
|
|
8
|
-
FormField,
|
|
9
|
-
FormItem,
|
|
10
|
-
FormLabel,
|
|
11
|
-
FormMessage,
|
|
12
|
-
} from '@/components/ui/form';
|
|
13
|
-
import { Input } from '@/components/ui/input';
|
|
14
|
-
import {
|
|
15
|
-
Select,
|
|
16
|
-
SelectContent,
|
|
17
|
-
SelectItem,
|
|
18
|
-
SelectTrigger,
|
|
19
|
-
SelectValue,
|
|
20
|
-
} from '@/components/ui/select';
|
|
21
|
-
import {
|
|
22
|
-
Sheet,
|
|
23
|
-
SheetContent,
|
|
24
|
-
SheetFooter,
|
|
25
|
-
SheetHeader,
|
|
26
|
-
SheetTitle,
|
|
27
|
-
} from '@/components/ui/sheet';
|
|
28
|
-
import { zodResolver } from '@hookform/resolvers/zod';
|
|
29
|
-
import { Loader2 } from 'lucide-react';
|
|
30
|
-
import { useEffect } from 'react';
|
|
31
|
-
import { useForm } from 'react-hook-form';
|
|
32
|
-
import { z } from 'zod';
|
|
33
|
-
import type { EnterpriseUser, EnterpriseUserRole } from './enterprise-types';
|
|
34
|
-
|
|
35
|
-
// ── Schema ─────────────────────────────────────────────────────────────────────
|
|
36
|
-
|
|
37
|
-
const userCreateSchema = z.object({
|
|
38
|
-
name: z.string().trim().min(1, 'Name is required.'),
|
|
39
|
-
email: z
|
|
40
|
-
.string()
|
|
41
|
-
.trim()
|
|
42
|
-
.min(1, 'Email is required.')
|
|
43
|
-
.email('Enter a valid email address.'),
|
|
44
|
-
role: z.enum(['student', 'hr_manager', 'enterprise_admin', 'viewer']),
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
type UserCreateValues = z.infer<typeof userCreateSchema>;
|
|
48
|
-
|
|
49
|
-
const DEFAULT_VALUES: UserCreateValues = {
|
|
50
|
-
name: '',
|
|
51
|
-
email: '',
|
|
52
|
-
role: 'student',
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
// ── Props ─────────────────────────────────────────────────────────────────────
|
|
56
|
-
|
|
57
|
-
export interface EnterpriseUserCreateSheetProps {
|
|
58
|
-
open: boolean;
|
|
59
|
-
onOpenChange: (open: boolean) => void;
|
|
60
|
-
onCreated?: (user: EnterpriseUser) => void;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// ── Component ─────────────────────────────────────────────────────────────────
|
|
64
|
-
|
|
65
|
-
export function EnterpriseUserCreateSheet({
|
|
66
|
-
open,
|
|
67
|
-
onOpenChange,
|
|
68
|
-
onCreated,
|
|
69
|
-
}: EnterpriseUserCreateSheetProps) {
|
|
70
|
-
const form = useForm<UserCreateValues>({
|
|
71
|
-
resolver: zodResolver(userCreateSchema),
|
|
72
|
-
defaultValues: DEFAULT_VALUES,
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
// Reset form whenever the sheet closes
|
|
76
|
-
useEffect(() => {
|
|
77
|
-
if (!open) {
|
|
78
|
-
form.reset(DEFAULT_VALUES);
|
|
79
|
-
}
|
|
80
|
-
}, [open, form]);
|
|
81
|
-
|
|
82
|
-
function handleOpenChange(nextOpen: boolean) {
|
|
83
|
-
if (!nextOpen) form.reset(DEFAULT_VALUES);
|
|
84
|
-
onOpenChange(nextOpen);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
async function onSubmit(values: UserCreateValues) {
|
|
88
|
-
// Optimistic mock creation — replace with real API call when available
|
|
89
|
-
const newUser: EnterpriseUser = {
|
|
90
|
-
id: Date.now(),
|
|
91
|
-
userId: Date.now() + 1,
|
|
92
|
-
name: values.name,
|
|
93
|
-
email: values.email,
|
|
94
|
-
role: values.role as EnterpriseUserRole,
|
|
95
|
-
status: 'pending',
|
|
96
|
-
lastAccessAt: null,
|
|
97
|
-
};
|
|
98
|
-
onCreated?.(newUser);
|
|
99
|
-
handleOpenChange(false);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const saving = form.formState.isSubmitting;
|
|
103
|
-
|
|
104
|
-
return (
|
|
105
|
-
<Sheet open={open} onOpenChange={handleOpenChange}>
|
|
106
|
-
<SheetContent side="right" className="flex flex-col gap-0 sm:max-w-md">
|
|
107
|
-
<SheetHeader className="border-b px-6 py-4">
|
|
108
|
-
<SheetTitle>New user</SheetTitle>
|
|
109
|
-
</SheetHeader>
|
|
110
|
-
|
|
111
|
-
<Form {...form}>
|
|
112
|
-
<form
|
|
113
|
-
onSubmit={form.handleSubmit(onSubmit)}
|
|
114
|
-
className="flex flex-1 flex-col overflow-hidden"
|
|
115
|
-
>
|
|
116
|
-
<div className="flex-1 space-y-5 overflow-y-auto px-6 py-5">
|
|
117
|
-
{/* Name */}
|
|
118
|
-
<FormField
|
|
119
|
-
control={form.control}
|
|
120
|
-
name="name"
|
|
121
|
-
render={({ field }) => (
|
|
122
|
-
<FormItem>
|
|
123
|
-
<FormLabel>Full name</FormLabel>
|
|
124
|
-
<FormControl>
|
|
125
|
-
<Input placeholder="e.g. Ana Beatriz Souza" {...field} />
|
|
126
|
-
</FormControl>
|
|
127
|
-
<FormMessage />
|
|
128
|
-
</FormItem>
|
|
129
|
-
)}
|
|
130
|
-
/>
|
|
131
|
-
|
|
132
|
-
{/* Email */}
|
|
133
|
-
<FormField
|
|
134
|
-
control={form.control}
|
|
135
|
-
name="email"
|
|
136
|
-
render={({ field }) => (
|
|
137
|
-
<FormItem>
|
|
138
|
-
<FormLabel>Email</FormLabel>
|
|
139
|
-
<FormControl>
|
|
140
|
-
<Input
|
|
141
|
-
type="email"
|
|
142
|
-
placeholder="user@company.com"
|
|
143
|
-
{...field}
|
|
144
|
-
/>
|
|
145
|
-
</FormControl>
|
|
146
|
-
<FormDescription>
|
|
147
|
-
An invite will be sent to this address.
|
|
148
|
-
</FormDescription>
|
|
149
|
-
<FormMessage />
|
|
150
|
-
</FormItem>
|
|
151
|
-
)}
|
|
152
|
-
/>
|
|
153
|
-
|
|
154
|
-
{/* Role */}
|
|
155
|
-
<FormField
|
|
156
|
-
control={form.control}
|
|
157
|
-
name="role"
|
|
158
|
-
render={({ field }) => (
|
|
159
|
-
<FormItem>
|
|
160
|
-
<FormLabel>Role</FormLabel>
|
|
161
|
-
<Select value={field.value} onValueChange={field.onChange}>
|
|
162
|
-
<FormControl>
|
|
163
|
-
<SelectTrigger className="w-full">
|
|
164
|
-
<SelectValue placeholder="Select a role" />
|
|
165
|
-
</SelectTrigger>
|
|
166
|
-
</FormControl>
|
|
167
|
-
<SelectContent>
|
|
168
|
-
<SelectItem value="enterprise_admin">
|
|
169
|
-
Admin — full account management
|
|
170
|
-
</SelectItem>
|
|
171
|
-
<SelectItem value="hr_manager">
|
|
172
|
-
HR / Manager — manages learners and reports
|
|
173
|
-
</SelectItem>
|
|
174
|
-
<SelectItem value="student">
|
|
175
|
-
Student — access to assigned courses
|
|
176
|
-
</SelectItem>
|
|
177
|
-
<SelectItem value="viewer">
|
|
178
|
-
Viewer — read-only access
|
|
179
|
-
</SelectItem>
|
|
180
|
-
</SelectContent>
|
|
181
|
-
</Select>
|
|
182
|
-
<FormMessage />
|
|
183
|
-
</FormItem>
|
|
184
|
-
)}
|
|
185
|
-
/>
|
|
186
|
-
</div>
|
|
187
|
-
|
|
188
|
-
<SheetFooter className="border-t px-6 py-4">
|
|
189
|
-
<Button
|
|
190
|
-
type="button"
|
|
191
|
-
variant="outline"
|
|
192
|
-
onClick={() => handleOpenChange(false)}
|
|
193
|
-
disabled={saving}
|
|
194
|
-
>
|
|
195
|
-
Cancel
|
|
196
|
-
</Button>
|
|
197
|
-
<Button type="submit" disabled={saving}>
|
|
198
|
-
{saving && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
|
|
199
|
-
Create user
|
|
200
|
-
</Button>
|
|
201
|
-
</SheetFooter>
|
|
202
|
-
</form>
|
|
203
|
-
</Form>
|
|
204
|
-
</SheetContent>
|
|
205
|
-
</Sheet>
|
|
206
|
-
);
|
|
207
|
-
}
|