@appcorp/fusion-storybook 0.2.88 → 0.2.89

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.
Files changed (146) hide show
  1. package/base-modules/admission/filter.js +3 -3
  2. package/base-modules/admission/form.js +1 -1
  3. package/base-modules/admission/more-actions.js +288 -2
  4. package/base-modules/admission/view.js +1 -1
  5. package/base-modules/attendance/form.js +3 -3
  6. package/base-modules/campus/form.js +2 -1
  7. package/base-modules/campus/validate.d.ts +13 -5
  8. package/base-modules/campus/validate.js +24 -19
  9. package/base-modules/class/form.js +2 -1
  10. package/base-modules/class/more-actions.js +2 -2
  11. package/base-modules/class/validate.d.ts +10 -5
  12. package/base-modules/class/validate.js +18 -16
  13. package/base-modules/class/view.js +2 -2
  14. package/base-modules/course/form.js +2 -1
  15. package/base-modules/course/validate.d.ts +7 -5
  16. package/base-modules/course/validate.js +12 -13
  17. package/base-modules/course/view.js +3 -3
  18. package/base-modules/discount-code/constants.d.ts +1 -1
  19. package/base-modules/discount-code/constants.js +1 -1
  20. package/base-modules/discount-code/form.js +2 -1
  21. package/base-modules/discount-code/more-actions.js +1 -1
  22. package/base-modules/discount-code/page.d.ts +10 -10
  23. package/base-modules/discount-code/page.js +31 -31
  24. package/base-modules/discount-code/validate.d.ts +5 -0
  25. package/base-modules/discount-code/validate.js +8 -3
  26. package/base-modules/discount-code/view.js +2 -2
  27. package/base-modules/enrollment/form.js +3 -2
  28. package/base-modules/enrollment/more-actions.js +5 -5
  29. package/base-modules/enrollment/page.d.ts +10 -10
  30. package/base-modules/enrollment/page.js +31 -31
  31. package/base-modules/enrollment/validate.d.ts +6 -0
  32. package/base-modules/enrollment/validate.js +13 -5
  33. package/base-modules/enrollment/view.js +2 -2
  34. package/base-modules/expense/filter.js +1 -1
  35. package/base-modules/expense/form.js +3 -3
  36. package/base-modules/expense/more-actions.js +6 -6
  37. package/base-modules/expense/page.d.ts +11 -11
  38. package/base-modules/expense/page.js +34 -34
  39. package/base-modules/expense/validate.d.ts +8 -0
  40. package/base-modules/expense/validate.js +13 -5
  41. package/base-modules/expense/view.js +2 -2
  42. package/base-modules/family/context.js +1 -1
  43. package/base-modules/family/form.js +1 -1
  44. package/base-modules/family/more-actions.js +2 -2
  45. package/base-modules/family/page.d.ts +10 -10
  46. package/base-modules/family/page.js +31 -31
  47. package/base-modules/family/validate.d.ts +4 -0
  48. package/base-modules/family/validate.js +8 -1
  49. package/base-modules/family/view.js +1 -1
  50. package/base-modules/family-member/context.js +1 -1
  51. package/base-modules/family-member/form.js +2 -1
  52. package/base-modules/family-member/more-actions.js +5 -5
  53. package/base-modules/family-member/page.d.ts +40 -13
  54. package/base-modules/family-member/page.js +34 -34
  55. package/base-modules/family-member/validate.d.ts +8 -0
  56. package/base-modules/family-member/validate.js +20 -5
  57. package/base-modules/family-member/view.js +3 -3
  58. package/base-modules/fee-structure/form.js +5 -4
  59. package/base-modules/fee-structure/more-actions.js +2 -2
  60. package/base-modules/fee-structure/page.d.ts +11 -11
  61. package/base-modules/fee-structure/page.js +34 -34
  62. package/base-modules/fee-structure/validate.d.ts +6 -0
  63. package/base-modules/fee-structure/validate.js +12 -3
  64. package/base-modules/fee-structure/view.js +3 -3
  65. package/base-modules/rbac/assign-permissions.js +9 -5
  66. package/base-modules/rbac/filter.js +5 -3
  67. package/base-modules/rbac/form.js +2 -1
  68. package/base-modules/rbac/more-actions.d.ts +0 -5
  69. package/base-modules/rbac/more-actions.js +3 -1
  70. package/base-modules/rbac/validate.d.ts +3 -0
  71. package/base-modules/rbac/validate.js +7 -1
  72. package/base-modules/rbac/view.js +7 -5
  73. package/base-modules/school/drawer.js +3 -1
  74. package/base-modules/school/form.js +2 -1
  75. package/base-modules/school/validate.d.ts +8 -0
  76. package/base-modules/school/validate.js +17 -6
  77. package/base-modules/school/view.js +2 -2
  78. package/base-modules/section/filter.js +1 -1
  79. package/base-modules/section/form.js +3 -2
  80. package/base-modules/section/page.d.ts +8 -8
  81. package/base-modules/section/page.js +25 -25
  82. package/base-modules/section/validate.d.ts +7 -0
  83. package/base-modules/section/validate.js +15 -5
  84. package/base-modules/section/view.js +3 -3
  85. package/base-modules/student-fee/filter.js +1 -1
  86. package/base-modules/student-fee/form.js +3 -2
  87. package/base-modules/student-fee/page.d.ts +13 -13
  88. package/base-modules/student-fee/page.js +40 -40
  89. package/base-modules/student-fee/validate.d.ts +11 -3
  90. package/base-modules/student-fee/validate.js +20 -12
  91. package/base-modules/student-fee/view.js +4 -4
  92. package/base-modules/student-profile/context/use-student-profile-module.js +2 -2
  93. package/base-modules/student-profile/filter.js +2 -2
  94. package/base-modules/student-profile/form.js +6 -5
  95. package/base-modules/student-profile/page.d.ts +10 -10
  96. package/base-modules/student-profile/page.js +31 -31
  97. package/base-modules/student-profile/validate.d.ts +8 -2
  98. package/base-modules/student-profile/validate.js +13 -10
  99. package/base-modules/student-profile/view.js +2 -2
  100. package/base-modules/subject/filter.js +1 -1
  101. package/base-modules/subject/form.js +2 -1
  102. package/base-modules/subject/more-actions.js +3 -3
  103. package/base-modules/subject/page.d.ts +9 -9
  104. package/base-modules/subject/page.js +28 -28
  105. package/base-modules/subject/validate.d.ts +12 -1
  106. package/base-modules/subject/validate.js +24 -10
  107. package/base-modules/subject/view.js +3 -3
  108. package/base-modules/teacher/context.js +3 -3
  109. package/base-modules/teacher/filter.js +1 -1
  110. package/base-modules/teacher/form.js +9 -32
  111. package/base-modules/teacher/more-actions.js +2 -2
  112. package/base-modules/teacher/page.d.ts +10 -10
  113. package/base-modules/teacher/page.js +31 -31
  114. package/base-modules/teacher/validate.d.ts +5 -1
  115. package/base-modules/teacher/validate.js +10 -25
  116. package/base-modules/teacher/view.js +3 -3
  117. package/base-modules/user/filter.js +1 -1
  118. package/base-modules/user/form.js +3 -2
  119. package/base-modules/user/page.d.ts +9 -9
  120. package/base-modules/user/page.js +28 -28
  121. package/base-modules/user/validate.d.ts +8 -1
  122. package/base-modules/user/validate.js +16 -6
  123. package/base-modules/user/view.js +1 -1
  124. package/base-modules/workspace/context.js +3 -3
  125. package/base-modules/workspace/drawer.js +1 -1
  126. package/base-modules/workspace/filter.js +1 -1
  127. package/base-modules/workspace/form.js +2 -1
  128. package/base-modules/workspace/more-actions.js +1 -1
  129. package/base-modules/workspace/page.d.ts +1 -1
  130. package/base-modules/workspace/page.js +2 -2
  131. package/base-modules/workspace/validate.d.ts +4 -0
  132. package/base-modules/workspace/validate.js +6 -2
  133. package/base-modules/workspace/view.js +2 -2
  134. package/base-modules/workspace-user/context.js +6 -6
  135. package/base-modules/workspace-user/form.js +2 -1
  136. package/base-modules/workspace-user/page.d.ts +9 -9
  137. package/base-modules/workspace-user/page.js +28 -28
  138. package/base-modules/workspace-user/validate.d.ts +4 -5
  139. package/base-modules/workspace-user/validate.js +6 -10
  140. package/base-modules/workspace-user/view.js +1 -1
  141. package/constants.d.ts +5 -1
  142. package/constants.js +2 -0
  143. package/package.json +1 -1
  144. package/tsconfig.build.tsbuildinfo +1 -1
  145. package/utils/get-translated-error.d.ts +5 -0
  146. package/utils/get-translated-error.js +5 -0
