@appcorp/fusion-storybook 0.2.91 → 0.2.94
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/admission/context/use-admission-module.js +21 -19
- package/base-modules/admission/validate.d.ts +5 -5
- package/base-modules/admission/validate.js +13 -5
- package/base-modules/campus/context.js +40 -21
- package/base-modules/campus/form.js +5 -1
- package/base-modules/campus/validate.d.ts +1 -1
- package/base-modules/campus/validate.js +3 -1
- package/base-modules/family-member/context.js +28 -23
- package/base-modules/family-member/form.js +8 -1
- package/base-modules/family-member/validate.d.ts +3 -3
- package/base-modules/family-member/validate.js +5 -3
- package/base-modules/school/context.js +24 -19
- package/base-modules/school/form.js +5 -1
- package/base-modules/school/validate.d.ts +1 -1
- package/base-modules/school/validate.js +6 -1
- package/base-modules/student-fee/form.js +1 -1
- package/base-modules/student-profile/context/use-student-profile-module.js +33 -27
- package/base-modules/student-profile/form.js +8 -1
- package/base-modules/student-profile/validate.d.ts +2 -2
- package/base-modules/student-profile/validate.js +3 -4
- package/base-modules/teacher/context.js +1 -1
- package/base-modules/teacher/form.js +8 -1
- package/base-modules/teacher/validate.d.ts +2 -2
- package/base-modules/teacher/validate.js +11 -2
- package/base-modules/user/context/use-user-module.js +16 -12
- package/base-modules/user/validate.d.ts +1 -1
- package/base-modules/user/validate.js +2 -2
- package/package.json +1 -1
- package/tsconfig.build.tsbuildinfo +1 -1
- package/utils/id-number.d.ts +1 -0
- package/utils/id-number.js +10 -0
- package/utils/to-e164-phone.d.ts +1 -0
- package/utils/to-e164-phone.js +11 -0
|
@@ -29,8 +29,8 @@ import { SCHOOL_API_ROUTES } from "../../constants";
|
|
|
29
29
|
import { invalidateSchoolCache } from "./cache";
|
|
30
30
|
import { schoolFormValidation } from "./validate";
|
|
31
31
|
import { getCachedWorkspaceSync } from "../workspace/cache";
|
|
32
|
-
import { formatNumber } from "@react-pakistan/util-functions/general/format-number";
|
|
33
32
|
import { formatPhoneDisplay } from "@react-pakistan/util-functions/general/format-phone-display";
|
|
33
|
+
import { toE164Phone } from "../../utils/to-e164-phone";
|
|
34
34
|
// ============================================================================
|
|
35
35
|
// 1.1 DRAWER TYPES
|
|
36
36
|
// ============================================================================
|
|
@@ -79,6 +79,7 @@ export const { actionTypes: SCHOOL_ACTION_TYPES, config: schoolModuleConfig, ini
|
|
|
79
79
|
// 1.4 ENHANCED SCHOOL HOOK WITH API INTEGRATION
|
|
80
80
|
// ============================================================================
|
|
81
81
|
export const useSchoolModule = () => {
|
|
82
|
+
var _a;
|
|
82
83
|
// ============================================================================
|
|
83
84
|
// 1.4.1 STATE & CORE HOOKS
|
|
84
85
|
// ============================================================================
|
|
@@ -91,24 +92,27 @@ export const useSchoolModule = () => {
|
|
|
91
92
|
// ============================================================================
|
|
92
93
|
// 1.4.2 API PARAMETERS
|
|
93
94
|
// ============================================================================
|
|
94
|
-
const updateParams = useMemo(() =>
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
95
|
+
const updateParams = useMemo(() => {
|
|
96
|
+
var _a;
|
|
97
|
+
return ({
|
|
98
|
+
address: state.address,
|
|
99
|
+
city: state.city,
|
|
100
|
+
code: state.code,
|
|
101
|
+
country: state.country,
|
|
102
|
+
currency: state.currency,
|
|
103
|
+
email: state.email,
|
|
104
|
+
enabled: state.enabled,
|
|
105
|
+
id: state.id,
|
|
106
|
+
logo: state.logo,
|
|
107
|
+
name: state.name,
|
|
108
|
+
phone: toE164Phone(state.phone, (_a = workspace === null || workspace === void 0 ? void 0 : workspace.school) === null || _a === void 0 ? void 0 : _a.country),
|
|
109
|
+
postalCode: state.postalCode,
|
|
110
|
+
principalId: state.principalId,
|
|
111
|
+
state: state.state,
|
|
112
|
+
website: state.website,
|
|
113
|
+
workspaceId: (workspace === null || workspace === void 0 ? void 0 : workspace.id) || "",
|
|
114
|
+
});
|
|
115
|
+
}, [
|
|
112
116
|
state.address,
|
|
113
117
|
state.city,
|
|
114
118
|
state.code,
|
|
@@ -125,6 +129,7 @@ export const useSchoolModule = () => {
|
|
|
125
129
|
state.state,
|
|
126
130
|
state.website,
|
|
127
131
|
workspace === null || workspace === void 0 ? void 0 : workspace.id,
|
|
132
|
+
(_a = workspace === null || workspace === void 0 ? void 0 : workspace.school) === null || _a === void 0 ? void 0 : _a.country,
|
|
128
133
|
]);
|
|
129
134
|
const byIdParams = useMemo(() => ({}), []);
|
|
130
135
|
const deleteParams = useMemo(() => ({}), []);
|
|
@@ -12,6 +12,7 @@ import { useSchoolModule } from "./context";
|
|
|
12
12
|
import { CURRENCY } from "../../type";
|
|
13
13
|
import { SCHOOL_API_ROUTES } from "../../constants";
|
|
14
14
|
import { useTranslations } from "next-intl";
|
|
15
|
+
import { formatPhone } from "@react-pakistan/util-functions/general/format-phone";
|
|
15
16
|
import { getTranslatedError } from "../../utils/get-translated-error";
|
|
16
17
|
export const SchoolForm = () => {
|
|
17
18
|
const t = useTranslations("school");
|
|
@@ -57,5 +58,8 @@ export const SchoolForm = () => {
|
|
|
57
58
|
// searchPlaceholder: t("formPrincipalSearchPlaceholder"),
|
|
58
59
|
// value: principalId || "",
|
|
59
60
|
// });
|
|
60
|
-
return (_jsxs("div", { className: "space-y-6", children: [_jsxs("div", { className: "grid grid-cols-1 gap-4", children: [_jsx(EnhancedInput, { id: "name", label: t("formNameLabel"), value: name, onChange: (e) => handleChange("name", e.target.value), error: getTranslatedError({ errors, key: "name", t }), placeholder: t("formNamePlaceholder"), required: true }), _jsx(EnhancedInput, { id: "code", label: t("formCodeLabel"), value: code, onChange: (e) => handleChange("code", e.target.value), error: getTranslatedError({ errors, key: "code", t }), placeholder: t("formCodePlaceholder"), required: true, info: t("formCodeInfo") }), currencyCombo, _jsx(EnhancedInput, { id: "address", label: t("formAddressLabel"), value: address || "", onChange: (e) => handleChange("address", e.target.value), error: getTranslatedError({ errors, key: "address", t }), placeholder: t("formAddressPlaceholder") }), _jsx(EnhancedInput, { id: "city", label: t("formCityLabel"), value: city || "", onChange: (e) => handleChange("city", e.target.value), error: getTranslatedError({ errors, key: "city", t }), placeholder: t("formCityPlaceholder") }), _jsx(EnhancedInput, { id: "state", label: t("formStateLabel"), value: stateField || "", onChange: (e) => handleChange("state", e.target.value), error: getTranslatedError({ errors, key: "state", t }), placeholder: t("formStatePlaceholder") }), _jsx(EnhancedInput, { id: "country", label: t("formCountryLabel"), value: country || "", onChange: (e) => handleChange("country", e.target.value), error: getTranslatedError({ errors, key: "country", t }), placeholder: t("formCountryPlaceholder") }), _jsx(EnhancedInput, { id: "postalCode", label: t("formPostalCodeLabel"), value: postalCode || "", onChange: (e) => handleChange("postalCode", e.target.value), error: getTranslatedError({ errors, key: "postalCode", t }), placeholder: t("formPostalCodePlaceholder") }), _jsx(EnhancedInput, { id: "phone", label: t("formPhoneLabel"), value: phone || "", onChange: (e) =>
|
|
61
|
+
return (_jsxs("div", { className: "space-y-6", children: [_jsxs("div", { className: "grid grid-cols-1 gap-4", children: [_jsx(EnhancedInput, { id: "name", label: t("formNameLabel"), value: name, onChange: (e) => handleChange("name", e.target.value), error: getTranslatedError({ errors, key: "name", t }), placeholder: t("formNamePlaceholder"), required: true }), _jsx(EnhancedInput, { id: "code", label: t("formCodeLabel"), value: code, onChange: (e) => handleChange("code", e.target.value), error: getTranslatedError({ errors, key: "code", t }), placeholder: t("formCodePlaceholder"), required: true, info: t("formCodeInfo") }), currencyCombo, _jsx(EnhancedInput, { id: "address", label: t("formAddressLabel"), value: address || "", onChange: (e) => handleChange("address", e.target.value), error: getTranslatedError({ errors, key: "address", t }), placeholder: t("formAddressPlaceholder") }), _jsx(EnhancedInput, { id: "city", label: t("formCityLabel"), value: city || "", onChange: (e) => handleChange("city", e.target.value), error: getTranslatedError({ errors, key: "city", t }), placeholder: t("formCityPlaceholder") }), _jsx(EnhancedInput, { id: "state", label: t("formStateLabel"), value: stateField || "", onChange: (e) => handleChange("state", e.target.value), error: getTranslatedError({ errors, key: "state", t }), placeholder: t("formStatePlaceholder") }), _jsx(EnhancedInput, { id: "country", label: t("formCountryLabel"), value: country || "", onChange: (e) => handleChange("country", e.target.value), error: getTranslatedError({ errors, key: "country", t }), placeholder: t("formCountryPlaceholder") }), _jsx(EnhancedInput, { id: "postalCode", label: t("formPostalCodeLabel"), value: postalCode || "", onChange: (e) => handleChange("postalCode", e.target.value), error: getTranslatedError({ errors, key: "postalCode", t }), placeholder: t("formPostalCodePlaceholder") }), _jsx(EnhancedInput, { id: "phone", label: t("formPhoneLabel"), value: phone || "", onChange: (e) => {
|
|
62
|
+
var _a;
|
|
63
|
+
return handleChange("phone", ((_a = formatPhone(e.target.value)) === null || _a === void 0 ? void 0 : _a.international) || e.target.value);
|
|
64
|
+
}, error: getTranslatedError({ errors, key: "phone", t }), placeholder: t("formPhonePlaceholder"), type: "tel" }), _jsx(EnhancedInput, { id: "email", label: t("formEmailLabel"), value: email || "", onChange: (e) => handleChange("email", e.target.value), error: getTranslatedError({ errors, key: "email", t }), placeholder: t("formEmailPlaceholder"), type: "email" })] }), _jsx(EnhancedInput, { id: "website", label: t("formWebsiteLabel"), value: website || "", onChange: (e) => handleChange("website", e.target.value), error: getTranslatedError({ errors, key: "website", t }), placeholder: t("formWebsitePlaceholder"), type: "url" }), _jsx(EnhancedInput, { id: "logo", label: t("formLogoLabel"), value: logo || "", onChange: (e) => handleChange("logo", e.target.value), error: getTranslatedError({ errors, key: "logo", t }), placeholder: t("formLogoPlaceholder"), type: "url" }), _jsx(EnhancedCheckbox, { id: "enabled", label: t("formEnabledLabel"), checked: enabled, error: getTranslatedError({ errors, key: "enabled", t }), onCheckedChange: (checked) => handleChange("enabled", checked), info: t("formEnabledInfo") })] }));
|
|
61
65
|
};
|
|
@@ -21,7 +21,7 @@ export declare const schoolFormValidation: z.ZodObject<{
|
|
|
21
21
|
state: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
22
22
|
country: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
23
23
|
postalCode: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
24
|
-
phone: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
24
|
+
phone: z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString>>, z.ZodTransform<string | null | undefined, string | null | undefined>>;
|
|
25
25
|
email: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
26
26
|
website: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
27
27
|
logo: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Zod validation schemas for account-school form data.
|
|
5
5
|
*/
|
|
6
6
|
import { z } from "zod";
|
|
7
|
+
import { toE164Phone } from "../../utils/to-e164-phone";
|
|
7
8
|
// ============================================================================
|
|
8
9
|
// VALIDATION KEYS
|
|
9
10
|
// ============================================================================
|
|
@@ -27,7 +28,11 @@ export const schoolFormValidation = z.object({
|
|
|
27
28
|
state: z.string().nullable().optional(),
|
|
28
29
|
country: z.string().nullable().optional(),
|
|
29
30
|
postalCode: z.string().nullable().optional(),
|
|
30
|
-
phone: z
|
|
31
|
+
phone: z
|
|
32
|
+
.string()
|
|
33
|
+
.nullable()
|
|
34
|
+
.optional()
|
|
35
|
+
.transform((val) => { var _a; return (val ? (_a = toE164Phone(val)) !== null && _a !== void 0 ? _a : val : val); }),
|
|
31
36
|
email: z.string().email(VALIDATION_KEYS.email).nullable().optional(),
|
|
32
37
|
website: z.string().url(VALIDATION_KEYS.website).nullable().optional(),
|
|
33
38
|
logo: z.string().nullable().optional(),
|
|
@@ -23,7 +23,7 @@ import { getTranslatedError } from "../../utils/get-translated-error";
|
|
|
23
23
|
export const StudentFeeForm = () => {
|
|
24
24
|
var _a, _b, _c, _d, _e;
|
|
25
25
|
const { state, handleChange } = useStudentFeeModule();
|
|
26
|
-
const { amount, amountDue, amountPaid, discountAmount, discountCodeId, dueDate, enabled, errors,
|
|
26
|
+
const { amount, amountDue, amountPaid, discountAmount, discountCodeId, dueDate, enabled, errors, feeStructureId, remarks, status, studentProfileId, } = state;
|
|
27
27
|
const workspace = getCachedWorkspaceSync();
|
|
28
28
|
const currency = (_b = (_a = workspace === null || workspace === void 0 ? void 0 : workspace.school) === null || _a === void 0 ? void 0 : _a.currency) !== null && _b !== void 0 ? _b : "";
|
|
29
29
|
const t = useTranslations("studentFee");
|
|
@@ -6,50 +6,55 @@ import { useModuleEntityV2, } from "@react-pakistan/util-functions/hooks/use-mod
|
|
|
6
6
|
import { useDebounce } from "@react-pakistan/util-functions/hooks/use-debounce";
|
|
7
7
|
import { generateThemeToast, TOAST_VARIANT, } from "@appcorp/shadcn/lib/toast-utils";
|
|
8
8
|
import { STUDENT_STATUS } from "../../../type";
|
|
9
|
-
import { formatNumber } from "@react-pakistan/util-functions/general/format-number";
|
|
10
9
|
import { formatPhoneDisplay } from "@react-pakistan/util-functions/general/format-phone-display";
|
|
10
|
+
import { toE164Phone } from "../../../utils/to-e164-phone";
|
|
11
11
|
import { STUDENT_PROFILE_API_ROUTES } from "../../../constants";
|
|
12
12
|
import { studentProfileFormValidation } from "../validate";
|
|
13
13
|
import { getCachedWorkspaceSync } from "../../workspace/cache";
|
|
14
14
|
import { useStudentProfileContext, STUDENT_PROFILE_ACTION_TYPES, STUDENT_PROFILE_DRAWER, } from "./module-base";
|
|
15
15
|
export const useStudentProfileModule = () => {
|
|
16
|
-
var _a;
|
|
16
|
+
var _a, _b, _c;
|
|
17
17
|
const context = useStudentProfileContext();
|
|
18
18
|
const { dispatch } = context;
|
|
19
19
|
const state = context.state;
|
|
20
20
|
const t = useTranslations("studentProfile");
|
|
21
21
|
const { theme } = useTheme();
|
|
22
22
|
const workspace = getCachedWorkspaceSync();
|
|
23
|
-
const schoolId = ((_a = workspace === null || workspace === void 0 ? void 0 : workspace.school) === null || _a === void 0 ? void 0 : _a.id) || "";
|
|
24
23
|
const listFetchNowRef = useRef(null);
|
|
25
24
|
const debouncedQuery = useDebounce(state.searchQuery, 800);
|
|
26
|
-
const listParams = useMemo(() =>
|
|
27
|
-
|
|
28
|
-
:
|
|
25
|
+
const listParams = useMemo(() => {
|
|
26
|
+
var _a;
|
|
27
|
+
return (Object.assign(Object.assign(Object.assign(Object.assign({ currentPage: state.currentPage, pageLimit: state.pageLimit, schoolId: ((_a = workspace === null || workspace === void 0 ? void 0 : workspace.school) === null || _a === void 0 ? void 0 : _a.id) || "" }, (debouncedQuery ? { searchQuery: debouncedQuery } : {})), (state.filterEnabled !== undefined
|
|
28
|
+
? { filterEnabled: String(state.filterEnabled) }
|
|
29
|
+
: {})), (state.filterGender ? { filterGender: state.filterGender } : {})), (state.filterStatus ? { filterStatus: state.filterStatus } : {})));
|
|
30
|
+
}, [
|
|
29
31
|
state.currentPage,
|
|
30
32
|
state.filterEnabled,
|
|
31
33
|
state.filterGender,
|
|
32
34
|
state.filterStatus,
|
|
33
35
|
state.pageLimit,
|
|
34
36
|
debouncedQuery,
|
|
35
|
-
|
|
37
|
+
(_a = workspace === null || workspace === void 0 ? void 0 : workspace.school) === null || _a === void 0 ? void 0 : _a.id,
|
|
36
38
|
]);
|
|
37
|
-
const updateParams = useMemo(() =>
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
39
|
+
const updateParams = useMemo(() => {
|
|
40
|
+
var _a, _b;
|
|
41
|
+
return ({
|
|
42
|
+
avatar: state.avatar,
|
|
43
|
+
bloodGroup: state.bloodGroup,
|
|
44
|
+
dateOfBirth: state.dateOfBirth,
|
|
45
|
+
email: state.email,
|
|
46
|
+
emergencyPhone: toE164Phone(state.emergencyPhone, (_a = workspace === null || workspace === void 0 ? void 0 : workspace.school) === null || _a === void 0 ? void 0 : _a.country),
|
|
47
|
+
enabled: state.enabled,
|
|
48
|
+
familyMemberId: state.familyMemberId,
|
|
49
|
+
firstName: state.firstName,
|
|
50
|
+
gender: state.gender,
|
|
51
|
+
id: state.id,
|
|
52
|
+
lastName: state.lastName,
|
|
53
|
+
phone: toE164Phone(state.phone, (_b = workspace === null || workspace === void 0 ? void 0 : workspace.school) === null || _b === void 0 ? void 0 : _b.country),
|
|
54
|
+
status: state.status,
|
|
55
|
+
studentCode: state.studentCode,
|
|
56
|
+
});
|
|
57
|
+
}, [
|
|
53
58
|
state.avatar,
|
|
54
59
|
state.bloodGroup,
|
|
55
60
|
state.dateOfBirth,
|
|
@@ -64,6 +69,7 @@ export const useStudentProfileModule = () => {
|
|
|
64
69
|
state.phone,
|
|
65
70
|
state.status,
|
|
66
71
|
state.studentCode,
|
|
72
|
+
(_b = workspace === null || workspace === void 0 ? void 0 : workspace.school) === null || _b === void 0 ? void 0 : _b.country,
|
|
67
73
|
]);
|
|
68
74
|
const byIdParams = useMemo(() => ({ id: state.id }), [state.id]);
|
|
69
75
|
const deleteParams = useMemo(() => ({ id: state.id }), [state.id]);
|
|
@@ -478,11 +484,11 @@ export const useStudentProfileModule = () => {
|
|
|
478
484
|
listFetchNowRef.current = listFetchNow;
|
|
479
485
|
}, [listFetchNow]);
|
|
480
486
|
useEffect(() => {
|
|
481
|
-
var _a;
|
|
482
|
-
if (!
|
|
487
|
+
var _a, _b;
|
|
488
|
+
if (!((_a = workspace === null || workspace === void 0 ? void 0 : workspace.school) === null || _a === void 0 ? void 0 : _a.id))
|
|
483
489
|
return;
|
|
484
|
-
(
|
|
485
|
-
}, [dispatch, listParams,
|
|
490
|
+
(_b = listFetchNowRef.current) === null || _b === void 0 ? void 0 : _b.call(listFetchNowRef);
|
|
491
|
+
}, [dispatch, listParams, (_c = workspace === null || workspace === void 0 ? void 0 : workspace.school) === null || _c === void 0 ? void 0 : _c.id, showToast, t]);
|
|
486
492
|
return Object.assign(Object.assign({}, context), { applyFilters,
|
|
487
493
|
byIdLoading,
|
|
488
494
|
clearFilters,
|
|
@@ -8,6 +8,7 @@ import { useTranslations } from "next-intl";
|
|
|
8
8
|
import { useStudentProfileModule } from "./context";
|
|
9
9
|
import { STATUS_OPTIONS, GENDER_OPTIONS } from "./constants";
|
|
10
10
|
import { STUDENT_PROFILE_API_ROUTES } from "../../constants";
|
|
11
|
+
import { formatPhone } from "@react-pakistan/util-functions/general/format-phone";
|
|
11
12
|
import { getTranslatedError } from "../../utils/get-translated-error";
|
|
12
13
|
export const StudentProfileForm = () => {
|
|
13
14
|
const t = useTranslations("studentProfile");
|
|
@@ -63,5 +64,11 @@ export const StudentProfileForm = () => {
|
|
|
63
64
|
});
|
|
64
65
|
return (_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "space-y-4", children: [_jsx("h3", { className: "text-lg font-semibold", children: t("formSectionPersonalInformation") }), _jsxs("div", { className: "grid grid-cols-1 gap-4", children: [_jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "firstName", t }), id: "firstName", info: t("formFirstNameInfo"), label: t("formFirstNameLabel"), onChange: (e) => handleChange("firstName", e.target.value), placeholder: t("formFirstNamePlaceholder"), required: true, value: firstName }), _jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "lastName", t }), id: "lastName", info: t("formLastNameInfo"), label: t("formLastNameLabel"), onChange: (e) => handleChange("lastName", e.target.value), placeholder: t("formLastNamePlaceholder"), required: true, value: lastName }), _jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "dateOfBirth", t }), id: "dateOfBirth", info: t("formDateOfBirthInfo"), label: t("formDateOfBirthLabel"), onChange: (e) => handleChange("dateOfBirth", e.target.value), onClick: (e) => { var _a, _b; return (_b = (_a = e.currentTarget).showPicker) === null || _b === void 0 ? void 0 : _b.call(_a); }, type: "date", value: dateOfBirth
|
|
65
66
|
? new Date(dateOfBirth).toISOString().split("formTLabel")[0]
|
|
66
|
-
: "" }), genderCombo] })] }), _jsxs("div", { className: "space-y-4", children: [_jsx("h3", { className: "text-lg font-semibold", children: t("formSectionContactInformation") }), _jsxs("div", { className: "grid grid-cols-1 gap-4", children: [_jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "phone", t }), id: "phone", info: t("formPhoneInfo"), label: t("formPhoneLabel"), onChange: (e) =>
|
|
67
|
+
: "" }), genderCombo] })] }), _jsxs("div", { className: "space-y-4", children: [_jsx("h3", { className: "text-lg font-semibold", children: t("formSectionContactInformation") }), _jsxs("div", { className: "grid grid-cols-1 gap-4", children: [_jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "phone", t }), id: "phone", info: t("formPhoneInfo"), label: t("formPhoneLabel"), onChange: (e) => {
|
|
68
|
+
var _a;
|
|
69
|
+
return handleChange("phone", ((_a = formatPhone(e.target.value)) === null || _a === void 0 ? void 0 : _a.international) || e.target.value);
|
|
70
|
+
}, placeholder: t("formPhonePlaceholder"), type: "tel", value: phone || "" }), _jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "emergencyPhone", t }), id: "emergencyPhone", info: t("formEmergencyPhoneInfo"), label: t("formEmergencyPhoneLabel"), onChange: (e) => {
|
|
71
|
+
var _a;
|
|
72
|
+
return handleChange("emergencyPhone", ((_a = formatPhone(e.target.value)) === null || _a === void 0 ? void 0 : _a.international) || e.target.value);
|
|
73
|
+
}, placeholder: t("formEmergencyPhonePlaceholder"), type: "tel", value: emergencyPhone || "" })] }), _jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "address", t }), id: "address", info: t("formAddressInfo"), label: t("formAddressLabel"), onChange: (e) => handleChange("address", e.target.value), placeholder: t("formAddressPlaceholder"), value: address || "" }), _jsxs("div", { className: "grid grid-cols-1 gap-4", children: [_jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "city", t }), id: "city", info: t("formCityInfo"), label: t("formCityLabel"), onChange: (e) => handleChange("city", e.target.value), placeholder: t("formCityPlaceholder"), value: city || "" }), _jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "state", t }), id: "state", info: t("formStateInfo"), label: t("formStateProvinceLabel"), onChange: (e) => handleChange("state", e.target.value), placeholder: t("formStatePlaceholder"), value: stateValue || "" }), _jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "country", t }), id: "country", info: t("formCountryInfo"), label: t("formCountryLabel"), onChange: (e) => handleChange("country", e.target.value), placeholder: t("formCountryPlaceholder"), value: country || "" }), _jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "postalCode", t }), id: "postalCode", info: t("formPostalCodeInfo"), label: t("formPostalCodeLabel"), onChange: (e) => handleChange("postalCode", e.target.value), placeholder: t("formPostalCodePlaceholder"), value: postalCode || "" })] })] }), _jsxs("div", { className: "space-y-4", children: [_jsx("h3", { className: "text-lg font-semibold", children: t("formSectionAcademicInformation") }), _jsxs("div", { className: "grid grid-cols-1 gap-4", children: [statusCombo, _jsx(EnhancedTextarea, { error: getTranslatedError({ errors, key: "remarks", t }), id: "remarks", info: t("formRemarksInfo"), label: t("formRemarksLabel"), onChange: (e) => handleChange("remarks", e.target.value), placeholder: t("formRemarksPlaceholder"), rows: 4, value: remarks || "" })] }), _jsx(EnhancedCheckbox, { checked: enabled, info: t("formEnabledInfo"), label: t("formEnabledLabel"), onCheckedChange: (checked) => handleChange("enabled", checked) })] })] }));
|
|
67
74
|
};
|
|
@@ -13,8 +13,8 @@ export declare const VALIDATION_KEYS: {
|
|
|
13
13
|
export declare const studentProfileFormValidation: z.ZodObject<{
|
|
14
14
|
firstName: z.ZodString;
|
|
15
15
|
lastName: z.ZodString;
|
|
16
|
-
phone: z.ZodOptional<z.ZodString
|
|
17
|
-
emergencyPhone: z.ZodOptional<z.ZodString
|
|
16
|
+
phone: z.ZodPipe<z.ZodOptional<z.ZodString>, z.ZodTransform<string | undefined, string | undefined>>;
|
|
17
|
+
emergencyPhone: z.ZodPipe<z.ZodOptional<z.ZodString>, z.ZodTransform<string | undefined, string | undefined>>;
|
|
18
18
|
status: z.ZodString;
|
|
19
19
|
dateOfBirth: z.ZodOptional<z.ZodString>;
|
|
20
20
|
enrollmentDate: z.ZodOptional<z.ZodString>;
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Zod validation schemas for student profile form data.
|
|
5
5
|
*/
|
|
6
6
|
import { z } from "zod";
|
|
7
|
+
import { toE164Phone } from "../../utils/to-e164-phone";
|
|
7
8
|
export const VALIDATION_KEYS = {
|
|
8
9
|
firstNameRequired: "validationStudentProfileFirstNameRequired",
|
|
9
10
|
lastNameRequired: "validationStudentProfileLastNameRequired",
|
|
@@ -16,13 +17,11 @@ export const studentProfileFormValidation = z.object({
|
|
|
16
17
|
phone: z
|
|
17
18
|
.string()
|
|
18
19
|
.optional()
|
|
19
|
-
.
|
|
20
|
-
/^([+]?[\s0-9]+)?(\d{3}|[(]?[0-9]+[)]?)?([-]?[\s]?[0-9])+$/.test(val), VALIDATION_KEYS.phoneInvalid),
|
|
20
|
+
.transform((val) => { var _a; return (val ? (_a = toE164Phone(val)) !== null && _a !== void 0 ? _a : val : val); }),
|
|
21
21
|
emergencyPhone: z
|
|
22
22
|
.string()
|
|
23
23
|
.optional()
|
|
24
|
-
.
|
|
25
|
-
/^([+]?[\s0-9]+)?(\d{3}|[(]?[0-9]+[)]?)?([-]?[\s]?[0-9])+$/.test(val), VALIDATION_KEYS.phoneInvalid),
|
|
24
|
+
.transform((val) => { var _a; return (val ? (_a = toE164Phone(val)) !== null && _a !== void 0 ? _a : val : val); }),
|
|
26
25
|
status: z.string().min(1, VALIDATION_KEYS.statusRequired),
|
|
27
26
|
dateOfBirth: z.string().optional(),
|
|
28
27
|
enrollmentDate: z.string().optional(),
|
|
@@ -456,7 +456,7 @@ export const useTeacherModule = () => {
|
|
|
456
456
|
finally {
|
|
457
457
|
uploadInProgressRef.current = false;
|
|
458
458
|
}
|
|
459
|
-
}, [dispatch, showToast, state.id, workspace === null || workspace === void 0 ? void 0 : workspace.id]);
|
|
459
|
+
}, [dispatch, showToast, state.id, t, workspace === null || workspace === void 0 ? void 0 : workspace.id]);
|
|
460
460
|
const applyFilters = useCallback(() => {
|
|
461
461
|
dispatch({
|
|
462
462
|
type: TEACHER_ACTION_TYPES.SET_CURRENT_PAGE,
|
|
@@ -9,6 +9,7 @@ import { useTranslations } from "next-intl";
|
|
|
9
9
|
import { useTeacherModule } from "./context";
|
|
10
10
|
import { GENDER_OPTIONS } from "./constants";
|
|
11
11
|
import { TEACHER_API_ROUTES } from "../../constants";
|
|
12
|
+
import { formatPhone } from "@react-pakistan/util-functions/general/format-phone";
|
|
12
13
|
import { getTranslatedError } from "../../utils/get-translated-error";
|
|
13
14
|
export const TeacherForm = () => {
|
|
14
15
|
const t = useTranslations("teacher");
|
|
@@ -45,7 +46,13 @@ export const TeacherForm = () => {
|
|
|
45
46
|
? new Date(joiningDate).toISOString().split("T")[0]
|
|
46
47
|
: "" }), genderCombo, _jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "dateOfBirth", t }), id: "dateOfBirth", info: t("formDateOfBirthInfo"), label: t("formDateOfBirthLabel"), onChange: (e) => handleChange("dateOfBirth", e.target.value), onClick: (e) => { var _a, _b; return (_b = (_a = e.currentTarget).showPicker) === null || _b === void 0 ? void 0 : _b.call(_a); }, type: "date", value: dateOfBirth
|
|
47
48
|
? new Date(dateOfBirth).toISOString().split("T")[0]
|
|
48
|
-
: "" }), _jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "phone", t }), id: "phone", info: t("formPhoneInfo"), label: t("formPhoneLabel"), onChange: (e) =>
|
|
49
|
+
: "" }), _jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "phone", t }), id: "phone", info: t("formPhoneInfo"), label: t("formPhoneLabel"), onChange: (e) => {
|
|
50
|
+
var _a;
|
|
51
|
+
return handleChange("phone", ((_a = formatPhone(e.target.value)) === null || _a === void 0 ? void 0 : _a.international) || e.target.value);
|
|
52
|
+
}, placeholder: t("formPhonePlaceholder"), type: "tel", value: phone || "" }), _jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "emergencyPhone", t }), id: "emergencyPhone", info: t("formEmergencyPhoneInfo"), label: t("formEmergencyPhoneLabel"), onChange: (e) => {
|
|
53
|
+
var _a;
|
|
54
|
+
return handleChange("emergencyPhone", ((_a = formatPhone(e.target.value)) === null || _a === void 0 ? void 0 : _a.international) || e.target.value);
|
|
55
|
+
}, placeholder: t("formEmergencyPhonePlaceholder"), type: "tel", value: emergencyPhone || "" }), _jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "qualification", t }), id: "qualification", info: t("formQualificationInfo"), label: t("formQualificationLabel"), onChange: (e) => handleChange("qualification", e.target.value), placeholder: t("formQualificationPlaceholder"), value: qualification || "" }), _jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "specialization", t }), id: "specialization", info: t("formSpecializationInfo"), label: t("formSpecializationLabel"), onChange: (e) => handleChange("specialization", e.target.value), placeholder: t("formSpecializationPlaceholder"), value: specialization || "" }), _jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "experience", t }), id: "experience", info: t("formExperienceInfo"), label: t("formExperienceLabel"), onChange: (e) => handleChange("experience", parseInt(e.target.value) || null), placeholder: t("formExperiencePlaceholder"), type: "number", value: (experience === null || experience === void 0 ? void 0 : experience.toString()) || "" }), _jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "address", t }), id: "address", info: t("formAddressInfo"), label: t("formAddressLabel"), onChange: (e) => handleChange("address", e.target.value), placeholder: t("formAddressPlaceholder"), value: address || "" }), _jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "city", t }), id: "city", info: t("formCityInfo"), label: t("formCityLabel"), onChange: (e) => handleChange("city", e.target.value), placeholder: t("formCityPlaceholder"), value: city || "" }), _jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "state", t }), id: "state", info: t("formStateProvinceInfo"), label: t("formStateProvinceLabel"), onChange: (e) => handleChange("state", e.target.value), placeholder: t("formStatePlaceholder"), value: stateValue || "" }), _jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "country", t }), id: "country", info: t("formCountryInfo"), label: t("formCountryLabel"), onChange: (e) => handleChange("country", e.target.value), placeholder: t("formCountryPlaceholder"), value: country || "" }), _jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "postalCode", t }), id: "postalCode", info: t("formPostalCodeInfo"), label: t("formPostalCodeLabel"), onChange: (e) => handleChange("postalCode", e.target.value), placeholder: t("formPostalCodePlaceholder"), value: postalCode || "" }), _jsx(EnhancedDropzone, { accept: ["image/*"], error: getTranslatedError({ errors, key: "avatar", t }), id: "avatar", info: t("formAvatarInfo"), label: t("formAvatarLabel"), maxFiles: 1, maxSize: 100 * 1024, onChange: (files) => {
|
|
49
56
|
if (files.length > 0) {
|
|
50
57
|
handleAvatarUpload === null || handleAvatarUpload === void 0 ? void 0 : handleAvatarUpload(files[0]);
|
|
51
58
|
}
|
|
@@ -15,7 +15,7 @@ export declare const teacherFormValidation: z.ZodObject<{
|
|
|
15
15
|
city: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
16
16
|
country: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
17
17
|
dateOfBirth: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
18
|
-
emergencyPhone: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
18
|
+
emergencyPhone: z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString>>, z.ZodTransform<string | null | undefined, string | null | undefined>>;
|
|
19
19
|
campusId: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
20
20
|
experience: z.ZodNullable<z.ZodOptional<z.ZodNumber>>;
|
|
21
21
|
firstName: z.ZodString;
|
|
@@ -27,7 +27,7 @@ export declare const teacherFormValidation: z.ZodObject<{
|
|
|
27
27
|
}>>>>;
|
|
28
28
|
joiningDate: z.ZodOptional<z.ZodString>;
|
|
29
29
|
lastName: z.ZodString;
|
|
30
|
-
phone: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
30
|
+
phone: z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString>>, z.ZodTransform<string | null | undefined, string | null | undefined>>;
|
|
31
31
|
postalCode: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
32
32
|
qualification: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
33
33
|
specialization: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Zod validation schemas for teacher form data with i18n-ready error keys.
|
|
5
5
|
*/
|
|
6
6
|
import { z } from "zod";
|
|
7
|
+
import { toE164Phone } from "../../utils/to-e164-phone";
|
|
7
8
|
// ============================================================================
|
|
8
9
|
// VALIDATION KEYS
|
|
9
10
|
// ============================================================================
|
|
@@ -21,7 +22,11 @@ export const teacherFormValidation = z.object({
|
|
|
21
22
|
city: z.string().optional().nullable(),
|
|
22
23
|
country: z.string().optional().nullable(),
|
|
23
24
|
dateOfBirth: z.string().optional().nullable(),
|
|
24
|
-
emergencyPhone: z
|
|
25
|
+
emergencyPhone: z
|
|
26
|
+
.string()
|
|
27
|
+
.nullable()
|
|
28
|
+
.optional()
|
|
29
|
+
.transform((val) => { var _a; return (val ? (_a = toE164Phone(val)) !== null && _a !== void 0 ? _a : val : val); }),
|
|
25
30
|
campusId: z.string().optional().nullable(),
|
|
26
31
|
experience: z.number().optional().nullable(),
|
|
27
32
|
firstName: z.string().min(1, VALIDATION_KEYS.firstName),
|
|
@@ -32,7 +37,11 @@ export const teacherFormValidation = z.object({
|
|
|
32
37
|
.nullable()),
|
|
33
38
|
joiningDate: z.string().optional(),
|
|
34
39
|
lastName: z.string().min(1, VALIDATION_KEYS.lastName),
|
|
35
|
-
phone: z
|
|
40
|
+
phone: z
|
|
41
|
+
.string()
|
|
42
|
+
.nullable()
|
|
43
|
+
.optional()
|
|
44
|
+
.transform((val) => { var _a; return (val ? (_a = toE164Phone(val)) !== null && _a !== void 0 ? _a : val : val); }),
|
|
36
45
|
postalCode: z.string().optional().nullable(),
|
|
37
46
|
qualification: z.string().optional().nullable(),
|
|
38
47
|
specialization: z.string().optional().nullable(),
|
|
@@ -12,10 +12,11 @@ import { getCachedWorkspaceSync } from "../../workspace/cache";
|
|
|
12
12
|
import { blobToWebP } from "webp-converter-browser";
|
|
13
13
|
import { supabasePublicStorageUrl } from "../../../constants";
|
|
14
14
|
import { toastNetworkError } from "../../../utils/toast-network-error";
|
|
15
|
-
import { formatNumber } from "@react-pakistan/util-functions/general/format-number";
|
|
16
15
|
import { formatPhoneDisplay } from "@react-pakistan/util-functions/general/format-phone-display";
|
|
16
|
+
import { toE164Phone } from "../../../utils/to-e164-phone";
|
|
17
17
|
import { useUserContext, USER_ACTION_TYPES, USER_DRAWER } from "../context";
|
|
18
18
|
export const useUserModule = () => {
|
|
19
|
+
var _a;
|
|
19
20
|
// ============================================================================
|
|
20
21
|
// 1.4.1 STATE & CORE HOOKS
|
|
21
22
|
// ============================================================================
|
|
@@ -39,17 +40,20 @@ export const useUserModule = () => {
|
|
|
39
40
|
debouncedQuery,
|
|
40
41
|
workspace === null || workspace === void 0 ? void 0 : workspace.id,
|
|
41
42
|
]);
|
|
42
|
-
const updateParams = useMemo(() =>
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
43
|
+
const updateParams = useMemo(() => {
|
|
44
|
+
var _a;
|
|
45
|
+
return ({
|
|
46
|
+
avatar: state.avatar,
|
|
47
|
+
email: (state.email || "").trim(),
|
|
48
|
+
enabled: state.enabled,
|
|
49
|
+
id: state.id,
|
|
50
|
+
name: (state.name || "").trim(),
|
|
51
|
+
password: state.password,
|
|
52
|
+
phone: toE164Phone(state.phone, (_a = workspace === null || workspace === void 0 ? void 0 : workspace.school) === null || _a === void 0 ? void 0 : _a.country),
|
|
53
|
+
userRole: state.userRole,
|
|
54
|
+
workspaceId: workspace === null || workspace === void 0 ? void 0 : workspace.id,
|
|
55
|
+
});
|
|
56
|
+
}, [state, workspace === null || workspace === void 0 ? void 0 : workspace.id, (_a = workspace === null || workspace === void 0 ? void 0 : workspace.school) === null || _a === void 0 ? void 0 : _a.country]);
|
|
53
57
|
const byIdParams = useMemo(() => ({ id: state.id }), [state.id]);
|
|
54
58
|
const deleteParams = useMemo(() => ({ id: state.id }), [state.id]);
|
|
55
59
|
// ============================================================================
|
|
@@ -16,7 +16,7 @@ export declare const userFormValidation: z.ZodObject<{
|
|
|
16
16
|
name: z.ZodString;
|
|
17
17
|
email: z.ZodEmail;
|
|
18
18
|
password: z.ZodOptional<z.ZodString>;
|
|
19
|
-
phone: z.ZodOptional<z.ZodString
|
|
19
|
+
phone: z.ZodPipe<z.ZodOptional<z.ZodString>, z.ZodTransform<string | undefined, string | undefined>>;
|
|
20
20
|
avatar: z.ZodOptional<z.ZodString>;
|
|
21
21
|
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
22
22
|
userRole: z.ZodEnum<typeof USER_ROLE> & z.ZodType<USER_ROLE.SUPER_ADMIN | USER_ROLE.TEACHER | USER_ROLE.STUDENT | USER_ROLE.PARENT | USER_ROLE.STAFF, USER_ROLE, z.core.$ZodTypeInternals<USER_ROLE.SUPER_ADMIN | USER_ROLE.TEACHER | USER_ROLE.STUDENT | USER_ROLE.PARENT | USER_ROLE.STAFF, USER_ROLE>>;
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { z } from "zod";
|
|
7
7
|
import { USER_ROLE } from "../../type";
|
|
8
|
+
import { toE164Phone } from "../../utils/to-e164-phone";
|
|
8
9
|
// ============================================================================
|
|
9
10
|
// VALIDATION KEYS
|
|
10
11
|
// ============================================================================
|
|
@@ -25,8 +26,7 @@ export const userFormValidation = z.object({
|
|
|
25
26
|
phone: z
|
|
26
27
|
.string()
|
|
27
28
|
.optional()
|
|
28
|
-
.
|
|
29
|
-
/^([+]?[\s0-9]+)?(\d{3}|[(]?[0-9]+[)]?)?([-]?[\s]?[0-9])+$/.test(val), VALIDATION_KEYS.phoneInvalid),
|
|
29
|
+
.transform((val) => { var _a; return (val ? (_a = toE164Phone(val)) !== null && _a !== void 0 ? _a : val : val); }),
|
|
30
30
|
avatar: z.string().optional(),
|
|
31
31
|
enabled: z.boolean().optional(),
|
|
32
32
|
userRole: z
|