@appcorp/fusion-storybook 0.2.61 → 0.2.64
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/base-modules/class/more-actions.js +1 -1
- package/base-modules/course/context.d.ts +12 -0
- package/base-modules/course/context.js +23 -7
- package/base-modules/course/form.js +34 -3
- package/base-modules/course/page.d.ts +1 -0
- package/base-modules/course/page.js +16 -5
- package/base-modules/course/validate.d.ts +1 -0
- package/base-modules/course/validate.js +1 -0
- package/base-modules/course/view.js +6 -2
- package/base-modules/enrollment/context.d.ts +13 -1
- package/base-modules/enrollment/context.js +3 -0
- package/base-modules/enrollment/form.js +31 -3
- package/base-modules/enrollment/more-actions.js +9 -7
- package/base-modules/enrollment/page.d.ts +1 -0
- package/base-modules/enrollment/page.js +15 -4
- package/base-modules/enrollment/validate.d.ts +1 -0
- package/base-modules/enrollment/validate.js +1 -0
- package/base-modules/enrollment/view.js +5 -2
- package/base-modules/section/cache.js +0 -1
- package/base-modules/section/context.d.ts +0 -6
- package/base-modules/section/context.js +0 -3
- package/base-modules/section/form.js +2 -36
- package/base-modules/section/more-actions.js +5 -7
- package/base-modules/section/page.d.ts +0 -1
- package/base-modules/section/page.js +3 -7
- package/base-modules/section/validate.d.ts +0 -1
- package/base-modules/section/validate.js +0 -1
- package/base-modules/section/view.js +2 -10
- package/constants.d.ts +0 -1
- package/constants.js +0 -1
- package/package.json +1 -1
- package/tsconfig.build.tsbuildinfo +1 -1
- package/types/academics.d.ts +5 -2
|
@@ -188,7 +188,7 @@ export const ClassMoreActions = () => {
|
|
|
188
188
|
showSuccessToast(t("messagesBulkSuccess"));
|
|
189
189
|
}
|
|
190
190
|
const schoolId = ((_f = workspace === null || workspace === void 0 ? void 0 : workspace.school) === null || _f === void 0 ? void 0 : _f.id) || "";
|
|
191
|
-
fetch(`${CLASS_API_ROUTES.
|
|
191
|
+
fetch(`${CLASS_API_ROUTES.UNIT}?currentPage=1&pageLimit=${pageLimit}&schoolId=${schoolId}`, {
|
|
192
192
|
headers: {
|
|
193
193
|
"Content-Type": "application/json",
|
|
194
194
|
},
|
|
@@ -26,6 +26,8 @@ export declare const COURSE_ACTION_TYPES: {
|
|
|
26
26
|
searchQuery: string;
|
|
27
27
|
disableSaveButton: boolean;
|
|
28
28
|
drawer: string | null;
|
|
29
|
+
classId: string;
|
|
30
|
+
classLabel: string;
|
|
29
31
|
code: string;
|
|
30
32
|
enabled: boolean;
|
|
31
33
|
errors: Record<string, string>;
|
|
@@ -46,6 +48,8 @@ export declare const COURSE_ACTION_TYPES: {
|
|
|
46
48
|
searchQuery: string;
|
|
47
49
|
disableSaveButton: boolean;
|
|
48
50
|
drawer: string | null;
|
|
51
|
+
classId: string;
|
|
52
|
+
classLabel: string;
|
|
49
53
|
code: string;
|
|
50
54
|
enabled: boolean;
|
|
51
55
|
errors: Record<string, string>;
|
|
@@ -68,6 +72,8 @@ export declare const COURSE_ACTION_TYPES: {
|
|
|
68
72
|
searchQuery: string;
|
|
69
73
|
disableSaveButton: boolean;
|
|
70
74
|
drawer: string | null;
|
|
75
|
+
classId: string;
|
|
76
|
+
classLabel: string;
|
|
71
77
|
code: string;
|
|
72
78
|
enabled: boolean;
|
|
73
79
|
errors: Record<string, string>;
|
|
@@ -88,6 +94,8 @@ export declare const COURSE_ACTION_TYPES: {
|
|
|
88
94
|
searchQuery: string;
|
|
89
95
|
disableSaveButton: boolean;
|
|
90
96
|
drawer: string | null;
|
|
97
|
+
classId: string;
|
|
98
|
+
classLabel: string;
|
|
91
99
|
code: string;
|
|
92
100
|
enabled: boolean;
|
|
93
101
|
errors: Record<string, string>;
|
|
@@ -108,6 +116,8 @@ export declare const COURSE_ACTION_TYPES: {
|
|
|
108
116
|
searchQuery: string;
|
|
109
117
|
disableSaveButton: boolean;
|
|
110
118
|
drawer: string | null;
|
|
119
|
+
classId: string;
|
|
120
|
+
classLabel: string;
|
|
111
121
|
code: string;
|
|
112
122
|
enabled: boolean;
|
|
113
123
|
errors: Record<string, string>;
|
|
@@ -158,6 +168,8 @@ export declare const useCourseModule: () => {
|
|
|
158
168
|
searchQuery: string;
|
|
159
169
|
disableSaveButton: boolean;
|
|
160
170
|
drawer: string | null;
|
|
171
|
+
classId: string;
|
|
172
|
+
classLabel: string;
|
|
161
173
|
code: string;
|
|
162
174
|
enabled: boolean;
|
|
163
175
|
errors: Record<string, string>;
|
|
@@ -54,6 +54,8 @@ const courseConfig = {
|
|
|
54
54
|
disableSaveButton: false,
|
|
55
55
|
drawer: null,
|
|
56
56
|
// Form State
|
|
57
|
+
classId: "",
|
|
58
|
+
classLabel: "",
|
|
57
59
|
code: "",
|
|
58
60
|
enabled: true,
|
|
59
61
|
errors: {},
|
|
@@ -102,6 +104,7 @@ export const useCourseModule = () => {
|
|
|
102
104
|
schoolId,
|
|
103
105
|
]);
|
|
104
106
|
const updateParams = useMemo(() => ({
|
|
107
|
+
classId: state.classId,
|
|
105
108
|
code: state.code,
|
|
106
109
|
enabled: state.enabled,
|
|
107
110
|
id: state.id,
|
|
@@ -172,7 +175,7 @@ export const useCourseModule = () => {
|
|
|
172
175
|
}
|
|
173
176
|
}, [resetFormAndCloseDrawer, showToast, t]);
|
|
174
177
|
const byIdCallback = useCallback(({ data, error }) => {
|
|
175
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
178
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
176
179
|
if (error) {
|
|
177
180
|
showToast(t("messagesNetworkError"), TOAST_VARIANT.ERROR);
|
|
178
181
|
return;
|
|
@@ -183,13 +186,26 @@ export const useCourseModule = () => {
|
|
|
183
186
|
type: COURSE_ACTION_TYPES.SET_INPUT_FIELD,
|
|
184
187
|
payload: { key: "id", value: course.id },
|
|
185
188
|
});
|
|
189
|
+
dispatch({
|
|
190
|
+
type: COURSE_ACTION_TYPES.SET_INPUT_FIELD,
|
|
191
|
+
payload: { key: "classId", value: course.classId },
|
|
192
|
+
});
|
|
193
|
+
dispatch({
|
|
194
|
+
type: COURSE_ACTION_TYPES.SET_INPUT_FIELD,
|
|
195
|
+
payload: {
|
|
196
|
+
key: "classLabel",
|
|
197
|
+
value: ((_a = course.class) === null || _a === void 0 ? void 0 : _a.name) && ((_b = course.class) === null || _b === void 0 ? void 0 : _b.code)
|
|
198
|
+
? `${course.class.name} (${course.class.code})`
|
|
199
|
+
: course.classId,
|
|
200
|
+
},
|
|
201
|
+
});
|
|
186
202
|
dispatch({
|
|
187
203
|
type: COURSE_ACTION_TYPES.SET_INPUT_FIELD,
|
|
188
204
|
payload: { key: "code", value: course.code },
|
|
189
205
|
});
|
|
190
206
|
dispatch({
|
|
191
207
|
type: COURSE_ACTION_TYPES.SET_INPUT_FIELD,
|
|
192
|
-
payload: { key: "enabled", value: (
|
|
208
|
+
payload: { key: "enabled", value: (_c = course.enabled) !== null && _c !== void 0 ? _c : true },
|
|
193
209
|
});
|
|
194
210
|
dispatch({
|
|
195
211
|
type: COURSE_ACTION_TYPES.SET_INPUT_FIELD,
|
|
@@ -203,9 +219,9 @@ export const useCourseModule = () => {
|
|
|
203
219
|
type: COURSE_ACTION_TYPES.SET_INPUT_FIELD,
|
|
204
220
|
payload: {
|
|
205
221
|
key: "sectionLabel",
|
|
206
|
-
value: ((
|
|
222
|
+
value: ((_e = (_d = course.section) === null || _d === void 0 ? void 0 : _d.class) === null || _e === void 0 ? void 0 : _e.code) && ((_f = course.section) === null || _f === void 0 ? void 0 : _f.name)
|
|
207
223
|
? `${course.section.class.code}-${course.section.name}`
|
|
208
|
-
: ((
|
|
224
|
+
: ((_g = course.section) === null || _g === void 0 ? void 0 : _g.name) || course.sectionId,
|
|
209
225
|
},
|
|
210
226
|
});
|
|
211
227
|
dispatch({
|
|
@@ -216,7 +232,7 @@ export const useCourseModule = () => {
|
|
|
216
232
|
type: COURSE_ACTION_TYPES.SET_INPUT_FIELD,
|
|
217
233
|
payload: {
|
|
218
234
|
key: "subjectLabel",
|
|
219
|
-
value: ((
|
|
235
|
+
value: ((_h = course.subject) === null || _h === void 0 ? void 0 : _h.name) || course.subjectId,
|
|
220
236
|
},
|
|
221
237
|
});
|
|
222
238
|
dispatch({
|
|
@@ -227,8 +243,8 @@ export const useCourseModule = () => {
|
|
|
227
243
|
type: COURSE_ACTION_TYPES.SET_INPUT_FIELD,
|
|
228
244
|
payload: {
|
|
229
245
|
key: "teacherLabel",
|
|
230
|
-
value: `${((
|
|
231
|
-
((
|
|
246
|
+
value: `${((_j = course.teacher) === null || _j === void 0 ? void 0 : _j.firstName) || ""} ${((_k = course.teacher) === null || _k === void 0 ? void 0 : _k.lastName) || ""}`.trim() ||
|
|
247
|
+
((_l = course.teacher) === null || _l === void 0 ? void 0 : _l.teacherCode) ||
|
|
232
248
|
course.teacherId,
|
|
233
249
|
},
|
|
234
250
|
});
|
|
@@ -10,7 +10,7 @@ import { EnhancedInput } from "@appcorp/shadcn/components/enhanced-input";
|
|
|
10
10
|
import { EnhancedCheckbox } from "@appcorp/shadcn/components/enhanced-checkbox";
|
|
11
11
|
import { useEnhancedCombobox } from "@appcorp/shadcn/hooks/use-enhanced-combobox";
|
|
12
12
|
import { useCourseModule } from "./context";
|
|
13
|
-
import { SECTION_API_ROUTES, SUBJECT_API_ROUTES, TEACHER_API_ROUTES, } from "../../constants";
|
|
13
|
+
import { CLASS_API_ROUTES, SECTION_API_ROUTES, SUBJECT_API_ROUTES, TEACHER_API_ROUTES, } from "../../constants";
|
|
14
14
|
import { useTranslations } from "next-intl";
|
|
15
15
|
import { useFetch } from "@react-pakistan/util-functions/hooks/use-fetch";
|
|
16
16
|
import { API_METHODS } from "@react-pakistan/util-functions";
|
|
@@ -19,7 +19,11 @@ export const CourseForm = () => {
|
|
|
19
19
|
const workspace = getCachedWorkspaceSync();
|
|
20
20
|
const t = useTranslations("course");
|
|
21
21
|
const { state, handleChange } = useCourseModule();
|
|
22
|
-
const { code, enabled, errors, sectionId, subjectId, teacherId } = state;
|
|
22
|
+
const { classId, code, enabled, errors, sectionId, subjectId, teacherId } = state;
|
|
23
|
+
const { data: classes } = useFetch("/api/v1/class", {
|
|
24
|
+
method: API_METHODS.GET,
|
|
25
|
+
params: { workspaceId: workspace === null || workspace === void 0 ? void 0 : workspace.id },
|
|
26
|
+
});
|
|
23
27
|
const { data: sections } = useFetch("/api/v1/sections", {
|
|
24
28
|
method: API_METHODS.GET,
|
|
25
29
|
params: { workspaceId: workspace === null || workspace === void 0 ? void 0 : workspace.id },
|
|
@@ -32,6 +36,33 @@ export const CourseForm = () => {
|
|
|
32
36
|
method: API_METHODS.GET,
|
|
33
37
|
params: { workspaceId: workspace === null || workspace === void 0 ? void 0 : workspace.id },
|
|
34
38
|
});
|
|
39
|
+
const { enhancedComboboxElement: classIdCombo } = useEnhancedCombobox({
|
|
40
|
+
emptyText: t("formNoClassEmpty"),
|
|
41
|
+
id: "classId",
|
|
42
|
+
info: t("formClassInfo"),
|
|
43
|
+
label: t("formClassLabel"),
|
|
44
|
+
onValueChange: (value) => {
|
|
45
|
+
var _a;
|
|
46
|
+
handleChange("classId", value);
|
|
47
|
+
handleChange("classLabel", ((_a = classes === null || classes === void 0 ? void 0 : classes.find((c) => c.id === value)) === null || _a === void 0 ? void 0 : _a.name) || "");
|
|
48
|
+
},
|
|
49
|
+
options: classes === null || classes === void 0 ? void 0 : classes.map((c) => ({
|
|
50
|
+
value: c.id,
|
|
51
|
+
label: `${c.name} (${c.code})`,
|
|
52
|
+
})),
|
|
53
|
+
placeholder: t("formClassPlaceholder"),
|
|
54
|
+
required: true,
|
|
55
|
+
searchEndpoint: CLASS_API_ROUTES.UNIT,
|
|
56
|
+
searchPlaceholder: t("formSearchClassPlaceholder"),
|
|
57
|
+
formatSearchResult: (item) => {
|
|
58
|
+
var _a, _b;
|
|
59
|
+
return ({
|
|
60
|
+
label: String((_a = item.label) !== null && _a !== void 0 ? _a : ""),
|
|
61
|
+
value: String((_b = item.value) !== null && _b !== void 0 ? _b : ""),
|
|
62
|
+
});
|
|
63
|
+
},
|
|
64
|
+
value: classId,
|
|
65
|
+
});
|
|
35
66
|
const { enhancedComboboxElement: sectionIdCombo } = useEnhancedCombobox({
|
|
36
67
|
emptyText: t("formNoSectionEmpty"),
|
|
37
68
|
id: "sectionId",
|
|
@@ -124,5 +155,5 @@ export const CourseForm = () => {
|
|
|
124
155
|
},
|
|
125
156
|
value: teacherId,
|
|
126
157
|
});
|
|
127
|
-
return (_jsxs("div", { className: "space-y-4", children: [_jsx(EnhancedInput, { error: errors.code, id: "code", info: t("formCourseCodeInfo"), label: t("formCourseCodeLabel"), onChange: (e) => handleChange("code", e.target.value), placeholder: t("formCourseCodePlaceholder"), required: true, value: code }), sectionIdCombo, subjectIdCombo, teacherIdCombo, _jsx(EnhancedCheckbox, { label: t("formActiveCourseLabel"), defaultChecked: enabled, onCheckedChange: (checked) => handleChange("enabled", checked), info: t("actionToggleEnableOrDisableCourse") })] }));
|
|
158
|
+
return (_jsxs("div", { className: "space-y-4", children: [_jsx(EnhancedInput, { error: errors.code, id: "code", info: t("formCourseCodeInfo"), label: t("formCourseCodeLabel"), onChange: (e) => handleChange("code", e.target.value), placeholder: t("formCourseCodePlaceholder"), required: true, value: code }), classIdCombo, sectionIdCombo, subjectIdCombo, teacherIdCombo, _jsx(EnhancedCheckbox, { label: t("formActiveCourseLabel"), defaultChecked: enabled, onCheckedChange: (checked) => handleChange("enabled", checked), info: t("actionToggleEnableOrDisableCourse") })] }));
|
|
128
159
|
};
|
|
@@ -29,6 +29,14 @@ import { RbacNoAccess } from "../../components/rbac-no-access";
|
|
|
29
29
|
const tableBodyCols = [
|
|
30
30
|
{ componentType: COMPONENT_TYPE.ID, key: "id" },
|
|
31
31
|
{ componentType: COMPONENT_TYPE.TEXT, key: "code" },
|
|
32
|
+
{
|
|
33
|
+
componentType: COMPONENT_TYPE.TEXT,
|
|
34
|
+
key: "class",
|
|
35
|
+
textFormatter: (_, row) => {
|
|
36
|
+
const cls = row.class;
|
|
37
|
+
return cls ? `${cls.name} (${cls.code})` : "N/A";
|
|
38
|
+
},
|
|
39
|
+
},
|
|
32
40
|
{
|
|
33
41
|
componentType: COMPONENT_TYPE.TEXT,
|
|
34
42
|
key: "section:name",
|
|
@@ -61,16 +69,17 @@ const createComponentInstances = () => ({
|
|
|
61
69
|
moreActions: _jsx(CourseMoreActions, {}),
|
|
62
70
|
view: _jsx(CourseView, {}),
|
|
63
71
|
});
|
|
64
|
-
const createCourseConfig = ({ cancelLabel, dispatch, drawerFilterDescription, drawerFilterTitle, drawerFormDescription, drawerFormTitle, drawerMoreActionsDescription, drawerMoreActionsTitle, drawerViewDescription, drawerViewTitle, labelActions, labelCode, labelEnabled, labelId, labelSection, labelSubject, labelTeacher, saveLabel, searchPlaceholder, tableDescription, tableTitle, }) => {
|
|
72
|
+
const createCourseConfig = ({ cancelLabel, dispatch, drawerFilterDescription, drawerFilterTitle, drawerFormDescription, drawerFormTitle, drawerMoreActionsDescription, drawerMoreActionsTitle, drawerViewDescription, drawerViewTitle, labelActions, labelClass, labelCode, labelEnabled, labelId, labelSection, labelSubject, labelTeacher, saveLabel, searchPlaceholder, tableDescription, tableTitle, }) => {
|
|
65
73
|
const components = createComponentInstances();
|
|
66
74
|
return {
|
|
67
75
|
moduleName: "course",
|
|
68
76
|
tableColumns: [
|
|
69
77
|
{ label: labelId, width: "5%" },
|
|
70
|
-
{ label: labelCode, width: "
|
|
71
|
-
{ label:
|
|
72
|
-
{ label:
|
|
73
|
-
{ label:
|
|
78
|
+
{ label: labelCode, width: "15%" },
|
|
79
|
+
{ label: labelClass, width: "15%" },
|
|
80
|
+
{ label: labelSection, width: "15%" },
|
|
81
|
+
{ label: labelSubject, width: "15%" },
|
|
82
|
+
{ label: labelTeacher, width: "15%" },
|
|
74
83
|
{ label: labelEnabled, width: "10%" },
|
|
75
84
|
{ label: labelActions, width: "5%" },
|
|
76
85
|
],
|
|
@@ -114,6 +123,7 @@ const CoursePageInner = (props) => {
|
|
|
114
123
|
drawerMoreActionsTitle: props.drawerMoreActionsTitle,
|
|
115
124
|
drawerMoreActionsDescription: props.drawerMoreActionsDescription,
|
|
116
125
|
labelActions: props.labelActions,
|
|
126
|
+
labelClass: props.labelClass,
|
|
117
127
|
labelCode: props.labelCode,
|
|
118
128
|
labelEnabled: props.labelEnabled,
|
|
119
129
|
labelId: props.labelId,
|
|
@@ -136,6 +146,7 @@ const CoursePageInner = (props) => {
|
|
|
136
146
|
props.drawerMoreActionsTitle,
|
|
137
147
|
props.drawerMoreActionsDescription,
|
|
138
148
|
props.labelActions,
|
|
149
|
+
props.labelClass,
|
|
139
150
|
props.labelCode,
|
|
140
151
|
props.labelEnabled,
|
|
141
152
|
props.labelId,
|
|
@@ -8,6 +8,7 @@ import { z } from "zod";
|
|
|
8
8
|
// VALIDATION SCHEMA
|
|
9
9
|
// ============================================================================
|
|
10
10
|
export const courseFormValidation = z.object({
|
|
11
|
+
classId: z.string().min(1, "Class is required"),
|
|
11
12
|
code: z.string().min(1, "Course code is required"),
|
|
12
13
|
sectionId: z.string().min(1, "Section is required"),
|
|
13
14
|
subjectId: z.string().min(1, "Subject is required"),
|
|
@@ -10,6 +10,7 @@ import { Badge } from "@appcorp/shadcn/components/ui/badge";
|
|
|
10
10
|
import { Separator } from "@appcorp/shadcn/components/ui/separator";
|
|
11
11
|
import { BookMarked, CheckCircle2, XCircle } from "lucide-react";
|
|
12
12
|
import { useCourseModule } from "./context";
|
|
13
|
+
import { getCachedClassesSync } from "../class/cache";
|
|
13
14
|
import { getCachedSectionsSync } from "../section/cache";
|
|
14
15
|
import { getCachedSubjectsSync } from "../subject/cache";
|
|
15
16
|
import { getCachedTeachersSync } from "../teacher/cache";
|
|
@@ -19,10 +20,13 @@ export const CourseView = () => {
|
|
|
19
20
|
var _a, _b, _c, _d, _e;
|
|
20
21
|
const t = useTranslations("course");
|
|
21
22
|
const { state } = useCourseModule();
|
|
22
|
-
const { code, enabled, sectionId, subjectId, teacherId } = state;
|
|
23
|
+
const { classId, code, enabled, sectionId, subjectId, teacherId } = state;
|
|
24
|
+
const classes = getCachedClassesSync().items;
|
|
23
25
|
const sections = getCachedSectionsSync().items;
|
|
24
26
|
const subjects = getCachedSubjectsSync().items;
|
|
25
27
|
const teachers = getCachedTeachersSync().items;
|
|
28
|
+
const cls = classes.find((c) => c.id === classId);
|
|
29
|
+
const className = cls ? `${cls.name} (${cls.code})` : (classId !== null && classId !== void 0 ? classId : "—");
|
|
26
30
|
const section = sections.find((s) => s.id === sectionId);
|
|
27
31
|
const sectionName = section
|
|
28
32
|
? ((_a = section.class) === null || _a === void 0 ? void 0 : _a.code)
|
|
@@ -36,7 +40,7 @@ export const CourseView = () => {
|
|
|
36
40
|
teacher.teacherCode ||
|
|
37
41
|
"—"
|
|
38
42
|
: "—";
|
|
39
|
-
return (_jsxs("div", { className: "space-y-4", children: [_jsx(Card, { children: _jsx(CardContent, { className: "pt-6", children: _jsxs("div", { className: "flex items-center gap-6", children: [_jsx("div", { className: "bg-primary/10 flex h-24 w-24 items-center justify-center rounded-full", children: _jsx(BookMarked, { className: "text-primary h-12 w-12" }) }), _jsxs("div", { className: "flex-1", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("h2", { className: "text-2xl font-bold", children: formatValue(code) }), enabled ? (_jsx(CheckCircle2, { className: "h-5 w-5 text-green-500" })) : (_jsx(XCircle, { className: "h-5 w-5 text-red-500" }))] }),
|
|
43
|
+
return (_jsxs("div", { className: "space-y-4", children: [_jsx(Card, { children: _jsx(CardContent, { className: "pt-6", children: _jsxs("div", { className: "flex items-center gap-6", children: [_jsx("div", { className: "bg-primary/10 flex h-24 w-24 items-center justify-center rounded-full", children: _jsx(BookMarked, { className: "text-primary h-12 w-12" }) }), _jsxs("div", { className: "flex-1", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("h2", { className: "text-2xl font-bold", children: formatValue(code) }), enabled ? (_jsx(CheckCircle2, { className: "h-5 w-5 text-green-500" })) : (_jsx(XCircle, { className: "h-5 w-5 text-red-500" }))] }), _jsxs("p", { className: "text-muted-foreground mt-1", children: [className, " \u2014 ", sectionName] })] })] }) }) }), _jsxs(Card, { children: [_jsxs(CardHeader, { className: "pb-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(BookMarked, { className: "text-primary h-5 w-5" }), _jsx(CardTitle, { className: "text-lg", children: t("viewSectionCourseDetails") })] }), _jsx(CardDescription, { children: t("viewSectionCompleteCourseInformation") })] }), _jsx(Separator, {}), _jsx(CardContent, { className: "pt-6", children: _jsxs("div", { className: "grid grid-cols-1 gap-6 md:grid-cols-2", children: [_jsxs("div", { className: "space-y-1", children: [_jsx("p", { className: "text-muted-foreground text-sm font-medium", children: t("viewFieldCourseCode") }), _jsx("p", { className: "text-base", children: formatValue(code) })] }), _jsxs("div", { className: "space-y-1", children: [_jsx("p", { className: "text-muted-foreground text-sm font-medium", children: t("labelClass") }), _jsx("p", { className: "text-base", children: className })] }), _jsxs("div", { className: "space-y-1", children: [_jsx("p", { className: "text-muted-foreground text-sm font-medium", children: t("section") }), _jsx("p", { className: "text-base", children: sectionName })] }), _jsxs("div", { className: "space-y-1", children: [_jsx("p", { className: "text-muted-foreground text-sm font-medium", children: t("viewFieldSubject") }), _jsx("p", { className: "text-base", children: subjectName })] }), _jsxs("div", { className: "space-y-1", children: [_jsx("p", { className: "text-muted-foreground text-sm font-medium", children: t("viewFieldTeacher") }), _jsx("p", { className: "text-base", children: teacherName })] }), _jsxs("div", { className: "space-y-1", children: [_jsx("p", { className: "text-muted-foreground text-sm font-medium", children: t("viewFieldStatus") }), _jsx(Badge, { variant: enabled ? "default" : "secondary", children: enabled
|
|
40
44
|
? t("viewFieldStatusActive")
|
|
41
45
|
: t("viewFieldStatusInactive") })] })] }) })] })] }));
|
|
42
46
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type RowAction, type TableRow } from "@appcorp/shadcn/components/enhanced-table";
|
|
2
|
-
import { EnrollmentBE, SectionBE, StudentProfileBE } from "../../type";
|
|
2
|
+
import { ClassBE, EnrollmentBE, SectionBE, StudentProfileBE } from "../../type";
|
|
3
3
|
export declare const ENROLLMENT_DRAWER: {
|
|
4
4
|
readonly FILTER_DRAWER: string;
|
|
5
5
|
readonly FORM_DRAWER: string;
|
|
@@ -26,6 +26,7 @@ export declare const ENROLLMENT_ACTION_TYPES: {
|
|
|
26
26
|
searchQuery: string;
|
|
27
27
|
disableSaveButton: boolean;
|
|
28
28
|
drawer: string | null;
|
|
29
|
+
classId: string;
|
|
29
30
|
enabled: boolean;
|
|
30
31
|
enrollmentDate: string;
|
|
31
32
|
errors: Record<string, string>;
|
|
@@ -33,6 +34,7 @@ export declare const ENROLLMENT_ACTION_TYPES: {
|
|
|
33
34
|
id: string;
|
|
34
35
|
sectionId: string;
|
|
35
36
|
studentProfileId: string;
|
|
37
|
+
class: ClassBE | undefined;
|
|
36
38
|
section: SectionBE | undefined;
|
|
37
39
|
studentProfile: StudentProfileBE | undefined;
|
|
38
40
|
}>, initialEnrollmentState: {
|
|
@@ -43,6 +45,7 @@ export declare const ENROLLMENT_ACTION_TYPES: {
|
|
|
43
45
|
searchQuery: string;
|
|
44
46
|
disableSaveButton: boolean;
|
|
45
47
|
drawer: string | null;
|
|
48
|
+
classId: string;
|
|
46
49
|
enabled: boolean;
|
|
47
50
|
enrollmentDate: string;
|
|
48
51
|
errors: Record<string, string>;
|
|
@@ -50,6 +53,7 @@ export declare const ENROLLMENT_ACTION_TYPES: {
|
|
|
50
53
|
id: string;
|
|
51
54
|
sectionId: string;
|
|
52
55
|
studentProfileId: string;
|
|
56
|
+
class: ClassBE | undefined;
|
|
53
57
|
section: SectionBE | undefined;
|
|
54
58
|
studentProfile: StudentProfileBE | undefined;
|
|
55
59
|
}, EnrollmentProvider: import("react").FC<{
|
|
@@ -62,6 +66,7 @@ export declare const ENROLLMENT_ACTION_TYPES: {
|
|
|
62
66
|
searchQuery: string;
|
|
63
67
|
disableSaveButton: boolean;
|
|
64
68
|
drawer: string | null;
|
|
69
|
+
classId: string;
|
|
65
70
|
enabled: boolean;
|
|
66
71
|
enrollmentDate: string;
|
|
67
72
|
errors: Record<string, string>;
|
|
@@ -69,6 +74,7 @@ export declare const ENROLLMENT_ACTION_TYPES: {
|
|
|
69
74
|
id: string;
|
|
70
75
|
sectionId: string;
|
|
71
76
|
studentProfileId: string;
|
|
77
|
+
class: ClassBE | undefined;
|
|
72
78
|
section: SectionBE | undefined;
|
|
73
79
|
studentProfile: StudentProfileBE | undefined;
|
|
74
80
|
}, action: any) => {
|
|
@@ -79,6 +85,7 @@ export declare const ENROLLMENT_ACTION_TYPES: {
|
|
|
79
85
|
searchQuery: string;
|
|
80
86
|
disableSaveButton: boolean;
|
|
81
87
|
drawer: string | null;
|
|
88
|
+
classId: string;
|
|
82
89
|
enabled: boolean;
|
|
83
90
|
enrollmentDate: string;
|
|
84
91
|
errors: Record<string, string>;
|
|
@@ -86,6 +93,7 @@ export declare const ENROLLMENT_ACTION_TYPES: {
|
|
|
86
93
|
id: string;
|
|
87
94
|
sectionId: string;
|
|
88
95
|
studentProfileId: string;
|
|
96
|
+
class: ClassBE | undefined;
|
|
89
97
|
section: SectionBE | undefined;
|
|
90
98
|
studentProfile: StudentProfileBE | undefined;
|
|
91
99
|
}, useEnrollmentContext: () => import("@react-pakistan/util-functions/factory/generic-module-factory").GenericModuleContextWithHandlers<{
|
|
@@ -96,6 +104,7 @@ export declare const ENROLLMENT_ACTION_TYPES: {
|
|
|
96
104
|
searchQuery: string;
|
|
97
105
|
disableSaveButton: boolean;
|
|
98
106
|
drawer: string | null;
|
|
107
|
+
classId: string;
|
|
99
108
|
enabled: boolean;
|
|
100
109
|
enrollmentDate: string;
|
|
101
110
|
errors: Record<string, string>;
|
|
@@ -103,6 +112,7 @@ export declare const ENROLLMENT_ACTION_TYPES: {
|
|
|
103
112
|
id: string;
|
|
104
113
|
sectionId: string;
|
|
105
114
|
studentProfileId: string;
|
|
115
|
+
class: ClassBE | undefined;
|
|
106
116
|
section: SectionBE | undefined;
|
|
107
117
|
studentProfile: StudentProfileBE | undefined;
|
|
108
118
|
}>;
|
|
@@ -143,6 +153,7 @@ export declare const useEnrollmentModule: () => {
|
|
|
143
153
|
searchQuery: string;
|
|
144
154
|
disableSaveButton: boolean;
|
|
145
155
|
drawer: string | null;
|
|
156
|
+
classId: string;
|
|
146
157
|
enabled: boolean;
|
|
147
158
|
enrollmentDate: string;
|
|
148
159
|
errors: Record<string, string>;
|
|
@@ -150,6 +161,7 @@ export declare const useEnrollmentModule: () => {
|
|
|
150
161
|
id: string;
|
|
151
162
|
sectionId: string;
|
|
152
163
|
studentProfileId: string;
|
|
164
|
+
class: ClassBE | undefined;
|
|
153
165
|
section: SectionBE | undefined;
|
|
154
166
|
studentProfile: StudentProfileBE | undefined;
|
|
155
167
|
};
|
|
@@ -54,6 +54,7 @@ const enrollmentConfig = {
|
|
|
54
54
|
disableSaveButton: false,
|
|
55
55
|
drawer: null,
|
|
56
56
|
// Form State
|
|
57
|
+
classId: "",
|
|
57
58
|
enabled: true,
|
|
58
59
|
enrollmentDate: new Date().toISOString().split("T")[0],
|
|
59
60
|
errors: {},
|
|
@@ -62,6 +63,7 @@ const enrollmentConfig = {
|
|
|
62
63
|
sectionId: "",
|
|
63
64
|
studentProfileId: "",
|
|
64
65
|
// Relations (populated from byId fetch)
|
|
66
|
+
class: undefined,
|
|
65
67
|
section: undefined,
|
|
66
68
|
studentProfile: undefined,
|
|
67
69
|
},
|
|
@@ -100,6 +102,7 @@ export const useEnrollmentModule = () => {
|
|
|
100
102
|
debouncedQuery,
|
|
101
103
|
]);
|
|
102
104
|
const updateParams = useMemo(() => ({
|
|
105
|
+
classId: state.classId,
|
|
103
106
|
enabled: state.enabled,
|
|
104
107
|
enrollmentDate: state.enrollmentDate,
|
|
105
108
|
id: state.id,
|
|
@@ -15,7 +15,7 @@ import { useEnhancedCombobox } from "@appcorp/shadcn/hooks/use-enhanced-combobox
|
|
|
15
15
|
import { Separator } from "@appcorp/shadcn/components/ui/separator";
|
|
16
16
|
import { API_METHODS, DATE_FORMATS, formatDate, } from "@react-pakistan/util-functions";
|
|
17
17
|
import { useEnrollmentModule } from "./context";
|
|
18
|
-
import { SECTION_API_ROUTES, STUDENT_PROFILE_API_ROUTES, } from "../../constants";
|
|
18
|
+
import { CLASS_API_ROUTES, SECTION_API_ROUTES, STUDENT_PROFILE_API_ROUTES, } from "../../constants";
|
|
19
19
|
import { useTranslations } from "next-intl";
|
|
20
20
|
import { useFetch } from "@react-pakistan/util-functions/hooks/use-fetch";
|
|
21
21
|
import { useEffect } from "react";
|
|
@@ -24,13 +24,17 @@ import { getCachedWorkspaceSync } from "../workspace/cache";
|
|
|
24
24
|
// COMPONENT
|
|
25
25
|
// ============================================================================
|
|
26
26
|
export const EnrollmentForm = () => {
|
|
27
|
-
const { state: { enabled, enrollmentDate, errors, sectionId, studentProfileId }, handleChange, } = useEnrollmentModule();
|
|
27
|
+
const { state: { classId, enabled, enrollmentDate, errors, sectionId, studentProfileId }, handleChange, } = useEnrollmentModule();
|
|
28
28
|
const workspace = getCachedWorkspaceSync();
|
|
29
29
|
const t = useTranslations("enrollment");
|
|
30
30
|
const { fetchNow: studentProfileFetchNow, data: studentProfileData } = useFetch(STUDENT_PROFILE_API_ROUTES.UNIT, {
|
|
31
31
|
method: API_METHODS.GET,
|
|
32
32
|
params: { workspaceId: workspace === null || workspace === void 0 ? void 0 : workspace.id },
|
|
33
33
|
});
|
|
34
|
+
const { fetchNow: classFetchNow, data: classData } = useFetch(CLASS_API_ROUTES.UNIT, {
|
|
35
|
+
method: API_METHODS.GET,
|
|
36
|
+
params: { workspaceId: workspace === null || workspace === void 0 ? void 0 : workspace.id },
|
|
37
|
+
});
|
|
34
38
|
const { fetchNow: sectionFetchNow, data: sectionData } = useFetch(SECTION_API_ROUTES.UNIT, {
|
|
35
39
|
method: API_METHODS.GET,
|
|
36
40
|
params: { workspaceId: workspace === null || workspace === void 0 ? void 0 : workspace.id },
|
|
@@ -38,6 +42,7 @@ export const EnrollmentForm = () => {
|
|
|
38
42
|
useEffect(() => {
|
|
39
43
|
if (workspace === null || workspace === void 0 ? void 0 : workspace.id) {
|
|
40
44
|
studentProfileFetchNow();
|
|
45
|
+
classFetchNow();
|
|
41
46
|
sectionFetchNow();
|
|
42
47
|
}
|
|
43
48
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
@@ -69,6 +74,29 @@ export const EnrollmentForm = () => {
|
|
|
69
74
|
},
|
|
70
75
|
value: studentProfileId || "",
|
|
71
76
|
});
|
|
77
|
+
const { enhancedComboboxElement: classIdCombo } = useEnhancedCombobox({
|
|
78
|
+
emptyText: t("formNoClassEmpty"),
|
|
79
|
+
id: "classId",
|
|
80
|
+
info: t("formClassInfo"),
|
|
81
|
+
label: t("formClassLabel"),
|
|
82
|
+
onValueChange: (value) => handleChange("classId", value),
|
|
83
|
+
options: ((classData === null || classData === void 0 ? void 0 : classData.items) || []).map((c) => ({
|
|
84
|
+
value: c.id,
|
|
85
|
+
label: `${c.name} (${c.code})`,
|
|
86
|
+
})),
|
|
87
|
+
placeholder: t("formClassPlaceholder"),
|
|
88
|
+
required: true,
|
|
89
|
+
searchEndpoint: CLASS_API_ROUTES.UNIT,
|
|
90
|
+
searchPlaceholder: t("formSearchClassPlaceholder"),
|
|
91
|
+
formatSearchResult: (item) => {
|
|
92
|
+
const cls = Object.assign({}, item);
|
|
93
|
+
return {
|
|
94
|
+
label: `${cls.name} (${cls.code})`,
|
|
95
|
+
value: cls.id,
|
|
96
|
+
};
|
|
97
|
+
},
|
|
98
|
+
value: classId || "",
|
|
99
|
+
});
|
|
72
100
|
const { enhancedComboboxElement: sectionIdCombo } = useEnhancedCombobox({
|
|
73
101
|
emptyText: t("formNoSectionEmpty"),
|
|
74
102
|
id: "sectionId",
|
|
@@ -98,5 +126,5 @@ export const EnrollmentForm = () => {
|
|
|
98
126
|
});
|
|
99
127
|
return (_jsxs("div", { className: "space-y-4", children: [_jsx(EnhancedInput, { error: errors.enrollmentDate, id: "enrollmentDate", info: t("formEnrollmentDateInfo"), label: t("formEnrollmentDateLabel"), onChange: (e) => handleChange("enrollmentDate", e.target.value), placeholder: t("formEnrollmentDatePlaceholder"), required: true, type: "date", value: enrollmentDate
|
|
100
128
|
? formatDate(enrollmentDate, DATE_FORMATS.YYYY_MM_DD)
|
|
101
|
-
: "" }), _jsx(Separator, {}), studentProfileIdCombo, sectionIdCombo, _jsx(EnhancedCheckbox, { checked: enabled, error: errors.enabled, id: "enabled", info: t("actionToggleEnableOrDisableEnrollment"), label: t("formActiveEnrollmentLabel"), onCheckedChange: (checked) => handleChange("enabled", checked) })] }));
|
|
129
|
+
: "" }), _jsx(Separator, {}), studentProfileIdCombo, classIdCombo, sectionIdCombo, _jsx(EnhancedCheckbox, { checked: enabled, error: errors.enabled, id: "enabled", info: t("actionToggleEnableOrDisableEnrollment"), label: t("formActiveEnrollmentLabel"), onCheckedChange: (checked) => handleChange("enabled", checked) })] }));
|
|
102
130
|
};
|
|
@@ -91,7 +91,7 @@ export const EnrollmentMoreActions = () => {
|
|
|
91
91
|
};
|
|
92
92
|
}, []);
|
|
93
93
|
const handleBulkFlow = useCallback(async (files, method) => {
|
|
94
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
94
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
95
95
|
const closeDrawer = () => {
|
|
96
96
|
dispatch({
|
|
97
97
|
type: ENROLLMENT_ACTION_TYPES.SET_DRAWER,
|
|
@@ -120,13 +120,15 @@ export const EnrollmentMoreActions = () => {
|
|
|
120
120
|
if (method === "POST") {
|
|
121
121
|
if (!((_b = row.studentProfileId) === null || _b === void 0 ? void 0 : _b.trim()))
|
|
122
122
|
msgs.push(t("validationRequiredStudentProfileId"));
|
|
123
|
-
if (!((_c = row.
|
|
123
|
+
if (!((_c = row.classId) === null || _c === void 0 ? void 0 : _c.trim()))
|
|
124
|
+
msgs.push(t("validationRequiredClassId"));
|
|
125
|
+
if (!((_d = row.sectionId) === null || _d === void 0 ? void 0 : _d.trim()))
|
|
124
126
|
msgs.push(t("validationRequiredSectionId"));
|
|
125
|
-
if (!((
|
|
127
|
+
if (!((_e = row.enrollmentDate) === null || _e === void 0 ? void 0 : _e.trim()))
|
|
126
128
|
msgs.push(t("validationRequiredEnrollmentDate"));
|
|
127
129
|
}
|
|
128
130
|
else {
|
|
129
|
-
if (!((
|
|
131
|
+
if (!((_f = row.id) === null || _f === void 0 ? void 0 : _f.trim()))
|
|
130
132
|
msgs.push(t("validationRequiredIdForUpdate"));
|
|
131
133
|
}
|
|
132
134
|
if (msgs.length > 0) {
|
|
@@ -169,7 +171,7 @@ export const EnrollmentMoreActions = () => {
|
|
|
169
171
|
return;
|
|
170
172
|
if (status.status === "completed") {
|
|
171
173
|
const r = status.results;
|
|
172
|
-
if (r && ((
|
|
174
|
+
if (r && ((_g = r.errors) === null || _g === void 0 ? void 0 : _g.length) > 0) {
|
|
173
175
|
const summary = formatErrorSummary(t, r.errors);
|
|
174
176
|
showSuccessToast(t("messagesBulkResults", {
|
|
175
177
|
created: r.created,
|
|
@@ -189,7 +191,7 @@ export const EnrollmentMoreActions = () => {
|
|
|
189
191
|
else {
|
|
190
192
|
showSuccessToast(t("messagesBulkSuccess"));
|
|
191
193
|
}
|
|
192
|
-
const schoolId = ((
|
|
194
|
+
const schoolId = ((_h = workspace === null || workspace === void 0 ? void 0 : workspace.school) === null || _h === void 0 ? void 0 : _h.id) || "";
|
|
193
195
|
fetch(`${ENROLLMENT_API_ROUTES.LIST}?currentPage=1&pageLimit=${pageLimit}&schoolId=${schoolId}`, {
|
|
194
196
|
headers: {
|
|
195
197
|
"Content-Type": "application/json",
|
|
@@ -213,7 +215,7 @@ export const EnrollmentMoreActions = () => {
|
|
|
213
215
|
}
|
|
214
216
|
else {
|
|
215
217
|
const r = status.results;
|
|
216
|
-
const detail = ((
|
|
218
|
+
const detail = ((_j = r === null || r === void 0 ? void 0 : r.errors) === null || _j === void 0 ? void 0 : _j.length)
|
|
217
219
|
? formatErrorSummary(t, r.errors)
|
|
218
220
|
: t("unknownError");
|
|
219
221
|
showErrorToast(t("messagesBulkFailed", { action: label }) + "\n" + detail);
|
|
@@ -34,6 +34,14 @@ const tableBodyCols = [
|
|
|
34
34
|
key: "studentProfile",
|
|
35
35
|
textFormatter: (_, row) => { var _a, _b; return (_b = (_a = row.studentProfile) === null || _a === void 0 ? void 0 : _a.studentCode) !== null && _b !== void 0 ? _b : "N/A"; },
|
|
36
36
|
},
|
|
37
|
+
{
|
|
38
|
+
componentType: COMPONENT_TYPE.TEXT,
|
|
39
|
+
key: "class",
|
|
40
|
+
textFormatter: (_, row) => {
|
|
41
|
+
const cls = row.class;
|
|
42
|
+
return cls ? `${cls.name} (${cls.code})` : "N/A";
|
|
43
|
+
},
|
|
44
|
+
},
|
|
37
45
|
{
|
|
38
46
|
componentType: COMPONENT_TYPE.TEXT,
|
|
39
47
|
key: "section",
|
|
@@ -64,16 +72,17 @@ const createComponentInstances = () => ({
|
|
|
64
72
|
moreActions: _jsx(EnrollmentMoreActions, {}),
|
|
65
73
|
view: _jsx(EnrollmentView, {}),
|
|
66
74
|
});
|
|
67
|
-
const createEnrollmentConfig = ({ cancelLabel, dispatch, drawerFilterDescription, drawerFilterTitle, drawerFormDescription, drawerFormTitle, drawerMoreActionsDescription, drawerMoreActionsTitle, drawerViewDescription, drawerViewTitle, labelActions, labelEnabled, labelEnrollmentDate, labelId, labelSection, labelStudent, saveLabel, searchPlaceholder, tableDescription, tableTitle, }) => {
|
|
75
|
+
const createEnrollmentConfig = ({ cancelLabel, dispatch, drawerFilterDescription, drawerFilterTitle, drawerFormDescription, drawerFormTitle, drawerMoreActionsDescription, drawerMoreActionsTitle, drawerViewDescription, drawerViewTitle, labelActions, labelClass, labelEnabled, labelEnrollmentDate, labelId, labelSection, labelStudent, saveLabel, searchPlaceholder, tableDescription, tableTitle, }) => {
|
|
68
76
|
const components = createComponentInstances();
|
|
69
77
|
return {
|
|
70
78
|
moduleName: "enrollment",
|
|
71
79
|
tableColumns: [
|
|
72
80
|
{ label: labelId, width: "5%" },
|
|
73
|
-
{ label: labelStudent, width: "
|
|
74
|
-
{ label:
|
|
81
|
+
{ label: labelStudent, width: "20%" },
|
|
82
|
+
{ label: labelClass, width: "15%" },
|
|
83
|
+
{ label: labelSection, width: "20%" },
|
|
75
84
|
{ label: labelEnrollmentDate, width: "20%" },
|
|
76
|
-
{ label: labelEnabled, width: "
|
|
85
|
+
{ label: labelEnabled, width: "10%" },
|
|
77
86
|
{ label: labelActions, width: "5%" },
|
|
78
87
|
],
|
|
79
88
|
cancelLabel,
|
|
@@ -116,6 +125,7 @@ const EnrollmentPageInner = (props) => {
|
|
|
116
125
|
drawerMoreActionsTitle: props.drawerMoreActionsTitle,
|
|
117
126
|
drawerMoreActionsDescription: props.drawerMoreActionsDescription,
|
|
118
127
|
labelActions: props.labelActions,
|
|
128
|
+
labelClass: props.labelClass,
|
|
119
129
|
labelEnabled: props.labelEnabled,
|
|
120
130
|
labelEnrollmentDate: props.labelEnrollmentDate,
|
|
121
131
|
labelId: props.labelId,
|
|
@@ -137,6 +147,7 @@ const EnrollmentPageInner = (props) => {
|
|
|
137
147
|
props.drawerMoreActionsTitle,
|
|
138
148
|
props.drawerMoreActionsDescription,
|
|
139
149
|
props.labelActions,
|
|
150
|
+
props.labelClass,
|
|
140
151
|
props.labelEnabled,
|
|
141
152
|
props.labelEnrollmentDate,
|
|
142
153
|
props.labelId,
|