@@ -444,7 +444,7 @@ export const useFamilyMemberModule = () => {
444
444
  {
445
445
  enabled: false,
446
446
  handleOnClick: handleCreate,
447
- label: t("actionsButtonAddFamilyMember"),
447
+ label: t("actionsButtonAdd"),
448
448
  order: 3,
449
449
  icon: Plus,
450
450
  },
@@ -9,9 +9,10 @@ import { EnhancedCheckbox } from "@appcorp/shadcn/components/enhanced-checkbox";
9
9
  import { EnhancedInput } from "@appcorp/shadcn/components/enhanced-input";
10
10
  import { useFamilyMemberModule } from "./context";
11
11
  import { useTranslations } from "next-intl";
12
+ import { getTranslatedError } from "@/utils/get-translated-error";
12
13
  export const FamilyMemberForm = () => {
13
14
  const { handleChange, state } = useFamilyMemberModule();
14
15
  const { bloodGroup, dateOfBirth, email, emergencyPhone, enabled, errors, firstName, gender, idNumber, isPrimary, lastName, occupation, phone, relationship, role, } = state;
15
16
  const t = useTranslations("familyMember");
16
- 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 md:grid-cols-2 gap-4", children: [_jsx(EnhancedInput, { error: errors.firstName, 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: errors.lastName, id: "lastName", info: t("formLastNameInfo"), label: t("formLastNameLabel"), onChange: (e) => handleChange("lastName", e.target.value), placeholder: t("formLastNamePlaceholder"), required: true, value: lastName })] }), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [_jsx(EnhancedInput, { error: errors.role, id: "role", info: t("formRoleInfo"), label: t("formRoleLabel"), onChange: (e) => handleChange("role", e.target.value), placeholder: t("formRolePlaceholder"), required: true, value: role }), _jsx(EnhancedInput, { error: errors.dateOfBirth, id: "dateOfBirth", info: t("formDateOfBirthInfo"), label: t("formDateOfBirthLabel"), onChange: (e) => handleChange("dateOfBirth", e.target.value), placeholder: "YYYY-MM-DD", type: "date", value: dateOfBirth })] }), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [_jsx(EnhancedInput, { error: errors.gender, id: "gender", info: t("formGenderInfo"), label: t("formGenderLabel"), onChange: (e) => handleChange("gender", e.target.value), placeholder: t("formGenderPlaceholder"), value: gender }), _jsx(EnhancedInput, { error: errors.bloodGroup, id: "bloodGroup", info: t("formBloodGroupInfo"), label: t("formBloodGroupLabel"), onChange: (e) => handleChange("bloodGroup", e.target.value), placeholder: t("formBloodGroupPlaceholder"), value: bloodGroup })] }), _jsx(EnhancedInput, { error: errors.idNumber, id: "idNumber", info: t("formIdNumberInfo"), label: t("formIdNumberLabel"), onChange: (e) => handleChange("idNumber", e.target.value), placeholder: t("formIdNumberPlaceholder"), value: idNumber })] }), _jsxs("div", { className: "space-y-4", children: [_jsx("h3", { className: "text-lg font-semibold", children: t("formSectionContactInformation") }), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [_jsx(EnhancedInput, { error: errors.phone, id: "phone", info: t("formPhoneInfo"), label: t("formPhoneLabel"), onChange: (e) => handleChange("phone", e.target.value), placeholder: t("formPhonePlaceholder"), type: "tel", value: phone }), _jsx(EnhancedInput, { error: errors.email, id: "email", info: t("formEmailInfo"), label: t("formEmailLabel"), onChange: (e) => handleChange("email", e.target.value), placeholder: t("formEmailPlaceholder"), type: "email", value: email })] }), _jsx(EnhancedInput, { error: errors.emergencyPhone, id: "emergencyPhone", info: t("formEmergencyPhoneInfo"), label: t("formEmergencyPhoneLabel"), onChange: (e) => handleChange("emergencyPhone", e.target.value), placeholder: t("formEmergencyPhonePlaceholder"), type: "tel", value: emergencyPhone })] }), _jsxs("div", { className: "space-y-4", children: [_jsx("h3", { className: "text-lg font-semibold", children: t("formSectionAdditionalInformation") }), _jsx(EnhancedInput, { error: errors.relationship, id: "relationship", info: t("formRelationshipInfo"), label: t("formRelationshipLabel"), onChange: (e) => handleChange("relationship", e.target.value), placeholder: t("formRelationshipPlaceholder"), value: relationship }), _jsx(EnhancedInput, { error: errors.occupation, id: "occupation", info: t("formOccupationInfo"), label: t("formOccupationLabel"), onChange: (e) => handleChange("occupation", e.target.value), placeholder: t("formOccupationPlaceholder"), value: occupation })] }), _jsxs("div", { className: "space-y-4", children: [_jsx("h3", { className: "text-lg font-semibold", children: t("formOptionStatus") }), _jsxs("div", { className: "flex items-center gap-4", children: [_jsx(EnhancedCheckbox, { checked: isPrimary, id: "isPrimary", label: t("formPrimaryContactLabel"), onCheckedChange: (checked) => handleChange("isPrimary", checked === true) }), _jsx(EnhancedCheckbox, { checked: enabled, id: "enabled", label: t("badgeActive"), onCheckedChange: (checked) => handleChange("enabled", checked === true) })] })] })] }));
17
+ 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 md:grid-cols-2 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 })] }), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [_jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "role", t }), id: "role", info: t("formRoleInfo"), label: t("formRoleLabel"), onChange: (e) => handleChange("role", e.target.value), placeholder: t("formRolePlaceholder"), required: true, value: role }), _jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "dateOfBirth", t }), id: "dateOfBirth", info: t("formDateOfBirthInfo"), label: t("formDateOfBirthLabel"), onChange: (e) => handleChange("dateOfBirth", e.target.value), placeholder: "YYYY-MM-DD", type: "date", value: dateOfBirth })] }), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [_jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "gender", t }), id: "gender", info: t("formGenderInfo"), label: t("formGenderLabel"), onChange: (e) => handleChange("gender", e.target.value), placeholder: t("formGenderPlaceholder"), value: gender }), _jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "bloodGroup", t }), id: "bloodGroup", info: t("formBloodGroupInfo"), label: t("formBloodGroupLabel"), onChange: (e) => handleChange("bloodGroup", e.target.value), placeholder: t("formBloodGroupPlaceholder"), value: bloodGroup })] }), _jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "idNumber", t }), id: "idNumber", info: t("formIdNumberInfo"), label: t("formIdNumberLabel"), onChange: (e) => handleChange("idNumber", e.target.value), placeholder: t("formIdNumberPlaceholder"), value: idNumber })] }), _jsxs("div", { className: "space-y-4", children: [_jsx("h3", { className: "text-lg font-semibold", children: t("formSectionContactInformation") }), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [_jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "phone", t }), id: "phone", info: t("formPhoneInfo"), label: t("formPhoneLabel"), onChange: (e) => handleChange("phone", e.target.value), placeholder: t("formPhonePlaceholder"), type: "tel", value: phone }), _jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "email", t }), id: "email", info: t("formEmailInfo"), label: t("formEmailLabel"), onChange: (e) => handleChange("email", e.target.value), placeholder: t("formEmailPlaceholder"), type: "email", value: email })] }), _jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "emergencyPhone", t }), id: "emergencyPhone", info: t("formEmergencyPhoneInfo"), label: t("formEmergencyPhoneLabel"), onChange: (e) => handleChange("emergencyPhone", e.target.value), placeholder: t("formEmergencyPhonePlaceholder"), type: "tel", value: emergencyPhone })] }), _jsxs("div", { className: "space-y-4", children: [_jsx("h3", { className: "text-lg font-semibold", children: t("formSectionAdditionalInformation") }), _jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "relationship", t }), id: "relationship", info: t("formRelationshipInfo"), label: t("formRelationshipLabel"), onChange: (e) => handleChange("relationship", e.target.value), placeholder: t("formRelationshipPlaceholder"), value: relationship }), _jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "occupation", t }), id: "occupation", info: t("formOccupationInfo"), label: t("formOccupationLabel"), onChange: (e) => handleChange("occupation", e.target.value), placeholder: t("formOccupationPlaceholder"), value: occupation })] }), _jsxs("div", { className: "space-y-4", children: [_jsx("h3", { className: "text-lg font-semibold", children: t("formSectionStatus") }), _jsxs("div", { className: "flex items-center gap-4", children: [_jsx(EnhancedCheckbox, { checked: isPrimary, id: "isPrimary", label: t("formPrimaryContactLabel"), onCheckedChange: (checked) => handleChange("isPrimary", checked === true) }), _jsx(EnhancedCheckbox, { checked: enabled, id: "enabled", label: t("badgeActive"), onCheckedChange: (checked) => handleChange("enabled", checked === true) })] })] })] }));
17
18
  };
