@campxdev/campx-web-utils 0.6.0 → 1.0.0

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 (124) hide show
  1. package/dist/README.md +46 -0
  2. package/dist/cjs/index.js +4 -0
  3. package/dist/cjs/index.js.map +1 -0
  4. package/dist/cjs/types/src/App.d.ts +1 -0
  5. package/dist/cjs/types/src/AppContent.d.ts +2 -0
  6. package/dist/cjs/types/src/components/ActivityLog.d.ts +13 -0
  7. package/dist/cjs/types/src/components/ChangePassword.d.ts +9 -0
  8. package/dist/cjs/types/src/config/axios.d.ts +12 -0
  9. package/dist/cjs/types/src/context/ConfirmDialogProvider.d.ts +4 -0
  10. package/dist/cjs/types/src/context/ErrorBoundary/ErrorBoundary.d.ts +5 -0
  11. package/dist/cjs/types/src/context/ErrorBoundary/Login.d.ts +17 -0
  12. package/dist/cjs/types/src/context/Providers.d.ts +9 -0
  13. package/dist/cjs/types/src/context/SnackbarProvider.d.ts +6 -0
  14. package/dist/cjs/types/src/context/application-store.d.ts +65 -0
  15. package/dist/cjs/types/src/hooks/useConfirm.d.ts +8 -0
  16. package/dist/cjs/types/src/index.d.ts +1 -0
  17. package/dist/cjs/types/src/layout/AppLayout/AppLayout.d.ts +23 -0
  18. package/dist/cjs/types/src/layout/AppLayout/components/HelpDocs.d.ts +11 -0
  19. package/dist/cjs/types/src/reportWebVitals.d.ts +3 -0
  20. package/dist/cjs/types/src/routes/main.d.ts +13 -0
  21. package/dist/cjs/types/src/selectors/BatchSelector.d.ts +2 -0
  22. package/dist/cjs/types/src/selectors/CourseSelector.d.ts +2 -0
  23. package/dist/cjs/types/src/selectors/DepartmentSelector.d.ts +2 -0
  24. package/dist/cjs/types/src/selectors/EmployeesSelector.d.ts +2 -0
  25. package/dist/cjs/types/src/selectors/FeeTypeSelector.d.ts +2 -0
  26. package/dist/cjs/types/src/selectors/HostelFloorSelector.d.ts +2 -0
  27. package/dist/cjs/types/src/selectors/HostelRoomSelector.d.ts +2 -0
  28. package/dist/cjs/types/src/selectors/PrintFormatSelector.d.ts +2 -0
  29. package/dist/cjs/types/src/selectors/ProgramSelector.d.ts +2 -0
  30. package/dist/cjs/types/src/selectors/RegulationSelector.d.ts +2 -0
  31. package/dist/cjs/types/src/selectors/SemesterSelector.d.ts +2 -0
  32. package/dist/cjs/types/src/selectors/YearRangeSelector.d.ts +7 -0
  33. package/dist/cjs/types/src/selectors/utils.d.ts +9 -0
  34. package/dist/cjs/types/src/setupTests.d.ts +1 -0
  35. package/dist/cjs/types/src/utils/constants.d.ts +4 -0
  36. package/dist/esm/index.js +4 -0
  37. package/dist/esm/index.js.map +1 -0
  38. package/dist/esm/types/src/App.d.ts +1 -0
  39. package/dist/esm/types/src/AppContent.d.ts +2 -0
  40. package/dist/esm/types/src/components/ActivityLog.d.ts +13 -0
  41. package/dist/esm/types/src/components/ChangePassword.d.ts +9 -0
  42. package/dist/esm/types/src/config/axios.d.ts +12 -0
  43. package/dist/esm/types/src/context/ConfirmDialogProvider.d.ts +4 -0
  44. package/dist/esm/types/src/context/ErrorBoundary/ErrorBoundary.d.ts +5 -0
  45. package/dist/esm/types/src/context/ErrorBoundary/Login.d.ts +17 -0
  46. package/dist/esm/types/src/context/Providers.d.ts +9 -0
  47. package/dist/esm/types/src/context/SnackbarProvider.d.ts +6 -0
  48. package/dist/esm/types/src/context/application-store.d.ts +65 -0
  49. package/dist/esm/types/src/context/export.d.ts +5 -0
  50. package/dist/esm/types/src/hooks/export.d.ts +1 -0
  51. package/dist/esm/types/src/hooks/useConfirm.d.ts +8 -0
  52. package/dist/esm/types/src/index.d.ts +1 -0
  53. package/dist/esm/types/src/layout/AppLayout/AppLayout.d.ts +23 -0
  54. package/dist/esm/types/src/layout/AppLayout/components/HelpDocs.d.ts +11 -0
  55. package/dist/esm/types/src/reportWebVitals.d.ts +3 -0
  56. package/dist/esm/types/src/routes/main.d.ts +13 -0
  57. package/dist/esm/types/src/selectors/BatchSelector.d.ts +2 -0
  58. package/dist/esm/types/src/selectors/CourseSelector.d.ts +2 -0
  59. package/dist/esm/types/src/selectors/DepartmentSelector.d.ts +2 -0
  60. package/dist/esm/types/src/selectors/EmployeesSelector.d.ts +2 -0
  61. package/dist/esm/types/src/selectors/FeeTypeSelector.d.ts +2 -0
  62. package/dist/esm/types/src/selectors/HostelFloorSelector.d.ts +2 -0
  63. package/dist/esm/types/src/selectors/HostelRoomSelector.d.ts +2 -0
  64. package/dist/esm/types/src/selectors/PrintFormatSelector.d.ts +2 -0
  65. package/dist/esm/types/src/selectors/ProgramSelector.d.ts +2 -0
  66. package/dist/esm/types/src/selectors/RegulationSelector.d.ts +2 -0
  67. package/dist/esm/types/src/selectors/SemesterSelector.d.ts +2 -0
  68. package/dist/esm/types/src/selectors/YearRangeSelector.d.ts +7 -0
  69. package/dist/esm/types/src/selectors/export.d.ts +12 -0
  70. package/dist/esm/types/src/selectors/utils.d.ts +9 -0
  71. package/dist/esm/types/src/setupTests.d.ts +1 -0
  72. package/dist/esm/types/src/utils/constants.d.ts +4 -0
  73. package/dist/index.d.ts +193 -0
  74. package/package.json +50 -17
  75. package/.prettierrc +0 -7
  76. package/craco.config.js +0 -22
  77. package/export.ts +0 -7
  78. package/public/favicon.ico +0 -0
  79. package/public/index.html +0 -43
  80. package/public/logo192.png +0 -0
  81. package/public/logo512.png +0 -0
  82. package/public/manifest.json +0 -25
  83. package/public/robots.txt +0 -3
  84. package/src/App.css +0 -38
  85. package/src/App.tsx +0 -16
  86. package/src/AppContent.tsx +0 -30
  87. package/src/components/ActivityLog.tsx +0 -96
  88. package/src/components/ChangePassword.tsx +0 -169
  89. package/src/config/axios.ts +0 -92
  90. package/src/context/ConfirmDialogProvider.tsx +0 -78
  91. package/src/context/ErrorBoundary/ErrorBoundary.tsx +0 -131
  92. package/src/context/ErrorBoundary/Login.tsx +0 -202
  93. package/src/context/Providers.tsx +0 -64
  94. package/src/context/SnackbarProvider.tsx +0 -42
  95. package/src/context/application-store.ts +0 -87
  96. package/src/hooks/useConfirm.ts +0 -57
  97. package/src/index.css +0 -13
  98. package/src/index.tsx +0 -19
  99. package/src/layout/AppLayout/AppLayout.tsx +0 -151
  100. package/src/layout/AppLayout/components/HelpDocs.tsx +0 -123
  101. package/src/logo.svg +0 -1
  102. package/src/react-app-env.d.ts +0 -1
  103. package/src/reportWebVitals.ts +0 -15
  104. package/src/routes/main.tsx +0 -27
  105. package/src/selectors/BatchSelector.tsx +0 -15
  106. package/src/selectors/CourseSelector.tsx +0 -16
  107. package/src/selectors/DepartmentSelector.tsx +0 -19
  108. package/src/selectors/EmployeesSelector.tsx +0 -20
  109. package/src/selectors/FeeTypeSelector.tsx +0 -15
  110. package/src/selectors/HostelFloorSelector.tsx +0 -19
  111. package/src/selectors/HostelRoomSelector.tsx +0 -20
  112. package/src/selectors/PrintFormatSelector.tsx +0 -17
  113. package/src/selectors/ProgramSelector.tsx +0 -16
  114. package/src/selectors/RegulationSelector.tsx +0 -19
  115. package/src/selectors/SemesterSelector.tsx +0 -16
  116. package/src/selectors/YearRangeSelector.tsx +0 -26
  117. package/src/selectors/utils.tsx +0 -39
  118. package/src/setupTests.ts +0 -5
  119. package/src/utils/constants.ts +0 -18
  120. package/tsconfig.json +0 -22
  121. /package/{src/context/export.ts → dist/cjs/types/src/context/export.d.ts} +0 -0
  122. /package/{src/hooks/export.ts → dist/cjs/types/src/hooks/export.d.ts} +0 -0
  123. /package/{src/selectors/export.ts → dist/cjs/types/src/selectors/export.d.ts} +0 -0
  124. /package/{types → dist/types}/theme.d.ts +0 -0
