@campxdev/shared 0.5.10 → 0.5.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@campxdev/shared",
3
- "version": "0.5.10",
3
+ "version": "0.5.12",
4
4
  "main": "./exports.ts",
5
5
  "scripts": {
6
6
  "start": "react-scripts start",
@@ -1,229 +1,236 @@
1
- import { Alert, Box, Button, styled, Typography } from "@mui/material";
2
- import { useEffect, useState } from "react";
1
+ import {Alert, Box, Button, Divider, styled, Typography} from '@mui/material'
2
+ import {useEffect, useState} from 'react'
3
3
  import {
4
- nointernet,
5
- pagenotfound,
6
- permissiondenied,
7
- unauth,
8
- internalserver,
9
- } from "../../assets/images";
10
- import Cookies from "js-cookie";
11
- import LoginForm from "../LoginForm";
12
- import { useModal } from "../DrawerWrapper/DrawerWrapper";
13
- import { PermissionsStore } from "../../permissions";
14
- import axios from "../../config/axios";
15
-
16
- const StyledAlert = styled(Alert)(({ theme }) => ({
17
- border: `1px solid ${theme.palette.error.main}`,
18
- display: "flex",
19
- alignItems: "center",
20
- "& .MuiAlert-message": {
21
- padding: 0,
22
- },
23
- "& .MuiTypography-root": {
24
- margin: 0,
25
- },
26
- position: "relative",
27
- "& .retryBtn": {
28
- color: "#661b2a",
29
- position: "absolute",
30
- right: 8,
31
- top: 8,
32
- },
33
- }));
34
-
35
- const StyledBox = styled(Box)(({ theme }) => ({
36
- width: "100%",
37
- display: "flex",
38
- flexDirection: "column",
39
- alignItems: "center",
40
- justifyContent: "center",
41
- }));
42
-
43
- export default function ErrorFallback({ error, resetErrorBoundary }) {
44
- if (error?.response?.status) {
45
- switch (error?.response?.status) {
46
- case 401:
47
- return <UnAuth resetBoundary={resetErrorBoundary} />;
48
-
49
- case 500:
50
- return <InternalServer resetBoundary={resetErrorBoundary} />;
51
-
52
- case 403:
53
- return <PemissionDenied resetBoundary={resetErrorBoundary} />;
54
-
55
- default:
56
- return <InternalServer resetBoundary={resetErrorBoundary} />;
57
- }
58
- }
59
-
60
- if (error?.message === "Network Error") {
61
- return <NoInternet resetBoundary={resetErrorBoundary} />;
62
- }
63
-
64
- return (
65
- <Box sx={{ marginTop: "16px", padding: "16px" }}>
66
- <StyledAlert severity="error">
67
- {error?.response?.data?.message ?? error?.message}
68
- <Button
69
- className="retryBtn"
70
- onClick={() => resetErrorBoundary()}
71
- size="small"
72
- color="error"
73
- variant="outlined"
74
- >
75
- Try Again
76
- </Button>
77
- </StyledAlert>
78
- </Box>
79
- );
4
+ nointernet,
5
+ pagenotfound,
6
+ permissiondenied,
7
+ unauth,
8
+ internalserver,
9
+ } from '../../assets/images'
10
+ import Cookies from 'js-cookie'
11
+ import LoginForm from '../LoginForm'
12
+ import {useModal} from '../DrawerWrapper/DrawerWrapper'
13
+ import {PermissionsStore} from '../../permissions'
14
+ import axios from '../../config/axios'
15
+
16
+ const StyledAlert = styled(Alert)(({theme}) => ({
17
+ border: `1px solid ${theme.palette.error.main}`,
18
+ display: 'flex',
19
+ alignItems: 'center',
20
+ '& .MuiAlert-message': {
21
+ padding: 0,
22
+ },
23
+ '& .MuiTypography-root': {
24
+ margin: 0,
25
+ },
26
+ position: 'relative',
27
+ '& .retryBtn': {
28
+ color: '#661b2a',
29
+ position: 'absolute',
30
+ right: 8,
31
+ top: 8,
32
+ },
33
+ }))
34
+
35
+ const StyledBox = styled(Box)(({theme}) => ({
36
+ width: '100%',
37
+ display: 'flex',
38
+ flexDirection: 'column',
39
+ alignItems: 'center',
40
+ justifyContent: 'center',
41
+ }))
42
+
43
+ export default function ErrorFallback({error, resetErrorBoundary}) {
44
+ if (error?.response?.status) {
45
+ switch (error?.response?.status) {
46
+ case 401:
47
+ return <UnAuth resetBoundary={resetErrorBoundary} />
48
+
49
+ case 500:
50
+ return (
51
+ <InternalServer resetBoundary={resetErrorBoundary} error={error} />
52
+ )
53
+
54
+ case 403:
55
+ return <PemissionDenied resetBoundary={resetErrorBoundary} />
56
+
57
+ default:
58
+ return (
59
+ <InternalServer resetBoundary={resetErrorBoundary} error={error} />
60
+ )
61
+ }
62
+ }
63
+
64
+ if (error?.message === 'Network Error') {
65
+ return <NoInternet resetBoundary={resetErrorBoundary} />
66
+ }
67
+
68
+ return (
69
+ <Box sx={{marginTop: '16px', padding: '16px'}}>
70
+ <StyledAlert severity='error'>
71
+ {error?.response?.data?.message ?? error?.message}
72
+ <Button
73
+ className='retryBtn'
74
+ onClick={() => resetErrorBoundary()}
75
+ size='small'
76
+ color='error'
77
+ variant='outlined'
78
+ >
79
+ Try Again
80
+ </Button>
81
+ </StyledAlert>
82
+ </Box>
83
+ )
80
84
  }
81
85
 
82
- export function PageNotFound({ resetBoundary }) {
83
- return (
84
- <>
85
- <StyledBox>
86
- <img
87
- src={pagenotfound}
88
- alt="page not found"
89
- width={470}
90
- style={{ marginTop: "20px" }}
91
- />
92
- <Typography variant="h1">Page Not Found.</Typography>
93
- <Button sx={{ marginTop: "20px" }} onClick={() => resetBoundary()}>
94
- Try Again
95
- </Button>
96
- </StyledBox>
97
- </>
98
- );
86
+ export function PageNotFound({resetBoundary}) {
87
+ return (
88
+ <>
89
+ <StyledBox>
90
+ <img
91
+ src={pagenotfound}
92
+ alt='page not found'
93
+ width={470}
94
+ style={{marginTop: '20px'}}
95
+ />
96
+ <Typography variant='h1'>Page Not Found.</Typography>
97
+ <Button sx={{marginTop: '20px'}} onClick={() => resetBoundary()}>
98
+ Try Again
99
+ </Button>
100
+ </StyledBox>
101
+ </>
102
+ )
99
103
  }
100
104
 
101
- export function NoInternet({ resetBoundary }) {
102
- return (
103
- <>
104
- <StyledBox>
105
- <img src={nointernet} alt="No Internet Found" width={470} />
106
- <Typography variant="h1">No Internet Found.</Typography>
107
- <Button sx={{ marginTop: "20px" }} onClick={() => resetBoundary()}>
108
- Try Again
109
- </Button>
110
- </StyledBox>
111
- </>
112
- );
105
+ export function NoInternet({resetBoundary}) {
106
+ return (
107
+ <>
108
+ <StyledBox>
109
+ <img src={nointernet} alt='No Internet Found' width={470} />
110
+ <Typography variant='h1'>No Internet Found.</Typography>
111
+ <Button sx={{marginTop: '20px'}} onClick={() => resetBoundary()}>
112
+ Try Again
113
+ </Button>
114
+ </StyledBox>
115
+ </>
116
+ )
113
117
  }
114
118
 
115
- export function PemissionDenied({ resetBoundary }) {
116
- return (
117
- <>
118
- <StyledBox>
119
- <img src={permissiondenied} alt="permission denied" width={470} />
120
- <Typography variant="h1">Permission Denied.</Typography>
121
- <Button sx={{ marginTop: "20px" }} onClick={() => resetBoundary()}>
122
- Try Again
123
- </Button>
124
- </StyledBox>
125
- </>
126
- );
119
+ export function PemissionDenied({resetBoundary}) {
120
+ return (
121
+ <>
122
+ <StyledBox>
123
+ <img src={permissiondenied} alt='permission denied' width={470} />
124
+ <Typography variant='h1'>Permission Denied.</Typography>
125
+ <Button sx={{marginTop: '20px'}} onClick={() => resetBoundary()}>
126
+ Try Again
127
+ </Button>
128
+ </StyledBox>
129
+ </>
130
+ )
127
131
  }
128
132
 
129
- export function InternalServer({ resetBoundary }) {
130
- return (
131
- <>
132
- <StyledBox>
133
- <img src={internalserver} alt="internal server error" width={470} />
134
- <Typography variant="h1" marginTop={"20px"}>
135
- Internal Server Error.
136
- </Typography>
137
- <Button
138
- size="small"
139
- variant="outlined"
140
- sx={{ marginTop: "20px" }}
141
- onClick={() => resetBoundary()}
142
- >
143
- Try Again
144
- </Button>
145
- </StyledBox>
146
- </>
147
- );
133
+ export function InternalServer({resetBoundary, error}) {
134
+ return (
135
+ <>
136
+ <StyledBox>
137
+ <img src={internalserver} alt='internal server error' width={470} />
138
+ <Typography variant='h1' marginTop={'20px'}>
139
+ Internal Server Error.
140
+ </Typography>
141
+ <Typography variant='body1'>
142
+ {error?.response?.data?.message}
143
+ </Typography>
144
+ <Button
145
+ size='small'
146
+ variant='outlined'
147
+ sx={{marginTop: '20px'}}
148
+ onClick={() => resetBoundary()}
149
+ >
150
+ Try Again
151
+ </Button>
152
+ </StyledBox>
153
+ </>
154
+ )
148
155
  }
149
156
 
150
- export function UnAuth({ resetBoundary }) {
151
- const modal = useModal();
152
- const [username, setUsername] = useState("");
153
- const [loading, setLoading] = useState(false);
154
-
155
- const url = window.location.origin;
156
- const origin = window?.location?.origin?.split(".");
157
- const isLocalHost =
158
- process.env.NODE_ENV === "development" ||
159
- origin?.slice(-2).join(".") === "campx.dev";
160
- const sessionCookie = Cookies.get("campx_session_key");
161
- const appinit = async () => {
162
- setLoading(true);
163
- await axios
164
- .get("/auth/my-permissions")
165
- .then((res) => {
166
- setUsername(res.data.user.fullName);
167
- PermissionsStore.update((s) => {
168
- s.permissions = {
169
- ...res.data?.permissions,
170
- can_settings_view: 1,
171
- can_dashboard_view: 1,
172
- can_individual_pages_view: 1,
173
- } as any;
174
- });
175
- setLoading(false);
176
- })
177
- .catch((e) => {
178
- modal({
179
- title: "Login",
180
- content: () => <LoginForm />,
181
- });
182
- });
183
- };
184
- function LoginPage() {
185
- if (isLocalHost) {
186
- if (!sessionCookie) {
187
- modal({
188
- title: "Login",
189
- content: () => <LoginForm />,
190
- });
191
- } else {
192
- appinit();
193
- }
194
- } else {
195
- if (!sessionCookie) {
196
- window.location.replace(`https://www.id.campx.in/?redirect_to=${url}`);
197
- } else {
198
- appinit();
199
- }
200
- }
201
- }
202
-
203
- return (
204
- <>
205
- <StyledBox>
206
- <img src={unauth} alt="unauthorized" width={470} />
207
- <Typography variant="h1" marginTop={"20px"}>
208
- UnAuthorized.
209
- </Typography>
210
- <Box
211
- sx={{
212
- display: "flex",
213
- marginTop: "20px",
214
- }}
215
- >
216
- <Button
217
- variant="outlined"
218
- sx={{ marginRight: "10px" }}
219
- onClick={() => resetBoundary()}
220
- >
221
- Try Again
222
- </Button>
223
-
224
- <Button onClick={() => LoginPage()}>Click here to Login</Button>
225
- </Box>
226
- </StyledBox>
227
- </>
228
- );
157
+ export function UnAuth({resetBoundary}) {
158
+ const modal = useModal()
159
+ const [username, setUsername] = useState('')
160
+ const [loading, setLoading] = useState(false)
161
+
162
+ const url = window.location.origin
163
+ const origin = window?.location?.origin?.split('.')
164
+ const isLocalHost =
165
+ process.env.NODE_ENV === 'development' ||
166
+ origin?.slice(-2).join('.') === 'campx.dev'
167
+ const sessionCookie = Cookies.get('campx_session_key')
168
+ const appinit = async () => {
169
+ setLoading(true)
170
+ await axios
171
+ .get('/auth/my-permissions')
172
+ .then((res) => {
173
+ setUsername(res.data.user.fullName)
174
+ PermissionsStore.update((s) => {
175
+ s.permissions = {
176
+ ...res.data?.permissions,
177
+ can_settings_view: 1,
178
+ can_dashboard_view: 1,
179
+ can_individual_pages_view: 1,
180
+ } as any
181
+ })
182
+ setLoading(false)
183
+ })
184
+ .catch((e) => {
185
+ modal({
186
+ title: 'Login',
187
+ content: () => <LoginForm />,
188
+ })
189
+ })
190
+ }
191
+ function LoginPage() {
192
+ if (isLocalHost) {
193
+ if (!sessionCookie) {
194
+ modal({
195
+ title: 'Login',
196
+ content: () => <LoginForm />,
197
+ })
198
+ } else {
199
+ appinit()
200
+ }
201
+ } else {
202
+ if (!sessionCookie) {
203
+ window.location.replace(`https://www.id.campx.in/?redirect_to=${url}`)
204
+ } else {
205
+ appinit()
206
+ }
207
+ }
208
+ }
209
+
210
+ return (
211
+ <>
212
+ <StyledBox>
213
+ <img src={unauth} alt='unauthorized' width={470} />
214
+ <Typography variant='h1' marginTop={'20px'}>
215
+ UnAuthorized.
216
+ </Typography>
217
+ <Box
218
+ sx={{
219
+ display: 'flex',
220
+ marginTop: '20px',
221
+ }}
222
+ >
223
+ <Button
224
+ variant='outlined'
225
+ sx={{marginRight: '10px'}}
226
+ onClick={() => resetBoundary()}
227
+ >
228
+ Try Again
229
+ </Button>
230
+
231
+ <Button onClick={() => LoginPage()}>Click here to Login</Button>
232
+ </Box>
233
+ </StyledBox>
234
+ </>
235
+ )
229
236
  }
@@ -7,8 +7,8 @@ import {
7
7
  ListItemText,
8
8
  styled,
9
9
  } from '@mui/material'
10
- import {ReactNode, useState} from 'react'
11
- import {Link, useMatch, useResolvedPath} from 'react-router-dom'
10
+ import {ReactNode, useEffect, useState} from 'react'
11
+ import {Link, useLocation, useMatch, useResolvedPath} from 'react-router-dom'
12
12
  import {PermissionsStore} from '../permissions'
13
13
  import {
14
14
  ListItemButton,
@@ -52,7 +52,6 @@ const RenderMenuItem = ({menuItem}) => {
52
52
  const permissions = PermissionsStore.useState((s) => s).permissions
53
53
  const hasAccess = permissionKey ? permissions[permissionKey] : accessIfNoKey
54
54
 
55
- if (!hasAccess && !children?.length) return null
56
55
  if (children?.length)
57
56
  return (
58
57
  <Box
@@ -71,36 +70,40 @@ const RenderMenuItem = ({menuItem}) => {
71
70
  )
72
71
 
73
72
  return (
74
- <StyledLink to={path}>
75
- <ListItemButton
76
- hasChildren={false}
77
- label={title}
78
- isActive={!!match}
79
- icon={icon}
80
- />
81
- </StyledLink>
73
+ <>
74
+ {hasAccess ? (
75
+ <StyledLink to={path}>
76
+ <ListItemButton
77
+ hasChildren={false}
78
+ label={title}
79
+ isActive={!!match}
80
+ icon={icon}
81
+ />
82
+ </StyledLink>
83
+ ) : null}
84
+ </>
82
85
  )
83
86
  }
84
87
 
85
88
  const DropDownMenu = ({path, title, icon, menuItems, permissionKey}) => {
89
+ let resolved = useResolvedPath(path)
90
+ let match = useMatch({path: resolved.pathname, end: false})
91
+
86
92
  const [open, setOpen] = useState(false)
87
93
  const permissions = PermissionsStore.useState((s) => s).permissions
88
94
 
89
95
  const validateDropdownAccess = () => {
90
- if (accessIfNoKey && !permissions) return true
91
- let arr = []
92
-
93
- for (let i = 0; i < menuItems.length; i++) {
94
- if (permissions[menuItems[i].permissionKey]) {
95
- arr.push(true)
96
- } else {
97
- arr.push(accessIfNoKey)
98
- }
99
- }
96
+ if (process.env.NODE_ENV === 'development' && !permissions) return true
100
97
 
101
- return arr.includes(true)
98
+ return menuItems?.every((item) =>
99
+ item?.permissionKey ? permissions[item.permissionKey] : accessIfNoKey
100
+ )
102
101
  }
103
102
 
103
+ useEffect(() => {
104
+ setOpen(!!match)
105
+ }, [resolved])
106
+
104
107
  if (!validateDropdownAccess()) return null
105
108
  return (
106
109
  <>