@@ -114,17 +114,17 @@ export const FamilyMemberMoreActions = () => {
114
114
  const msgs = [];
115
115
  if (method === "POST") {
116
116
  if (!((_b = row.familyId) === null || _b === void 0 ? void 0 : _b.trim()))
117
- msgs.push(t("validationRequiredFamilyId"));
117
+ msgs.push(t("validationFamilyMemberFamilyIdRequired"));
118
118
  if (!((_c = row.firstName) === null || _c === void 0 ? void 0 : _c.trim()))
119
- msgs.push(t("validationRequiredFirstName"));
119
+ msgs.push(t("validationFamilyMemberFirstNameRequired"));
120
120
  if (!((_d = row.lastName) === null || _d === void 0 ? void 0 : _d.trim()))
121
- msgs.push(t("validationRequiredLastName"));
121
+ msgs.push(t("validationFamilyMemberLastNameRequired"));
122
122
  if (!((_e = row.role) === null || _e === void 0 ? void 0 : _e.trim()))
123
- msgs.push(t("validationRequiredRole"));
123
+ msgs.push(t("validationFamilyMemberRoleRequired"));
124
124
  }
125
125
  else {
126
126
  if (!((_f = row.id) === null || _f === void 0 ? void 0 : _f.trim()))
127
- msgs.push(t("validationRequiredIdForUpdate"));
127
+ msgs.push(t("validationFamilyMemberIdForUpdateRequired"));
128
128
  }
129
129
  if (msgs.length > 0) {
130
130
  validationErrors.push({ row: i + 1, messages: msgs });
@@ -14,8 +14,13 @@
14
14
  */
15
15
  import { FC } from "react";
16
16
  import { USER_ROLE } from "../../type";
17
- interface Props {
18
- cancelLabel: string;
17
+ interface ConfigProps {
18
+ dispatch: React.Dispatch<{
19
+ type: string;
20
+ payload?: unknown;
21
+ }>;
22
+ drawerButtonCancel: string;
23
+ drawerButtonSave: string;
19
24
  drawerFilterDescription: string;
20
25
  drawerFilterTitle: string;
21
26
  drawerFormDescription: string;
@@ -24,19 +29,41 @@ interface Props {
24
29
  drawerMoreActionsTitle: string;
25
30
  drawerViewDescription: string;
26
31
  drawerViewTitle: string;
27
- labelActions: string;
28
- labelEmail: string;
29
- labelEnabled: string;
30
- labelFirstName: string;
31
- labelId: string;
32
- labelPhone: string;
33
- labelPrimaryContact: string;
34
- labelRole: string;
35
- saveLabel: string;
36
- searchPlaceholder: string;
32
+ tableColumnHeaderActions: string;
33
+ tableColumnHeaderEmail: string;
34
+ tableColumnHeaderEnabled: string;
35
+ tableColumnHeaderFirstName: string;
36
+ tableColumnHeaderId: string;
37
+ tableColumnHeaderPhone: string;
38
+ tableColumnHeaderPrimaryContact: string;
39
+ tableColumnHeaderRole: string;
37
40
  tableDescription: string;
41
+ tableSearchPlaceholder: string;
38
42
  tableTitle: string;
39
- userRole: USER_ROLE;
40
43
  }
44
+ type Props = Omit<ConfigProps, "dispatch"> & {
45
+ drawerButtonCancel: string;
46
+ drawerButtonSave: string;
47
+ drawerFilterDescription: string;
48
+ drawerFilterTitle: string;
49
+ drawerFormDescription: string;
50
+ drawerFormTitle: string;
51
+ drawerMoreActionsDescription: string;
52
+ drawerMoreActionsTitle: string;
53
+ drawerViewDescription: string;
54
+ drawerViewTitle: string;
55
+ tableColumnHeaderActions: string;
56
+ tableColumnHeaderEmail: string;
57
+ tableColumnHeaderEnabled: string;
58
+ tableColumnHeaderFirstName: string;
59
+ tableColumnHeaderId: string;
60
+ tableColumnHeaderPhone: string;
61
+ tableColumnHeaderPrimaryContact: string;
62
+ tableColumnHeaderRole: string;
63
+ tableDescription: string;
64
+ tableSearchPlaceholder: string;
65
+ tableTitle: string;
66
+ userRole: USER_ROLE;
67
+ };
41
68
  export declare const FamilyMemberPage: FC<Props>;
42
69
  export {};
@@ -46,21 +46,21 @@ const createComponentInstances = () => ({
46
46
  moreActions: _jsx(FamilyMemberMoreActions, {}),
47
47
  view: _jsx(FamilyMemberView, {}),
48
48
  });
49
- const createFamilyMemberConfig = ({ cancelLabel, dispatch, drawerFilterDescription, drawerFilterTitle, drawerFormDescription, drawerFormTitle, drawerMoreActionsDescription, drawerMoreActionsTitle, drawerViewDescription, drawerViewTitle, labelActions, labelEmail, labelEnabled, labelFirstName, labelId, labelPhone, labelPrimaryContact, labelRole, saveLabel, searchPlaceholder, tableDescription, tableTitle, }) => {
49
+ const createFamilyMemberConfig = ({ dispatch, drawerButtonCancel, drawerButtonSave, drawerFilterDescription, drawerFilterTitle, drawerFormDescription, drawerFormTitle, drawerMoreActionsDescription, drawerMoreActionsTitle, drawerViewDescription, drawerViewTitle, tableColumnHeaderActions, tableColumnHeaderEmail, tableColumnHeaderEnabled, tableColumnHeaderFirstName, tableColumnHeaderId, tableColumnHeaderPhone, tableColumnHeaderPrimaryContact, tableColumnHeaderRole, tableDescription, tableSearchPlaceholder, tableTitle, }) => {
50
50
  const components = createComponentInstances();
51
51
  return {
52
52
  moduleName: "familyMember",
53
53
  tableColumns: [
54
- { label: labelId, width: "5%" },
55
- { label: labelFirstName, width: "20%" },
56
- { label: labelRole, width: "15%" },
57
- { label: labelEmail, width: "20%" },
58
- { label: labelPhone, width: "15%" },
59
- { label: labelPrimaryContact, width: "10%" },
60
- { label: labelEnabled, width: "10%" },
61
- { label: labelActions, width: "5%" },
54
+ { label: tableColumnHeaderId, width: "5%" },
55
+ { label: tableColumnHeaderFirstName, width: "20%" },
56
+ { label: tableColumnHeaderRole, width: "15%" },
57
+ { label: tableColumnHeaderEmail, width: "20%" },
58
+ { label: tableColumnHeaderPhone, width: "15%" },
59
+ { label: tableColumnHeaderPrimaryContact, width: "10%" },
60
+ { label: tableColumnHeaderEnabled, width: "10%" },
61
+ { label: tableColumnHeaderActions, width: "5%" },
62
62
  ],
63
- cancelLabel,
63
+ cancelLabel: drawerButtonCancel,
64
64
  drawerFilterDescription,
65
65
  drawerFilterTitle,
66
66
  drawerFormDescription,
@@ -72,8 +72,8 @@ const createFamilyMemberConfig = ({ cancelLabel, dispatch, drawerFilterDescripti
72
72
  filterContent: components.filter,
73
73
  formContent: components.form,
74
74
  moreActionsContent: components.moreActions,
75
- saveLabel,
76
- searchPlaceholder,
75
+ saveLabel: drawerButtonSave,
76
+ searchPlaceholder: tableSearchPlaceholder,
77
77
  tableDescription,
78
78
  tableTitle,
79
79
  viewContent: components.view,
@@ -91,7 +91,8 @@ const FamilyMemberPageInner = (props) => {
91
91
  // Memoize config creation - destructure props to avoid object reference changes
92
92
  const familyMemberConfig = useMemo(() => createFamilyMemberConfig({
93
93
  dispatch: context.dispatch,
94
- cancelLabel: props.cancelLabel,
94
+ drawerButtonCancel: props.drawerButtonCancel,
95
+ drawerButtonSave: props.drawerButtonSave,
95
96
  drawerFormTitle: props.drawerFormTitle,
96
97
  drawerFormDescription: props.drawerFormDescription,
97
98
  drawerViewTitle: props.drawerViewTitle,
@@ -100,21 +101,21 @@ const FamilyMemberPageInner = (props) => {
100
101
  drawerFilterDescription: props.drawerFilterDescription,
101
102
  drawerMoreActionsTitle: props.drawerMoreActionsTitle,
102
103
  drawerMoreActionsDescription: props.drawerMoreActionsDescription,
103
- labelActions: props.labelActions,
104
- labelEmail: props.labelEmail,
105
- labelEnabled: props.labelEnabled,
106
- labelFirstName: props.labelFirstName,
107
- labelId: props.labelId,
108
- labelPhone: props.labelPhone,
109
- labelPrimaryContact: props.labelPrimaryContact,
110
- labelRole: props.labelRole,
111
- saveLabel: props.saveLabel,
112
- searchPlaceholder: props.searchPlaceholder,
104
+ tableColumnHeaderActions: props.tableColumnHeaderActions,
105
+ tableColumnHeaderEmail: props.tableColumnHeaderEmail,
106
+ tableColumnHeaderEnabled: props.tableColumnHeaderEnabled,
107
+ tableColumnHeaderFirstName: props.tableColumnHeaderFirstName,
108
+ tableColumnHeaderId: props.tableColumnHeaderId,
109
+ tableColumnHeaderPhone: props.tableColumnHeaderPhone,
110
+ tableColumnHeaderPrimaryContact: props.tableColumnHeaderPrimaryContact,
111
+ tableColumnHeaderRole: props.tableColumnHeaderRole,
113
112
  tableDescription: props.tableDescription,
113
+ tableSearchPlaceholder: props.tableSearchPlaceholder,
114
114
  tableTitle: props.tableTitle,
115
115
  }), [
116
116
  context.dispatch,
117
- props.cancelLabel,
117
+ props.drawerButtonCancel,
118
+ props.drawerButtonSave,
118
119
  props.drawerFormTitle,
119
120
  props.drawerFormDescription,
120
121
  props.drawerViewTitle,
@@ -123,17 +124,16 @@ const FamilyMemberPageInner = (props) => {
123
124
  props.drawerFilterDescription,
124
125
  props.drawerMoreActionsTitle,
125
126
  props.drawerMoreActionsDescription,
126
- props.labelActions,
127
- props.labelEmail,
128
- props.labelEnabled,
129
- props.labelFirstName,
130
- props.labelId,
131
- props.labelPhone,
132
- props.labelPrimaryContact,
133
- props.labelRole,
134
- props.saveLabel,
135
- props.searchPlaceholder,
127
+ props.tableColumnHeaderActions,
128
+ props.tableColumnHeaderEmail,
129
+ props.tableColumnHeaderEnabled,
130
+ props.tableColumnHeaderFirstName,
131
+ props.tableColumnHeaderId,
132
+ props.tableColumnHeaderPhone,
133
+ props.tableColumnHeaderPrimaryContact,
134
+ props.tableColumnHeaderRole,
136
135
  props.tableDescription,
136
+ props.tableSearchPlaceholder,
137
137
  props.tableTitle,
138
138
  ]);
139
139
  const hasPermission = resolveRbacPermissions({
@@ -4,6 +4,14 @@
4
4
  * Zod validation schemas for family-member form data.
5
5
  */
6
6
  import { z } from "zod";
7
+ export declare const VALIDATION_KEYS: {
8
+ readonly familyId: "validationFamilyMemberFamilyIdRequired";
9
+ readonly firstName: "validationFamilyMemberFirstNameRequired";
10
+ readonly lastName: "validationFamilyMemberLastNameRequired";
11
+ readonly role: "validationFamilyMemberRoleRequired";
12
+ readonly emailInvalid: "validationFamilyMemberEmailInvalid";
13
+ readonly idForUpdate: "validationFamilyMemberIdForUpdateRequired";
14
+ };
7
15
  export declare const familyMemberFormValidation: z.ZodObject<{
8
16
  familyId: z.ZodString;
9
17
  firstName: z.ZodString;
@@ -5,18 +5,33 @@
5
5
  */
6
6
  import { z } from "zod";
7
7
  // ============================================================================
8
+ // VALIDATION KEYS (used as Zod error messages, translated via getTranslatedError)
9
+ // ============================================================================
10
+ export const VALIDATION_KEYS = {
11
+ familyId: "validationFamilyMemberFamilyIdRequired",
12
+ firstName: "validationFamilyMemberFirstNameRequired",
13
+ lastName: "validationFamilyMemberLastNameRequired",
14
+ role: "validationFamilyMemberRoleRequired",
15
+ emailInvalid: "validationFamilyMemberEmailInvalid",
16
+ idForUpdate: "validationFamilyMemberIdForUpdateRequired",
17
+ };
18
+ // ============================================================================
8
19
  // VALIDATION SCHEMA
9
20
  // ============================================================================
10
21
  export const familyMemberFormValidation = z.object({
11
- familyId: z.string().min(1, "Family is required"),
12
- firstName: z.string().min(1, "First name is required"),
13
- lastName: z.string().min(1, "Last name is required"),
14
- role: z.string().min(1, "Role is required"),
22
+ familyId: z.string().min(1, VALIDATION_KEYS.familyId),
23
+ firstName: z.string().min(1, VALIDATION_KEYS.firstName),
24
+ lastName: z.string().min(1, VALIDATION_KEYS.lastName),
25
+ role: z.string().min(1, VALIDATION_KEYS.role),
15
26
  dateOfBirth: z.string().optional(),
16
27
  gender: z.string().optional(),
17
28
  bloodGroup: z.string().optional(),
18
29
  phone: z.string().optional(),
19
- email: z.string().email().optional().or(z.literal("")),
30
+ email: z
31
+ .string()
32
+ .email(VALIDATION_KEYS.emailInvalid)
33
+ .optional()
34
+ .or(z.literal("")),
20
35
  relationship: z.string().optional(),
21
36
  occupation: z.string().optional(),
22
37
  emergencyPhone: z.string().optional(),
@@ -34,9 +34,9 @@ export const FamilyMemberView = () => {
34
34
  return "—";
35
35
  return formatDate(new Date(value).toISOString(), DATE_FORMATS.LOCALE_DATE);
36
36
  };
37
- 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: [_jsxs(Avatar, { className: "h-24 w-24", children: [_jsx(AvatarImage, { src: avatar || undefined, alt: fullName }), _jsx(AvatarFallback, { className: "text-2xl", children: initials || "FM" })] }), _jsxs("div", { className: "flex-1", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("h2", { className: "text-2xl font-bold", children: fullName }), enabled ? (_jsxs(Badge, { variant: "default", className: "gap-1", children: [_jsx(CheckCircle2, { className: "h-3 w-3" }), t("badgeActive")] })) : (_jsxs(Badge, { variant: "secondary", className: "gap-1", children: [_jsx(XCircle, { className: "h-3 w-3" }), t("badgeInactive")] })), isPrimary && (_jsxs(Badge, { variant: "outline", className: "gap-1", children: [_jsx(ShieldCheck, { className: "h-3 w-3" }), t("viewFieldPrimaryContact")] }))] }), _jsx("p", { className: "text-muted-foreground mt-1 text-sm", children: t("viewFieldFamilyMemberProfile") }), _jsxs("div", { className: "mt-3 flex flex-wrap items-center gap-2", children: [role ? (_jsx(Badge, { variant: "secondary", className: "capitalize", children: formatEnumValue(role) })) : null, relationship ? (_jsx(Badge, { variant: "outline", className: "capitalize", children: formatEnumValue(relationship) })) : null, gender ? (_jsx(Badge, { variant: "outline", className: "capitalize", children: formatEnumValue(gender) })) : null] })] })] }) }) }), _jsxs(Card, { children: [_jsxs(CardHeader, { className: "pb-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(User, { className: "text-primary h-5 w-5" }), _jsx(CardTitle, { className: "text-lg", children: t("viewSectionPersonalInformation") })] }), _jsx(CardDescription, { children: t("viewSectionBasicIdentityAndProfileDetails") })] }), _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("viewFieldFirstName") }), _jsx("p", { className: "text-base", children: formatValue(firstName) })] }), _jsxs("div", { className: "space-y-1", children: [_jsx("p", { className: "text-muted-foreground text-sm font-medium", children: t("viewFieldLastName") }), _jsx("p", { className: "text-base", children: formatValue(lastName) })] }), _jsxs("div", { className: "space-y-1", children: [_jsx("p", { className: "text-muted-foreground text-sm font-medium", children: t("viewFieldRole") }), role ? (_jsx(Badge, { variant: "secondary", className: "capitalize", children: formatEnumValue(role) })) : (_jsx("p", { className: "text-base", children: "\u2014" }))] }), _jsxs("div", { className: "space-y-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Calendar, { className: "text-muted-foreground h-4 w-4" }), _jsx("p", { className: "text-muted-foreground text-sm font-medium", children: t("viewFieldDateOfBirth") })] }), _jsx("p", { className: "text-base", children: formatDateValue(dateOfBirth) })] }), _jsxs("div", { className: "space-y-1", children: [_jsx("p", { className: "text-muted-foreground text-sm font-medium", children: t("viewFieldGender") }), gender ? (_jsx(Badge, { variant: "outline", className: "capitalize", children: formatEnumValue(gender) })) : (_jsx("p", { className: "text-base", children: "\u2014" }))] }), _jsxs("div", { className: "space-y-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Heart, { className: "text-muted-foreground h-4 w-4" }), _jsx("p", { className: "text-muted-foreground text-sm font-medium", children: t("viewFieldBloodGroup") })] }), _jsx("p", { className: "text-base", children: formatValue(bloodGroup) })] }), _jsxs("div", { className: "space-y-1 md:col-span-2", children: [_jsx("p", { className: "text-muted-foreground text-sm font-medium", children: t("viewFieldIdNumber") }), _jsx("p", { className: "text-base", children: formatValue(idNumber) })] })] }) })] }), _jsxs(Card, { children: [_jsxs(CardHeader, { className: "pb-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Phone, { className: "text-primary h-5 w-5" }), _jsx(CardTitle, { className: "text-lg", children: t("viewSectionContactInformation") })] }), _jsx(CardDescription, { children: t("viewSectionReachabilityAndEmergencyContactDetails") })] }), _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: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Phone, { className: "text-muted-foreground h-4 w-4" }), _jsx("p", { className: "text-muted-foreground text-sm font-medium", children: t("viewFieldPhone") })] }), _jsx("p", { className: "text-base", children: formatPhoneDisplay(phone) || formatValue(phone) })] }), _jsxs("div", { className: "space-y-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Mail, { className: "text-muted-foreground h-4 w-4" }), _jsx("p", { className: "text-muted-foreground text-sm font-medium", children: t("viewFieldEmail") })] }), _jsx("p", { className: "text-base", children: formatValue(email) })] }), _jsxs("div", { className: "space-y-1 md:col-span-2", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Phone, { className: "text-muted-foreground h-4 w-4" }), _jsx("p", { className: "text-muted-foreground text-sm font-medium", children: t("viewFieldEmergencyPhone") })] }), _jsx("p", { className: "text-base", children: formatPhoneDisplay(emergencyPhone) ||
38
- formatValue(emergencyPhone) })] })] }) })] }), _jsxs(Card, { children: [_jsxs(CardHeader, { className: "pb-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Users, { className: "text-primary h-5 w-5" }), _jsx(CardTitle, { className: "text-lg", children: t("viewFieldFamilyRole") })] }), _jsx(CardDescription, { children: t("viewFieldRelationshipAndHouseholdResponsibilities") })] }), _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("viewFieldRelationship") }), relationship ? (_jsx(Badge, { variant: "secondary", className: "capitalize", children: formatEnumValue(relationship) })) : (_jsx("p", { className: "text-base", children: "\u2014" }))] }), _jsxs("div", { className: "space-y-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Briefcase, { className: "text-muted-foreground h-4 w-4" }), _jsx("p", { className: "text-muted-foreground text-sm font-medium", children: t("viewFieldOccupation") })] }), _jsx("p", { className: "text-base", children: formatValue(occupation) })] })] }) })] }), _jsxs(Card, { children: [_jsxs(CardHeader, { className: "pb-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(ShieldCheck, { className: "text-primary h-5 w-5" }), _jsx(CardTitle, { className: "text-lg", children: t("viewFieldStatus") })] }), _jsx(CardDescription, { children: t("viewFieldPrimaryContactAndAccountActivity") })] }), _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: "flex items-start gap-3", children: [_jsx(ShieldCheck, { className: "text-primary mt-0.5 h-5 w-5" }), _jsxs("div", { children: [_jsx("p", { className: "font-medium", children: isPrimary
39
- ? t("viewFieldPrimaryContact")
37
+ 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: [_jsxs(Avatar, { className: "h-24 w-24", children: [_jsx(AvatarImage, { src: avatar || undefined, alt: fullName }), _jsx(AvatarFallback, { className: "text-2xl", children: initials || "FM" })] }), _jsxs("div", { className: "flex-1", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("h2", { className: "text-2xl font-bold", children: fullName }), enabled ? (_jsxs(Badge, { variant: "default", className: "gap-1", children: [_jsx(CheckCircle2, { className: "h-3 w-3" }), t("badgeActive")] })) : (_jsxs(Badge, { variant: "secondary", className: "gap-1", children: [_jsx(XCircle, { className: "h-3 w-3" }), t("badgeInactive")] })), isPrimary && (_jsxs(Badge, { variant: "outline", className: "gap-1", children: [_jsx(ShieldCheck, { className: "h-3 w-3" }), t("formPrimaryContactLabel")] }))] }), _jsx("p", { className: "text-muted-foreground mt-1 text-sm", children: t("viewFieldFamilyMemberProfile") }), _jsxs("div", { className: "mt-3 flex flex-wrap items-center gap-2", children: [role ? (_jsx(Badge, { variant: "secondary", className: "capitalize", children: formatEnumValue(role) })) : null, relationship ? (_jsx(Badge, { variant: "outline", className: "capitalize", children: formatEnumValue(relationship) })) : null, gender ? (_jsx(Badge, { variant: "outline", className: "capitalize", children: formatEnumValue(gender) })) : null] })] })] }) }) }), _jsxs(Card, { children: [_jsxs(CardHeader, { className: "pb-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(User, { className: "text-primary h-5 w-5" }), _jsx(CardTitle, { className: "text-lg", children: t("formSectionPersonalInformation") })] }), _jsx(CardDescription, { children: t("viewSectionBasicIdentityAndProfileDetails") })] }), _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("formFirstNameLabel") }), _jsx("p", { className: "text-base", children: formatValue(firstName) })] }), _jsxs("div", { className: "space-y-1", children: [_jsx("p", { className: "text-muted-foreground text-sm font-medium", children: t("formLastNameLabel") }), _jsx("p", { className: "text-base", children: formatValue(lastName) })] }), _jsxs("div", { className: "space-y-1", children: [_jsx("p", { className: "text-muted-foreground text-sm font-medium", children: t("formRoleLabel") }), role ? (_jsx(Badge, { variant: "secondary", className: "capitalize", children: formatEnumValue(role) })) : (_jsx("p", { className: "text-base", children: "\u2014" }))] }), _jsxs("div", { className: "space-y-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Calendar, { className: "text-muted-foreground h-4 w-4" }), _jsx("p", { className: "text-muted-foreground text-sm font-medium", children: t("formDateOfBirthLabel") })] }), _jsx("p", { className: "text-base", children: formatDateValue(dateOfBirth) })] }), _jsxs("div", { className: "space-y-1", children: [_jsx("p", { className: "text-muted-foreground text-sm font-medium", children: t("formGenderLabel") }), gender ? (_jsx(Badge, { variant: "outline", className: "capitalize", children: formatEnumValue(gender) })) : (_jsx("p", { className: "text-base", children: "\u2014" }))] }), _jsxs("div", { className: "space-y-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Heart, { className: "text-muted-foreground h-4 w-4" }), _jsx("p", { className: "text-muted-foreground text-sm font-medium", children: t("formBloodGroupLabel") })] }), _jsx("p", { className: "text-base", children: formatValue(bloodGroup) })] }), _jsxs("div", { className: "space-y-1 md:col-span-2", children: [_jsx("p", { className: "text-muted-foreground text-sm font-medium", children: t("formIdNumberLabel") }), _jsx("p", { className: "text-base", children: formatValue(idNumber) })] })] }) })] }), _jsxs(Card, { children: [_jsxs(CardHeader, { className: "pb-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Phone, { className: "text-primary h-5 w-5" }), _jsx(CardTitle, { className: "text-lg", children: t("formSectionContactInformation") })] }), _jsx(CardDescription, { children: t("viewSectionReachabilityAndEmergencyContactDetails") })] }), _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: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Phone, { className: "text-muted-foreground h-4 w-4" }), _jsx("p", { className: "text-muted-foreground text-sm font-medium", children: t("formPhoneLabel") })] }), _jsx("p", { className: "text-base", children: formatPhoneDisplay(phone) || formatValue(phone) })] }), _jsxs("div", { className: "space-y-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Mail, { className: "text-muted-foreground h-4 w-4" }), _jsx("p", { className: "text-muted-foreground text-sm font-medium", children: t("formEmailLabel") })] }), _jsx("p", { className: "text-base", children: formatValue(email) })] }), _jsxs("div", { className: "space-y-1 md:col-span-2", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Phone, { className: "text-muted-foreground h-4 w-4" }), _jsx("p", { className: "text-muted-foreground text-sm font-medium", children: t("formEmergencyPhoneLabel") })] }), _jsx("p", { className: "text-base", children: formatPhoneDisplay(emergencyPhone) ||
38
+ formatValue(emergencyPhone) })] })] }) })] }), _jsxs(Card, { children: [_jsxs(CardHeader, { className: "pb-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Users, { className: "text-primary h-5 w-5" }), _jsx(CardTitle, { className: "text-lg", children: t("viewFieldFamilyRole") })] }), _jsx(CardDescription, { children: t("viewFieldRelationshipAndHouseholdResponsibilities") })] }), _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("formRelationshipLabel") }), relationship ? (_jsx(Badge, { variant: "secondary", className: "capitalize", children: formatEnumValue(relationship) })) : (_jsx("p", { className: "text-base", children: "\u2014" }))] }), _jsxs("div", { className: "space-y-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Briefcase, { className: "text-muted-foreground h-4 w-4" }), _jsx("p", { className: "text-muted-foreground text-sm font-medium", children: t("formOccupationLabel") })] }), _jsx("p", { className: "text-base", children: formatValue(occupation) })] })] }) })] }), _jsxs(Card, { children: [_jsxs(CardHeader, { className: "pb-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(ShieldCheck, { className: "text-primary h-5 w-5" }), _jsx(CardTitle, { className: "text-lg", children: t("viewFieldStatus") })] }), _jsx(CardDescription, { children: t("viewFieldPrimaryContactAndAccountActivity") })] }), _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: "flex items-start gap-3", children: [_jsx(ShieldCheck, { className: "text-primary mt-0.5 h-5 w-5" }), _jsxs("div", { children: [_jsx("p", { className: "font-medium", children: isPrimary
39
+ ? t("formPrimaryContactLabel")
40
40
  : t("viewFieldSecondaryContact") }), _jsx("p", { className: "text-muted-foreground text-sm", children: isPrimary
41
41
  ? t("viewFieldThisIsPrimaryFamilyContact")
42
42
  : t("viewFieldThisIsAdditionalFamilyContact") })] })] }), _jsxs("div", { className: "flex items-start gap-3", children: [enabled ? (_jsx(CheckCircle2, { className: "mt-0.5 h-5 w-5 text-green-500" })) : (_jsx(XCircle, { className: "mt-0.5 h-5 w-5 text-red-500" })), _jsxs("div", { children: [_jsx("p", { className: "font-medium", children: enabled ? t("badgeActive") : t("badgeInactive") }), _jsx("p", { className: "text-muted-foreground text-sm", children: enabled
@@ -17,6 +17,7 @@ import { useTranslations } from "next-intl";
17
17
  import { useFetch } from "@react-pakistan/util-functions/hooks/use-fetch";
18
18
  import { API_METHODS } from "@react-pakistan/util-functions";
19
19
  import { useEffect } from "react";
20
+ import { getTranslatedError } from "@/utils/get-translated-error";
20
21
  export const FeeStructureForm = () => {
21
22
  var _a, _b, _c;
22
23
  const { state, handleChange } = useFeeStructureModule();
@@ -54,7 +55,7 @@ export const FeeStructureForm = () => {
54
55
  emptyText: t("formNoFeeTypeEmpty"),
55
56
  id: "feeType",
56
57
  info: t("formFeeTypeInfo"),
57
- label: t("formOptionFeeType"),
58
+ label: t("formFeeTypeLabel"),
58
59
  onValueChange: (value) => handleChange("feeType", value),
59
60
  options: FEE_TYPE_OPTIONS.map((opt) => ({
60
61
  value: opt.value,
@@ -77,7 +78,7 @@ export const FeeStructureForm = () => {
77
78
  emptyText: t("formNoFrequencyEmpty"),
78
79
  id: "frequency",
79
80
  info: t("formFrequencyInfo"),
80
- label: t("formOptionFrequency"),
81
+ label: t("formFrequencyLabel"),
81
82
  onValueChange: (value) => handleChange("frequency", value),
82
83
  options: FREQUENCY_OPTIONS.map((opt) => ({
83
84
  value: opt.value,
@@ -117,7 +118,7 @@ export const FeeStructureForm = () => {
117
118
  },
118
119
  value: classId || "",
119
120
  });
120
- return (_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "grid grid-cols-1 gap-4", children: [_jsx(EnhancedInput, { error: errors.name, id: "name", info: t("formNameInfo"), label: t("formNameLabel"), onChange: (e) => handleChange("name", e.target.value), placeholder: t("formNamePlaceholder"), required: true, value: name || "" }), feeTypeCombo, _jsx(EnhancedInput, { error: errors.amount, id: "amount", info: t(`amountInfo`, {
121
+ return (_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "grid grid-cols-1 gap-4", children: [_jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "name", t }), id: "name", info: t("formNameInfo"), label: t("formNameLabel"), onChange: (e) => handleChange("name", e.target.value), placeholder: t("formNamePlaceholder"), required: true, value: name || "" }), feeTypeCombo, _jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "amount", t }), id: "amount", info: t("formAmountInfo", {
121
122
  currency: (_c = (_b = workspace === null || workspace === void 0 ? void 0 : workspace.school) === null || _b === void 0 ? void 0 : _b.currency) !== null && _c !== void 0 ? _c : "",
122
- }), label: t("formAmountLabel"), min: "0", onChange: (e) => handleChange("amount", Number(e.target.value)), placeholder: t("formAmountPlaceholder"), required: true, step: "0.01", type: "number", value: amount }), frequencyCombo, classIdCombo, _jsx(EnhancedTextarea, { error: errors.description, id: "description", info: t("formDescriptionInfo"), label: t("formDescriptionLabel"), onChange: (e) => handleChange("description", e.target.value), placeholder: t("formDescriptionPlaceholder"), rows: 3, value: description || "" })] }), _jsx(EnhancedCheckbox, { defaultChecked: enabled, label: t("formActiveFeeStructureLabel"), onCheckedChange: (checked) => handleChange("enabled", checked) })] }));
123
+ }), label: t("formAmountLabel"), min: "0", onChange: (e) => handleChange("amount", Number(e.target.value)), placeholder: t("formAmountPlaceholder"), required: true, step: "0.01", type: "number", value: amount }), frequencyCombo, classIdCombo, _jsx(EnhancedTextarea, { error: getTranslatedError({ errors, key: "description", t }), id: "description", info: t("formDescriptionInfo"), label: t("formDescriptionLabel"), onChange: (e) => handleChange("description", e.target.value), placeholder: t("formDescriptionPlaceholder"), rows: 3, value: description || "" })] }), _jsx(EnhancedCheckbox, { defaultChecked: enabled, label: t("formActiveFeeStructureLabel"), onCheckedChange: (checked) => handleChange("enabled", checked) })] }));
123
124
  };
