@campxdev/shared 1.8.50 → 1.9.1
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 +1 -1
- package/src/components/ApplicationProfile/ApplicationProfile.tsx +29 -27
- package/src/components/ApplicationProfile/UserProfileRelation.tsx +9 -53
- package/src/components/ErrorBoundary/ErrorFallback.tsx +5 -6
- package/src/components/Institutions/InsititutionsDialog.tsx +86 -0
- package/src/components/Institutions/InsititutionsNotAssignedDialog .tsx +12 -0
- package/src/components/Institutions/InstitutionsDropdown.tsx +33 -0
- package/src/components/Institutions/index.tsx +1 -0
- package/src/components/Institutions/services.ts +12 -0
- package/src/components/Layout/Header/AppHeader.tsx +3 -7
- package/src/components/Layout/Header/AppsMenu.tsx +6 -7
- package/src/components/Layout/Header/HeaderActions/HeaderActions.tsx +2 -2
- package/src/components/Layout/Header/applications.ts +7 -7
- package/src/components/LoginForm.tsx +21 -26
- package/src/components/ModalButtons/DialogButton.tsx +28 -24
- package/src/components/NoDataIllustration.tsx +8 -5
- package/src/components/Tables/common/NoRecordsFound.tsx +5 -1
- package/src/components/Tables/common/no-data-illu.svg +24 -1
- package/src/components/UploadButton/UploadButton.tsx +3 -3
- package/src/config/axios.ts +4 -3
- package/src/constants/UIConstants.ts +1 -1
- package/src/contexts/LoginFormProvider.tsx +3 -5
- package/src/contexts/Providers.tsx +40 -18
- package/src/contexts/RootModal.tsx +76 -0
- package/src/hooks/useAuth.ts +122 -27
- package/src/shared-state/InstitutionsStore.ts +8 -0
- package/src/shared-state/PermissionsStore.ts +5 -1
- package/src/components/Layout/Header/SchoolSwitch/SchoolSwitch.tsx +0 -33
- /package/src/components/ApplicationProfile/{Service.ts → services.ts} +0 -0
package/package.json
CHANGED
|
@@ -11,6 +11,10 @@ import { useEffect, useState } from 'react'
|
|
|
11
11
|
import { useMutation, useQuery } from 'react-query'
|
|
12
12
|
import { toast } from 'react-toastify'
|
|
13
13
|
import { useImmer } from 'use-immer'
|
|
14
|
+
import { PageContent } from '../PageContent'
|
|
15
|
+
import PageHeader from '../PageHeader'
|
|
16
|
+
import useConfirm from '../PopupConfirm/useConfirm'
|
|
17
|
+
import Spinner from '../Spinner'
|
|
14
18
|
import UserProfileRelation from './UserProfileRelation'
|
|
15
19
|
import {
|
|
16
20
|
defaultFilterObj,
|
|
@@ -18,20 +22,16 @@ import {
|
|
|
18
22
|
fetchProfiles,
|
|
19
23
|
removeUserApplicationProfile,
|
|
20
24
|
updateUserApplicationProfile,
|
|
21
|
-
} from './
|
|
22
|
-
import useConfirm from '../PopupConfirm/useConfirm'
|
|
23
|
-
import Spinner from '../Spinner'
|
|
24
|
-
import PageHeader from '../PageHeader'
|
|
25
|
-
import { PageContent } from '../PageContent'
|
|
25
|
+
} from './services'
|
|
26
26
|
|
|
27
|
-
import { SingleSelect } from '../Input'
|
|
28
|
-
import ActionButton from '../ActionButton'
|
|
29
27
|
import { axiosErrorToast } from '../../config/axios'
|
|
30
|
-
import { DialogButton } from '../ModalButtons'
|
|
31
|
-
import SearchBar from '../FilterComponents/SearchBar'
|
|
32
|
-
import Table from '../Tables/BasicTable/Table'
|
|
33
28
|
import { ValidateAccess } from '../../permissions'
|
|
34
29
|
import { Permission, PermissionsStore } from '../../shared-state'
|
|
30
|
+
import ActionButton from '../ActionButton'
|
|
31
|
+
import SearchBar from '../FilterComponents/SearchBar'
|
|
32
|
+
import { SingleSelect } from '../Input'
|
|
33
|
+
import { DialogButton } from '../ModalButtons'
|
|
34
|
+
import Table from '../Tables/BasicTable/Table'
|
|
35
35
|
|
|
36
36
|
interface ApplicationProfileProps {
|
|
37
37
|
application: 'exams' | 'square' | 'payments' | 'enroll_x' | 'hostels'
|
|
@@ -44,14 +44,14 @@ interface ApplicationProfileProps {
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
function ApplicationProfile({
|
|
47
|
-
application
|
|
47
|
+
application,
|
|
48
48
|
title,
|
|
49
49
|
permissions,
|
|
50
50
|
}: ApplicationProfileProps) {
|
|
51
51
|
const { isConfirmed } = useConfirm()
|
|
52
52
|
const [filters, setFilters] = useImmer(defaultFilterObj)
|
|
53
53
|
const { data, isLoading, refetch } = useQuery(
|
|
54
|
-
['application-users',
|
|
54
|
+
['application-users', filters],
|
|
55
55
|
() => fetchApplicationUsers({ application, ...filters }),
|
|
56
56
|
)
|
|
57
57
|
|
|
@@ -80,14 +80,14 @@ function ApplicationProfile({
|
|
|
80
80
|
const columns = [
|
|
81
81
|
{
|
|
82
82
|
title: 'User',
|
|
83
|
-
key: '',
|
|
84
|
-
dataIndex: '',
|
|
83
|
+
key: 'user',
|
|
84
|
+
dataIndex: 'user',
|
|
85
85
|
render: (_, row) => <UserComponent userData={row} />,
|
|
86
86
|
},
|
|
87
87
|
{
|
|
88
88
|
title: 'Profile',
|
|
89
|
-
key: '',
|
|
90
|
-
dataIndex: '',
|
|
89
|
+
key: 'profile',
|
|
90
|
+
dataIndex: 'profile',
|
|
91
91
|
render: (_, row) => (
|
|
92
92
|
<RenderProfileDropDown
|
|
93
93
|
profiles={profiles?.profiles}
|
|
@@ -100,8 +100,8 @@ function ApplicationProfile({
|
|
|
100
100
|
},
|
|
101
101
|
{
|
|
102
102
|
title: 'Actions',
|
|
103
|
-
key: '',
|
|
104
|
-
dataIndex: '',
|
|
103
|
+
key: 'actions',
|
|
104
|
+
dataIndex: 'actions',
|
|
105
105
|
render: (_, row) => (
|
|
106
106
|
<ValidateAccess
|
|
107
107
|
accessKey={
|
|
@@ -133,16 +133,15 @@ function ApplicationProfile({
|
|
|
133
133
|
s.offset = value * s.limit - s.limit
|
|
134
134
|
})
|
|
135
135
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
}
|
|
136
|
+
|
|
137
|
+
if (profilesLoading) return <Spinner />
|
|
139
138
|
return (
|
|
140
139
|
<>
|
|
141
140
|
<PageHeader
|
|
142
141
|
title={title}
|
|
143
142
|
actions={[
|
|
144
143
|
<ValidateAccess
|
|
145
|
-
key={
|
|
144
|
+
key={1}
|
|
146
145
|
accessKey={
|
|
147
146
|
permissions
|
|
148
147
|
? Permission[permissions.add]
|
|
@@ -150,7 +149,6 @@ function ApplicationProfile({
|
|
|
150
149
|
}
|
|
151
150
|
>
|
|
152
151
|
<DialogButton
|
|
153
|
-
key={0}
|
|
154
152
|
title={'Add User Profile Relation'}
|
|
155
153
|
anchor={({ open }) => (
|
|
156
154
|
<ActionButton onClick={open}>
|
|
@@ -185,7 +183,7 @@ function ApplicationProfile({
|
|
|
185
183
|
/>
|
|
186
184
|
<Table
|
|
187
185
|
columns={columns}
|
|
188
|
-
dataSource={data?.
|
|
186
|
+
dataSource={data?.result ?? []}
|
|
189
187
|
loading={isLoading || removingUserProfile}
|
|
190
188
|
pagination={{
|
|
191
189
|
limit: filters.limit,
|
|
@@ -213,17 +211,19 @@ export const RenderProfileDropDown = ({
|
|
|
213
211
|
const CanEdit = permissions
|
|
214
212
|
? permissionState.permissions[Permission[permissions.edit]]
|
|
215
213
|
: permissionState.permissions['can_dashboard_view']
|
|
214
|
+
|
|
216
215
|
const [state, setState] = useState({
|
|
217
|
-
userId:
|
|
218
|
-
profileId:
|
|
216
|
+
userId: null,
|
|
217
|
+
profileId: null,
|
|
219
218
|
})
|
|
220
219
|
|
|
221
220
|
useEffect(() => {
|
|
222
221
|
setState((pre) => ({
|
|
223
222
|
userId: data.id,
|
|
224
|
-
profileId: data
|
|
223
|
+
profileId: data?.profiles?.find((p) => p.application === application)?.id,
|
|
225
224
|
}))
|
|
226
225
|
}, [data])
|
|
226
|
+
|
|
227
227
|
const { mutate, isLoading } = useMutation(updateUserApplicationProfile, {
|
|
228
228
|
onSuccess: (res) => {
|
|
229
229
|
refetchFn()
|
|
@@ -246,6 +246,8 @@ export const RenderProfileDropDown = ({
|
|
|
246
246
|
application: application,
|
|
247
247
|
})
|
|
248
248
|
}
|
|
249
|
+
|
|
250
|
+
if (!data) return null
|
|
249
251
|
return (
|
|
250
252
|
<>
|
|
251
253
|
<StyledDropDownContainer>
|
|
@@ -1,24 +1,17 @@
|
|
|
1
1
|
import { yupResolver } from '@hookform/resolvers/yup'
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
CircularProgress,
|
|
5
|
-
Popper,
|
|
6
|
-
Stack,
|
|
7
|
-
styled,
|
|
8
|
-
} from '@mui/material'
|
|
9
|
-
import { useState } from 'react'
|
|
10
|
-
import { Controller, useForm } from 'react-hook-form'
|
|
2
|
+
import { Stack } from '@mui/material'
|
|
3
|
+
import { useForm } from 'react-hook-form'
|
|
11
4
|
import { useMutation, useQueryClient } from 'react-query'
|
|
12
5
|
import { toast } from 'react-toastify'
|
|
6
|
+
import { useImmer } from 'use-immer'
|
|
7
|
+
import { axiosErrorToast } from '../../config/axios'
|
|
8
|
+
import ActionButton from '../ActionButton'
|
|
9
|
+
import { FormMultiSelect, FormSingleSelect } from '../HookForm'
|
|
13
10
|
import {
|
|
14
11
|
createApplicationUserProfile,
|
|
15
12
|
fetchUsers,
|
|
16
13
|
userProfileSchema,
|
|
17
|
-
} from './
|
|
18
|
-
import { useImmer } from 'use-immer'
|
|
19
|
-
import { axiosErrorToast } from '../../config/axios'
|
|
20
|
-
import { FormMultiSelect, FormSingleSelect } from '../HookForm'
|
|
21
|
-
import ActionButton from '../ActionButton'
|
|
14
|
+
} from './services'
|
|
22
15
|
interface UserProps {
|
|
23
16
|
options: {
|
|
24
17
|
label: any
|
|
@@ -59,7 +52,7 @@ function UserProfileRelation({ close, application, profiles }) {
|
|
|
59
52
|
{
|
|
60
53
|
onSuccess: (res) => {
|
|
61
54
|
setState((s) => {
|
|
62
|
-
s.options = res.
|
|
55
|
+
s.options = res.result?.map((item) => ({
|
|
63
56
|
label: item.fullName,
|
|
64
57
|
value: item.id,
|
|
65
58
|
}))
|
|
@@ -80,6 +73,7 @@ function UserProfileRelation({ close, application, profiles }) {
|
|
|
80
73
|
}
|
|
81
74
|
|
|
82
75
|
const handleInputChange = (e) => {
|
|
76
|
+
//TODO : debounce
|
|
83
77
|
if (e) {
|
|
84
78
|
setState((s) => {
|
|
85
79
|
s.inputValue = e.target.value
|
|
@@ -134,41 +128,3 @@ function UserProfileRelation({ close, application, profiles }) {
|
|
|
134
128
|
)
|
|
135
129
|
}
|
|
136
130
|
export default UserProfileRelation
|
|
137
|
-
|
|
138
|
-
const StyledPopper = styled(Popper)(({ theme }) => ({
|
|
139
|
-
'& .MuiPaper-root': {
|
|
140
|
-
borderRadius: '10px',
|
|
141
|
-
borderTopRightRadius: 0,
|
|
142
|
-
borderTopLeftRadius: 0,
|
|
143
|
-
boxShadow: '0px 4px 16px #0000000F',
|
|
144
|
-
marginTop: '1px',
|
|
145
|
-
'& .MuiAutocomplete-listbox': {
|
|
146
|
-
minWidth: '240px',
|
|
147
|
-
padding: '10px',
|
|
148
|
-
'& .MuiAutocomplete-option': {
|
|
149
|
-
padding: '10px',
|
|
150
|
-
background: 'none',
|
|
151
|
-
'&.Mui-focused': {
|
|
152
|
-
background: 'none',
|
|
153
|
-
},
|
|
154
|
-
},
|
|
155
|
-
'& .MuiCheckbox-root': {
|
|
156
|
-
padding: 0,
|
|
157
|
-
marginRight: '10px',
|
|
158
|
-
},
|
|
159
|
-
},
|
|
160
|
-
'&::-webkit-scrollbar': {
|
|
161
|
-
width: '0.5em',
|
|
162
|
-
height: '0.5em',
|
|
163
|
-
},
|
|
164
|
-
|
|
165
|
-
'&::-webkit-scrollbar-thumb': {
|
|
166
|
-
backgroundColor: 'rgba(0, 0, 0, 0.15)',
|
|
167
|
-
borderRadius: '3px',
|
|
168
|
-
|
|
169
|
-
'&:hover': {
|
|
170
|
-
background: 'rgba(0, 0, 0, 0.2)',
|
|
171
|
-
},
|
|
172
|
-
},
|
|
173
|
-
},
|
|
174
|
-
}))
|
|
@@ -12,6 +12,7 @@ import LoginForm from '../LoginForm'
|
|
|
12
12
|
import { useModal } from '../DrawerWrapper/DrawerWrapper'
|
|
13
13
|
import { PermissionsStore } from '../../shared-state'
|
|
14
14
|
import axios from '../../config/axios'
|
|
15
|
+
import { openRootModal } from '../../contexts/RootModal'
|
|
15
16
|
|
|
16
17
|
const StyledAlert = styled(Alert)(({ theme }) => ({
|
|
17
18
|
height: '60px',
|
|
@@ -187,18 +188,16 @@ export function UnAuth({ resetBoundary }) {
|
|
|
187
188
|
setLoading(false)
|
|
188
189
|
})
|
|
189
190
|
.catch((e) => {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
content: () => <LoginForm />,
|
|
191
|
+
openRootModal({
|
|
192
|
+
key: 'login',
|
|
193
193
|
})
|
|
194
194
|
})
|
|
195
195
|
}
|
|
196
196
|
function LoginPage() {
|
|
197
197
|
if (isLocalHost) {
|
|
198
198
|
if (!sessionCookie) {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
content: () => <LoginForm />,
|
|
199
|
+
openRootModal({
|
|
200
|
+
key: 'login',
|
|
202
201
|
})
|
|
203
202
|
} else {
|
|
204
203
|
appinit()
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { Box, Stack, Typography, styled } from '@mui/material'
|
|
2
|
+
import { InsititutionsStore } from '../../shared-state/InstitutionsStore'
|
|
3
|
+
import Image from '../Image/Image'
|
|
4
|
+
|
|
5
|
+
export default function InsititutionsDialog({ close }) {
|
|
6
|
+
const { institutions } = InsititutionsStore.useState((s) => s)
|
|
7
|
+
|
|
8
|
+
return (
|
|
9
|
+
<Stack
|
|
10
|
+
gap={4}
|
|
11
|
+
sx={{
|
|
12
|
+
padding: '20px',
|
|
13
|
+
alignItems: 'center',
|
|
14
|
+
}}
|
|
15
|
+
>
|
|
16
|
+
<Typography variant="h3" textAlign={'center'}>
|
|
17
|
+
Select an Instituition
|
|
18
|
+
</Typography>
|
|
19
|
+
|
|
20
|
+
<StyledInstitutionContainer>
|
|
21
|
+
{institutions?.map((item, index) => (
|
|
22
|
+
<InstitutionCard institution={item} key={index} />
|
|
23
|
+
))}
|
|
24
|
+
</StyledInstitutionContainer>
|
|
25
|
+
</Stack>
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const InstitutionCard = ({ institution }) => {
|
|
30
|
+
const urlTenantKey = window.location.pathname.split('/')[1]
|
|
31
|
+
const handleClick = () => {
|
|
32
|
+
localStorage.setItem('institution_key', institution?.code)
|
|
33
|
+
window.location.replace(
|
|
34
|
+
`${window.location.origin}/${urlTenantKey}/${institution?.code}`,
|
|
35
|
+
)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
<Box
|
|
40
|
+
sx={{
|
|
41
|
+
display: 'flex',
|
|
42
|
+
flexDirection: 'column',
|
|
43
|
+
alignItems: 'center',
|
|
44
|
+
gap: '20px',
|
|
45
|
+
padding: '14px',
|
|
46
|
+
border: '1px solid black',
|
|
47
|
+
borderRadius: '10px',
|
|
48
|
+
cursor: 'pointer',
|
|
49
|
+
width: '200px',
|
|
50
|
+
flexShrink: 0,
|
|
51
|
+
}}
|
|
52
|
+
onClick={handleClick}
|
|
53
|
+
>
|
|
54
|
+
<Image
|
|
55
|
+
alt="logo"
|
|
56
|
+
height={100}
|
|
57
|
+
width="auto"
|
|
58
|
+
src={institution?.images?.url}
|
|
59
|
+
/>
|
|
60
|
+
<Typography variant="body2">{institution?.name}</Typography>
|
|
61
|
+
</Box>
|
|
62
|
+
)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export const StyledInstitutionContainer = styled(Box)(({ theme }) => ({
|
|
66
|
+
width: '87%',
|
|
67
|
+
overflowX: 'auto',
|
|
68
|
+
display: 'flex',
|
|
69
|
+
flex: 1,
|
|
70
|
+
justifyContent: 'flex-start',
|
|
71
|
+
padding: '20px',
|
|
72
|
+
gap: '20px',
|
|
73
|
+
'&::-webkit-scrollbar': {
|
|
74
|
+
width: '0.5em',
|
|
75
|
+
height: '0.5em',
|
|
76
|
+
backgroundColor: 'rgba(0, 0, 0, 0.1)',
|
|
77
|
+
},
|
|
78
|
+
'&::-webkit-scrollbar-thumb': {
|
|
79
|
+
backgroundColor: 'rgba(0, 0, 0, 0.2)',
|
|
80
|
+
borderRadius: '3px',
|
|
81
|
+
|
|
82
|
+
'&:hover': {
|
|
83
|
+
background: 'rgba(0, 0, 0, 0.3)',
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
}))
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Box, Typography } from '@mui/material'
|
|
2
|
+
|
|
3
|
+
export default function InsititutionsNotAssignedDialog() {
|
|
4
|
+
return (
|
|
5
|
+
<Box padding="40px 10px">
|
|
6
|
+
<Typography variant="body2" textAlign="center">
|
|
7
|
+
You have not been assigned to any institutions. Please contact your
|
|
8
|
+
administrator.
|
|
9
|
+
</Typography>
|
|
10
|
+
</Box>
|
|
11
|
+
)
|
|
12
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { useState } from 'react'
|
|
2
|
+
import { FormSingleSelect } from '../HookForm'
|
|
3
|
+
import { SingleSelect } from '../Input'
|
|
4
|
+
import { InsititutionsStore } from '../../shared-state/InstitutionsStore'
|
|
5
|
+
import { urlTenantKey } from '../../contexts/Providers'
|
|
6
|
+
|
|
7
|
+
export default function SchoolSwitch() {
|
|
8
|
+
const { current, institutions } = InsititutionsStore.useState((s) => s)
|
|
9
|
+
|
|
10
|
+
const handleChange = (e) => {
|
|
11
|
+
localStorage.setItem('institution_key', e.target.value)
|
|
12
|
+
window.location.replace(
|
|
13
|
+
`${window.location.origin}/${urlTenantKey}/${e.target.value}`,
|
|
14
|
+
)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<SingleSelect
|
|
19
|
+
containerProps={{
|
|
20
|
+
sx: {
|
|
21
|
+
minWidth: '200px',
|
|
22
|
+
},
|
|
23
|
+
}}
|
|
24
|
+
size="small"
|
|
25
|
+
options={institutions?.map((item) => ({
|
|
26
|
+
label: item.name,
|
|
27
|
+
value: item.code,
|
|
28
|
+
}))}
|
|
29
|
+
value={current?.code}
|
|
30
|
+
onChange={handleChange}
|
|
31
|
+
/>
|
|
32
|
+
)
|
|
33
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './InsititutionsDialog'
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import axios from '../../config/axios'
|
|
2
|
+
|
|
3
|
+
export const institutions = {
|
|
4
|
+
async fetchInsititutions() {
|
|
5
|
+
const res = await axios.get('/square/institutions')
|
|
6
|
+
return res.data
|
|
7
|
+
},
|
|
8
|
+
async fetchInsititutionByCode(code: string) {
|
|
9
|
+
const res = await axios.get(`/square/institutions/code/${code}`)
|
|
10
|
+
return res.data
|
|
11
|
+
},
|
|
12
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { Box,
|
|
1
|
+
import { Box, Typography } from '@mui/material'
|
|
2
2
|
import { ReactNode } from 'react'
|
|
3
3
|
import { isDevelopment } from '../../../constants/isDevelopment'
|
|
4
|
-
import { applications } from './applications'
|
|
5
4
|
import AppsMenu from './AppsMenu'
|
|
5
|
+
import { applications } from './applications'
|
|
6
6
|
import {
|
|
7
7
|
collegex,
|
|
8
8
|
commutex,
|
|
@@ -13,17 +13,13 @@ import {
|
|
|
13
13
|
peoplex,
|
|
14
14
|
} from './assets'
|
|
15
15
|
|
|
16
|
-
import
|
|
17
|
-
import CogWheelMenu from './HeaderActions/CogWheelMenu'
|
|
16
|
+
import HeaderActions from './HeaderActions/HeaderActions'
|
|
18
17
|
import {
|
|
19
18
|
StyledHeader,
|
|
20
19
|
StyledImageWrapper,
|
|
21
20
|
StyledLogosWrapper,
|
|
22
21
|
StyledRouterLink,
|
|
23
22
|
} from './styles'
|
|
24
|
-
import UserBox from './HeaderActions/UserBox'
|
|
25
|
-
import FreshDeskHelpButton from './HeaderActions/FreshDeskHelpButton'
|
|
26
|
-
import HeaderActions from './HeaderActions/HeaderActions'
|
|
27
23
|
|
|
28
24
|
const imageMap = {
|
|
29
25
|
ums: collegex,
|
|
@@ -1,19 +1,18 @@
|
|
|
1
|
+
import AppsOutageIcon from '@mui/icons-material/AppsOutage'
|
|
1
2
|
import { Box, Menu, Typography, styled } from '@mui/material'
|
|
2
|
-
import Cookies from 'js-cookie'
|
|
3
3
|
import { useState } from 'react'
|
|
4
|
+
import { campxTenantKey, instituitionKey } from '../../../contexts/Providers'
|
|
5
|
+
import { PermissionsStore } from '../../../shared-state'
|
|
4
6
|
import { applications } from './applications'
|
|
5
7
|
import { AppsIcon } from './icons'
|
|
6
8
|
import {
|
|
7
9
|
StyledDescription,
|
|
8
10
|
StyledIconButton,
|
|
11
|
+
StyledImageBox,
|
|
12
|
+
StyledLink,
|
|
9
13
|
StyledMenuItem,
|
|
10
14
|
StyledMenuItemContainer,
|
|
11
|
-
StyledLink,
|
|
12
|
-
StyledImageBox,
|
|
13
15
|
} from './styles'
|
|
14
|
-
import { PermissionsStore } from '../../../shared-state'
|
|
15
|
-
import AppsOutageIcon from '@mui/icons-material/AppsOutage'
|
|
16
|
-
export const campxTenantKey = Cookies.get('campx_tenant')
|
|
17
16
|
|
|
18
17
|
const AppsMenu = () => {
|
|
19
18
|
const permissionState = PermissionsStore.useState((s) => s)
|
|
@@ -74,7 +73,7 @@ const AppsMenu = () => {
|
|
|
74
73
|
{applicationList.map((item, index) => {
|
|
75
74
|
return (
|
|
76
75
|
<StyledLink
|
|
77
|
-
href={item.path + `/${campxTenantKey
|
|
76
|
+
href={item.path + `/${campxTenantKey}/${instituitionKey}`}
|
|
78
77
|
key={index}
|
|
79
78
|
>
|
|
80
79
|
<StyledMenuItemContainer
|
|
@@ -2,7 +2,7 @@ import { Box } from '@mui/material'
|
|
|
2
2
|
import UserBox from './UserBox'
|
|
3
3
|
import CogWheelMenu from './CogWheelMenu'
|
|
4
4
|
import FreshDeskHelpButton from './FreshDeskHelpButton'
|
|
5
|
-
import
|
|
5
|
+
import InstitutionsDropDown from '../../../Institutions/InstitutionsDropdown'
|
|
6
6
|
|
|
7
7
|
export default function HeaderActions({
|
|
8
8
|
cogWheelMenu,
|
|
@@ -11,7 +11,7 @@ export default function HeaderActions({
|
|
|
11
11
|
}) {
|
|
12
12
|
return (
|
|
13
13
|
<>
|
|
14
|
-
|
|
14
|
+
<InstitutionsDropDown />
|
|
15
15
|
<FreshDeskHelpButton />
|
|
16
16
|
{cogWheelMenu?.length ? <CogWheelMenu menu={cogWheelMenu} /> : null}
|
|
17
17
|
<UserBox fullName={fullName} actions={userBoxActions} />
|
|
@@ -81,13 +81,13 @@ export const applications = [
|
|
|
81
81
|
icon: hostelSmall,
|
|
82
82
|
description: 'Manage Hostels in the Campus',
|
|
83
83
|
},
|
|
84
|
-
{
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
},
|
|
84
|
+
// {
|
|
85
|
+
// title: 'CommuteX',
|
|
86
|
+
// key: 'commute',
|
|
87
|
+
// path: isDevelopment ? origins.commute.dev : origins.commute.prod,
|
|
88
|
+
// icon: commuteSmall,
|
|
89
|
+
// description: 'Manage Commute in the Campus',
|
|
90
|
+
// },
|
|
91
91
|
...(isDevelopment
|
|
92
92
|
? [
|
|
93
93
|
{
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
1
2
|
import { Visibility, VisibilityOff } from '@mui/icons-material'
|
|
2
3
|
import {
|
|
3
4
|
Alert,
|
|
@@ -13,20 +14,21 @@ import axiosBase from 'axios'
|
|
|
13
14
|
import Cookies from 'js-cookie'
|
|
14
15
|
import { useEffect, useState } from 'react'
|
|
15
16
|
import { useForm } from 'react-hook-form'
|
|
17
|
+
import { Link } from 'react-router-dom'
|
|
18
|
+
import axios from '../config/axios'
|
|
19
|
+
import adminAxios from '../utils/adminAxios'
|
|
16
20
|
import ActionButton from './ActionButton'
|
|
17
21
|
import { FormTextField } from './HookForm'
|
|
18
|
-
import axios from '../config/axios'
|
|
19
22
|
import ResetPassword from './ResetPassword'
|
|
20
|
-
import
|
|
21
|
-
import {
|
|
22
|
-
import adminAxios from '../utils/adminAxios'
|
|
23
|
+
import Image from './Image/Image'
|
|
24
|
+
import { campxLogoPrimary } from '../assets/images'
|
|
23
25
|
|
|
24
26
|
export function LoginForm({
|
|
25
27
|
loginUrl,
|
|
26
|
-
|
|
28
|
+
close,
|
|
27
29
|
}: {
|
|
28
30
|
loginUrl?: string
|
|
29
|
-
|
|
31
|
+
close: any
|
|
30
32
|
}) {
|
|
31
33
|
const [showPassword, setShowPassword] = useState(false)
|
|
32
34
|
const [forgotMail, setForgotMail] = useState(null)
|
|
@@ -86,6 +88,19 @@ export function LoginForm({
|
|
|
86
88
|
|
|
87
89
|
return (
|
|
88
90
|
<Box sx={{ position: 'relative', height: '100%' }}>
|
|
91
|
+
<Box
|
|
92
|
+
sx={{
|
|
93
|
+
display: 'flex',
|
|
94
|
+
justifyContent: 'center',
|
|
95
|
+
margin: '30px 0',
|
|
96
|
+
flexDirection: 'column',
|
|
97
|
+
gap: '10px',
|
|
98
|
+
alignItems: 'center',
|
|
99
|
+
}}
|
|
100
|
+
>
|
|
101
|
+
<Image alt="" height="auto" width={'200px'} src={campxLogoPrimary} />
|
|
102
|
+
<Typography variant="body2">Developer Login</Typography>
|
|
103
|
+
</Box>
|
|
89
104
|
{resetPassword ? (
|
|
90
105
|
<>
|
|
91
106
|
<ResetPassword />
|
|
@@ -168,26 +183,6 @@ export function LoginForm({
|
|
|
168
183
|
{error}
|
|
169
184
|
</Alert>
|
|
170
185
|
)}
|
|
171
|
-
|
|
172
|
-
{showSuperAdminForm && (
|
|
173
|
-
<Box
|
|
174
|
-
sx={{
|
|
175
|
-
position: 'absolute',
|
|
176
|
-
bottom: '20px',
|
|
177
|
-
right: '20px',
|
|
178
|
-
}}
|
|
179
|
-
>
|
|
180
|
-
<DialogButton
|
|
181
|
-
title="Super Admin Login"
|
|
182
|
-
anchor={({ open }) => (
|
|
183
|
-
<Button onClick={open} size="small" variant="text">
|
|
184
|
-
Super Admin Login
|
|
185
|
-
</Button>
|
|
186
|
-
)}
|
|
187
|
-
content={({ close }) => <SuperAdminLoginForm close={close} />}
|
|
188
|
-
/>
|
|
189
|
-
</Box>
|
|
190
|
-
)}
|
|
191
186
|
</Box>
|
|
192
187
|
)
|
|
193
188
|
}
|
|
@@ -83,7 +83,7 @@ export default function DialogButton({
|
|
|
83
83
|
|
|
84
84
|
interface CustomDialogProps {
|
|
85
85
|
content: (props: { close: () => void }) => ReactNode
|
|
86
|
-
title
|
|
86
|
+
title?: string
|
|
87
87
|
onClose: () => void
|
|
88
88
|
open: boolean
|
|
89
89
|
dialogProps?: Omit<DialogProps, 'open'>
|
|
@@ -96,30 +96,34 @@ export const CustomDialog = ({
|
|
|
96
96
|
content,
|
|
97
97
|
open,
|
|
98
98
|
}: CustomDialogProps) => {
|
|
99
|
+
const props = {
|
|
100
|
+
PaperProps: {
|
|
101
|
+
...dialogProps?.PaperProps,
|
|
102
|
+
elevation: 2,
|
|
103
|
+
sx: { borderRadius: '10px' },
|
|
104
|
+
},
|
|
105
|
+
fullWidth: true,
|
|
106
|
+
onClose: onClose,
|
|
107
|
+
open: open,
|
|
108
|
+
transitionDuration: 140,
|
|
109
|
+
TransitionComponent: Transition,
|
|
110
|
+
sx: {
|
|
111
|
+
...dialogProps?.sx,
|
|
112
|
+
'& .MuiBackdrop-root': { backgroundColor: 'rgba(0, 0, 0, 0.4)' },
|
|
113
|
+
},
|
|
114
|
+
...dialogProps,
|
|
115
|
+
}
|
|
116
|
+
|
|
99
117
|
return (
|
|
100
|
-
<Dialog
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
transitionDuration={140}
|
|
110
|
-
TransitionComponent={Transition}
|
|
111
|
-
sx={{
|
|
112
|
-
...dialogProps?.sx,
|
|
113
|
-
'& .MuiBackdrop-root': { backgroundColor: 'rgba(0, 0, 0, 0.4)' },
|
|
114
|
-
}}
|
|
115
|
-
{...dialogProps}
|
|
116
|
-
>
|
|
117
|
-
<StyledDialogHeader>
|
|
118
|
-
<DialogTitle>{title}</DialogTitle>
|
|
119
|
-
<IconButton onClick={onClose} sx={{ color: 'black' }}>
|
|
120
|
-
<Close />
|
|
121
|
-
</IconButton>
|
|
122
|
-
</StyledDialogHeader>
|
|
118
|
+
<Dialog {...props}>
|
|
119
|
+
{title && (
|
|
120
|
+
<StyledDialogHeader>
|
|
121
|
+
<DialogTitle>{title}</DialogTitle>
|
|
122
|
+
<IconButton onClick={onClose} sx={{ color: 'black' }}>
|
|
123
|
+
<Close />
|
|
124
|
+
</IconButton>
|
|
125
|
+
</StyledDialogHeader>
|
|
126
|
+
)}
|
|
123
127
|
<StyledDialogContent>{content({ close: onClose })}</StyledDialogContent>
|
|
124
128
|
</Dialog>
|
|
125
129
|
)
|