@campxdev/shared 1.10.42 → 1.10.46

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": "1.10.42",
3
+ "version": "1.10.46",
4
4
  "main": "./exports.ts",
5
5
  "scripts": {
6
6
  "start": "react-scripts start",
@@ -41,7 +41,7 @@ interface AppHeaderProps {
41
41
  onClick: any
42
42
  }[]
43
43
  customHeaderActions?: ReactNode
44
- cogWheelMenu?: { label: string; path: string }[]
44
+ cogWheelMenu?: { label: string; path: string; openNewTab?: boolean }[]
45
45
  }
46
46
 
47
47
  export default function AppHeader({
@@ -1,10 +1,10 @@
1
1
  import { SettingsOutlined } from '@mui/icons-material'
2
2
  import { IconButton } from '@mui/material'
3
- import { useHistory } from '../../../../hooks/useRouter'
3
+ import { useNavigate } from 'react-router-dom'
4
4
  import DropDownButton from '../../../DropDownButton/DropDownButton'
5
5
 
6
6
  const CogWheelMenu = ({ menu }) => {
7
- const history = useHistory()
7
+ const navigate = useNavigate()
8
8
 
9
9
  return (
10
10
  <DropDownButton
@@ -16,7 +16,9 @@ const CogWheelMenu = ({ menu }) => {
16
16
  menu={menu?.map((item) => ({
17
17
  label: item?.label,
18
18
  onClick: () => {
19
- history.push(item?.path)
19
+ item?.openNewTab
20
+ ? window.open(item?.path, '_blank')
21
+ : navigate(item?.path)
20
22
  },
21
23
  }))}
22
24
  menuProps={{
@@ -1,13 +1,9 @@
1
1
  import { Box, styled } from '@mui/material'
2
- import UserBox from './UserBox'
3
- import CogWheelMenu from './CogWheelMenu'
4
- import FreshDeskHelpButton from './FreshDeskHelpButton'
5
2
  import InstitutionsDropDown from '../../../Institutions/InstitutionsDropdown'
6
- import SearchButton from '../Search/SearchButton'
7
- import { NotificationsNoneOutlined } from '@mui/icons-material'
8
- import { useEffect } from 'react'
3
+ import CogWheelMenu from './CogWheelMenu'
4
+ import UserBox from './UserBox'
9
5
 
10
- const StyledBeamerBox = styled(Box)(() => ({
6
+ const StyledBeamedBox = styled(Box)(() => ({
11
7
  width: '60px',
12
8
  }))
13
9
 
@@ -21,7 +17,7 @@ export default function HeaderActions({
21
17
  <InstitutionsDropDown />
22
18
  {/* <SearchButton /> */}
23
19
  {/* <FreshDeskHelpButton /> */}
24
- <StyledBeamerBox></StyledBeamerBox>
20
+ <StyledBeamedBox></StyledBeamedBox>
25
21
  {cogWheelMenu?.length ? <CogWheelMenu menu={cogWheelMenu} /> : null}
26
22
  <UserBox fullName={fullName} actions={userBoxActions} />
27
23
  </>
@@ -15,13 +15,13 @@ import Cookies from 'js-cookie'
15
15
  import { useEffect, useState } from 'react'
16
16
  import { useForm } from 'react-hook-form'
17
17
  import { Link } from 'react-router-dom'
18
+ import { campxLogoPrimary } from '../assets/images'
18
19
  import axios from '../config/axios'
19
20
  import adminAxios from '../utils/adminAxios'
20
21
  import ActionButton from './ActionButton'
21
22
  import { FormTextField } from './HookForm'
22
- import ResetPassword from './ResetPassword'
23
23
  import Image from './Image/Image'
24
- import { campxLogoPrimary } from '../assets/images'
24
+ import ResetPassword from './ResetPassword'
25
25
 
26
26
  export function LoginForm({
27
27
  loginUrl,
@@ -43,7 +43,10 @@ export function LoginForm({
43
43
  method: 'POST',
44
44
  baseURL: process.env.REACT_APP_API_HOST,
45
45
  url: loginUrl ? loginUrl : `/auth-server/auth/login`,
46
- data: values,
46
+ data: {
47
+ ...values,
48
+ type: 'WEB',
49
+ },
47
50
  })
48
51
  Cookies.set('campx_tenant', res?.data?.subDomain)
49
52
  Cookies.set('campx_session_key', res.data?.token)
@@ -0,0 +1,301 @@
1
+ import {
2
+ Box,
3
+ Divider,
4
+ Table,
5
+ TableBody,
6
+ TableCell,
7
+ TableHead,
8
+ TableRow,
9
+ Typography,
10
+ } from '@mui/material'
11
+ import { StyledCardBorder } from './styles'
12
+
13
+ function FeeCard({ data, feeDetails }) {
14
+ const studentFirstPart = [
15
+ { label: 'Roll.No', value: data?.admission?.rollNo ?? '-' },
16
+ { label: 'Branch', value: data?.admission?.branchCode ?? '-' },
17
+ { label: 'Seat', value: data?.admission?.quota?.name ?? '-' },
18
+ { label: 'Student Mobile', value: data?.admission?.mobile ?? '-' },
19
+ ]
20
+
21
+ const studentSecondPart = [
22
+ { label: 'Name', value: data?.admission?.fullName ?? '-' },
23
+ {
24
+ label: 'Semester',
25
+ value: data?.admission?.detained
26
+ ? 'Detained'
27
+ : data?.admission?.discontinued
28
+ ? 'Discontinued'
29
+ : data?.admission?.semNo ?? '-',
30
+ },
31
+ {
32
+ label: 'ScholarShip',
33
+ value: data?.admission?.hasScholarship ? 'Yes' : 'No',
34
+ },
35
+ { label: 'Parent Mobile', value: data?.admission?.parentMobile ?? '-' },
36
+ ]
37
+
38
+ const totalLateFinesPaid = feeDetails?.map((row) => {
39
+ const latefines = row[1]?.map((latefee) => {
40
+ const fines = latefee?.debits?.reduce((acc, curr) => {
41
+ if (curr.isFine && curr.debit > 0) {
42
+ return acc + curr.debit
43
+ }
44
+ return acc
45
+ }, 0)
46
+ return fines
47
+ })
48
+ return latefines
49
+ })
50
+
51
+ const lateFines = feeDetails?.map((row) => {
52
+ const latefine = row[1]?.map((latefee) => {
53
+ const fines = latefee?.credits?.reduce((acc, curr) => {
54
+ if (curr.isFine && curr.credit > 0) {
55
+ return acc + curr.credit
56
+ }
57
+ return acc
58
+ }, 0)
59
+ return fines
60
+ })
61
+ return latefine
62
+ })
63
+
64
+ function amountDue(row: any) {
65
+ const debitTotal = row?.debits?.reduce((acc, curr) => {
66
+ if (!curr.isFine) {
67
+ acc += curr.debit
68
+ }
69
+ return acc
70
+ }, 0)
71
+
72
+ const creditTotal = row?.credits?.reduce((acc, curr) => {
73
+ if (!curr.isFine) {
74
+ acc += curr.credit
75
+ }
76
+ return acc
77
+ }, 0)
78
+
79
+ const difference = Math.abs(creditTotal - debitTotal)
80
+ return difference
81
+ }
82
+ return (
83
+ <StyledCardBorder>
84
+ <Box
85
+ className='school-details'
86
+ sx={{
87
+ display: 'flex',
88
+ flexDirection: 'column',
89
+ padding: '20px',
90
+ alignItems: 'center',
91
+ gap: '10px',
92
+ }}
93
+ >
94
+ <Box>
95
+ <img
96
+ src={data?.institution?.images?.url}
97
+ alt='school-logo'
98
+ width={'200px'}
99
+ />
100
+ </Box>
101
+
102
+ <Typography variant='h6' sx={{ fontSize: '22px' }}>
103
+ {data?.institution?.name}
104
+ </Typography>
105
+ <Typography variant='h6' textAlign={'center'} sx={{ fontSize: '16px' }}>
106
+ {data?.institution?.recognitionDetails}
107
+ </Typography>
108
+ <Typography variant='h6' textAlign={'center'} sx={{ fontSize: '16px' }}>
109
+ {data?.institution?.address}
110
+ </Typography>
111
+ </Box>
112
+ <Divider />
113
+ <Typography
114
+ variant='h6'
115
+ textAlign={'center'}
116
+ sx={{ margin: '10px', fontSize: '22px' }}
117
+ >
118
+ STUDENT FEE CARD
119
+ </Typography>
120
+ <Divider />
121
+ <Box
122
+ className='student-details'
123
+ sx={{
124
+ display: 'flex',
125
+ padding: '10px',
126
+ gap: '30px',
127
+ justifyContent: 'space-around',
128
+ }}
129
+ >
130
+ <Box sx={{ display: 'flex', gap: '22px' }}>
131
+ <Box>
132
+ {studentFirstPart?.map((item, index) => (
133
+ <Box key={index} sx={{ mt: '10px' }}>
134
+ <Typography variant='h6'>{item.label}</Typography>
135
+ </Box>
136
+ ))}
137
+ </Box>
138
+ <Box>
139
+ {studentFirstPart?.map((item, index) => (
140
+ <Box key={index} sx={{ mt: '10px' }}>
141
+ <Typography variant='subtitle1'>{item.value}</Typography>
142
+ </Box>
143
+ ))}
144
+ </Box>
145
+ </Box>
146
+
147
+ <Box sx={{ display: 'flex', gap: '12px' }}>
148
+ <Box>
149
+ {studentSecondPart?.map((item, index) => (
150
+ <Box key={index} sx={{ mt: '10px' }}>
151
+ <Typography variant='h6'>{item.label}</Typography>
152
+ </Box>
153
+ ))}
154
+ </Box>
155
+ <Box>
156
+ {studentSecondPart?.map((item, index) => (
157
+ <Box key={index} sx={{ mt: '10px' }}>
158
+ <Typography variant='subtitle1'>{item.value}</Typography>
159
+ </Box>
160
+ ))}
161
+ </Box>
162
+ </Box>
163
+
164
+ <img
165
+ src={data?.admission?.photo}
166
+ alt='student-photo'
167
+ width={'150px'}
168
+ height={'120px'}
169
+ />
170
+ </Box>
171
+
172
+ <Divider />
173
+
174
+ <Box>
175
+ <Table>
176
+ <TableHead>
177
+ <TableRow>
178
+ <TableCell>SI.No</TableCell>
179
+ <TableCell>Fee</TableCell>
180
+ <TableCell>Payable</TableCell>
181
+ <TableCell>Paid</TableCell>
182
+ <TableCell>Rec.No(s)</TableCell>
183
+ <TableCell>Rec.Date(s)</TableCell>
184
+ <TableCell>Bank Details</TableCell>
185
+ <TableCell>Due</TableCell>
186
+ <TableCell>Excess paid</TableCell>
187
+ </TableRow>
188
+ </TableHead>
189
+
190
+ {feeDetails?.map((fee, index) => (
191
+ <>
192
+ <TableRow>
193
+ <TableCell colSpan={9}>{fee[0]} Year</TableCell>
194
+ </TableRow>
195
+ <>
196
+ {fee[1]?.map((item, i) => (
197
+ <TableBody key={i}>
198
+ <TableCell>{i + 1}</TableCell>
199
+ <TableCell>{item.feeName}</TableCell>
200
+ <TableCell>
201
+ {item?.credits?.reduce((acc, curr) => {
202
+ if (!curr.isFine) {
203
+ acc = acc + curr.credit
204
+ }
205
+ return acc
206
+ }, 0)}
207
+ </TableCell>
208
+ <TableCell>
209
+ {item?.debits?.reduce((acc, curr) => {
210
+ if (!curr.isFine) {
211
+ acc = acc + curr.debit
212
+ }
213
+ return acc
214
+ }, 0)}
215
+ </TableCell>
216
+ <TableCell>{item?.receipts.join(', ')}</TableCell>
217
+ <TableCell>{item?.receiptDates?.join(', ')}</TableCell>
218
+ <TableCell>{item.bankDetails?.join(' ')}</TableCell>
219
+ <TableCell>
220
+ {amountDue(item)}
221
+ {lateFines[index][i] > 0 &&
222
+ totalLateFinesPaid[index][i] == 0 && (
223
+ <Typography variant='caption' color={'red'}>
224
+ {'(+' +
225
+ `${
226
+ lateFines[index][i] -
227
+ totalLateFinesPaid[index][i]
228
+ }` +
229
+ ' Late fee)'}
230
+ </Typography>
231
+ )}
232
+ </TableCell>
233
+ <TableCell>
234
+ {item?.debits?.reduce((acc, curr) => {
235
+ if (curr.isFine) {
236
+ acc = acc + curr.debit
237
+ }
238
+ return acc
239
+ }, 0)}
240
+ </TableCell>
241
+ </TableBody>
242
+ ))}
243
+ </>
244
+ <TableHead>
245
+ <TableRow>
246
+ <TableCell colSpan={2}>
247
+ <Typography variant='h6'>{fee[0]} year total</Typography>
248
+ </TableCell>
249
+ <TableCell>
250
+ <Typography variant='h6'>
251
+ {data?.totalFeesByYear[index]?.amount}
252
+ </Typography>
253
+ </TableCell>
254
+ <TableCell colSpan={4}>
255
+ <Typography variant='h6'>
256
+ {data?.totalFeesPaidByYear[index]?.amount}{' '}
257
+ </Typography>
258
+ </TableCell>
259
+ <TableCell>
260
+ <Typography variant='h6'>
261
+ {data?.totalFeesDueByYear[index]?.amount}
262
+ </Typography>
263
+ </TableCell>
264
+ <TableCell>
265
+ <Typography variant='h6'>
266
+ {data?.totalFeesExcessiveByYear[index]?.amount}
267
+ </Typography>
268
+ </TableCell>
269
+ </TableRow>
270
+ </TableHead>
271
+ </>
272
+ ))}
273
+
274
+ <TableHead>
275
+ <TableRow>
276
+ <TableCell colSpan={2}>
277
+ <Typography variant='h6'>Grand total</Typography>
278
+ </TableCell>
279
+ <TableCell>
280
+ <Typography variant='h6'>{data?.grandFeeTotal}</Typography>
281
+ </TableCell>
282
+ <TableCell colSpan={4}>
283
+ <Typography variant='h6'>{data?.grandFeePaidTotal} </Typography>
284
+ </TableCell>
285
+ <TableCell>
286
+ <Typography variant='h6'>{data?.grandFeeDueTotal}</Typography>
287
+ </TableCell>
288
+ <TableCell>
289
+ <Typography variant='h6'>
290
+ {data?.grandFeeExcessiveTotal}
291
+ </Typography>
292
+ </TableCell>
293
+ </TableRow>
294
+ </TableHead>
295
+ </Table>
296
+ </Box>
297
+ </StyledCardBorder>
298
+ )
299
+ }
300
+
301
+ export default FeeCard
@@ -0,0 +1,39 @@
1
+ import { Container } from '@mui/material'
2
+ import _ from 'lodash'
3
+ import { useQuery } from 'react-query'
4
+ import { useSearchParams } from 'react-router-dom'
5
+ import axios from '../../config/axios'
6
+ import Spinner from '../Spinner'
7
+ import FeeCard from './FeeCard'
8
+
9
+ function PrintStudentCard({ url }) {
10
+ const [search] = useSearchParams()
11
+ const { data, isLoading } = useQuery('print-student-card', () =>
12
+ axios
13
+ .get(url, {
14
+ params: {
15
+ id: search.get('id'),
16
+ idType: search.get('idType'),
17
+ },
18
+ })
19
+ .then((res) => res.data),
20
+ )
21
+
22
+ if (isLoading) return <Spinner />
23
+
24
+ const feeDetails = Object.entries(
25
+ _.groupBy(data?.feeDataResult, 'year'),
26
+ )?.map((item) => {
27
+ return item
28
+ })
29
+
30
+ return (
31
+ <>
32
+ <Container>
33
+ <FeeCard data={data} feeDetails={feeDetails} />
34
+ </Container>
35
+ </>
36
+ )
37
+ }
38
+
39
+ export default PrintStudentCard
@@ -0,0 +1 @@
1
+ export { default } from './PrintStudentCard'
@@ -0,0 +1,34 @@
1
+ import { Box, Typography, styled } from '@mui/material'
2
+
3
+ export const StyledCardBorder = styled(Box)(({ theme }) => ({
4
+ border: theme.borders.grayLight,
5
+ display: 'inline-block',
6
+ width: '100%',
7
+ height: 'auto',
8
+ }))
9
+
10
+ export const StyledSchoolHeader = styled(Box)(({ theme }) => ({
11
+ textAlign: 'center',
12
+ }))
13
+
14
+ export const StyledMainBox = styled(Box)({
15
+ display: 'flex',
16
+ marginTop: '30px',
17
+ gap: '10px',
18
+ alignItems: 'flex-end',
19
+ marginBottom: '20px',
20
+ })
21
+
22
+ export const StyledSearch = styled(Box)({
23
+ border: '1px solid #22222233 ',
24
+ padding: '7px',
25
+ maxHeight: '55px',
26
+ borderRadius: '10px',
27
+ width: '400px',
28
+ })
29
+ export const StyledSearchLabel = styled(Typography)({
30
+ fontSize: '14px',
31
+ fontWeight: 'bold',
32
+ margin: '0px 0px 3px 10px',
33
+ color: '#888888',
34
+ })
@@ -36,6 +36,7 @@ import { CustomDrawer } from './ModalButtons/DrawerButton'
36
36
  import ExcelJsonUpload from './ExcelToJsonInput/ExcelJsonUpload'
37
37
  import ExcelToJsonInput from './ExcelToJsonInput'
38
38
  import ApplicationProfile from './ApplicationProfile'
39
+ import PrintStudentCard from './StudentCard'
39
40
  import PopoverButton from './ModalButtons/PopoverButton'
40
41
  export { default as Image } from './Image'
41
42
  export { default as PageHeader } from './PageHeader'
@@ -101,6 +102,7 @@ export {
101
102
  ExcelJsonUpload,
102
103
  ExcelToJsonInput,
103
104
  ApplicationProfile,
105
+ PrintStudentCard,
104
106
  PopoverButton,
105
107
  }
106
108
 
@@ -685,6 +685,11 @@ export enum Permission {
685
685
  CAN_HOSTEL_TICKETS_DELETE = 'can_hostel_tickets_delete',
686
686
  CAN_HOSTEL_TICKETS_ADD = 'can_hostel_tickets_add',
687
687
 
688
+ // Hosteler attendence
689
+ CAN_HOSTELER_ATTENDANCE_VIEW = 'can_hosteler_attendance_view',
690
+ CAN_HOSTELER_ATTENDANCE_EDIT = 'can_hosteler_attendance_edit',
691
+ CAN_HOSTELER_ATTENDANCE_ADD = 'can_hosteler_attendance_add',
692
+
688
693
  // Square
689
694
  // manage
690
695