@campxdev/shared 3.1.3 → 3.1.5

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": "3.1.3",
3
+ "version": "3.1.5",
4
4
  "main": "./exports.ts",
5
5
  "scripts": {
6
6
  "start": "react-scripts start",
@@ -1,11 +1,7 @@
1
- import TourIcon from '@mui/icons-material/Tour'
2
1
  import { Box, Button, Typography } from '@mui/material'
3
- import { ReactNode, useEffect, useState } from 'react'
4
- import ReactJoyride, { Step, CallBackProps } from 'react-joyride'
5
- import { useQuery } from 'react-query'
6
- import axios from '../config/axios'
2
+ import { ReactNode, useState } from 'react'
3
+ import ReactJoyride, { Step } from 'react-joyride'
7
4
  import './CustomJoyRideStyles.css'
8
- import Spinner from './Spinner'
9
5
 
10
6
  function ReactJoyRide({
11
7
  steps,
@@ -17,95 +13,65 @@ function ReactJoyRide({
17
13
  tourName: string
18
14
  }) {
19
15
  const [run, setRun] = useState(false)
20
- const [stepIndex, setStepIndex] = useState(0)
21
-
22
- const fetchTours = (params) => {
23
- return axios.get(`/square/tours`).then((res) => res.data)
24
- }
25
-
26
- const { data: toursData, isLoading: toursLoading } = useQuery(
27
- 'tours',
28
- fetchTours,
29
- )
30
-
31
- useEffect(() => {}, [run])
32
-
33
- const completeTour = async () => {
34
- try {
35
- await axios.post(`/square/tours/complete`, { tourName })
36
- } catch (error) {
37
- // console.error('Error in Completing Tour:', error)
38
- }
39
- }
40
-
41
- const handleJoyRideCallback = (data: CallBackProps) => {
42
- const { action, status, index } = data
43
-
44
- if (action === 'next' || action === 'prev') {
45
- setStepIndex(index + (action === 'next' ? 1 : 0))
46
- }
47
-
48
- if (action === 'reset') {
49
- setRun(false)
50
- setStepIndex(0)
51
- completeTour()
52
- }
53
- }
54
16
 
55
17
  const customSteps = steps.map((step, index) => ({
56
- ...step,
57
- title: '', // Remove the automatic title
58
- content: (
59
- <Box sx={{ fontFamily: 'Roboto, sans-serif',display: 'flex', flexDirection: 'column', }}>
60
-
61
- <Typography
62
- variant="caption"
63
- sx={{
64
- color: '#6b7280',
65
- fontWeight: 500,
66
- textTransform: 'uppercase',
67
- letterSpacing: '0.5px',
68
- fontSize: '11px',
18
+ ...step,
19
+ title: '', // Remove the automatic title
20
+ content: (
21
+ <Box
22
+ sx={{
23
+ fontFamily: 'Roboto, sans-serif',
24
+ display: 'flex',
25
+ flexDirection: 'column',
26
+ }}
27
+ >
28
+ <Typography
29
+ variant="caption"
30
+ sx={{
31
+ color: '#6b7280',
32
+ fontWeight: 500,
33
+ textTransform: 'uppercase',
34
+ letterSpacing: '0.5px',
35
+ fontSize: '11px',
36
+ }}
37
+ >
38
+ Step {index + 1}
39
+ </Typography>
40
+ <Box sx={{ padding: '4px 0' }}>
41
+ <Typography
42
+ sx={{
43
+ lineHeight: 1.5,
44
+ color: '#4b5563',
45
+ fontFamily: 'Poppins, sans-serif',
46
+ fontSize: '16px',
47
+ fontWeight: '600',
48
+ marginTop: '12px',
69
49
  }}
70
50
  >
71
- Step {index + 1}
51
+ {step.title}
72
52
  </Typography>
73
- <Box sx={{ padding: '4px 0' }}>
74
- <Typography
75
- sx={{
76
- lineHeight: 1.5,
77
- color: '#4b5563',
78
- fontFamily: 'Poppins, sans-serif',
79
- fontSize: '16px',
80
- fontWeight: '600',
81
- marginTop: '12px',
82
- }}
83
- >
84
- {step.title}
85
- </Typography>
86
- </Box>
87
- <Box sx={{ padding: '4px 0' }}>
88
- <Typography
89
- sx={{
90
- fontSize: '14px',
91
- lineHeight: 1.5,
92
- color: '#4b5563',
93
- fontFamily: 'Heebo, sans-serif',
94
- fontWeight: '500',
95
- }}
96
- >
97
- {step.content}
98
- </Typography>
99
- </Box>
100
53
  </Box>
101
- ),
102
- }))
54
+ <Box sx={{ padding: '4px 0' }}>
55
+ <Typography
56
+ sx={{
57
+ fontSize: '14px',
58
+ lineHeight: 1.5,
59
+ color: '#4b5563',
60
+ fontFamily: 'Heebo, sans-serif',
61
+ fontWeight: '500',
62
+ }}
63
+ >
64
+ {step.content}
65
+ </Typography>
66
+ </Box>
67
+ </Box>
68
+ ),
69
+ }))
103
70
 
104
71
  return (
105
72
  <>
106
73
  <Box>
107
74
  <ReactJoyride
108
- callback={handleJoyRideCallback}
109
75
  run={run}
110
76
  steps={customSteps}
111
77
  styles={{
@@ -119,7 +85,8 @@ function ReactJoyRide({
119
85
  },
120
86
  tooltip: {
121
87
  borderRadius: '12px',
122
- boxShadow: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',
88
+ boxShadow:
89
+ '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',
123
90
  fontSize: '14px',
124
91
  padding: '20px',
125
92
  minWidth: '320px',
@@ -132,7 +99,7 @@ function ReactJoyRide({
132
99
  fontSize: '16px',
133
100
  fontWeight: '600',
134
101
  color: '#1f2937',
135
- fontFamily: 'Poppins, sans-serif',
102
+ fontFamily: 'Poppins, sans-serif',
136
103
  },
137
104
  tooltipContent: {
138
105
  fontSize: '14px',
@@ -140,7 +107,7 @@ function ReactJoyRide({
140
107
  color: '#4b5563',
141
108
  padding: '0',
142
109
  fontFamily: 'Heebo, sans-serif !important',
143
- fontWeight: '400'
110
+ fontWeight: '400',
144
111
  },
145
112
  buttonNext: {
146
113
  backgroundColor: '#121212',
@@ -246,7 +213,8 @@ function ReactJoyRide({
246
213
  '&:hover': {
247
214
  backgroundColor: '#1E027F',
248
215
  color: 'white',
249
- boxShadow: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',
216
+ boxShadow:
217
+ '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',
250
218
  transform: 'translateY(-50%) translateX(-4px)',
251
219
  },
252
220
  '&:active': {
@@ -41,6 +41,7 @@ const ClassRoomSelector = (props: ClassRoomSelectorProps) => {
41
41
  axios
42
42
  .get(api, {
43
43
  params: filters,
44
+ workspace: false,
44
45
  })
45
46
  .then((response) => {
46
47
  setOptions(response.data)
@@ -54,7 +55,9 @@ const ClassRoomSelector = (props: ClassRoomSelectorProps) => {
54
55
  }
55
56
  } else if (options.length === 0) {
56
57
  axios
57
- .get(api)
58
+ .get(api, {
59
+ workspace: false,
60
+ })
58
61
  .then((response) => {
59
62
  setOptions(response.data)
60
63
  })
@@ -29,7 +29,9 @@ export default function CourseSelector(props: CourseSelectorProps) {
29
29
  const handleOpen = () => {
30
30
  if (options.length === 0) {
31
31
  axios
32
- .get(api)
32
+ .get(api, {
33
+ workspace: false,
34
+ })
33
35
  .then((response) => {
34
36
  setOptions(response.data)
35
37
  })
@@ -27,7 +27,9 @@ export default function DepartmentSelector(props: DepartmentSelectorProps) {
27
27
  const handleOpen = () => {
28
28
  if (options.length === 0) {
29
29
  axios
30
- .get(api)
30
+ .get(api, {
31
+ workspace: false,
32
+ })
31
33
  .then((response) => {
32
34
  setOptions(response.data.data)
33
35
  })
@@ -43,6 +43,7 @@ const ExamGroupSelector = (props: ExamGroupSelectorProps) => {
43
43
  isArchived: 'false',
44
44
  isExamPublished: 'true',
45
45
  },
46
+ workspace: false,
46
47
  })
47
48
  .then((response) => {
48
49
  setOptions(
@@ -64,6 +65,7 @@ const ExamGroupSelector = (props: ExamGroupSelectorProps) => {
64
65
  isArchived: 'false',
65
66
  isExamPublished: 'true',
66
67
  },
68
+ workspace: false,
67
69
  })
68
70
  .then((response) => {
69
71
  setOptions(
@@ -38,6 +38,7 @@ const FacultySelector = (props: FacultySelectorProps) => {
38
38
  axios
39
39
  .get(api, {
40
40
  params: filters,
41
+ workspace: false,
41
42
  })
42
43
  .then((response) => {
43
44
  setOptions(response.data.data)
@@ -19,7 +19,9 @@ export default function FeeTypeSelector(props: FeeTypeSelectorProps) {
19
19
  const handleOpen = () => {
20
20
  if (options.length === 0) {
21
21
  axios
22
- .get('/paymentx/fee-types')
22
+ .get('/paymentx/fee-types', {
23
+ workspace: false,
24
+ })
23
25
  .then((response) => {
24
26
  setOptions(response.data)
25
27
  })
@@ -43,6 +43,7 @@ const MultiFacultySelector = (props: MultiFacultySelectorProps) => {
43
43
  axios
44
44
  .get(api, {
45
45
  params: filters,
46
+ workspace: false,
46
47
  })
47
48
  .then((response) => {
48
49
  setOptions(response.data.data)
@@ -54,7 +55,7 @@ const MultiFacultySelector = (props: MultiFacultySelectorProps) => {
54
55
  }
55
56
  } else if (options.length === 0) {
56
57
  axios
57
- .get(api)
58
+ .get(api, { workspace: false })
58
59
  .then((response) => {
59
60
  setOptions(response.data.data)
60
61
  })
@@ -30,7 +30,7 @@ const MultiFeeTypeSelector = (props: MultiProgramSelectorProps) => {
30
30
  const handleOpen = () => {
31
31
  if (options.length === 0) {
32
32
  axios
33
- .get('/paymentx/fee-types')
33
+ .get('/paymentx/fee-types', { workspace: false })
34
34
  .then((response) => {
35
35
  setOptions(response.data)
36
36
  })
@@ -38,6 +38,7 @@ const MultiProgramSelector = (props: MultiProgramSelectorProps) => {
38
38
  axios
39
39
  .get(api, {
40
40
  params: filters,
41
+ workspace: false,
41
42
  })
42
43
  .then((response) => {
43
44
  setOptions(response.data)
@@ -49,7 +50,9 @@ const MultiProgramSelector = (props: MultiProgramSelectorProps) => {
49
50
  }
50
51
  } else if (options.length === 0) {
51
52
  axios
52
- .get(api)
53
+ .get(api, {
54
+ workspace: false,
55
+ })
53
56
  .then((response) => {
54
57
  setOptions(response.data)
55
58
  })
@@ -38,6 +38,7 @@ export default function MultiQuotaSelector(props: MultiQuotaSelectorProps) {
38
38
  axios
39
39
  .get(api, {
40
40
  params: filters,
41
+ workspace: false,
41
42
  })
42
43
  .then((response) => {
43
44
  setOptions(
@@ -51,7 +52,9 @@ export default function MultiQuotaSelector(props: MultiQuotaSelectorProps) {
51
52
  }
52
53
  } else if (options.length === 0) {
53
54
  axios
54
- .get(api)
55
+ .get(api, {
56
+ workspace: false,
57
+ })
55
58
  .then((response) => {
56
59
  setOptions(
57
60
  api == '/square/quotas' ? response.data : response.data.quota,
@@ -35,6 +35,7 @@ const ProgramSelector = (props: ProgramSelectorProps) => {
35
35
  axios
36
36
  .get(api, {
37
37
  params: filters,
38
+ workspace: false,
38
39
  })
39
40
  .then((response) => {
40
41
  setOptions(response.data)
@@ -46,7 +47,9 @@ const ProgramSelector = (props: ProgramSelectorProps) => {
46
47
  }
47
48
  } else if (options.length === 0) {
48
49
  axios
49
- .get(api)
50
+ .get(api, {
51
+ workspace: false,
52
+ })
50
53
  .then((response) => {
51
54
  setOptions(response.data)
52
55
  })
@@ -33,6 +33,7 @@ export default function QuotaSelector(props: QuotaSelectorProps) {
33
33
  axios
34
34
  .get(api, {
35
35
  params: filters,
36
+ workspace: false,
36
37
  })
37
38
  .then((response) => {
38
39
  setOptions(
@@ -46,7 +47,9 @@ export default function QuotaSelector(props: QuotaSelectorProps) {
46
47
  }
47
48
  } else if (options.length === 0) {
48
49
  axios
49
- .get(api)
50
+ .get(api, {
51
+ workspace: false,
52
+ })
50
53
  .then((response) => {
51
54
  setOptions(
52
55
  api == '/square/quotas' ? response.data : response.data.quota,
@@ -33,6 +33,7 @@ const SemesterSelector = (props: SemesterSelectorProps) => {
33
33
  axios
34
34
  .get(api, {
35
35
  params: filters,
36
+ workspace: false,
36
37
  })
37
38
  .then((response) => {
38
39
  setOptions(response.data)
@@ -44,7 +45,9 @@ const SemesterSelector = (props: SemesterSelectorProps) => {
44
45
  }
45
46
  } else if (options.length === 0) {
46
47
  axios
47
- .get(api)
48
+ .get(api, {
49
+ workspace: false,
50
+ })
48
51
  .then((response) => {
49
52
  setOptions(response.data)
50
53
  })
@@ -3,14 +3,30 @@ import Cookies from 'js-cookie'
3
3
  import { toast } from 'react-toastify'
4
4
  import { NetworkStore } from '../components/ErrorBoundary/GlobalNetworkLoadingIndicator'
5
5
 
6
- const isDevelopment = process.env.NODE_ENV == 'development'
6
+ // Declare the extended axios types to include our custom property
7
+ declare module 'axios' {
8
+ export interface AxiosRequestConfig {
9
+ workspace?: boolean
10
+ }
11
+ }
12
+
13
+ export const isDevelopment = window.location.hostname.includes('localhost')
7
14
 
8
- const tenantCode =
9
- isDevelopment || window.location.hostname === 'localhost'
10
- ? Cookies.get('campx_tenant')
11
- : window.location.hostname.split('.')[0]
15
+ const tenantCode = window.location.hostname.split('.')[0]
12
16
  const institutionCode = window.location.pathname.split('/')[1]
13
17
 
18
+ // Workspace to API endpoint prefix mapping
19
+ const workspaceApiMapping: Record<string, string> = {
20
+ 'student-workspace': '/student-api',
21
+ 'faculty-workspace': '/faculty-api',
22
+ 'department-workspace': '/department-api',
23
+ 'academic-coordinator-workspace': '/academic-coordinator-api',
24
+ 'academic-admin-workspace': '/academic-admin-api',
25
+ 'hostel-admin-workspace': '/hostel-admin-api',
26
+ 'transport-coordinator-workspace': '/transport-coordinator-api',
27
+ 'employee-workspace': '/employee-api',
28
+ }
29
+
14
30
  export const formatParams = (params) => {
15
31
  return Object.fromEntries(
16
32
  Object.entries(params ?? {})?.map((i) => [
@@ -35,6 +51,26 @@ axios.interceptors.request.use(
35
51
  NetworkStore.update((s) => {
36
52
  s.loading = true
37
53
  })
54
+
55
+ // Handle workspace routing (default: true)
56
+ if (
57
+ config.workspace !== false &&
58
+ window.location.pathname.split('/')[2] &&
59
+ window.location.pathname.split('/')[2] !== 'common-workspace' &&
60
+ workspaceApiMapping[window.location.pathname.split('/')[2]]
61
+ ) {
62
+ const workspacePrefix =
63
+ workspaceApiMapping[window.location.pathname.split('/')[2]]
64
+ if (
65
+ workspacePrefix &&
66
+ typeof workspacePrefix === 'string' &&
67
+ workspacePrefix.trim()
68
+ ) {
69
+ config.url = `${workspacePrefix}${config.url}`
70
+ }
71
+ }
72
+
73
+ // Add session keys from cookies if available
38
74
  const sessionKey = Cookies.get('campx_session_key')
39
75
  const openPaymentsKey = Cookies.get('campx_open_payments_key')
40
76
 
@@ -73,6 +109,7 @@ axios.interceptors.response.use(
73
109
 
74
110
  // Check if the error is an unauthorized error (401)
75
111
  if (err?.response && err?.response?.status === 401) {
112
+ // Clear session keys from cookies on unauthorized error
76
113
  Cookies.remove('campx_session_key')
77
114
  Cookies.remove('campx_tenant')
78
115
  Cookies.remove('campx_institution')
@@ -3,7 +3,6 @@ import ConfirmContextProvider from '../components/PopupConfirm/ConfirmContextPro
3
3
  import MuiThemeProvider from '../theme/MuiThemeProvider'
4
4
  import QueryClientProvider from './QueryClientProvider'
5
5
 
6
- import Cookies from 'js-cookie'
7
6
  import { ReactNode, useEffect } from 'react'
8
7
  import { ToastContainer } from '../components'
9
8
  import DialogProvider from '../components/DrawerWrapper/DrawerWrapper'
@@ -11,41 +10,19 @@ import GlobalNetworkLoadingIndicator from '../components/ErrorBoundary/GlobalNet
11
10
  import ErrorModalProvider from '../components/ErrorModalWrapper/ErrorModalWrapper'
12
11
  import RootModal from './RootModal'
13
12
 
14
- const isDevelopment = process.env.NODE_ENV == 'development'
13
+ const isDevelopment = window.location.hostname.includes('localhost')
15
14
 
16
- export const campxTenantKey = isDevelopment
17
- ? Cookies.get('campx_tenant')
18
- : window.location.hostname.split('.')[0]
19
- export const urlTenantKey = isDevelopment
20
- ? Cookies.get('campx_tenant')
21
- : window.location.hostname.split('.')[0]
22
- export const instituitionKey =
23
- window.location.pathname.split('/')[1] != ''
24
- ? window.location.pathname.split('/')[1]
25
- : Cookies.get('campx_institution')
15
+ export const campxTenantKey = window.location.hostname.split('.')[0]
16
+ export const urlTenantKey = window.location.hostname.split('.')[0]
17
+ export const instituitionKey = window.location.pathname.split('/')[1]
26
18
 
27
19
  export default function Providers({ children }: { children: ReactNode }) {
28
20
  var baseName = '/'
29
- var tenantCode
30
- var institutionCode =
31
- window.location.pathname.split('/')[1] != ''
32
- ? window.location.pathname.split('/')[1]
33
- : Cookies.get('campx_institution')
21
+ var tenantCode = window.location.hostname.split('.')[0]
22
+ var institutionCode = window.location.pathname.split('/')[1]
34
23
 
35
- if (isDevelopment) {
36
- tenantCode = Cookies.get('campx_tenant')
37
- if (
38
- tenantCode &&
39
- institutionCode &&
40
- window.location.pathname !== '/auth/login'
41
- ) {
42
- baseName = `/${institutionCode}`
43
- }
44
- } else {
45
- tenantCode = window.location.hostname.split('.')[0]
46
- if (institutionCode && window.location.pathname !== '/auth/login') {
47
- baseName = `/${institutionCode}`
48
- }
24
+ if (institutionCode && window.location.pathname !== '/auth/login') {
25
+ baseName = `/${institutionCode}`
49
26
  }
50
27
 
51
28
  useEffect(() => {
@@ -104,7 +104,7 @@ const useAuth = ({
104
104
 
105
105
  const appInit = async () => {
106
106
  try {
107
- const res = await axios.get(permissionsEndpoint)
107
+ const res = await axios.get(permissionsEndpoint, { workspace: false })
108
108
  const isAdmin = checkIsAdmin(res.data.user)
109
109
  setLoading(false)
110
110
  setData(res.data)