@syzy/apphost 1.0.1 → 1.0.2

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 (213) hide show
  1. package/dist/App.js +83 -0
  2. package/dist/AppHostProvider.js +4 -0
  3. package/dist/AppHostRoutes.js +7 -0
  4. package/dist/api/image-api.js +45 -0
  5. package/dist/api/mapping-api.js +427 -0
  6. package/dist/bookingModule/components/AmenityForm.js +19 -0
  7. package/dist/bookingModule/components/BillingManagement.js +17 -0
  8. package/dist/bookingModule/components/CreateRoomForm.js +19 -0
  9. package/dist/bookingModule/components/ExtraRequirementForm.js +19 -0
  10. package/dist/bookingModule/components/ReservationForm.js +18 -0
  11. package/dist/bookingModule/components/RoomCategoryForm.js +19 -0
  12. package/dist/bookingModule/components/RoomCategoryPriceForm.js +20 -0
  13. package/dist/bookingModule/components/RoomExtraRequirementCapture.js +18 -0
  14. package/dist/bookingModule/components/RoomFacilityForm.js +19 -0
  15. package/dist/bookingModule/components/RoomReservationAction.js +18 -0
  16. package/dist/components/Home/Home.js +14 -0
  17. package/dist/components/Loader/Loader.js +5 -0
  18. package/dist/components/Login/Login.js +149 -0
  19. package/dist/components/Login/loginSchema.js +41 -0
  20. package/dist/components/Mappings/BranchMapping/Branch.js +135 -0
  21. package/dist/components/Mappings/BranchMapping/BranchTableColumns.js +21 -0
  22. package/dist/components/Mappings/BranchMapping/MappingFormBranchUser.js +150 -0
  23. package/dist/components/Mappings/BranchMapping/MappingTableColumns.js +29 -0
  24. package/dist/components/Mappings/BranchMapping/branchSchema.js +34 -0
  25. package/dist/components/Mappings/ComponentMapping/ComponentRoleMapping.js +98 -0
  26. package/dist/components/Mappings/ComponentMapping/componentRoleColumns.js +29 -0
  27. package/dist/components/Mappings/MappingForm/MappingForm.js +142 -0
  28. package/dist/components/Mappings/MappingForm/mappingSchema.js +32 -0
  29. package/dist/components/Mappings/RoleMapping/MappingFormUserRole.js +194 -0
  30. package/dist/components/Mappings/RoleMapping/UserRoleTableColumns.js +33 -0
  31. package/dist/components/NavBar/Sidebar.js +56 -0
  32. package/dist/components/ProfileForm/ProfileForm.js +190 -0
  33. package/dist/components/ProfileForm/ProfileList.js +33 -0
  34. package/dist/components/ProfileForm/profileColumns.js +67 -0
  35. package/dist/components/ProfileForm/profileSchema.js +50 -0
  36. package/dist/components/SettingsPage/SettingsPage.js +240 -0
  37. package/dist/components/api/settings-api.js +131 -0
  38. package/dist/components/common/Form/FormActionButtons.js +6 -0
  39. package/dist/components/common/Form/FormLabel.js +6 -0
  40. package/dist/components/common/ListTable/ListHeader.js +5 -0
  41. package/dist/components/common/ListTable/ListTable.js +31 -0
  42. package/dist/components/common/Modal/Modal.js +6 -0
  43. package/dist/config/EnvConfig.js +13 -0
  44. package/dist/config/amplifyConfig.js +45 -0
  45. package/dist/configureAppHost.js +5 -0
  46. package/dist/customGraphQL/customMutations.js +53 -0
  47. package/dist/customGraphQL/customQueries.js +104 -0
  48. package/dist/domain/input/input-types.js +1 -0
  49. package/dist/domain/model/BranchDto.js +8 -0
  50. package/dist/domain/model/ComponentMappingDto.js +19 -0
  51. package/dist/domain/model/MappingDto.js +16 -0
  52. package/dist/domain/model/PrefixDescriptionDto.js +13 -0
  53. package/dist/domain/model/ProfileDto.js +20 -0
  54. package/dist/domain/model/RoleMappingDto.js +19 -0
  55. package/dist/domain/model/SettingsDto.js +7 -0
  56. package/dist/domain/model/UserMappingDto.js +28 -0
  57. package/dist/domain/model/imageDto.js +1 -0
  58. package/dist/domain/type/EntityTypes.js +6 -0
  59. package/dist/domain/type/MappingOptions.js +1 -0
  60. package/dist/domain/type/MappingTypes.js +7 -0
  61. package/dist/domain/type/Nullable.js +1 -0
  62. package/dist/domain/type/ResettingPeriodOptions.js +8 -0
  63. package/dist/domain/type/RolesEnum.js +7 -0
  64. package/dist/domain/type/SelectType.js +1 -0
  65. package/dist/domain/type/StatusEnum.js +6 -0
  66. package/dist/domain/type/signUpOptions.js +4 -0
  67. package/dist/domain/type/statusOptions.js +4 -0
  68. package/dist/graphql/profileQueries.js +89 -0
  69. package/dist/hoc/withSyzyAuth.js +87 -0
  70. package/dist/hooks/useCurrentUser.js +6 -0
  71. package/dist/hooks/useDispatch.js +7 -0
  72. package/dist/hooks/usePermission.js +7 -0
  73. package/dist/index.js +3 -15
  74. package/dist/main.js +60 -0
  75. package/dist/services/Client.Service.js +96 -0
  76. package/dist/services/Storage-service.js +26 -0
  77. package/dist/services/navigationMenu.js +9 -0
  78. package/dist/static/constants.js +34 -0
  79. package/dist/store/AppAction.js +5 -0
  80. package/dist/store/AppContext.js +3 -0
  81. package/dist/store/AppContextType.js +6 -0
  82. package/dist/store/AppProvider.js +32 -0
  83. package/dist/store/HostedInContainerContext.js +11 -0
  84. package/dist/store/SesssionReducer.js +16 -0
  85. package/dist/types/App.d.ts +4 -0
  86. package/dist/types/AppHostProvider.d.ts +6 -0
  87. package/dist/types/AppHostRoutes.d.ts +1 -0
  88. package/dist/types/api/image-api.d.ts +8 -0
  89. package/dist/types/api/mapping-api.d.ts +80 -0
  90. package/dist/types/bookingModule/components/AmenityForm.d.ts +3 -0
  91. package/dist/types/bookingModule/components/BillingManagement.d.ts +3 -0
  92. package/dist/types/bookingModule/components/CreateRoomForm.d.ts +3 -0
  93. package/dist/types/bookingModule/components/ExtraRequirementForm.d.ts +3 -0
  94. package/dist/types/bookingModule/components/ReservationForm.d.ts +3 -0
  95. package/dist/types/bookingModule/components/RoomCategoryForm.d.ts +3 -0
  96. package/dist/types/bookingModule/components/RoomCategoryPriceForm.d.ts +3 -0
  97. package/dist/types/bookingModule/components/RoomExtraRequirementCapture.d.ts +3 -0
  98. package/dist/types/bookingModule/components/RoomFacilityForm.d.ts +3 -0
  99. package/dist/types/bookingModule/components/RoomReservationAction.d.ts +3 -0
  100. package/dist/types/components/Home/Home.d.ts +3 -0
  101. package/dist/types/components/Loader/Loader.d.ts +2 -0
  102. package/dist/types/components/Login/Login.d.ts +7 -0
  103. package/dist/types/components/Login/loginSchema.d.ts +27 -0
  104. package/dist/types/components/Mappings/BranchMapping/Branch.d.ts +5 -0
  105. package/dist/types/components/Mappings/BranchMapping/BranchTableColumns.d.ts +10 -0
  106. package/dist/types/components/Mappings/BranchMapping/MappingFormBranchUser.d.ts +3 -0
  107. package/dist/types/components/Mappings/BranchMapping/MappingTableColumns.d.ts +14 -0
  108. package/dist/types/components/Mappings/BranchMapping/branchSchema.d.ts +37 -0
  109. package/dist/types/components/Mappings/ComponentMapping/ComponentRoleMapping.d.ts +3 -0
  110. package/dist/types/components/Mappings/ComponentMapping/componentRoleColumns.d.ts +3 -0
  111. package/dist/types/components/Mappings/MappingForm/MappingForm.d.ts +35 -0
  112. package/dist/types/components/Mappings/MappingForm/mappingSchema.d.ts +23 -0
  113. package/dist/types/components/Mappings/RoleMapping/MappingFormUserRole.d.ts +5 -0
  114. package/dist/types/components/Mappings/RoleMapping/UserRoleTableColumns.d.ts +3 -0
  115. package/dist/types/components/NavBar/Sidebar.d.ts +4 -0
  116. package/dist/types/components/ProfileForm/ProfileForm.d.ts +3 -0
  117. package/dist/types/components/ProfileForm/ProfileList.d.ts +3 -0
  118. package/dist/types/components/ProfileForm/profileColumns.d.ts +3 -0
  119. package/dist/types/components/ProfileForm/profileSchema.d.ts +52 -0
  120. package/dist/types/components/SettingsPage/SettingsPage.d.ts +3 -0
  121. package/dist/types/components/api/settings-api.d.ts +26 -0
  122. package/dist/types/components/common/Form/FormActionButtons.d.ts +11 -0
  123. package/dist/types/components/common/Form/FormLabel.d.ts +8 -0
  124. package/dist/types/components/common/ListTable/ListHeader.d.ts +8 -0
  125. package/dist/types/components/common/ListTable/ListTable.d.ts +17 -0
  126. package/dist/types/components/common/Modal/Modal.d.ts +11 -0
  127. package/dist/types/config/EnvConfig.d.ts +13 -0
  128. package/dist/types/config/amplifyConfig.d.ts +1 -0
  129. package/dist/types/configureAppHost.d.ts +6 -0
  130. package/dist/types/customGraphQL/customMutations.d.ts +3 -0
  131. package/dist/types/customGraphQL/customQueries.d.ts +7 -0
  132. package/dist/types/domain/input/input-types.d.ts +47 -0
  133. package/dist/types/domain/model/BranchDto.d.ts +9 -0
  134. package/dist/types/domain/model/ComponentMappingDto.d.ts +24 -0
  135. package/dist/types/domain/model/MappingDto.d.ts +30 -0
  136. package/dist/types/domain/model/PrefixDescriptionDto.d.ts +16 -0
  137. package/dist/types/domain/model/ProfileDto.d.ts +21 -0
  138. package/dist/types/domain/model/RoleMappingDto.d.ts +14 -0
  139. package/dist/types/domain/model/SettingsDto.d.ts +8 -0
  140. package/dist/types/domain/model/UserMappingDto.d.ts +14 -0
  141. package/dist/types/domain/model/imageDto.d.ts +4 -0
  142. package/dist/types/domain/type/EntityTypes.d.ts +5 -0
  143. package/dist/types/domain/type/MappingOptions.d.ts +5 -0
  144. package/dist/types/domain/type/MappingTypes.d.ts +6 -0
  145. package/dist/types/domain/type/Nullable.d.ts +13 -0
  146. package/dist/types/domain/type/ResettingPeriodOptions.d.ts +2 -0
  147. package/dist/types/domain/type/RolesEnum.d.ts +6 -0
  148. package/dist/types/domain/type/SelectType.d.ts +16 -0
  149. package/dist/types/domain/type/StatusEnum.d.ts +5 -0
  150. package/dist/types/domain/type/signUpOptions.d.ts +2 -0
  151. package/dist/types/domain/type/statusOptions.d.ts +2 -0
  152. package/dist/types/graphql/profileQueries.d.ts +4 -0
  153. package/dist/types/hoc/withSyzyAuth.d.ts +2 -0
  154. package/dist/types/hooks/useCurrentUser.d.ts +3 -0
  155. package/dist/types/hooks/useDispatch.d.ts +3 -0
  156. package/dist/types/hooks/usePermission.d.ts +1 -0
  157. package/dist/types/index.d.ts +3 -0
  158. package/dist/types/main.d.ts +4 -0
  159. package/dist/types/services/Client.Service.d.ts +12 -0
  160. package/dist/types/services/Storage-service.d.ts +2 -0
  161. package/dist/types/services/navigationMenu.d.ts +1 -0
  162. package/dist/types/static/constants.d.ts +34 -0
  163. package/dist/types/store/AppAction.d.ts +11 -0
  164. package/dist/types/store/AppContext.d.ts +3 -0
  165. package/dist/types/store/AppContextType.d.ts +12 -0
  166. package/dist/types/store/AppProvider.d.ts +7 -0
  167. package/dist/types/store/HostedInContainerContext.d.ts +5 -0
  168. package/dist/types/store/SesssionReducer.d.ts +4 -0
  169. package/dist/types/types.d.ts +26 -0
  170. package/dist/types/util/AuthUtils.d.ts +1 -0
  171. package/dist/types/util/LogEnum.d.ts +6 -0
  172. package/dist/types/util/Logger.d.ts +6 -0
  173. package/dist/types/util/SyzyDate.d.ts +69 -0
  174. package/dist/types/util/dateUtils.d.ts +10 -0
  175. package/dist/types/util/hostedinContainer.d.ts +1 -0
  176. package/dist/types/util/model-types.d.ts +96 -0
  177. package/dist/types/util/prefixAndResettingValidation.d.ts +9 -0
  178. package/dist/types/util/transformToData.d.ts +1 -0
  179. package/dist/types.js +14 -0
  180. package/dist/util/AuthUtils.js +10 -0
  181. package/dist/util/LogEnum.js +7 -0
  182. package/dist/util/Logger.js +18 -0
  183. package/dist/util/SyzyDate.js +265 -0
  184. package/dist/util/dateUtils.js +24 -0
  185. package/dist/util/hostedinContainer.js +9 -0
  186. package/dist/util/model-types.js +18 -0
  187. package/dist/util/prefixAndResettingValidation.js +54 -0
  188. package/dist/util/transformToData.js +9 -0
  189. package/package.json +14 -9
  190. package/dist/__federation_shared_@tanstack/react-query-DHuUsaNz.js +0 -2517
  191. package/dist/__federation_shared_react-CikWE6qG.js +0 -7
  192. package/dist/__federation_shared_react-bootstrap-BKlZRvMR.js +0 -7516
  193. package/dist/__federation_shared_react-dom-vrQ70Ay8.js +0 -372
  194. package/dist/__federation_shared_react-router-dom-BKminmS4.js +0 -10448
  195. package/dist/__federation_shared_react-select-B6kehBDI.js +0 -4056
  196. package/dist/__federation_shared_react-toastify-B0S0UGr3.js +0 -412
  197. package/dist/_commonjsHelpers-C6fGbg64.js +0 -6
  198. package/dist/_virtual___federation_fn_import-XZCKozko.js +0 -217
  199. package/dist/favicon.ico +0 -0
  200. package/dist/index-DgtWMtjZ.js +0 -184
  201. package/dist/index-eZknuYwc.js +0 -1219
  202. package/dist/jsx-runtime-D_t4bG-_.js +0 -264
  203. package/dist/manifest.webmanifest +0 -1
  204. package/dist/pwa/Hotel-icon.jpg +0 -0
  205. package/dist/pwa/apple-touch-icon-180x180.png +0 -0
  206. package/dist/pwa/favicon.ico +0 -0
  207. package/dist/pwa/maskable-icon-512x512.png +0 -0
  208. package/dist/pwa/pwa-192x192.png +0 -0
  209. package/dist/pwa/pwa-512x512.png +0 -0
  210. package/dist/pwa/pwa-64x64.png +0 -0
  211. package/dist/registerSW.js +0 -1
  212. package/dist/sw.js +0 -1
  213. package/dist/workbox-1ef09536.js +0 -1