@@ -1,202 +0,0 @@
1
- import { Button, Icons, TextField } from '@campxdev/react-blueprint';
2
- import { yupResolver } from '@hookform/resolvers/yup';
3
- import { Box, Stack } from '@mui/material';
4
- import DeviceDetector from 'device-detector-js';
5
- import Cookies from 'js-cookie';
6
- import { useEffect, useState } from 'react';
7
- import { Controller, useForm } from 'react-hook-form';
8
- import { useMutation } from 'react-query';
9
-
10
- import * as Yup from 'yup';
11
- import { axios } from '../../config/axios';
12
-
13
- type DeviceInformation = {
14
- deviceType: string;
15
- clientName: string;
16
- os: string;
17
- osVersion: string;
18
- latitude: number | null;
19
- longitude: number | null;
20
- tokenType: string;
21
- };
22
-
23
- export type DeviceState = {
24
- deviceInformation: DeviceInformation;
25
- isLocationAllowed: boolean;
26
- };
27
-
28
- type LoginDetails = {
29
- username: string;
30
- password: string;
31
- };
32
-
33
- const performLogin = async (body: any) => {
34
- if (!body.latitude || !body.longitude) {
35
- const response = await fetch(
36
- 'https://www.googleapis.com/geolocation/v1/geolocate?key=AIzaSyB2YCpo1yi107RYj1LdZu2DCcpcO93reFY',
37
- {
38
- method: 'POST',
39
- headers: {
40
- 'Content-Type': 'application/json',
41
- },
42
- body: JSON.stringify({
43
- considerIp: 'true',
44
- }),
45
- },
46
- );
47
- const data = await response.json();
48
- body.latitude = data.location.lat;
49
- body.longitude = data.location.lng;
50
- }
51
- return axios.post(`/auth-server/auth/login`, body).then((res) => res.data);
52
- };
53
-
54
- const validationSchema = Yup.object().shape({
55
- username: Yup.string().required('Username is required'),
56
- password: Yup.string().required('Password is required'),
57
- });
58
-
59
- export const Login = ({ close }: { close: () => void }) => {
60
- const [deviceState, setDeviceState] = useState<DeviceState>({
61
- deviceInformation: {
62
- deviceType: 'browser',
63
- clientName: 'unknown',
64
- os: 'unknown',
65
- osVersion: 'unknown',
66
- latitude: null,
67
- longitude: null,
68
- tokenType: 'WEB',
69
- },
70
- isLocationAllowed: true,
71
- });
72
-
73
- useEffect(() => {
74
- navigator.geolocation.getCurrentPosition((position) => {
75
- setDeviceState((s) => ({
76
- ...s,
77
- deviceInformation: {
78
- ...s.deviceInformation,
79
- latitude: position.coords.latitude,
80
- longitude: position.coords.longitude,
81
- },
82
- }));
83
- });
84
- navigator.permissions
85
- .query({ name: 'geolocation' })
86
- .then((permissionStatus) => {
87
- if (permissionStatus.state === 'denied') {
88
- setDeviceState((s) => ({
89
- ...s,
90
- isLocationAllowed: false,
91
- }));
92
- }
93
- });
94
-
95
- const detector = new DeviceDetector();
96
- const deviceInfo = detector.parse(navigator.userAgent);
97
- setDeviceState((s) => ({
98
- ...s,
99
- deviceInformation: {
100
- ...s.deviceInformation,
101
- clientName: deviceInfo.client?.name || s.deviceInformation.clientName,
102
- os: deviceInfo.os?.name || s.deviceInformation.os,
103
- osVersion: deviceInfo.os?.version || s.deviceInformation.osVersion,
104
- },
105
- }));
106
- }, []);
107
-
108
- const {
109
- handleSubmit,
110
- control,
111
- formState: { errors },
112
- } = useForm<LoginDetails>({
113
- resolver: yupResolver(validationSchema),
114
- });
115
-
116
- const { mutate, isLoading } = useMutation(performLogin, {
117
- onSuccess(data) {
118
- if (data.loginSuccessful) {
119
- Cookies.remove('campx_session_key');
120
- Cookies.remove('campx_tenant');
121
- Cookies.remove('campx_institution');
122
- Cookies.set('campx_session_key', data?.token);
123
- Cookies.set('campx_tenant', data?.subDomain);
124
- Cookies.set('campx_institution', data?.institutionCode);
125
- close();
126
- window.location.reload();
127
- }
128
- },
129
- });
130
-
131
- const onSubmit = async (body: LoginDetails) => {
132
- mutate({ ...body, ...deviceState.deviceInformation });
133
- };
134
-
135
- return (
136
- <>
137
- <Stack gap="16px" justifyContent="space-between" alignItems="center">
138
- <Box height="36px" width="194.8px">
139
- <Icons.CampxFullLogoIcon />
140
- </Box>
141
- <Stack gap="10px" justifyContent="center" alignItems="center">
142
- <Controller
143
- control={control}
144
- render={({ field }: { field: any }) => {
145
- return (
146
- <TextField
147
- size="medium"
148
- name="username"
149
- sx={{
150
- width: '400px',
151
- }}
152
- placeholder="Enter Username or Email"
153
- containerProps={{ my: '0' }}
154
- onChange={field.onChange}
155
- label="Username or Email"
156
- error={!!errors.username}
157
- required
158
- />
159
- );
160
- }}
161
- name="username"
162
- />
163
- <Controller
164
- control={control}
165
- render={({ field }: { field: any }) => {
166
- return (
167
- <TextField
168
- size="medium"
169
- name="password"
170
- sx={{
171
- width: '400px',
172
- }}
173
- placeholder="Enter password"
174
- onChange={field.onChange}
175
- containerProps={{ my: '0' }}
176
- label="Password"
177
- type="password"
178
- error={!!errors.password}
179
- required
180
- />
181
- );
182
- }}
183
- name="password"
184
- />
185
- <Button
186
- type="submit"
187
- color="primary"
188
- variant="contained"
189
- sx={{
190
- width: '400px',
191
- }}
192
- onClick={handleSubmit(onSubmit)}
193
- disabled={isLoading}
194
- loading={isLoading}
195
- >
196
- Login
197
- </Button>
198
- </Stack>
199
- </Stack>
200
- </>
201
- );
202
- };
@@ -1,64 +0,0 @@
1
- import { lightTheme, MuiThemeProvider } from '@campxdev/react-blueprint';
2
- import { LocalizationProvider } from '@mui/x-date-pickers';
3
- import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFnsV3';
4
- import {
5
- combineReducers,
6
- configureStore,
7
- ReducersMapObject,
8
- } from '@reduxjs/toolkit';
9
- import { ReactNode, useEffect } from 'react';
10
- import { QueryClient, QueryClientProvider } from 'react-query';
11
- import { Provider } from 'react-redux';
12
- import { BrowserRouter } from 'react-router-dom';
13
- import { institutionCode, tenantCode } from '../utils/constants';
14
- import { ConfirmDialogProvider } from './ConfirmDialogProvider';
15
- import { SnackbarProvider } from './SnackbarProvider';
16
-
17
- export const Providers = ({
18
- children,
19
- basename,
20
- theme = lightTheme,
21
- reducers = {},
22
- }: {
23
- children: ReactNode;
24
- basename?: string;
25
- theme?: any;
26
- reducers?: ReducersMapObject;
27
- }) => {
28
- const queryClient = new QueryClient({
29
- defaultOptions: {
30
- queries: {
31
- refetchOnWindowFocus: false,
32
- retry: false,
33
- useErrorBoundary: true,
34
- },
35
- },
36
- });
37
-
38
- var baseName = tenantCode && institutionCode ? `/${institutionCode}` : '/';
39
- useEffect(() => {
40
- if (window.location.pathname === '/' && institutionCode && tenantCode) {
41
- window.location.replace(window.location.origin + `/${institutionCode}`);
42
- }
43
- }, [institutionCode, tenantCode]);
44
-
45
- const store = configureStore({
46
- reducer: combineReducers(reducers),
47
- });
48
-
49
- return (
50
- <Provider store={store}>
51
- <BrowserRouter basename={basename ?? baseName}>
52
- <QueryClientProvider client={queryClient}>
53
- <MuiThemeProvider theme={theme}>
54
- <SnackbarProvider>
55
- <LocalizationProvider dateAdapter={AdapterDateFns}>
56
- <ConfirmDialogProvider>{children}</ConfirmDialogProvider>
57
- </LocalizationProvider>
58
- </SnackbarProvider>
59
- </MuiThemeProvider>
60
- </QueryClientProvider>
61
- </BrowserRouter>
62
- </Provider>
63
- );
64
- };
@@ -1,42 +0,0 @@
1
- import { Severity, Snackbar } from '@campxdev/react-blueprint';
2
- import { createContext, ReactNode } from 'react';
3
- import { ApplicationStore } from './application-store';
4
-
5
- interface SnackbarContextProps {
6
- showSnackbar: (message: string, severity?: Severity) => void;
7
- }
8
-
9
- const SnackbarContext = createContext<SnackbarContextProps | undefined>(
10
- undefined,
11
- );
12
-
13
- interface SnackbarProviderProps {
14
- children: ReactNode;
15
- }
16
-
17
- export const SnackbarProvider = ({ children }: SnackbarProviderProps) => {
18
- const snackbar = ApplicationStore.useState((s) => s.snackbar);
19
- const showSnackbar = (message: string, severity: Severity = 'info') => {
20
- ApplicationStore.update((s) => {
21
- s.snackbar.open = true;
22
- s.snackbar.message = message;
23
- s.snackbar.severity = severity;
24
- });
25
- };
26
- return (
27
- <SnackbarContext.Provider value={{ showSnackbar }}>
28
- {children}
29
- <Snackbar
30
- open={snackbar.open}
31
- message={snackbar.message}
32
- severity={snackbar.severity}
33
- autoHideDuration={1500}
34
- onClose={() => {
35
- ApplicationStore.update((s) => {
36
- s.snackbar.open = false;
37
- });
38
- }}
39
- />
40
- </SnackbarContext.Provider>
41
- );
42
- };
@@ -1,87 +0,0 @@
1
- import { ConfirmDialogType, Severity } from '@campxdev/react-blueprint';
2
- import { Store } from 'pullstate';
3
-
4
- type Classroom = {
5
- id: number;
6
- batchName?: string;
7
- branchCode?: string;
8
- courseId: number;
9
- currentSemester: number;
10
- name: string;
11
- programId: number;
12
- regulationId?: number;
13
- section?: string;
14
- timetableSlotTemplateId?: number;
15
- };
16
-
17
- export type ApplicationStoreType = {
18
- isLoginDialogOpen: boolean;
19
- snackbar: {
20
- open: boolean;
21
- message: string;
22
- severity: Severity;
23
- };
24
- confirmDialog: {
25
- isOpen: boolean;
26
- title: string;
27
- message: string;
28
- onConfirm: () => void;
29
- onCancel: () => void;
30
- type: ConfirmDialogType;
31
- confirmButtonText?: string;
32
- cancelButtonText?: string;
33
- };
34
- user?: {
35
- id: number;
36
- fullName: string;
37
- semNo?: number;
38
- rollNo?: string;
39
- courseId?: number;
40
- branchCode?: string;
41
- classroom?: Classroom;
42
- email?: string;
43
- employeeId?: string;
44
- departmentIds?: string[];
45
- designationId?: string;
46
- institutionIds: number[];
47
- isAdminUser?: boolean;
48
- isSuperUser?: boolean;
49
- studentId?: number;
50
- admissionId?: string;
51
- mStudentId?: string;
52
- };
53
- institution?: {
54
- institutions: [];
55
- loading: false;
56
- error: null;
57
- current: null;
58
- };
59
- asset?: {
60
- favIcon: null;
61
- institutionLogo: null;
62
- institutionName: null;
63
- };
64
- };
65
-
66
- export const initialApplicationState: ApplicationStoreType = {
67
- isLoginDialogOpen: false,
68
- snackbar: {
69
- open: false,
70
- message: '',
71
- severity: 'success',
72
- },
73
- confirmDialog: {
74
- isOpen: false,
75
- title: '',
76
- message: '',
77
- onConfirm: () => {},
78
- onCancel: () => {},
79
- type: 'confirm',
80
- },
81
- user: undefined,
82
- institution: undefined,
83
- asset: undefined,
84
- };
85
- export const ApplicationStore = new Store<ApplicationStoreType>(
86
- initialApplicationState,
87
- );
@@ -1,57 +0,0 @@
1
- import { ConfirmDialogType } from '@campxdev/react-blueprint';
2
- import { ApplicationStore } from '../context/application-store';
3
-
4
- const defaultConfirmDialogState = {
5
- isOpen: false,
6
- title: '',
7
- message: '',
8
- confirmButtonText: '',
9
- cancelButtonText: '',
10
- type: 'confirm' as ConfirmDialogType,
11
- onConfirm: () => {},
12
- onCancel: () => {},
13
- };
14
-
15
- export const useConfirm = () => {
16
- const isConfirmed = ({
17
- title,
18
- message,
19
- confirmButtonText,
20
- cancelButtonText,
21
- type = 'confirm',
22
- }: {
23
- title: string;
24
- message: string;
25
- confirmButtonText?: string;
26
- cancelButtonText?: string;
27
- type?: ConfirmDialogType;
28
- }): Promise<boolean> =>
29
- new Promise((resolve) => {
30
- ApplicationStore.update((s) => {
31
- s.confirmDialog = {
32
- isOpen: true,
33
- title,
34
- message,
35
- confirmButtonText,
36
- cancelButtonText,
37
- type,
38
- onConfirm: () => {
39
- resolve(true);
40
- resetDialog();
41
- },
42
- onCancel: () => {
43
- resolve(false);
44
- resetDialog();
45
- },
46
- };
47
- });
48
- });
49
-
50
- const resetDialog = () => {
51
- ApplicationStore.update((s) => {
52
- s.confirmDialog = defaultConfirmDialogState;
53
- });
54
- };
55
-
56
- return isConfirmed;
57
- };
package/src/index.css DELETED
@@ -1,13 +0,0 @@
1
- body {
2
- margin: 0;
3
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4
- 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5
- sans-serif;
6
- -webkit-font-smoothing: antialiased;
7
- -moz-osx-font-smoothing: grayscale;
8
- }
9
-
10
- code {
11
- font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12
- monospace;
13
- }
package/src/index.tsx DELETED
@@ -1,19 +0,0 @@
1
- import React from 'react';
2
- import ReactDOM from 'react-dom/client';
3
- import App from './App';
4
- import './index.css';
5
- import reportWebVitals from './reportWebVitals';
6
-
7
- const root = ReactDOM.createRoot(
8
- document.getElementById('root') as HTMLElement,
9
- );
10
- root.render(
11
- <React.StrictMode>
12
- <App />
13
- </React.StrictMode>,
14
- );
15
-
16
- // If you want to start measuring performance in your app, pass a function
17
- // to log results (for example: reportWebVitals(console.log))
18
- // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
19
- reportWebVitals();
@@ -1,151 +0,0 @@
1
- import { AppHeader, Sidebar, Spinner } from '@campxdev/react-blueprint';
2
- import { SideMenuItemProps } from '@campxdev/react-blueprint/src/components/Navigation/Sidebar/Sidebar';
3
- import { Box, Stack, styled, useMediaQuery, useTheme } from '@mui/material';
4
- import { motion } from 'framer-motion';
5
- import Cookies from 'js-cookie';
6
- import { ReactNode, Suspense, useState } from 'react';
7
- import { ChangePasswordDialog } from '../../components/ChangePassword';
8
- import { axios } from '../../config/axios';
9
- import { ErrorBoundary } from '../../context/export';
10
- import HelpDocs from './components/HelpDocs';
11
-
12
- type Props = {
13
- actions?: ReactNode[];
14
- profileActions?: ReactNode[];
15
- children?: ReactNode;
16
- menu: SideMenuItemProps[];
17
- mainContainerSx?: any;
18
- handleLogout?: any;
19
- userName?: string;
20
- designation?: string;
21
- clientName?: string;
22
- institutionData?: any[];
23
- defaultCollapsed?: boolean;
24
- helpDocsConfig?: Record<
25
- string,
26
- { actions: { name: string; onClick: () => void }[] }
27
- >;
28
- };
29
-
30
- export const AppLayout: React.FC<Props> = ({
31
- actions = [],
32
- profileActions = [],
33
- children,
34
- institutionData = [],
35
- menu,
36
- mainContainerSx,
37
- handleLogout,
38
- userName = '',
39
- designation = '',
40
- clientName = '',
41
- defaultCollapsed = true,
42
- helpDocsConfig,
43
- }) => {
44
- const [collapsed, setCollapsed] = useState(defaultCollapsed);
45
- const theme = useTheme();
46
- const isSmallScreen = useMediaQuery(theme.breakpoints.down('md'));
47
-
48
- function logout() {
49
- axios
50
- .post('/auth-server/auth/logout')
51
- .then((res) => {
52
- Cookies.remove('campx_tenant');
53
- Cookies.remove('campx_session_key');
54
- Cookies.remove('campx_institution');
55
- window.location.href = '/';
56
- })
57
- .catch((err) => {
58
- // toast("Unable To Logout.");
59
- });
60
- }
61
-
62
- const fullPath = window.location.pathname;
63
- const pathSegments = fullPath.split('/').filter(Boolean);
64
- const actualPath = pathSegments.slice(1).join('/');
65
- const normalizedPath = actualPath.replace(/\/\d+/g, '/:id');
66
- const helpDocsActions = helpDocsConfig?.[`/${normalizedPath}`]?.actions || [];
67
-
68
- return (
69
- <AppLayoutContainer>
70
- <Sidebar menu={menu} collapsed={collapsed} setCollapsed={setCollapsed} />
71
- <motion.div
72
- animate={{
73
- width: collapsed ? 'calc(100% - 84px)' : 'calc(100% - 278px)',
74
- }}
75
- transition={{ duration: 0.3, ease: 'circOut' }}
76
- style={{
77
- margin: '12px 12px 12px 0px',
78
- width: isSmallScreen ? '100%' : 'calc(100% - 84px)',
79
- display: isSmallScreen ? 'contents' : 'block',
80
- }}
81
- >
82
- <AppHeader
83
- clientName={clientName}
84
- userFullName={userName}
85
- designation={designation}
86
- actions={actions}
87
- profileActions={[<ChangePasswordDialog />, ...profileActions]}
88
- collapsed={collapsed}
89
- showActiveDevices={false}
90
- onLogoutClick={handleLogout ?? logout}
91
- institutionsData={institutionData}
92
- {...(isSmallScreen && {
93
- profileSx: { width: 32, height: 32, fontSize: '12px' },
94
- })}
95
- />
96
- {helpDocsConfig && helpDocsActions.length > 0 && (
97
- <HelpDocs actions={helpDocsActions} />
98
- )}
99
-
100
- <OutletContainer
101
- sx={{
102
- margin: '12px 0px 0px 0px',
103
- backgroundColor: theme.palette.surface.paperBackground,
104
- ...mainContainerSx,
105
- }}
106
- onClick={() => {
107
- setCollapsed(true);
108
- }}
109
- >
110
- <Suspense fallback={<Spinner />}>
111
- <ErrorBoundary>{children}</ErrorBoundary>
112
- </Suspense>
113
- </OutletContainer>
114
- </motion.div>
115
- </AppLayoutContainer>
116
- );
117
- };
118
-
119
- const AppLayoutContainer = styled(Stack)(({ theme }: { theme?: any }) => ({
120
- flexDirection: 'row',
121
- backgroundColor: theme.palette.surface.defaultBackground,
122
-
123
- [theme.breakpoints.down('md')]: { flexWrap: 'wrap' },
124
- }));
125
-
126
- const OutletContainer = styled(Box)(({ theme }: { theme?: any }) => ({
127
- borderRadius: '8px',
128
- height: 'calc(100vh - 96px)',
129
- overflowY: 'scroll',
130
- width: '100%',
131
-
132
- '&::-webkit-scrollbar': {
133
- width: '0.5em',
134
- height: '0.2em',
135
- backgroundColor: theme.palette.surface.defaultBackground,
136
- },
137
-
138
- '&::-webkit-scrollbar-thumb': {
139
- backgroundColor: theme.palette.primary.light,
140
- borderRadius: '3px',
141
-
142
- '&:hover': { backgroundColor: theme.palette.primary.main },
143
- },
144
-
145
- [theme.breakpoints.down('md')]: {
146
- margin: '0px 12px 12px 12px',
147
- height: 'calc(100vh - 118px)',
148
-
149
- '&::-webkit-scrollbar': { display: 'none' },
150
- },
151
- }));