@appcorp/fusion-storybook 0.1.4

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 (131) hide show
  1. package/README.md +147 -0
  2. package/base-modules/admission/cache.d.ts +14 -0
  3. package/base-modules/admission/cache.js +31 -0
  4. package/base-modules/admission/constants.d.ts +32 -0
  5. package/base-modules/admission/constants.js +37 -0
  6. package/base-modules/admission/context.d.ts +369 -0
  7. package/base-modules/admission/context.js +755 -0
  8. package/base-modules/admission/filter.d.ts +1 -0
  9. package/base-modules/admission/filter.js +31 -0
  10. package/base-modules/admission/form.d.ts +1 -0
  11. package/base-modules/admission/form.js +86 -0
  12. package/base-modules/admission/more-actions.d.ts +1 -0
  13. package/base-modules/admission/more-actions.js +5 -0
  14. package/base-modules/admission/page.d.ts +16 -0
  15. package/base-modules/admission/page.js +128 -0
  16. package/base-modules/admission/validate.d.ts +38 -0
  17. package/base-modules/admission/validate.js +70 -0
  18. package/base-modules/admission/view.d.ts +1 -0
  19. package/base-modules/admission/view.js +40 -0
  20. package/base-modules/discount-code/cache.d.ts +27 -0
  21. package/base-modules/discount-code/cache.js +46 -0
  22. package/base-modules/discount-code/constants.d.ts +19 -0
  23. package/base-modules/discount-code/constants.js +26 -0
  24. package/base-modules/discount-code/context.d.ts +154 -0
  25. package/base-modules/discount-code/context.js +416 -0
  26. package/base-modules/discount-code/filter.d.ts +9 -0
  27. package/base-modules/discount-code/filter.js +14 -0
  28. package/base-modules/discount-code/form.d.ts +1 -0
  29. package/base-modules/discount-code/form.js +44 -0
  30. package/base-modules/discount-code/more-actions.d.ts +9 -0
  31. package/base-modules/discount-code/more-actions.js +13 -0
  32. package/base-modules/discount-code/page.d.ts +16 -0
  33. package/base-modules/discount-code/page.js +120 -0
  34. package/base-modules/discount-code/validate.d.ts +19 -0
  35. package/base-modules/discount-code/validate.js +38 -0
  36. package/base-modules/discount-code/view.d.ts +1 -0
  37. package/base-modules/discount-code/view.js +26 -0
  38. package/base-modules/family/cache.d.ts +14 -0
  39. package/base-modules/family/cache.js +31 -0
  40. package/base-modules/family/constants.d.ts +22 -0
  41. package/base-modules/family/constants.js +26 -0
  42. package/base-modules/family/context.d.ts +173 -0
  43. package/base-modules/family/context.js +441 -0
  44. package/base-modules/family/filter.d.ts +1 -0
  45. package/base-modules/family/filter.js +28 -0
  46. package/base-modules/family/form.d.ts +1 -0
  47. package/base-modules/family/form.js +12 -0
  48. package/base-modules/family/more-actions.d.ts +1 -0
  49. package/base-modules/family/more-actions.js +5 -0
  50. package/base-modules/family/page.d.ts +16 -0
  51. package/base-modules/family/page.js +120 -0
  52. package/base-modules/family/validate.d.ts +15 -0
  53. package/base-modules/family/validate.js +18 -0
  54. package/base-modules/family/view.d.ts +1 -0
  55. package/base-modules/family/view.js +18 -0
  56. package/base-modules/family-member/cache.d.ts +14 -0
  57. package/base-modules/family-member/cache.js +31 -0
  58. package/base-modules/family-member/constants.d.ts +22 -0
  59. package/base-modules/family-member/constants.js +26 -0
  60. package/base-modules/family-member/context.d.ts +215 -0
  61. package/base-modules/family-member/context.js +486 -0
  62. package/base-modules/family-member/filter.d.ts +1 -0
  63. package/base-modules/family-member/filter.js +28 -0
  64. package/base-modules/family-member/form.d.ts +1 -0
  65. package/base-modules/family-member/form.js +17 -0
  66. package/base-modules/family-member/more-actions.d.ts +1 -0
  67. package/base-modules/family-member/more-actions.js +5 -0
  68. package/base-modules/family-member/page.d.ts +16 -0
  69. package/base-modules/family-member/page.js +122 -0
  70. package/base-modules/family-member/validate.d.ts +24 -0
  71. package/base-modules/family-member/validate.js +27 -0
  72. package/base-modules/family-member/view.d.ts +1 -0
  73. package/base-modules/family-member/view.js +40 -0
  74. package/base-modules/student-profile/cache.d.ts +14 -0
  75. package/base-modules/student-profile/cache.js +31 -0
  76. package/base-modules/student-profile/constants.d.ts +105 -0
  77. package/base-modules/student-profile/constants.js +132 -0
  78. package/base-modules/student-profile/context.d.ts +290 -0
  79. package/base-modules/student-profile/context.js +583 -0
  80. package/base-modules/student-profile/filter.d.ts +1 -0
  81. package/base-modules/student-profile/filter.js +26 -0
  82. package/base-modules/student-profile/form.d.ts +1 -0
  83. package/base-modules/student-profile/form.js +19 -0
  84. package/base-modules/student-profile/more-actions.d.ts +1 -0
  85. package/base-modules/student-profile/more-actions.js +5 -0
  86. package/base-modules/student-profile/page.d.ts +9 -0
  87. package/base-modules/student-profile/page.js +86 -0
  88. package/base-modules/student-profile/validate.d.ts +23 -0
  89. package/base-modules/student-profile/validate.js +34 -0
  90. package/base-modules/student-profile/view.d.ts +1 -0
  91. package/base-modules/student-profile/view.js +29 -0
  92. package/base-modules/workspace/cache.d.ts +9 -0
  93. package/base-modules/workspace/cache.js +28 -0
  94. package/base-modules/workspace/constants.d.ts +10 -0
  95. package/base-modules/workspace/constants.js +18 -0
  96. package/base-modules/workspace/context.d.ts +187 -0
  97. package/base-modules/workspace/context.js +293 -0
  98. package/base-modules/workspace/drawer.d.ts +1 -0
  99. package/base-modules/workspace/drawer.js +24 -0
  100. package/base-modules/workspace/filter.d.ts +1 -0
  101. package/base-modules/workspace/filter.js +13 -0
  102. package/base-modules/workspace/form.d.ts +1 -0
  103. package/base-modules/workspace/form.js +40 -0
  104. package/base-modules/workspace/more-actions.d.ts +1 -0
  105. package/base-modules/workspace/more-actions.js +13 -0
  106. package/base-modules/workspace/page.d.ts +1 -0
  107. package/base-modules/workspace/page.js +31 -0
  108. package/base-modules/workspace/validate.d.ts +9 -0
  109. package/base-modules/workspace/validate.js +8 -0
  110. package/base-modules/workspace/view.d.ts +1 -0
  111. package/base-modules/workspace/view.js +52 -0
  112. package/components/rbac-no-access.d.ts +6 -0
  113. package/components/rbac-no-access.js +4 -0
  114. package/constants.d.ts +81 -0
  115. package/constants.js +81 -0
  116. package/lib/utils.d.ts +2 -0
  117. package/lib/utils.js +5 -0
  118. package/package.json +104 -0
  119. package/tsconfig.build.tsbuildinfo +1 -0
  120. package/type.d.ts +1141 -0
  121. package/type.js +427 -0
  122. package/utils/admission-pdf.d.ts +78 -0
  123. package/utils/admission-pdf.js +73 -0
  124. package/utils/clear-cache.d.ts +1 -0
  125. package/utils/clear-cache.js +8 -0
  126. package/utils/format-value.d.ts +1 -0
  127. package/utils/format-value.js +1 -0
  128. package/utils/pdf-generator.d.ts +41 -0
  129. package/utils/pdf-generator.js +107 -0
  130. package/utils/resolve-rbac-permissions.d.ts +11 -0
  131. package/utils/resolve-rbac-permissions.js +251 -0