@@ -116,12 +116,12 @@ export const FeeStructureMoreActions = () => {
116
116
  if (method === "POST") {
117
117
  const result = feeStructureFormValidation.safeParse(Object.assign(Object.assign({}, row), { amount: Number(row.amount) }));
118
118
  if (!result.success) {
119
- msgs.push(...result.error.issues.map((issue) => `${issue.path.join(".")}: ${issue.message}`));
119
+ msgs.push(...result.error.issues.map((issue) => `${issue.path.join(".")}: ${t(issue.message)}`));
120
120
  }
121
121
  }
122
122
  else {
123
123
  if (!((_b = row.id) === null || _b === void 0 ? void 0 : _b.trim()))
124
- msgs.push(t("validationRequiredIdForUpdate"));
124
+ msgs.push(t("validationFeeStructureIdForUpdateRequired"));
125
125
  }
126
126
  if (msgs.length > 0) {
127
127
  validationErrors.push({ row: i + 1, messages: msgs });
@@ -18,7 +18,8 @@
18
18
  import { FC } from "react";
19
19
  import { USER_ROLE } from "../../type";
20
20
  interface Props {
21
- cancelLabel: string;
21
+ drawerButtonCancel: string;
22
+ drawerButtonSave: string;
22
23
  drawerFilterDescription: string;
23
24
  drawerFilterTitle: string;
24
25
  drawerFormDescription: string;
@@ -27,17 +28,16 @@ interface Props {
27
28
  drawerMoreActionsTitle: string;
28
29
  drawerViewDescription: string;
29
30
  drawerViewTitle: string;
30
- labelActions: string;
31
- labelAmount: string;
32
- labelDescription: string;
33
- labelEnabled: string;
34
- labelFeeType: string;
35
- labelFrequency: string;
36
- labelId: string;
37
- labelName: string;
38
- saveLabel: string;
39
- searchPlaceholder: string;
31
+ tableColumnHeaderActions: string;
32
+ tableColumnHeaderAmount: string;
33
+ tableColumnHeaderDescription: string;
34
+ tableColumnHeaderEnabled: string;
35
+ tableColumnHeaderFeeType: string;
36
+ tableColumnHeaderFrequency: string;
37
+ tableColumnHeaderId: string;
38
+ tableColumnHeaderName: string;
40
39
  tableDescription: string;
40
+ tableSearchPlaceholder: string;
41
41
  tableTitle: string;
42
42
  userRole: USER_ROLE;
43
43
  }
@@ -66,21 +66,21 @@ const createComponentInstances = () => ({
66
66
  moreActions: _jsx(FeeStructureMoreActions, {}),
67
67
  view: _jsx(FeeStructureView, {}),
68
68
  });
69
- const createFeeStructureConfig = ({ cancelLabel, dispatch, drawerFilterDescription, drawerFilterTitle, drawerFormDescription, drawerFormTitle, drawerMoreActionsDescription, drawerMoreActionsTitle, drawerViewDescription, drawerViewTitle, labelActions, labelAmount, labelDescription, labelEnabled, labelFeeType, labelFrequency, labelId, labelName, saveLabel, searchPlaceholder, tableDescription, tableTitle, }) => {
69
+ const createFeeStructureConfig = ({ dispatch, drawerButtonCancel, drawerButtonSave, drawerFilterDescription, drawerFilterTitle, drawerFormDescription, drawerFormTitle, drawerMoreActionsDescription, drawerMoreActionsTitle, drawerViewDescription, drawerViewTitle, tableColumnHeaderActions, tableColumnHeaderAmount, tableColumnHeaderDescription, tableColumnHeaderEnabled, tableColumnHeaderFeeType, tableColumnHeaderFrequency, tableColumnHeaderId, tableColumnHeaderName, tableDescription, tableSearchPlaceholder, tableTitle, }) => {
70
70
  const components = createComponentInstances();
71
71
  return {
72
72
  moduleName: "feeStructure",
73
73
  tableColumns: [
74
- { label: labelId, width: "5%" },
75
- { label: labelName, width: "20%" },
76
- { label: labelFeeType, width: "15%" },
77
- { label: labelAmount, width: "15%" },
78
- { label: labelFrequency, width: "10%" },
79
- { label: labelDescription, width: "20%" },
80
- { label: labelEnabled, width: "10%" },
81
- { label: labelActions, width: "5%" },
74
+ { label: tableColumnHeaderId, width: "5%" },
75
+ { label: tableColumnHeaderName, width: "20%" },
76
+ { label: tableColumnHeaderFeeType, width: "15%" },
77
+ { label: tableColumnHeaderAmount, width: "15%" },
78
+ { label: tableColumnHeaderFrequency, width: "10%" },
79
+ { label: tableColumnHeaderDescription, width: "20%" },
80
+ { label: tableColumnHeaderEnabled, width: "10%" },
81
+ { label: tableColumnHeaderActions, width: "5%" },
82
82
  ],
83
- cancelLabel,
83
+ cancelLabel: drawerButtonCancel,
84
84
  drawerFilterDescription,
85
85
  drawerFilterTitle,
86
86
  drawerFormDescription,
@@ -92,8 +92,8 @@ const createFeeStructureConfig = ({ cancelLabel, dispatch, drawerFilterDescripti
92
92
  filterContent: components.filter,
93
93
  formContent: components.form,
94
94
  moreActionsContent: components.moreActions,
95
- saveLabel,
96
- searchPlaceholder,
95
+ saveLabel: drawerButtonSave,
96
+ searchPlaceholder: tableSearchPlaceholder,
97
97
  tableDescription,
98
98
  tableTitle,
99
99
  viewContent: components.view,
@@ -110,7 +110,8 @@ const FeeStructurePageInner = (props) => {
110
110
  const context = useFeeStructureModule();
111
111
  const feeStructureConfig = useMemo(() => createFeeStructureConfig({
112
112
  dispatch: context.dispatch,
113
- cancelLabel: props.cancelLabel,
113
+ drawerButtonCancel: props.drawerButtonCancel,
114
+ drawerButtonSave: props.drawerButtonSave,
114
115
  drawerFormTitle: props.drawerFormTitle,
115
116
  drawerFormDescription: props.drawerFormDescription,
116
117
  drawerViewTitle: props.drawerViewTitle,
@@ -119,21 +120,21 @@ const FeeStructurePageInner = (props) => {
119
120
  drawerFilterDescription: props.drawerFilterDescription,
120
121
  drawerMoreActionsTitle: props.drawerMoreActionsTitle,
121
122
  drawerMoreActionsDescription: props.drawerMoreActionsDescription,
122
- labelActions: props.labelActions,
123
- labelAmount: props.labelAmount,
124
- labelDescription: props.labelDescription,
125
- labelEnabled: props.labelEnabled,
126
- labelFeeType: props.labelFeeType,
127
- labelFrequency: props.labelFrequency,
128
- labelId: props.labelId,
129
- labelName: props.labelName,
130
- saveLabel: props.saveLabel,
131
- searchPlaceholder: props.searchPlaceholder,
123
+ tableColumnHeaderActions: props.tableColumnHeaderActions,
124
+ tableColumnHeaderAmount: props.tableColumnHeaderAmount,
125
+ tableColumnHeaderDescription: props.tableColumnHeaderDescription,
126
+ tableColumnHeaderEnabled: props.tableColumnHeaderEnabled,
127
+ tableColumnHeaderFeeType: props.tableColumnHeaderFeeType,
128
+ tableColumnHeaderFrequency: props.tableColumnHeaderFrequency,
129
+ tableColumnHeaderId: props.tableColumnHeaderId,
130
+ tableColumnHeaderName: props.tableColumnHeaderName,
132
131
  tableDescription: props.tableDescription,
132
+ tableSearchPlaceholder: props.tableSearchPlaceholder,
133
133
  tableTitle: props.tableTitle,
134
134
  }), [
135
135
  context.dispatch,
136
- props.cancelLabel,
136
+ props.drawerButtonCancel,
137
+ props.drawerButtonSave,
137
138
  props.drawerFormTitle,
138
139
  props.drawerFormDescription,
139
140
  props.drawerViewTitle,
@@ -142,17 +143,16 @@ const FeeStructurePageInner = (props) => {
142
143
  props.drawerFilterDescription,
143
144
  props.drawerMoreActionsTitle,
144
145
  props.drawerMoreActionsDescription,
145
- props.labelActions,
146
- props.labelAmount,
147
- props.labelDescription,
148
- props.labelEnabled,
149
- props.labelFeeType,
150
- props.labelFrequency,
151
- props.labelId,
152
- props.labelName,
153
- props.saveLabel,
154
- props.searchPlaceholder,
146
+ props.tableColumnHeaderActions,
147
+ props.tableColumnHeaderAmount,
148
+ props.tableColumnHeaderDescription,
149
+ props.tableColumnHeaderEnabled,
150
+ props.tableColumnHeaderFeeType,
151
+ props.tableColumnHeaderFrequency,
152
+ props.tableColumnHeaderId,
153
+ props.tableColumnHeaderName,
155
154
  props.tableDescription,
155
+ props.tableSearchPlaceholder,
156
156
  props.tableTitle,
157
157
  ]);
158
158
  const hasPermission = resolveRbacPermissions({
@@ -5,6 +5,12 @@
5
5
  */
6
6
  import { z } from "zod";
7
7
  import { FEE_TYPE } from "../../type";
8
+ export declare const VALIDATION_KEYS: {
9
+ readonly name: "validationFeeStructureNameRequired";
10
+ readonly feeType: "validationFeeStructureFeeTypeRequired";
11
+ readonly amountPositive: "validationFeeStructureAmountPositive";
12
+ readonly idForUpdate: "validationFeeStructureIdForUpdateRequired";
13
+ };
8
14
  export declare const feeStructureFormValidation: z.ZodObject<{
9
15
  name: z.ZodString;
10
16
  feeType: z.ZodEnum<typeof FEE_TYPE>;
@@ -5,10 +5,19 @@
5
5
  */
6
6
  import { z } from "zod";
7
7
  import { FEE_TYPE } from "../../type";
8
+ // ============================================================================
9
+ // VALIDATION KEYS (used as Zod error messages, translated via getTranslatedError)
10
+ // ============================================================================
11
+ export const VALIDATION_KEYS = {
12
+ name: "validationFeeStructureNameRequired",
13
+ feeType: "validationFeeStructureFeeTypeRequired",
14
+ amountPositive: "validationFeeStructureAmountPositive",
15
+ idForUpdate: "validationFeeStructureIdForUpdateRequired",
16
+ };
8
17
  export const feeStructureFormValidation = z.object({
9
- name: z.string().min(1, "Name is required"),
10
- feeType: z.nativeEnum(FEE_TYPE, { error: "Fee type is required" }),
11
- amount: z.number().positive("Amount must be positive"),
18
+ name: z.string().min(1, VALIDATION_KEYS.name),
19
+ feeType: z.nativeEnum(FEE_TYPE, { error: VALIDATION_KEYS.feeType }),
20
+ amount: z.number().positive(VALIDATION_KEYS.amountPositive),
12
21
  classId: z.string().optional().nullable(),
13
22
  frequency: z.string().optional().nullable(),
14
23
  description: z.string().optional().nullable(),