@@ -0,0 +1,29 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Status } from "../../../domain/type/StatusEnum";
3
+ export const BranchUserTableColumns = [
4
+ {
5
+ header: "ID",
6
+ accessor: "userId",
7
+ },
8
+ {
9
+ header: "User",
10
+ accessor: "userName",
11
+ },
12
+ {
13
+ header: "Branch",
14
+ accessor: "branchName",
15
+ },
16
+ {
17
+ header: "Created",
18
+ accessor: "createdDt",
19
+ },
20
+ {
21
+ header: "Disabled",
22
+ accessor: (row) => row.disabledDt ? new Date(row.disabledDt).toLocaleString() : "-",
23
+ },
24
+ {
25
+ header: "Status",
26
+ accessor: (row) => (_jsx("span", { className: `status-message ${row.status === Status.Active ? "text-success" : "text-danger"}`, children: row.status })),
27
+ align: "center",
28
+ },
29
+ ];
@@ -0,0 +1,34 @@
1
+ // src/components/validation/branchSchema.ts
2
+ import { z } from "zod";
3
+ export const branchSchema = z.object({
4
+ branchName: z
5
+ .string()
6
+ .min(1, "Branch name is required")
7
+ .min(3, "Branch name must be at least 3 characters"),
8
+ branchAddress: z
9
+ .string()
10
+ .min(1, "Branch address is required")
11
+ .min(5, "Branch address must be at least 5 characters"),
12
+ branchContactNumber: z
13
+ .string()
14
+ .min(10, "Contact number must be 10 digits")
15
+ .max(10, "Contact number must be 10 digits")
16
+ .regex(/^\d{10}$/, "Enter a valid 10-digit phone number"),
17
+ // Required for API inputs
18
+ pk: z.string().optional(),
19
+ sk: z.string().optional(),
20
+ status: z.enum(["ACTIVE", "INACTIVE"]).optional(),
21
+ createdDt: z.string().optional(),
22
+ });
23
+ export const useBranchSchema = () => {
24
+ const initiateBranch = {
25
+ branchName: "",
26
+ branchAddress: "",
27
+ branchContactNumber: "",
28
+ pk: "",
29
+ sk: "",
30
+ status: "ACTIVE",
31
+ createdDt: "",
32
+ };
33
+ return { branchSchema, initiateBranch };
34
+ };
@@ -0,0 +1,98 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useContext, useMemo, useState } from "react";
3
+ import MappingForm from "../MappingForm/MappingForm";
4
+ import FormModal from "../../common/Modal/Modal";
5
+ import ListTable from "../../common/ListTable/ListTable";
6
+ import { toast } from "react-toastify";
7
+ import { MappingTypes } from "../../../domain/type/MappingTypes";
8
+ import { getCompoMappingByRoleIdAndCompoIdFun, useCreateMappingMutation, useListComponentRoleMappings, useUpdateMappingMutation, } from "../../../api/mapping-api";
9
+ import { EntityTypes } from "../../../domain/type/EntityTypes";
10
+ import { Status } from "../../../domain/type/StatusEnum";
11
+ import { SyzyDate } from "../../../util/SyzyDate";
12
+ import { DATE_FORMAT_ISO_YYYY_MM_DD_HH_MM_SS } from "../../../util/dateUtils";
13
+ import AppContext from "../../../store/AppContext";
14
+ import { logger } from "../../../util/Logger";
15
+ import { componentMap } from "../../../App";
16
+ import { roles } from "../RoleMapping/MappingFormUserRole";
17
+ import { ComponentRoleTableColumns } from "./componentRoleColumns";
18
+ import ListHeader from "../../common/ListTable/ListHeader";
19
+ import { ToastContainer } from "react-toastify";
20
+ /* ---------------- Component Role Mapping ---------------- */
21
+ const ComponentRoleMappingPage = () => {
22
+ const { user } = useContext(AppContext) || {};
23
+ const loggedInUserName = user?.userName;
24
+ const [showModal, setShowModal] = useState(false);
25
+ const [editingRow, setEditingRow] = useState();
26
+ const currentISODate = new SyzyDate().toDateFormatString(DATE_FORMAT_ISO_YYYY_MM_DD_HH_MM_SS);
27
+ const { data = [], isLoading, refetch } = useListComponentRoleMappings();
28
+ const createMappingMutation = useCreateMappingMutation();
29
+ const updateMappingMutation = useUpdateMappingMutation();
30
+ const tableLoading = isLoading || createMappingMutation.isPending || updateMappingMutation.isPending;
31
+ /* ---------------- Component Options ---------------- */
32
+ const components = useMemo(() => Object.keys(componentMap).map((key, index) => ({
33
+ id: `Component#${String(index + 1).padStart(2, "0")}`,
34
+ name: key,
35
+ })), []);
36
+ /* ---------------- Add / Edit ---------------- */
37
+ const handleAdd = () => {
38
+ setEditingRow(undefined);
39
+ setShowModal(true);
40
+ };
41
+ const handleEdit = (row) => {
42
+ setEditingRow(row);
43
+ setShowModal(true);
44
+ };
45
+ /* ---------------- Submit ---------------- */
46
+ const handleSubmit = async (mappings) => {
47
+ try {
48
+ for (const map of mappings) {
49
+ const role = roles.find(r => r.id === map.targetId);
50
+ const component = components.find(c => c.id === map.sourceId);
51
+ if (!role || !component || !loggedInUserName)
52
+ continue;
53
+ const payload = {
54
+ pk: role.id,
55
+ sk: `COMPId#${component.id}`,
56
+ entity: EntityTypes.COMPONENT,
57
+ userId: "",
58
+ userName: "",
59
+ roleId: role.id,
60
+ roleName: role.name,
61
+ componentId: component.id,
62
+ componentTitle: component.name,
63
+ status: map.status,
64
+ createdDt: editingRow?.createdDt || currentISODate,
65
+ createdBy: loggedInUserName,
66
+ disabledDt: map.status === Status.Inactive ? currentISODate : "",
67
+ };
68
+ const existing = await getCompoMappingByRoleIdAndCompoIdFun(payload.pk, payload.sk);
69
+ if (existing) {
70
+ await updateMappingMutation.mutateAsync(payload);
71
+ }
72
+ else {
73
+ await createMappingMutation.mutateAsync(payload);
74
+ }
75
+ }
76
+ toast.success("Component-Role mapping saved successfully");
77
+ setShowModal(false);
78
+ refetch();
79
+ }
80
+ catch (err) {
81
+ logger.error(err);
82
+ toast.error("Component-Role mapping failed");
83
+ }
84
+ };
85
+ /* ---------------- Render ---------------- */
86
+ return (_jsxs(_Fragment, { children: [_jsx(ToastContainer, {}), _jsxs("div", { className: "container", children: [_jsx(ListHeader, { title: "Users List", buttonLabel: "Add Mapping", onButtonClick: handleAdd }), isLoading ? null : (_jsx(ListTable, { columns: ComponentRoleTableColumns, data: data, emptyMessage: "No component-role mappings found", onEdit: handleEdit, loading: tableLoading })), _jsx(FormModal, { show: showModal, title: editingRow
87
+ ? "Edit Component-Role Mapping"
88
+ : "Assign Role to Component", onClose: () => setShowModal(false), size: "lg", children: _jsx(MappingForm, { mode: "default", hideBranch: true, hideTarget: false, sourceLabel: MappingTypes.Components, targetLabel: MappingTypes.Roles, sourceOptions: components, targetOptions: roles, onSubmit: handleSubmit, initialMapping: editingRow
89
+ ? {
90
+ branchId: "DEFAULT_BRANCH",
91
+ sourceId: editingRow.sk.replace("COMPId#", ""),
92
+ sourceName: editingRow.componentTitle,
93
+ targetId: editingRow.pk,
94
+ status: editingRow.status,
95
+ }
96
+ : undefined }) })] })] }));
97
+ };
98
+ export default ComponentRoleMappingPage;
@@ -0,0 +1,29 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Status } from "../../../domain/type/StatusEnum";
3
+ export const ComponentRoleTableColumns = [
4
+ {
5
+ header: "Role",
6
+ accessor: "roleName",
7
+ },
8
+ {
9
+ header: "Component",
10
+ accessor: "componentTitle",
11
+ },
12
+ {
13
+ header: "Created Date",
14
+ accessor: (row) => row.createdDt
15
+ ? new Date(row.createdDt).toLocaleString()
16
+ : "-",
17
+ },
18
+ {
19
+ header: "Disabled Date",
20
+ accessor: (row) => row.disabledDt
21
+ ? new Date(row.disabledDt).toLocaleString()
22
+ : "-",
23
+ },
24
+ {
25
+ header: "Status",
26
+ accessor: (row) => (_jsx("span", { className: `status-message ${row.status === Status.Active ? "text-success" : "text-danger"}`, children: row.status })),
27
+ align: "center",
28
+ },
29
+ ];
@@ -0,0 +1,142 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useRef, useState } from "react";
3
+ import { Form, Col } from "react-bootstrap";
4
+ import Select from "react-select";
5
+ import { useForm } from "react-hook-form";
6
+ import { zodResolver } from "@hookform/resolvers/zod";
7
+ import './MappingForm.css';
8
+ import { statusOptions } from "../../../domain/type/statusOptions";
9
+ import { Status } from "../../../domain/type/StatusEnum";
10
+ import '../../../styles/button.css';
11
+ import { mappingFormSchema } from "./mappingSchema";
12
+ import FormActionButtons from "../../common/Form/FormActionButtons";
13
+ import FormLabel from "../../common/Form/FormLabel";
14
+ const MappingForm = ({ branchOptions = [], sourceLabel, targetLabel, sourceOptions, targetOptions, onSubmit, mode = "default", hideBranch = false, hideTarget = false, onSourceChange, selectedUserBranch, initialMapping, userHasNoBranch }) => {
15
+ const showBranchUserOnly = mode === "branch-user";
16
+ const { handleSubmit, setValue, formState: { errors } } = useForm({
17
+ resolver: zodResolver(mappingFormSchema),
18
+ defaultValues: {
19
+ branchSelections: [],
20
+ sourceSelections: [],
21
+ targetSelections: [],
22
+ status: Status.Active,
23
+ hideBranch,
24
+ hideTarget
25
+ }
26
+ });
27
+ const [selectedBranches, setSelectedBranches] = useState([]);
28
+ const [selectedSources, setSelectedSources] = useState([]);
29
+ const [selectedTargets, setSelectedTargets] = useState([]);
30
+ const [status, setStatus] = useState(Status.Active);
31
+ const toSelectOption = (opt, type) => {
32
+ if (type === "source" && sourceLabel === "User") {
33
+ return {
34
+ value: opt.id,
35
+ label: `${opt.name} (${opt.id})`,
36
+ };
37
+ }
38
+ return {
39
+ value: opt.id,
40
+ label: opt.name,
41
+ };
42
+ };
43
+ /** Prefill form if editing */
44
+ const hasInitialized = useRef(false);
45
+ useEffect(() => {
46
+ if (!initialMapping || hasInitialized.current)
47
+ return;
48
+ if (sourceOptions.length === 0)
49
+ return;
50
+ hasInitialized.current = true;
51
+ // Branch
52
+ if (!hideBranch && initialMapping.branchId) {
53
+ const branchOpt = branchOptions.find(b => b.id === initialMapping.branchId);
54
+ if (branchOpt) {
55
+ setSelectedBranches([branchOpt]);
56
+ setValue("branchSelections", [branchOpt], { shouldDirty: false });
57
+ }
58
+ }
59
+ // Source (User)
60
+ const srcOpt = sourceOptions.find(s => s.id === initialMapping.sourceId);
61
+ if (srcOpt) {
62
+ setSelectedSources([srcOpt]);
63
+ setValue("sourceSelections", [srcOpt], { shouldDirty: false });
64
+ }
65
+ // Target (Role)
66
+ if (initialMapping.targetId) {
67
+ const tgtOpt = targetOptions.find(t => t.id === initialMapping.targetId);
68
+ if (tgtOpt) {
69
+ setSelectedTargets([tgtOpt]);
70
+ setValue("targetSelections", [tgtOpt], { shouldDirty: false });
71
+ }
72
+ }
73
+ // Status
74
+ setStatus(initialMapping.status);
75
+ setValue("status", initialMapping.status, { shouldDirty: false });
76
+ }, [initialMapping, sourceOptions]);
77
+ /** Clear form */
78
+ const handleClear = () => {
79
+ setSelectedBranches([]);
80
+ setSelectedSources([]);
81
+ setSelectedTargets([]);
82
+ setStatus(Status.Active);
83
+ setValue("branchSelections", []);
84
+ setValue("sourceSelections", []);
85
+ setValue("targetSelections", []);
86
+ setValue("status", Status.Active);
87
+ };
88
+ useEffect(() => {
89
+ setValue("hideBranch", hideBranch, { shouldValidate: true });
90
+ setValue("hideTarget", hideTarget, { shouldValidate: true });
91
+ }, [hideBranch, hideTarget]);
92
+ /** Submit handler */
93
+ const handleZodSubmit = (formData) => {
94
+ let mappings = [];
95
+ if (hideBranch) {
96
+ const branchId = branchOptions?.[0]?.id || "DEFAULT_BRANCH";
97
+ mappings = formData.sourceSelections.flatMap(src => formData.targetSelections.map(tgt => ({
98
+ branchId,
99
+ sourceId: src.id,
100
+ targetId: tgt.id,
101
+ status: formData.status
102
+ })));
103
+ }
104
+ else if (showBranchUserOnly) {
105
+ mappings = formData.branchSelections.flatMap(branch => formData.sourceSelections.map(src => ({
106
+ branchId: branch.id,
107
+ sourceId: src.id,
108
+ targetId: "",
109
+ status: formData.status
110
+ })));
111
+ }
112
+ else {
113
+ mappings = formData.branchSelections.flatMap(branch => formData.sourceSelections.flatMap(src => formData.targetSelections.map(tgt => ({
114
+ branchId: branch.id,
115
+ sourceId: src.id,
116
+ targetId: tgt.id,
117
+ status: formData.status
118
+ }))));
119
+ }
120
+ onSubmit(mappings);
121
+ handleClear();
122
+ };
123
+ return (_jsxs(Form, { onSubmit: handleSubmit(handleZodSubmit), className: "mapping-form", children: [!hideBranch && (_jsxs(Col, { children: [_jsx(FormLabel, { label: "Branch", required: true }), _jsx(Select, { isMulti: true, options: branchOptions.map(opt => toSelectOption(opt, "branch")), value: selectedBranches.map(opt => toSelectOption(opt, "branch")), closeMenuOnSelect: false, onChange: (selected) => {
124
+ const formatted = selected?.map(s => ({ id: s.value, name: s.label })) || [];
125
+ setSelectedBranches(formatted);
126
+ setValue("branchSelections", formatted, { shouldValidate: true, shouldDirty: true, });
127
+ } }), errors.branchSelections && _jsx(Form.Text, { className: "text-danger", children: errors.branchSelections.message })] })), !hideTarget && (_jsxs(Col, { children: [_jsx(FormLabel, { label: targetLabel, required: true }), _jsx(Select, { isMulti: true, options: targetOptions.map(opt => toSelectOption(opt, "target")), value: selectedTargets.map(opt => toSelectOption(opt, "target")), closeMenuOnSelect: false, onChange: (selected) => {
128
+ const formatted = selected?.map(s => ({ id: s.value, name: s.label })) || [];
129
+ setSelectedTargets(formatted);
130
+ setValue("targetSelections", formatted, { shouldValidate: true, shouldDirty: true, });
131
+ } }), errors.targetSelections && (_jsx(Form.Text, { className: "text-danger", children: errors.targetSelections.message }))] })), _jsxs(Col, { children: [_jsx(FormLabel, { label: sourceLabel, required: true }), _jsx(Select, { isMulti: true, options: sourceOptions.map(opt => toSelectOption(opt, "source")), value: selectedSources.map(opt => toSelectOption(opt, "source")), closeMenuOnSelect: false, onChange: (selected) => {
132
+ const formatted = selected?.map(s => ({ id: s.value, name: sourceOptions.find(opt => opt.id === s.value)?.name || "" })) || [];
133
+ setSelectedSources(formatted);
134
+ setValue("sourceSelections", formatted, { shouldValidate: true, shouldDirty: true, });
135
+ onSourceChange?.(formatted);
136
+ } }), errors.sourceSelections && _jsx(Form.Text, { className: "text-danger", children: errors.sourceSelections.message }), selectedUserBranch && selectedUserBranch.length > 0 && (_jsxs("div", { className: "mt-1 text-primary fw-bold", children: ["Branch: ", selectedUserBranch.join(", ")] })), userHasNoBranch && (_jsx("div", { className: "mt-2 text-danger fw-semibold", children: "\u26A0\uFE0F Selected user is not assigned to any branch. Please assign a branch before mapping roles." }))] }), _jsxs(Col, { children: [_jsx(FormLabel, { label: "Status" }), _jsx(Select, { isClearable: false, options: statusOptions, closeMenuOnSelect: false, value: statusOptions.find(s => s.value.toUpperCase() === status.toUpperCase()), onChange: (selected) => {
137
+ const newStatus = selected?.value || Status.Active;
138
+ setStatus(newStatus);
139
+ setValue("status", newStatus);
140
+ } })] }), _jsx(FormActionButtons, { isEditMode: !!initialMapping, onClear: handleClear, disableSubmit: userHasNoBranch })] }));
141
+ };
142
+ export default MappingForm;
@@ -0,0 +1,32 @@
1
+ import { z } from "zod";
2
+ export const mappingOptionSchema = z.object({
3
+ id: z.string().min(1, "Invalid option id"),
4
+ name: z.string().min(1, "Invalid option name"),
5
+ });
6
+ export const mappingFormSchema = z.object({
7
+ branchSelections: z.array(mappingOptionSchema),
8
+ sourceSelections: z.array(mappingOptionSchema)
9
+ .min(1, "Please select at least one source"),
10
+ targetSelections: z.array(mappingOptionSchema),
11
+ status: z.string().min(1, "Status is required"),
12
+ hideBranch: z.boolean(), // REQUIRED
13
+ hideTarget: z.boolean(), // REQUIRED
14
+ })
15
+ .refine((data) => {
16
+ if (!data.hideBranch && data.branchSelections.length === 0) {
17
+ return false;
18
+ }
19
+ return true;
20
+ }, {
21
+ message: "Please select at least one branch",
22
+ path: ["branchSelections"]
23
+ })
24
+ .refine((data) => {
25
+ if (!data.hideTarget && data.targetSelections.length === 0) {
26
+ return false;
27
+ }
28
+ return true;
29
+ }, {
30
+ message: "Please select at least one target",
31
+ path: ["targetSelections"]
32
+ });
@@ -0,0 +1,194 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useEffect, useState } from "react";
3
+ import MappingForm from "../MappingForm/MappingForm";
4
+ import FormModal from "../../common/Modal/Modal";
5
+ import ListTable from "../../common/ListTable/ListTable";
6
+ import { toast } from "react-toastify";
7
+ import { Status } from "../../../domain/type/StatusEnum";
8
+ import { getBranchIdByUserId, useCreateMappingMutation, useListProfiles, useUpdateMappingMutation, fetchUserRoleMappings, getBranchNameById, } from "../../../api/mapping-api";
9
+ import { SyzyDate } from "../../../util/SyzyDate";
10
+ import { EntityTypes } from "../../../domain/type/EntityTypes";
11
+ import { DATE_FORMAT_ISO_YYYY_MM_DD_HH_MM_SS } from "../../../util/dateUtils";
12
+ import { logger } from "../../../util/Logger";
13
+ import { UserRoleTableColumns } from "./UserRoleTableColumns";
14
+ import ListHeader from "../../common/ListTable/ListHeader";
15
+ import { ToastContainer } from "react-toastify";
16
+ /* ---------------- Roles ---------------- */
17
+ export const roles = [
18
+ { id: "Role#01", name: "SUPERADMIN" },
19
+ { id: "Role#02", name: "SUPPORTADMIN" },
20
+ { id: "Role#03", name: "ADMIN" },
21
+ { id: "Role#04", name: "EMPLOYEE" },
22
+ ];
23
+ const MappingFormUserRole = () => {
24
+ const [showModal, setShowModal] = useState(false);
25
+ const [editingRow, setEditingRow] = useState();
26
+ const [users, setUsers] = useState([]);
27
+ const [mappings, setMappings] = useState([]);
28
+ const [loading, setLoading] = useState(true);
29
+ const [selectedUserBranch, setSelectedUserBranch] = useState([]);
30
+ const [isUserSelected, setIsUserSelected] = useState(false);
31
+ const currentISODate = new SyzyDate().toDateFormatString(DATE_FORMAT_ISO_YYYY_MM_DD_HH_MM_SS);
32
+ const { data: profiles, isLoading } = useListProfiles();
33
+ const createMappingMutation = useCreateMappingMutation();
34
+ const updateMappingMutation = useUpdateMappingMutation();
35
+ const tableLoading = isLoading || createMappingMutation.isPending || updateMappingMutation.isPending;
36
+ const userHasNoBranch = isUserSelected && selectedUserBranch.length === 0 && !editingRow;
37
+ const handleUserChange = async (selectedUsers) => {
38
+ if (selectedUsers.length === 1) {
39
+ setIsUserSelected(true);
40
+ const userId = selectedUsers[0].id;
41
+ const branchPk = await getBranchIdByUserId(userId);
42
+ if (branchPk.length === 0) {
43
+ setSelectedUserBranch([]);
44
+ return;
45
+ }
46
+ const branchName = await Promise.all(branchPk.map(async (id) => await getBranchNameById(id)));
47
+ setSelectedUserBranch(branchName);
48
+ }
49
+ else {
50
+ setIsUserSelected(false);
51
+ setSelectedUserBranch([]);
52
+ }
53
+ };
54
+ /* ---------------- Load Users ---------------- */
55
+ useEffect(() => {
56
+ if (profiles) {
57
+ setUsers(profiles.map((p) => ({ id: p.sk, name: p.name })));
58
+ }
59
+ }, [profiles]);
60
+ /* ---------------- Load User-Role Mappings ---------------- */
61
+ const loadMappings = async () => {
62
+ try {
63
+ const result = await fetchUserRoleMappings();
64
+ const enriched = await Promise.all(result.map(async (m) => {
65
+ // Extract branchId from pk
66
+ const match = m.pk.match(/^BRANCH#([^#]+)#USER#/);
67
+ const branchId = match ? match[1] : "";
68
+ const branchName = branchId ? await getBranchNameById(branchId) : "";
69
+ return {
70
+ ...m,
71
+ branchId,
72
+ branchName,
73
+ };
74
+ }));
75
+ setMappings(enriched);
76
+ }
77
+ catch (err) {
78
+ toast.error("Failed to load user-role mappings");
79
+ }
80
+ finally {
81
+ setLoading(false);
82
+ }
83
+ };
84
+ useEffect(() => {
85
+ loadMappings();
86
+ }, []);
87
+ /* ---------------- Add / Edit ---------------- */
88
+ const handleAdd = () => {
89
+ setEditingRow(undefined);
90
+ setShowModal(true);
91
+ setSelectedUserBranch([]);
92
+ setIsUserSelected(false);
93
+ };
94
+ const handleEdit = (row) => {
95
+ setEditingRow(row);
96
+ setSelectedUserBranch([row.branchName]);
97
+ setIsUserSelected(true);
98
+ setShowModal(true);
99
+ };
100
+ /* ---------------- Submit ---------------- */
101
+ const handleSubmit = async (data) => {
102
+ try {
103
+ for (const map of data) {
104
+ const user = users.find(u => u.id === map.sourceId);
105
+ const role = roles.find(r => r.id === map.targetId);
106
+ if (!user || !role)
107
+ continue;
108
+ if (editingRow) {
109
+ const isRoleChanged = editingRow.roleId !== role.id;
110
+ const isUserChanged = editingRow.userId !== user.id;
111
+ if (isRoleChanged || isUserChanged) {
112
+ const buildInactivePayload = (row, disabledDt) => ({
113
+ pk: editingRow.pk,
114
+ sk: row.roleId,
115
+ entity: EntityTypes.ROLE,
116
+ userId: row.userId,
117
+ branchName: editingRow.branchName,
118
+ userName: row.userName,
119
+ roleId: row.roleId,
120
+ roleName: row.roleName,
121
+ componentId: "null",
122
+ componentTitle: "null",
123
+ status: Status.Inactive,
124
+ createdDt: row.createdDt,
125
+ createdBy: `${user.id}#${user.name}`,
126
+ disabledDt,
127
+ });
128
+ // 1️⃣ Deactivate OLD role for THIS branch only
129
+ await updateMappingMutation.mutateAsync(buildInactivePayload(editingRow, currentISODate));
130
+ // 2️⃣ Create NEW role for SAME branch only
131
+ const newPayload = {
132
+ pk: editingRow.pk,
133
+ sk: role.id,
134
+ entity: EntityTypes.ROLE,
135
+ userId: user.id,
136
+ branchName: editingRow.branchName,
137
+ userName: user.name,
138
+ roleId: role.id,
139
+ roleName: role.name,
140
+ componentId: "null",
141
+ componentTitle: "null",
142
+ status: Status.Active,
143
+ createdDt: currentISODate,
144
+ createdBy: `${user.id}#${user.name}`,
145
+ disabledDt: "",
146
+ };
147
+ await createMappingMutation.mutateAsync(newPayload);
148
+ }
149
+ }
150
+ else {
151
+ const branchIds = await getBranchIdByUserId(user.id);
152
+ for (const branchId of branchIds) {
153
+ const branchName = await getBranchNameById(branchId);
154
+ const payload = {
155
+ pk: `${branchId}#USER#${user.id}`,
156
+ sk: role.id,
157
+ entity: EntityTypes.ROLE,
158
+ userId: user.id,
159
+ branchName,
160
+ userName: user.name,
161
+ roleId: role.id,
162
+ roleName: role.name,
163
+ componentId: "null",
164
+ componentTitle: "null",
165
+ status: map.status,
166
+ createdDt: currentISODate,
167
+ createdBy: `${user.id}#${user.name}`,
168
+ disabledDt: "",
169
+ };
170
+ await createMappingMutation.mutateAsync(payload);
171
+ }
172
+ }
173
+ }
174
+ toast.success("User-Role mapping saved successfully");
175
+ setShowModal(false);
176
+ loadMappings();
177
+ }
178
+ catch (err) {
179
+ logger.error(err);
180
+ toast.error("User-Role mapping failed");
181
+ }
182
+ };
183
+ /* ---------------- Render ---------------- */
184
+ return (_jsxs(_Fragment, { children: [_jsx(ToastContainer, {}), _jsxs("div", { className: "container", children: [_jsx(ListHeader, { title: "User & Role Mappings List", buttonLabel: "Add Mapping", onButtonClick: handleAdd }), loading ? null : (_jsx(ListTable, { columns: UserRoleTableColumns, data: mappings, emptyMessage: "No user-role mappings found", onEdit: handleEdit, loading: tableLoading })), _jsx(FormModal, { show: showModal, title: editingRow ? "Edit User-Role Mapping" : "Assign Role to User", onClose: () => setShowModal(false), size: "lg", children: _jsx(MappingForm, { mode: "default", hideBranch: true, hideTarget: false, sourceLabel: "User", targetLabel: "Role", sourceOptions: users, targetOptions: roles, onSubmit: handleSubmit, onSourceChange: handleUserChange, selectedUserBranch: selectedUserBranch ?? "", userHasNoBranch: userHasNoBranch, initialMapping: editingRow
185
+ ? {
186
+ sourceId: editingRow.userId,
187
+ sourceName: editingRow.userName,
188
+ branchName: editingRow.branchName,
189
+ targetId: editingRow.roleId,
190
+ status: editingRow.status,
191
+ }
192
+ : undefined }) })] })] }));
193
+ };
194
+ export default MappingFormUserRole;
@@ -0,0 +1,33 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Status } from "../../../domain/type/StatusEnum";
3
+ export const UserRoleTableColumns = [
4
+ {
5
+ header: "ID",
6
+ accessor: "userId",
7
+ },
8
+ {
9
+ header: "User",
10
+ accessor: "userName",
11
+ },
12
+ {
13
+ header: "Branch",
14
+ accessor: (row) => row.branchName || "-",
15
+ },
16
+ {
17
+ header: "Role",
18
+ accessor: "roleName",
19
+ },
20
+ {
21
+ header: "Created",
22
+ accessor: (row) => row.createdDt ? new Date(row.createdDt).toLocaleString() : "-",
23
+ },
24
+ {
25
+ header: "Disabled",
26
+ accessor: (row) => row.disabledDt ? new Date(row.disabledDt).toLocaleString() : "-",
27
+ },
28
+ {
29
+ header: "Status",
30
+ accessor: (row) => (_jsx("span", { className: `status-message ${row.status === Status.Active ? "text-success" : "text-danger"}`, children: row.status })),
31
+ align: "center",
32
+ },
33
+ ];
@@ -0,0 +1,56 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import React, { useEffect, useState } from "react";
3
+ import { NavLink, useNavigate } from "react-router-dom";
4
+ import { getSidebarMenu } from "../../services/navigationMenu";
5
+ import { Link } from "react-router-dom";
6
+ import './sidebar.css';
7
+ import { useDispatch } from "../../hooks/useDispatch";
8
+ import { signOut } from "aws-amplify/auth";
9
+ import { AppActionEnum } from "../../store/AppAction";
10
+ import { RiLogoutBoxLine } from "react-icons/ri";
11
+ import { FaArrowRight } from "react-icons/fa";
12
+ import { FaArrowLeft } from "react-icons/fa";
13
+ import { FaChevronDown, FaChevronUp } from "react-icons/fa";
14
+ import * as FA from "react-icons/fa";
15
+ import * as FA6 from "react-icons/fa6";
16
+ import * as IO from "react-icons/io5";
17
+ import * as IO4 from "react-icons/io";
18
+ import * as RI from "react-icons/ri";
19
+ const iconPacks = { FA, FA6, IO, IO4, RI };
20
+ const Sidebar = () => {
21
+ const navigate = useNavigate();
22
+ const { dispatch } = useDispatch();
23
+ const [menus, setMenus] = useState([]);
24
+ const [activeMenu, setActiveMenu] = useState(null);
25
+ const [isExpanded, setIsExpanded] = useState(false);
26
+ const handleToggle = () => {
27
+ setIsExpanded(prevState => !prevState);
28
+ };
29
+ const handleMenuClick = (menu) => {
30
+ setActiveMenu(prevMenu => (prevMenu === menu ? null : menu));
31
+ };
32
+ const signOutFn = async () => {
33
+ await signOut({ global: true });
34
+ dispatch({ type: AppActionEnum.SignOut });
35
+ navigate("/");
36
+ };
37
+ const getIcon = (iconName, pack = "FA") => {
38
+ const library = iconPacks[pack] || FA;
39
+ return library[iconName] ? React.createElement(library[iconName]) : null;
40
+ };
41
+ useEffect(() => {
42
+ const fetchMenu = async () => {
43
+ const data = await getSidebarMenu();
44
+ setMenus(data);
45
+ };
46
+ fetchMenu();
47
+ }, []);
48
+ return (_jsx(_Fragment, { children: _jsx("div", { className: "wrapper", children: _jsxs("aside", { id: "sidebar", className: isExpanded ? '' : 'expand', children: [_jsxs("div", { children: [_jsx("button", { type: "button", className: "toggle-btn", onClick: handleToggle, children: isExpanded ? _jsx(FaArrowRight, { className: 'icon' }) : _jsx(FaArrowLeft, { className: 'icon' }) }), _jsx("div", { className: "sidebar-logo", children: _jsxs("div", { children: [_jsx(Link, { to: '/', children: "HMS" }), _jsx("br", {}), _jsx("span", { children: "Salem" })] }) })] }), _jsxs("ul", { className: "sidebar-nav", children: [menus.map((menu, index) => (_jsx("li", { className: "sidebar-item", children: menu.children && menu.children.length > 0 ? (_jsxs(_Fragment, { children: [_jsxs(Link, { to: menu.children[0].path, className: `d-flex justify-content-between sidebar-link has-dropdown ${menu.children.some((child) => location.pathname.startsWith(child.path))
49
+ ? "active" : ""}`, onClick: (e) => {
50
+ e.preventDefault();
51
+ handleMenuClick(menu.title);
52
+ }, "aria-controls": `menu-${index}`, children: [_jsxs("div", { children: [_jsx("span", { className: "icon", children: getIcon(menu.icon, menu.iconPack) }), _jsx("span", { className: "label", children: menu.title })] }), _jsx("span", { className: "arrow-icon d-flex justify-content-center align-items-center", children: activeMenu === menu.title ? _jsx(FaChevronUp, {}) : _jsx(FaChevronDown, {}) })] }), _jsx("ul", { id: `menu-${index}`, className: `sidebar-dropdown list-unstyled ${activeMenu === menu.title ? "show" : "collapse"}`, children: menu.children.map((child, cIndex) => (_jsx("li", { className: "sidebar-item", children: _jsx(Link, { to: child.path, className: `sidebar-link ${location.pathname === child.path ? "active-child" : ""}`, children: _jsx("span", { className: "label test", children: child.title }) }) }, cIndex))) })] })) : (
53
+ // Normal single-level item
54
+ _jsxs(NavLink, { to: menu.path, className: ({ isActive }) => `sidebar-link d-flex align-items-center ${isActive ? "active-link" : ""}`, children: [_jsx("div", { className: "icon", children: getIcon(menu.icon, menu.iconPack) }), _jsx("div", { className: "label", children: menu.title })] })) }, index))), _jsx("li", { className: "sidebar-item", children: _jsxs(Link, { to: '/', className: "sidebar-link", onClick: signOutFn, children: [_jsx(RiLogoutBoxLine, { className: 'log-icon' }), _jsx("span", { className: "label", children: "Logout" })] }) })] })] }) }) }));
55
+ };
56
+ export default Sidebar;