@@ -0,0 +1,293 @@
1
+ "use client";
2
+ /**
3
+ * Workspace Module — business logic + API integration
4
+ *
5
+ * This module wires the generic module state (created by
6
+ * `createGenericModule`) to network actions using `useModuleEntityV2`.
7
+ * It contains the domain-specific handlers (create/view/edit/delete),
8
+ * local validation wiring, and optimistic UI helpers.
9
+ *
10
+ * Key responsibilities:
11
+ * - expose `useWorkspaceModule()` which UI components call for actions
12
+ * - keep the module-specific `apiParams` and callbacks in one place
13
+ * - ensure cache invalidation and toast notifications on mutation
14
+ *
15
+ * Exported utilities:
16
+ * - `WorkspaceStateContextProvider` — provider component used by the page
17
+ * - `useWorkspaceModule()` — hook that returns handlers and state
18
+ */
19
+ import { useCallback, useEffect, useMemo, useState } from "react";
20
+ import { validateForm } from "@react-pakistan/util-functions";
21
+ import { useModuleEntityV2, } from "@react-pakistan/util-functions/hooks/use-module-entity-v2";
22
+ import { createGenericModule } from "@react-pakistan/util-functions/factory/generic-module-factory";
23
+ import { DRAWER_TYPES } from "@react-pakistan/util-functions/factory/generic-component-factory";
24
+ import { WORKSPACE_API_ROUTES } from "./constants";
25
+ import { getCachedWorkspaceSync, invalidateWorkspaceCache } from "./cache";
26
+ import { workspaceFormValidation } from "./validate";
27
+ import { generateThemeToast, TOAST_VARIANT, } from "@appcorp/shadcn/lib/toast-utils";
28
+ import { useTranslations } from "next-intl";
29
+ import { AUTH_API_ROUTES } from "@/constants";
30
+ // ============================================================================
31
+ // CONFIGURATION
32
+ // ============================================================================
33
+ const workspaceConfig = {
34
+ name: "Workspace",
35
+ displayName: "Workspace",
36
+ initialState: {
37
+ // Form State
38
+ agreedCurrency: "",
39
+ agreedPrice: 0,
40
+ billingDate: null,
41
+ billingInterval: "",
42
+ classesCount: 0,
43
+ coursesCount: 0,
44
+ description: "",
45
+ dueDateLength: 0,
46
+ enabled: true,
47
+ familiesCount: 0,
48
+ id: "",
49
+ logo: "",
50
+ name: "",
51
+ planEndDate: null,
52
+ planId: "",
53
+ planStartDate: null,
54
+ secrets: {},
55
+ staffAccountsCount: 0,
56
+ storageUsedMB: 0,
57
+ studentsCount: 0,
58
+ subdomain: "",
59
+ teachersCount: 0,
60
+ // UI State
61
+ disableSaveButton: false,
62
+ drawer: null,
63
+ errors: {},
64
+ },
65
+ drawerTypes: DRAWER_TYPES,
66
+ // Custom actions
67
+ customActions: {
68
+ SET_WORKSPACE: "SET_WORKSPACE",
69
+ },
70
+ };
71
+ // ============================================================================
72
+ // CREATE WORKSPACE MODULE
73
+ // ============================================================================
74
+ export const { actionTypes: WORKSPACE_ACTION_TYPES, config: workspaceModuleConfig, initialState: initialWorkspaceState, Provider: WorkspaceProvider, reducer: workspaceReducer, useContext: useWorkspaceContext, } = createGenericModule(workspaceConfig);
75
+ // ============================================================================
76
+ // DRAWER TYPES
77
+ // ============================================================================
78
+ export const WORKSPACE_DRAWER = {
79
+ FORM_DRAWER: DRAWER_TYPES.FORM_DRAWER,
80
+ MORE_ACTIONS_DRAWER: "MORE_ACTIONS_DRAWER",
81
+ VIEW_DRAWER: DRAWER_TYPES.VIEW_DRAWER,
82
+ };
83
+ // ============================================================================
84
+ // ENHANCED WORKSPACE HOOK WITH API INTEGRATION
85
+ // ============================================================================
86
+ export const useWorkspaceModule = () => {
87
+ const context = useWorkspaceContext();
88
+ const [plans, setPlans] = useState([]);
89
+ const workspace = getCachedWorkspaceSync();
90
+ const t = useTranslations("workspace");
91
+ // ============================================================================
92
+ // UTILITIES
93
+ // ============================================================================
94
+ const showToast = useCallback((message, variant) => {
95
+ generateThemeToast({ description: message, variant });
96
+ }, []);
97
+ const resetFormAndCloseDrawer = useCallback(() => {
98
+ context.dispatch({
99
+ type: WORKSPACE_ACTION_TYPES.SET_ERRORS,
100
+ payload: { errors: {} },
101
+ });
102
+ context.dispatch({
103
+ type: WORKSPACE_ACTION_TYPES.SET_DISABLE_SAVE_BUTTON,
104
+ payload: { disabled: false },
105
+ });
106
+ context.dispatch({
107
+ type: WORKSPACE_ACTION_TYPES.SET_DRAWER,
108
+ payload: { drawer: null },
109
+ });
110
+ }, [context.dispatch]);
111
+ // ============================================================================
112
+ // API PARAMETERS
113
+ // ============================================================================
114
+ const apiParams = useMemo(() => ({
115
+ update: {
116
+ agreedCurrency: context.state.agreedCurrency,
117
+ agreedPrice: context.state.agreedPrice,
118
+ billingDate: context.state.billingDate,
119
+ billingInterval: context.state.billingInterval,
120
+ classesCount: context.state.classesCount,
121
+ coursesCount: context.state.coursesCount,
122
+ description: context.state.description,
123
+ dueDateLength: context.state.dueDateLength,
124
+ enabled: context.state.enabled,
125
+ familiesCount: context.state.familiesCount,
126
+ id: context.state.id,
127
+ logo: context.state.logo,
128
+ name: context.state.name,
129
+ planEndDate: context.state.planEndDate,
130
+ planId: context.state.planId,
131
+ planStartDate: context.state.planStartDate,
132
+ secrets: context.state.secrets,
133
+ staffAccountsCount: context.state.staffAccountsCount,
134
+ storageUsedMB: context.state.storageUsedMB,
135
+ studentsCount: context.state.studentsCount,
136
+ subdomain: context.state.subdomain,
137
+ teachersCount: context.state.teachersCount,
138
+ },
139
+ }), [
140
+ context.state.agreedCurrency,
141
+ context.state.agreedPrice,
142
+ context.state.billingDate,
143
+ context.state.billingInterval,
144
+ context.state.classesCount,
145
+ context.state.coursesCount,
146
+ context.state.description,
147
+ context.state.dueDateLength,
148
+ context.state.enabled,
149
+ context.state.familiesCount,
150
+ context.state.id,
151
+ context.state.logo,
152
+ context.state.name,
153
+ context.state.planEndDate,
154
+ context.state.planId,
155
+ context.state.planStartDate,
156
+ context.state.secrets,
157
+ context.state.staffAccountsCount,
158
+ context.state.storageUsedMB,
159
+ context.state.studentsCount,
160
+ context.state.subdomain,
161
+ context.state.teachersCount,
162
+ ]);
163
+ // ============================================================================
164
+ // API CALLBACKS
165
+ // ============================================================================
166
+ const listCallback = useCallback(() => { }, []);
167
+ const updateCallback = ({ data, error }) => {
168
+ if (error) {
169
+ showToast(t("messagesUpdateFailed"), TOAST_VARIANT.ERROR);
170
+ return;
171
+ }
172
+ if (data) {
173
+ showToast(t("messagesSaveSuccess"), TOAST_VARIANT.SUCCESS);
174
+ invalidateWorkspaceCache();
175
+ resetFormAndCloseDrawer();
176
+ }
177
+ };
178
+ const byIdCallback = useCallback(() => { }, []);
179
+ const deleteCallback = useCallback(() => { }, []);
180
+ // ============================================================================
181
+ // HANDLERS
182
+ // ============================================================================
183
+ const handleChange = useCallback((field, value) => {
184
+ context.dispatch({
185
+ type: WORKSPACE_ACTION_TYPES.SET_INPUT_FIELD,
186
+ payload: { key: field, value },
187
+ });
188
+ }, [context.dispatch]);
189
+ const handleCloseDrawer = useCallback(() => {
190
+ resetFormAndCloseDrawer();
191
+ }, [resetFormAndCloseDrawer]);
192
+ const handleEdit = useCallback(() => {
193
+ context.dispatch({
194
+ type: WORKSPACE_ACTION_TYPES.SET_DRAWER,
195
+ payload: { drawer: WORKSPACE_DRAWER.FORM_DRAWER },
196
+ });
197
+ }, [context.dispatch]);
198
+ const handleView = useCallback(() => {
199
+ context.dispatch({
200
+ type: WORKSPACE_ACTION_TYPES.SET_DRAWER,
201
+ payload: { drawer: WORKSPACE_DRAWER.VIEW_DRAWER },
202
+ });
203
+ }, [context.dispatch]);
204
+ // ============================================================================
205
+ // NETWORK ACTIONS
206
+ // ============================================================================
207
+ const handleSubmit = useCallback(() => {
208
+ context.dispatch({
209
+ type: WORKSPACE_ACTION_TYPES.SET_DISABLE_SAVE_BUTTON,
210
+ payload: { disabled: true },
211
+ });
212
+ validateForm({
213
+ params: apiParams.update,
214
+ schema: workspaceFormValidation,
215
+ successCallback: () => {
216
+ updateFetchNow(undefined, {
217
+ body: JSON.stringify(apiParams.update),
218
+ });
219
+ },
220
+ errorCallback: (errors) => {
221
+ context.dispatch({
222
+ type: WORKSPACE_ACTION_TYPES.SET_ERRORS,
223
+ payload: { errors },
224
+ });
225
+ context.dispatch({
226
+ type: WORKSPACE_ACTION_TYPES.SET_DISABLE_SAVE_BUTTON,
227
+ payload: { disabled: false },
228
+ });
229
+ showToast(t("messagesFormErrors"), TOAST_VARIANT.ERROR);
230
+ },
231
+ });
232
+ }, [context.dispatch, apiParams.update, t, showToast]);
233
+ // ============================================================================
234
+ // API HOOKS
235
+ // ============================================================================
236
+ const { updateFetchNow, updateLoading } = useModuleEntityV2({
237
+ updateCallback,
238
+ updateParams: apiParams.update,
239
+ listCallback,
240
+ byIdCallback,
241
+ deleteCallback,
242
+ listParams: {},
243
+ byIdParams: {},
244
+ deleteParams: {},
245
+ searchQuery: "",
246
+ listUrl: WORKSPACE_API_ROUTES.UNIT,
247
+ unitUrl: WORKSPACE_API_ROUTES.UNIT,
248
+ unitByIdUrl: WORKSPACE_API_ROUTES.UNIT,
249
+ });
250
+ // ============================================================================
251
+ // EFFECTS
252
+ // ============================================================================
253
+ useEffect(() => {
254
+ if (workspace) {
255
+ context.dispatch({
256
+ type: WORKSPACE_ACTION_TYPES.SET_FORM_DATA,
257
+ payload: { form: workspace },
258
+ });
259
+ }
260
+ }, []);
261
+ // Fetch plans for the combobox
262
+ useEffect(() => {
263
+ const fetchPlans = async () => {
264
+ try {
265
+ const response = await fetch(AUTH_API_ROUTES.PLAN, {
266
+ method: "GET",
267
+ headers: {
268
+ "Content-Type": "application/json",
269
+ "x-api-token": process.env.NEXT_PUBLIC_API_KEY,
270
+ },
271
+ });
272
+ if (response.ok) {
273
+ const data = await response.json();
274
+ setPlans(data.items || []);
275
+ }
276
+ }
277
+ catch (_a) {
278
+ showToast(t("messagesFetchFailed"), TOAST_VARIANT.ERROR);
279
+ }
280
+ };
281
+ fetchPlans();
282
+ }, []);
283
+ // ============================================================================
284
+ // RETURN
285
+ // ============================================================================
286
+ return Object.assign(Object.assign({}, context), { plans,
287
+ handleChange,
288
+ handleCloseDrawer,
289
+ handleEdit,
290
+ handleSubmit,
291
+ handleView,
292
+ updateLoading });
293
+ };
@@ -0,0 +1 @@
1
+ export declare const WorkspaceDrawer: () => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,24 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ /**
4
+ * Workspace Drawer Component
5
+ *
6
+ * Renders form and view drawers for the workspace single-entity module.
7
+ */
8
+ import { EnhancedDrawerHeader } from "@appcorp/shadcn/components/enhanced-drawer-header";
9
+ import { EnhancedDrawerFooter, DRAWER_FOOTER_COMPONENT_TYPE, } from "@appcorp/shadcn/components/enhanced-drawer-footer";
10
+ import { DrawerGeneric } from "@appcorp/shadcn/components/drawer-generic";
11
+ import { useWorkspaceModule, WORKSPACE_DRAWER } from "./context";
12
+ import { WorkspaceForm } from "./form";
13
+ import { WorkspaceView } from "./view";
14
+ import { WorkspaceMoreActions } from "./more-actions";
15
+ export const WorkspaceDrawer = () => {
16
+ const { handleCloseDrawer, handleSubmit, state, updateLoading } = useWorkspaceModule();
17
+ const { disableSaveButton, drawer, errors } = state;
18
+ const isFormDrawer = drawer === WORKSPACE_DRAWER.FORM_DRAWER;
19
+ const isViewDrawer = drawer === WORKSPACE_DRAWER.VIEW_DRAWER;
20
+ const isMoreActionsDrawer = drawer === WORKSPACE_DRAWER.MORE_ACTIONS_DRAWER;
21
+ const applyFilters = () => { };
22
+ const clearFilters = () => { };
23
+ return (_jsx(DrawerGeneric, { filterDrawer: null, filterDrawerHeader: null, filterDrawerFooter: null, formDrawer: isFormDrawer ? _jsx(WorkspaceForm, {}) : null, formDrawerHeader: isFormDrawer ? (_jsx(EnhancedDrawerHeader, { title: "Edit Workspace", description: "Update your workspace settings" })) : null, formDrawerFooter: isFormDrawer ? (_jsx(EnhancedDrawerFooter, { applyFilters: applyFilters, clearFilters: clearFilters, closeDrawer: handleCloseDrawer, disableSaveButton: disableSaveButton, drawerType: DRAWER_FOOTER_COMPONENT_TYPE.FORM_DRAWER, errors: errors, handleSubmit: handleSubmit, updateLoading: updateLoading })) : null, viewDrawer: isViewDrawer ? _jsx(WorkspaceView, {}) : null, viewDrawerHeader: isViewDrawer ? (_jsx(EnhancedDrawerHeader, { title: "Workspace Details", description: "View your workspace information" })) : null, viewDrawerFooter: isViewDrawer ? (_jsx(EnhancedDrawerFooter, { applyFilters: applyFilters, clearFilters: clearFilters, closeDrawer: handleCloseDrawer, disableSaveButton: disableSaveButton, drawerType: DRAWER_FOOTER_COMPONENT_TYPE.VIEW_DRAWER, errors: errors, handleSubmit: handleSubmit, updateLoading: updateLoading })) : null, moreActionsDrawer: isMoreActionsDrawer ? _jsx(WorkspaceMoreActions, {}) : null, moreActionsDrawerHeader: isMoreActionsDrawer ? (_jsx(EnhancedDrawerHeader, { title: "More Actions", description: "Additional workspace actions" })) : null, moreActionsDrawerFooter: isMoreActionsDrawer ? (_jsx(EnhancedDrawerFooter, { applyFilters: applyFilters, clearFilters: clearFilters, closeDrawer: handleCloseDrawer, disableSaveButton: disableSaveButton, drawerType: DRAWER_FOOTER_COMPONENT_TYPE.MORE_ACTIONS_DRAWER, errors: errors, handleSubmit: handleSubmit, updateLoading: updateLoading })) : null, onOpenChange: (open) => !open && handleCloseDrawer(), open: isFormDrawer || isViewDrawer || isMoreActionsDrawer }));
24
+ };
@@ -0,0 +1 @@
1
+ export declare const WorkspaceFilter: () => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,13 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ /**
4
+ * Workspace Filter
5
+ *
6
+ * Placeholder component for workspace filters.
7
+ * Currently no filters are available for workspaces.
8
+ */
9
+ import { useTranslations } from "next-intl";
10
+ export const WorkspaceFilter = () => {
11
+ const t = useTranslations("workspace");
12
+ return (_jsx("div", { className: "p-6 text-center text-muted-foreground", children: _jsx("p", { children: t("filter") }) }));
13
+ };
@@ -0,0 +1 @@
1
+ export declare const WorkspaceForm: () => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,40 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ /**
4
+ * Workspace Form
5
+ *
6
+ * Form component for creating/editing workspace information.
7
+ */
8
+ import { useState } from "react";
9
+ import { useWorkspaceModule } from "./context";
10
+ import { useTranslations } from "next-intl";
11
+ import { EnhancedInput } from "@appcorp/shadcn/components/enhanced-input";
12
+ import { EnhancedTextarea } from "@appcorp/shadcn/components/enhanced-textarea";
13
+ import { EnhancedCombobox } from "@appcorp/shadcn/components/enhanced-combobox";
14
+ import { Shield, Eye, EyeOff } from "lucide-react";
15
+ import { secretKeys } from "./constants";
16
+ const SecretsEditor = ({ secrets, errors, onChange }) => {
17
+ const [visibleMap, setVisibleMap] = useState(() => Object.fromEntries(secretKeys.map((k) => [k, false])));
18
+ const toggle = (key) => setVisibleMap((s) => (Object.assign(Object.assign({}, s), { [key]: !s[key] })));
19
+ return (_jsx("div", { className: "space-y-3", children: secretKeys.map((key) => {
20
+ const val = secrets[key] || "";
21
+ return (_jsxs("div", { className: "relative", children: [_jsx(EnhancedInput, { id: `secrets.${key}`, label: key, value: String(val), onChange: (e) => onChange(key, e.target.value), error: errors[`secrets.${key}`], placeholder: "Enter value (visible only to admins)", type: visibleMap[key] ? "text" : "password" }), _jsx("button", { type: "button", "aria-label": visibleMap[key] ? `Hide ${key}` : `Show ${key}`, onClick: () => toggle(key), className: "absolute inset-y-0 top-7 right-3 flex items-center justify-center p-1 text-sm text-muted-foreground hover:text-foreground", children: visibleMap[key] ? (_jsx(EyeOff, { className: "h-4 w-4" })) : (_jsx(Eye, { className: "h-4 w-4" })) })] }, key));
22
+ }) }));
23
+ };
24
+ // ============================================================================
25
+ // WORKSPACE FORM
26
+ // ============================================================================
27
+ export const WorkspaceForm = () => {
28
+ const { state, handleChange, plans } = useWorkspaceModule();
29
+ const t = useTranslations("workspace");
30
+ const secrets = state.secrets || {};
31
+ const handleSecretChange = (key, value) => {
32
+ handleChange("secrets", Object.assign(Object.assign({}, secrets), { [key]: value }));
33
+ };
34
+ return (_jsxs("div", { className: "space-y-6", children: [_jsx(EnhancedInput, { id: "name", label: t("formNameLabel"), value: state.name, onChange: (e) => handleChange("name", e.target.value), error: state.errors.name, placeholder: t("formNamePlaceholder"), required: true, readOnly: true }), _jsx(EnhancedInput, { id: "subdomain", label: t("formSubdomainLabel"), value: state.subdomain, onChange: (e) => handleChange("subdomain", e.target.value), error: state.errors.subdomain, placeholder: t("formSubdomainPlaceholder"), required: true, info: `This will be your workspace URL: ${state.subdomain}.edupilotpro.com`, readOnly: true }), _jsx(EnhancedTextarea, { id: "description", label: t("formDescriptionLabel"), value: state.description || "", onChange: (e) => handleChange("description", e.target.value), error: state.errors.description, placeholder: t("formDescriptionPlaceholder"), rows: 3 }), _jsx(EnhancedInput, { id: "logo", label: "Logo URL", value: state.logo || "", onChange: (e) => handleChange("logo", e.target.value), error: state.errors.logo, placeholder: "Enter logo URL (optional)", type: "url", readOnly: true }), _jsx(EnhancedCombobox, { id: "planId", label: "Plan", value: state.planId || "", onValueChange: (value) => handleChange("planId", value), options: plans
35
+ .filter(({ name }) => name.match("PKR"))
36
+ .map((plan) => ({
37
+ label: plan.name,
38
+ value: plan.id,
39
+ })), error: state.errors.planId, placeholder: "Select a plan", info: "Choose the subscription plan for this workspace" }), _jsxs("div", { className: "border-t pt-6 mt-6", children: [_jsxs("div", { className: "flex items-center gap-2 mb-4", children: [_jsx(Shield, { className: "h-5 w-5 text-primary" }), _jsx("h3", { className: "text-lg font-semibold", children: "Secrets Configuration" })] }), _jsx("p", { className: "text-sm text-muted-foreground mb-4", children: "Configure encrypted secrets for external services like SMTP, API keys, etc." }), _jsx(SecretsEditor, { secrets: secrets, errors: state.errors, onChange: handleSecretChange })] })] }));
40
+ };
@@ -0,0 +1 @@
1
+ export declare const WorkspaceMoreActions: () => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,13 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ /**
4
+ * Workspace More Actions
5
+ *
6
+ * Placeholder component for additional workspace actions.
7
+ * Currently no additional actions are available for workspaces.
8
+ */
9
+ import { useTranslations } from "next-intl";
10
+ export const WorkspaceMoreActions = () => {
11
+ const t = useTranslations("workspace");
12
+ return (_jsx("div", { className: "p-6 text-center text-muted-foreground", children: _jsx("p", { children: t("moreActions") }) }));
13
+ };
@@ -0,0 +1 @@
1
+ export declare const WorkspacePage: () => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,31 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useWorkspaceModule, WorkspaceProvider } from "./context";
4
+ import { WorkspaceView } from "./view";
5
+ import { WorkspaceDrawer } from "./drawer";
6
+ import { Button } from "@appcorp/shadcn/components/ui/button";
7
+ import { Edit } from "lucide-react";
8
+ // import { useAuthStateContext } from "@/contexts/auth-context";
9
+ import { resolveRbacPermissions } from "@/utils/resolve-rbac-permissions";
10
+ import { USER_ROLE } from "@/type";
11
+ import { RbacNoAccess } from "@/components/rbac-no-access";
12
+ import { useTranslations } from "next-intl";
13
+ // ============================================================================
14
+ // WORKSPACE PAGE COMPONENT
15
+ // ============================================================================
16
+ const WorkspaceInnerPage = () => {
17
+ // const { user } = useAuthStateContext();
18
+ // const userRole = user?.user_metadata?.role as USER_ROLE;
19
+ const userRole = USER_ROLE.SCHOOL_ADMIN; // Default for storybook
20
+ const { handleEdit } = useWorkspaceModule();
21
+ const t = useTranslations("workspace");
22
+ const hasPermission = resolveRbacPermissions({
23
+ userRole,
24
+ moduleName: "Workspace",
25
+ });
26
+ if (!hasPermission) {
27
+ return _jsx(RbacNoAccess, { moduleName: "Workspace" });
28
+ }
29
+ return (_jsx("div", { className: "container mx-auto px-4 py-8", children: _jsxs("div", { className: "mx-auto max-w-6xl", children: [_jsxs("div", { className: "mb-8", children: [_jsx("h1", { className: "text-3xl font-bold text-gray-900", children: t("tableTitle") }), _jsx("p", { className: "mt-2 text-gray-600", children: t("tableDescription") })] }), _jsx("div", { className: "mb-6 flex justify-end", children: _jsxs(Button, { onClick: handleEdit, className: "flex items-center space-x-2", children: [_jsx(Edit, { className: "h-4 w-4" }), _jsx("span", { children: t("headerActionsEdit") })] }) }), _jsx(WorkspaceView, {}), _jsx(WorkspaceDrawer, {})] }) }));
30
+ };
31
+ export const WorkspacePage = () => (_jsx(WorkspaceProvider, { children: _jsx(WorkspaceInnerPage, {}) }));
@@ -0,0 +1,9 @@
1
+ import { z } from "zod";
2
+ export declare const workspaceFormValidation: z.ZodObject<{
3
+ id: z.ZodOptional<z.ZodString>;
4
+ name: z.ZodString;
5
+ subdomain: z.ZodString;
6
+ planId: z.ZodOptional<z.ZodString>;
7
+ enabled: z.ZodOptional<z.ZodBoolean>;
8
+ }, z.core.$strip>;
9
+ export type WorkspaceForm = z.infer<typeof workspaceFormValidation>;
@@ -0,0 +1,8 @@
1
+ import { z } from "zod";
2
+ export const workspaceFormValidation = z.object({
3
+ id: z.string().optional(),
4
+ name: z.string().min(1, "Name is required"),
5
+ subdomain: z.string().min(1, "Subdomain is required"),
6
+ planId: z.string().optional(),
7
+ enabled: z.boolean().optional(),
8
+ });
@@ -0,0 +1 @@
1
+ export declare const WorkspaceView: () => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,52 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ /**
4
+ * Workspace View
5
+ *
6
+ * Read-only view component for displaying workspace information.
7
+ */
8
+ import { useWorkspaceModule } from "./context";
9
+ import { useTranslations } from "next-intl";
10
+ import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@appcorp/shadcn/components/ui/card";
11
+ import { Badge } from "@appcorp/shadcn/components/ui/badge";
12
+ import { Separator } from "@appcorp/shadcn/components/ui/separator";
13
+ import { Building2, Globe, FileText, Image, CheckCircle2, XCircle, Calendar, CreditCard, Users, BookOpen, GraduationCap, Home, HardDrive, Clock, Shield, } from "lucide-react";
14
+ import { DATE_FORMATS, formatDate } from "@react-pakistan/util-functions";
15
+ import { formatValue } from "@/utils/format-value";
16
+ export const WorkspaceView = () => {
17
+ const { state } = useWorkspaceModule();
18
+ const t = useTranslations("workspace");
19
+ const formatCurrency = (amount, currency) => {
20
+ if (!amount)
21
+ return "—";
22
+ const numAmount = typeof amount === "string" ? parseFloat(amount) : amount;
23
+ if (isNaN(numAmount))
24
+ return "—";
25
+ return new Intl.NumberFormat("en-US", {
26
+ style: "currency",
27
+ currency: currency || "USD",
28
+ }).format(numAmount);
29
+ };
30
+ // Helper function to format billing interval
31
+ const formatBillingInterval = (interval) => {
32
+ if (!interval)
33
+ return "—";
34
+ return interval.charAt(0).toUpperCase() + interval.slice(1).toLowerCase();
35
+ };
36
+ // Helper function to format storage
37
+ const formatStorage = (mb) => {
38
+ if (mb < 1024)
39
+ return `${mb} MB`;
40
+ return `${(mb / 1024).toFixed(1)} GB`;
41
+ };
42
+ return (_jsxs("div", { className: "space-y-6", children: [_jsxs(Card, { children: [_jsxs(CardHeader, { className: "pb-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Building2, { className: "h-5 w-5 text-primary" }), _jsx(CardTitle, { className: "text-lg", children: t("basicInfoTitle") })] }), _jsx(CardDescription, { children: t("basicInfoDescription") })] }), _jsx(Separator, {}), _jsx(CardContent, { className: "pt-6", children: _jsxs("div", { className: "grid grid-cols-2 md:grid-cols-2 gap-6", children: [_jsxs("div", { className: "space-y-1 md:col-span-2", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Building2, { className: "h-4 w-4 text-muted-foreground" }), _jsx("p", { className: "text-sm font-medium text-muted-foreground", children: t("viewLabelsName") })] }), _jsx("p", { className: "text-base", children: formatValue(state.name) })] }), _jsxs("div", { className: "space-y-1 md:col-span-2", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Globe, { className: "h-4 w-4 text-muted-foreground" }), _jsx("p", { className: "text-sm font-medium text-muted-foreground", children: t("viewLabelsSubdomain") })] }), _jsx("p", { className: "text-base", children: formatValue(state.subdomain) }), state.subdomain && (_jsxs("p", { className: "text-sm text-muted-foreground", children: [t("urlPrefix"), state.subdomain, ".edupilotpro.com"] }))] }), _jsxs("div", { className: "space-y-1 md:col-span-2", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(FileText, { className: "h-4 w-4 text-muted-foreground" }), _jsx("p", { className: "text-sm font-medium text-muted-foreground", children: t("viewLabelsDescription") })] }), _jsx("p", { className: "text-base", children: formatValue(state.description) === "—"
43
+ ? t("noDescriptionProvided")
44
+ : state.description })] }), state.logo && (_jsxs("div", { className: "space-y-1 md:col-span-2", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Image, { className: "h-4 w-4 text-muted-foreground" }), _jsx("p", { className: "text-sm font-medium text-muted-foreground", children: t("viewLabelsLogo") })] }), _jsx("div", { className: "mt-2", children: _jsx("img", { src: state.logo, alt: t("viewLabelsLogoAlt"), className: "h-16 w-16 object-contain rounded border", onError: (e) => {
45
+ e.currentTarget.style.display = "none";
46
+ } }) })] })), _jsxs("div", { className: "space-y-1", children: [_jsx("p", { className: "text-sm font-medium text-muted-foreground", children: t("viewLabelsStatus") }), _jsxs(Badge, { variant: state.enabled ? "default" : "destructive", className: "gap-1", children: [state.enabled ? (_jsx(CheckCircle2, { className: "h-3 w-3" })) : (_jsx(XCircle, { className: "h-3 w-3" })), state.enabled
47
+ ? t("viewStatusEnabled")
48
+ : t("viewStatusDisabled")] })] })] }) })] }), _jsxs(Card, { children: [_jsxs(CardHeader, { className: "pb-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(CreditCard, { className: "h-5 w-5 text-primary" }), _jsx(CardTitle, { className: "text-lg", children: t("planBillingTitle") })] }), _jsx(CardDescription, { children: t("planBillingDescription") })] }), _jsx(Separator, {}), _jsx(CardContent, { className: "pt-6", children: _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-6", children: [_jsxs("div", { className: "space-y-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(CreditCard, { className: "h-4 w-4 text-muted-foreground" }), _jsx("p", { className: "text-sm font-medium text-muted-foreground", children: t("planIdLabel") })] }), _jsx("p", { className: "font-mono text-sm", children: formatValue(state.planId) })] }), _jsxs("div", { className: "space-y-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Calendar, { className: "h-4 w-4 text-muted-foreground" }), _jsx("p", { className: "text-sm font-medium text-muted-foreground", children: t("planStartDateLabel") })] }), _jsx("p", { className: "text-base", children: formatDate(state.planStartDate || "", DATE_FORMATS.LOCALE_DATE) })] }), _jsxs("div", { className: "space-y-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Calendar, { className: "h-4 w-4 text-muted-foreground" }), _jsx("p", { className: "text-sm font-medium text-muted-foreground", children: t("planEndDateLabel") })] }), _jsx("p", { className: "text-base", children: formatDate(state.planEndDate || "", DATE_FORMATS.LOCALE_DATE) })] }), _jsxs("div", { className: "space-y-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Clock, { className: "h-4 w-4 text-muted-foreground" }), _jsx("p", { className: "text-sm font-medium text-muted-foreground", children: t("billingIntervalLabel") })] }), _jsx("p", { className: "text-base", children: formatBillingInterval(state.billingInterval) })] }), _jsxs("div", { className: "space-y-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(CreditCard, { className: "h-4 w-4 text-muted-foreground" }), _jsx("p", { className: "text-sm font-medium text-muted-foreground", children: t("agreedPriceLabel") })] }), _jsx("p", { className: "text-base", children: formatCurrency(state.agreedPrice, state.agreedCurrency) })] }), _jsxs("div", { className: "space-y-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Globe, { className: "h-4 w-4 text-muted-foreground" }), _jsx("p", { className: "text-sm font-medium text-muted-foreground", children: t("currencyLabel") })] }), _jsx("p", { className: "text-base", children: formatValue(state.agreedCurrency) })] })] }) })] }), _jsxs(Card, { children: [_jsxs(CardHeader, { className: "pb-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Users, { className: "h-5 w-5 text-primary" }), _jsx(CardTitle, { className: "text-lg", children: t("usageStatsTitle") })] }), _jsx(CardDescription, { children: t("usageStatsDescription") })] }), _jsx(Separator, {}), _jsx(CardContent, { className: "pt-6", children: _jsxs("div", { className: "grid grid-cols-2 md:grid-cols-3 gap-6", children: [_jsxs("div", { className: "space-y-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(GraduationCap, { className: "h-4 w-4 text-muted-foreground" }), _jsx("p", { className: "text-sm font-medium text-muted-foreground", children: t("studentsLabel") })] }), _jsx("p", { className: "text-2xl font-bold text-primary", children: state.studentsCount })] }), _jsxs("div", { className: "space-y-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Users, { className: "h-4 w-4 text-muted-foreground" }), _jsx("p", { className: "text-sm font-medium text-muted-foreground", children: t("teachersLabel") })] }), _jsx("p", { className: "text-2xl font-bold text-primary", children: state.teachersCount })] }), _jsxs("div", { className: "space-y-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(BookOpen, { className: "h-4 w-4 text-muted-foreground" }), _jsx("p", { className: "text-sm font-medium text-muted-foreground", children: t("classesLabel") })] }), _jsx("p", { className: "text-2xl font-bold text-primary", children: state.classesCount })] }), _jsxs("div", { className: "space-y-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(BookOpen, { className: "h-4 w-4 text-muted-foreground" }), _jsx("p", { className: "text-sm font-medium text-muted-foreground", children: t("coursesLabel") })] }), _jsx("p", { className: "text-2xl font-bold text-primary", children: state.coursesCount })] }), _jsxs("div", { className: "space-y-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Home, { className: "h-4 w-4 text-muted-foreground" }), _jsx("p", { className: "text-sm font-medium text-muted-foreground", children: t("familiesLabel") })] }), _jsx("p", { className: "text-2xl font-bold text-primary", children: state.familiesCount })] }), _jsxs("div", { className: "space-y-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(HardDrive, { className: "h-4 w-4 text-muted-foreground" }), _jsx("p", { className: "text-sm font-medium text-muted-foreground", children: t("storageUsedLabel") })] }), _jsx("p", { className: "text-2xl font-bold text-primary", children: formatStorage(state.storageUsedMB) })] })] }) })] }), _jsxs(Card, { children: [_jsxs(CardHeader, { className: "pb-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Shield, { className: "h-5 w-5 text-primary" }), _jsx(CardTitle, { className: "text-lg", children: t("secretsTitle") })] }), _jsx(CardDescription, { children: t("secretsDescription") })] }), _jsx(Separator, {}), _jsx(CardContent, { className: "pt-6", children: _jsx("div", { className: "space-y-4", children: _jsxs("div", { children: [_jsxs("div", { className: "flex items-center gap-2 mb-2", children: [_jsx(Shield, { className: "h-4 w-4 text-muted-foreground" }), _jsx("p", { className: "text-sm font-medium text-muted-foreground", children: t("secretsJsonLabel") })] }), state.secrets ? (_jsx("div", { className: "space-y-2", children: Object.keys(state.secrets).length ===
49
+ 0 ? (_jsx("p", { className: "text-muted-foreground italic", children: t("noSecretsConfigured") })) : (Object.entries(state.secrets).map(([k, v]) => (_jsxs("div", { className: "flex items-center justify-between bg-muted/10 border border-border/60 rounded-md p-3", children: [_jsx("div", { className: "text-sm font-medium text-foreground", children: k }), _jsx("div", { className: "text-sm font-mono text-foreground/80", children: typeof v === "string" && v.length > 0
50
+ ? `${String(v).slice(0, 3)}${"*".repeat(Math.max(0, String(v).length - 3))}`
51
+ : "—" })] }, k)))) })) : (_jsx("p", { className: "text-muted-foreground italic", children: t("noSecretsConfigured") })), _jsx("p", { className: "text-xs text-muted-foreground mt-2", children: t("secretsHelpText") })] }) }) })] })] }));
52
+ };
@@ -0,0 +1,6 @@
1
+ import { FC } from "react";
2
+ interface RbacNoAccessProps {
3
+ moduleName?: string;
4
+ }
5
+ export declare const RbacNoAccess: FC<RbacNoAccessProps>;
6
+ export {};
@@ -0,0 +1,4 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ export const RbacNoAccess = ({ moduleName }) => {
3
+ return (_jsxs("div", { className: "flex flex-col items-center justify-center h-full gap-6 p-8", children: [_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", xmlnsXlink: "http://www.w3.org/1999/xlink", width: "293", height: "330", viewBox: "0 0 586.47858 659.29778", role: "img", "aria-label": "Access restricted illustration", className: "text-primary", children: [_jsx("circle", { cx: "332.47856", cy: "254", r: "254.00001", fill: "#f2f2f2" }), _jsx("path", { d: "M498.46363,113.58835H33.17063c-.99774-.02133-1.78931-.84746-1.76797-1.84521,.02069-.96771,.80026-1.74727,1.76797-1.76796H498.46363c.99774,.02133,1.78931,.84746,1.76794,1.84521-.02069,.96771-.80023,1.74727-1.76794,1.76796Z", fill: "#cacaca" }), _jsx("rect", { x: "193.77441", y: "174.47256", width: "163.61147", height: "34.98639", rx: "17.49318", ry: "17.49318", fill: "#fff" }), _jsx("path", { d: "M128.17493,244.44534H422.98542c9.66122,0,17.49316,7.83197,17.49316,17.49319h0c0,9.66122-7.83194,17.49319-17.49316,17.49319H128.17493c-9.66122,0-17.49318-7.83197-17.49318-17.49319h0c0-9.66122,7.83196-17.49319,17.49318-17.49319Z", fill: "#fff" }), _jsx("path", { d: "M128.17493,314.41812H422.98542c9.66122,0,17.49316,7.83197,17.49316,17.49319h0c0,9.66122-7.83194,17.49319-17.49316,17.49319H128.17493c-9.66122,0-17.49318-7.83197-17.49318-17.49319h0c0-9.66122,7.83196-17.49319,17.49318-17.49319Z", fill: "#fff" }), _jsx("path", { d: "M91.64085,657.75932l-.69385-.06793c-23.54068-2.42871-44.82135-15.08929-58.18845-34.61835-3.66138-5.44159-6.62299-11.32251-8.815-17.50409l-.21069-.58966,.62375-.05048c7.44699-.59924,15.09732-1.86292,18.49585-2.46417l-21.91473-7.42511-.1355-.65033c-1.29926-6.10406,1.24612-12.38458,6.4285-15.86176,5.19641-3.64447,12.08731-3.76111,17.40405-.29449,2.38599,1.52399,4.88162,3.03339,7.29489,4.49359,8.29321,5.01636,16.8688,10.20337,23.29828,17.30121,9.74951,10.97778,14.02298,25.76984,11.63,40.25562l4.7829,17.47595Z", fill: "#f2f2f2" }), _jsx("polygon", { points: "171.30016 646.86102 182.10017 646.85999 187.23916 605.198 171.29716 605.19897 171.30016 646.86102", fill: "#a0616a" }), _jsx("path", { d: "M170.9192,658.12816l33.21436-.00122v-.41998c-.00049-7.13965-5.78833-12.92737-12.92798-12.92773h-.00079l-6.06702-4.60278-11.3197,4.60345-2.89941,.00012,.00055,13.34814Z", fill: "#2f2e41" }), _jsx("polygon", { points: "84.74116 616.94501 93.38016 623.42603 122.49316 593.185 109.74116 583.61902 84.74116 616.94501", fill: "#a0616a" }), _jsx("path", { d: "M77.67448,625.72966l26.569,19.93188,.25208-.336c4.2843-5.71136,3.12799-13.81433-2.58279-18.09937l-.00064-.00049-2.09079-7.32275-11.81735-3.11102-2.31931-1.73993-8.01019,10.67767Z", fill: "#2f2e41" }), _jsx("path", { d: "M120.64463,451.35271s.59625,16.26422,1.3483,29.30737c.12335,2.13916-4.88821,4.46301-4.75842,6.7901,.08609,1.54395,1.02808,3.04486,1.1156,4.65472,.09235,1.69897-1.20822,3.20282-1.1156,4.95984,.09052,1.71667,1.57422,3.6853,1.66373,5.44244,.96317,18.9093,4.45459,41.54633,.9584,47.87439-1.72299,3.11871-23.68533,46.32446-23.68533,46.32446,0,0,12.23666,18.35498,15.73285,12.23663,4.61771-8.08099,40.20615-45.88745,40.20615-53.10712,0-7.21088,8.23346-61.25323,8.23346-61.25323l5.74103,31.98169,2.63239,6.33655-.82715,3.71997,1.70117,5.02045,.09192,4.96838,1.65619,9.22614s-4.98199,71.88159-2.17633,73.88312c2.81439,2.01038,16.44086,5.62018,18.04901,2.01038,1.59955-3.6098,12.0108-75.01947,12.0108-75.01947,0,0,1.6781-32.72424,3.49622-63.14111,.1048-1.76556,1.34607-3.89825,1.4422-5.63763,.11365-2.01898-.67297-4.64111-.56818-6.599,.11365-2.24628,1.11005-3.82831,1.20618-5.97852,.74292-16.6156-3.42761-36.84912-4.7561-38.84192-4.01202-6.01343-7.62177-10.82074-7.62177-10.82074,0,0-54.03558-17.75403-68.47485,.28625l-3.30185,25.37585Z", fill: "#2f2e41" }), _jsx("path", { d: "M174.53779,284.10378l-21.4209-4.28418-9.9964,13.56656h0c-18.65262,18.34058-18.93359,34.52753-15.60379,60.47382v36.41553l-2.41,24.41187s-8.53156,17.84521,.26788,22.00006,66.59857,3.80066,72.117,2.14209,.73517-3.69482-.71399-11.4245c-2.72211-14.51929-.90131-7.51562-.71399-12.13849,2.68585-66.31363-3.57013-93.5379-4.20544-100.69376l-10.89398-19.75858-6.42639-10.71042Z", fill: "#3f3d56" }), _jsx("path", { d: "M287.43909,337.57097c-2.23248,4.23007-7.47144,5.84943-11.70148,3.61694-.45099-.23804-.88013-.51541-1.28229-.82895l-46.26044,29.37308,.13336-15.9924,44.93842-26.07846c3.20093-3.58887,8.70514-3.90332,12.29401-.70239,3.00305,2.67844,3.7796,7.0657,1.87842,10.61218Z", fill: "#a0616a" }), _jsx("path", { d: "M157.62488,302.62425l-5.26666-.55807c-4.86633-.50473-9.64093,1.57941-12.57947,5.491-1.12549,1.48346-1.9339,3.18253-2.37491,4.99164l-.00317,.01447c-1.32108,5.44534,.75095,11.15201,5.25803,14.48117l18.19031,13.41101c12.76544,17.24899,36.75653,28.69272,64.89832,37.98978l43.74274-27.16666-15.47186-18.73843-30.00336,16.0798-44.59833-34.52374-.0257-.02075-16.97424-10.936-4.79169-.5152Z", fill: "#3f3d56" }), _jsx("circle", { cx: "167.29993", cy: "248.60526", r: "24.9798", fill: "#a0616a" }), _jsx("path", { d: "M167.8769,273.59047c-.20135,.00662-.4032,.01108-.6048,.01657-.0863,.22388-.17938,.44583-.2868,.66357l.8916-.68015Z", fill: "#2f2e41" }), _jsx("path", { d: "M174.73243,249.29823c.03918,.24612,.09912,.48846,.17914,.72449-.03302-.24731-.09308-.49026-.17914-.72449Z", fill: "#2f2e41" }), _jsx("path", { d: "M192.59852,224.6942c-1.0282,3.19272-1.94586-.85715-5.32825-.12869-4.06885,.87625-8.80377,.57532-12.13586-1.91879-4.96478-3.64273-11.39874-4.62335-17.22333-2.62509-5.70154,2.01706-15.25348,3.43933-16.73907,9.30179-.51642,2.03781-.7215,4.24933-1.97321,5.9382-1.09436,1.47662-2.82166,2.31854-4.26608,3.45499-4.87726,3.83743-1.14954,14.73981,1.15881,20.50046,2.30838,5.76065,7.60355,9.95721,13.42526,12.10678,5.63281,2.07977,11.7464,2.44662,17.75531,2.28317,1.04517-2.7106,.59363-5.84137-.26874-8.65134-.93359-3.04199-2.31592-5.97791-2.70593-9.13599s.46643-6.74527,3.11444-8.50986c2.4339-1.62192,6.39465-.63388,7.32062,1.98843-.54028-3.27841,2.7807-6.4509,6.20508-7.00882,3.67651-.599,7.35291,.72833,11.01886,1.38901s2.36475-14.77301,.64209-18.98425Z", fill: "#2f2e41" }), _jsx("circle", { cx: "281.3585", cy: "285.71051", r: "51.12006", transform: "translate(-26.58509 542.54478) rotate(-85.26884)", fill: "currentColor" }), _jsx("path", { d: "M294.78675,264.41051l-13.42828,13.42828-13.42828-13.42828c-2.17371-2.17374-5.69806-2.17374-7.87177,0s-2.17371,5.69803,0,7.87177l13.42828,13.42828-13.42828,13.42828c-2.17169,2.17575-2.1684,5.70007,.00739,7.87177,2.17285,2.16879,5.69153,2.16879,7.86438-.00003l13.42828-13.42828,13.42828,13.42828c2.17578,2.17169,5.70007,2.1684,7.87177-.00735,2.16882-2.17288,2.16882-5.6915,0-7.86438l-13.42828-13.42828,13.42828-13.42828c2.17371-2.17374,2.17371-5.69803,0-7.87177s-5.69806-2.17374-7.87177,0h0Z", fill: "#fff" }), _jsx("path", { d: "M261.21387,242.74385c1.5069,4.53946-.95154,9.44101-5.49097,10.94791-.48401,.16064-.9812,.27823-1.4859,.35141l-10.83051,53.71692-11.44788-11.16785,12.29266-50.48209c-.37366-4.7944,3.21008-8.98395,8.00452-9.3576,4.01166-.31265,7.71509,2.16425,8.95807,5.9913Z", fill: "#a0616a" }), _jsx("path", { d: "M146.12519,312.22478l-4.04883,3.41412c-3.73322,3.16214-5.53476,8.05035-4.74649,12.87888,.29129,1.83917,.95773,3.59879,1.95786,5.16949l.00824,.0123c3.01477,4.72311,8.5672,7.17865,14.08978,6.23117l22.27075-3.84171c21.28461,2.72995,46.15155-6.65967,72.34302-20.53055l10.67969-50.37274-24.23297-1.80811-9.16821,32.78271-55.78815,8.28149-.03278,.00415-19.64294,4.67767-3.68896,3.1011Z", fill: "#3f3d56" }), _jsx("path", { d: "M272.93684,658.99046l-271.75,.30731c-.65759-.00214-1.18896-.53693-1.18683-1.19452,.00211-.6546,.53223-1.18469,1.18683-1.18683l271.75-.30731c.65759,.00214,1.18896,.53693,1.18683,1.19452-.00208,.6546-.53223,1.18469-1.18683,1.18683Z", fill: "#cacaca" }), _jsxs("g", { children: [_jsx("ellipse", { cx: "56.77685", cy: "82.05834", rx: "8.45661", ry: "8.64507", fill: "#3f3d56" }), _jsx("ellipse", { cx: "85.9906", cy: "82.05834", rx: "8.45661", ry: "8.64507", fill: "#3f3d56" }), _jsx("ellipse", { cx: "115.20435", cy: "82.05834", rx: "8.45661", ry: "8.64507", fill: "#3f3d56" }), _jsx("path", { d: "M148.51577,88.89113c-.25977,0-.51904-.10059-.71484-.30078l-5.70605-5.83301c-.38037-.38867-.38037-1.00977,0-1.39844l5.70605-5.83252c.38721-.39453,1.021-.40088,1.41406-.01562,.39502,.38623,.40186,1.01953,.01562,1.41406l-5.02197,5.1333,5.02197,5.13379c.38623,.39453,.37939,1.02783-.01562,1.41406-.19434,.19043-.44678,.28516-.69922,.28516Z", fill: "#3f3d56" }), _jsx("path", { d: "M158.10415,88.89113c-.25244,0-.50488-.09473-.69922-.28516-.39502-.38623-.40186-1.01904-.01562-1.41406l5.02148-5.13379-5.02148-5.1333c-.38623-.39453-.37939-1.02783,.01562-1.41406,.39404-.38672,1.02783-.37939,1.41406,.01562l5.70557,5.83252c.38037,.38867,.38037,1.00977,0,1.39844l-5.70557,5.83301c-.1958,.2002-.45508,.30078-.71484,.30078Z", fill: "#3f3d56" }), _jsx("path", { d: "M456.61398,74.41416h-10.60999c-1.21002,0-2.19,.97998-2.19,2.19v10.62c0,1.21002,.97998,2.19,2.19,2.19h10.60999c1.21002,0,2.20001-.97998,2.20001-2.19v-10.62c0-1.21002-.98999-2.19-2.20001-2.19Z", fill: "#3f3d56" }), _jsx("path", { d: "M430.61398,74.41416h-10.60999c-1.21002,0-2.19,.97998-2.19,2.19v10.62c0,1.21002,.97998,2.19,2.19,2.19h10.60999c1.21002,0,2.20001-.97998,2.20001-2.19v-10.62c0-1.21002-.98999-2.19-2.20001-2.19Z", fill: "#3f3d56" }), _jsx("path", { d: "M481.11398,74.91416h-10.60999c-1.21002,0-2.19,.97998-2.19,2.19v10.62c0,1.21002,.97998,2.19,2.19,2.19h10.60999c1.21002,0,2.20001-.97998,2.20001-2.19v-10.62c0-1.21002-.98999-2.19-2.20001-2.19Z", fill: "#3f3d56" }), _jsx("path", { d: "M321.19229,78.95414h-84.81c-1.48004,0-2.67004,1.20001-2.67004,2.67004s1.19,2.66998,2.67004,2.66998h84.81c1.46997,0,2.66998-1.20001,2.66998-2.66998s-1.20001-2.67004-2.66998-2.67004Z", fill: "#3f3d56" })] })] }), _jsxs("div", { className: "text-center max-w-sm", children: [_jsx("h1", { className: "text-2xl font-bold text-gray-900 dark:text-gray-100 mb-2", children: "Access Restricted" }), _jsxs("p", { className: "text-gray-500 dark:text-gray-400 text-sm leading-relaxed", children: ["You don't have permission to access", " ", _jsx("span", { className: "font-medium text-gray-700 dark:text-gray-300", children: moduleName ? `the ${moduleName} module` : "this module" }), ". Please contact your administrator if you believe this is an error."] })] })] }));
4
+ };