@campxdev/shared 1.8.4 → 1.8.5-0.alpha-2
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 +342 -0
- package/src/components/ApplicationProfile/Service.ts +68 -0
- package/src/components/ApplicationProfile/UserProfileRelation.tsx +174 -0
- package/src/components/ApplicationProfile/index.tsx +1 -0
- package/src/components/DropDownButton/DropdownMenuItem.tsx +12 -0
- package/src/components/ErrorBoundary/ErrorBoundary.tsx +8 -3
- package/src/components/ErrorBoundary/ErrorFallback.tsx +7 -2
- package/src/components/FloatingContainer.tsx +1 -1
- package/src/components/HookForm/MultiSelect.tsx +8 -0
- package/src/components/Input/DatePicker.tsx +11 -0
- package/src/components/Input/MultiSelect.tsx +11 -0
- package/src/components/Layout/Header/AppHeader.tsx +2 -1
- package/src/components/Layout/Header/AppsMenu.tsx +51 -23
- package/src/components/Layout/Header/HeaderActions/FreshChatButton.tsx +61 -0
- package/src/components/Layout/Header/HeaderActions/FreshDeskHelpButton.tsx +36 -7
- package/src/components/Layout/Header/HeaderActions/HeaderActions.tsx +2 -0
- package/src/components/Layout/Header/SchoolSwitch/SchoolSwitch.tsx +33 -0
- package/src/components/Layout/Header/applications.ts +8 -9
- package/src/components/Layout/Header/assets/chat_with_us.png +0 -0
- package/src/components/Layout/Header/assets/index.ts +2 -0
- package/src/components/Layout/Helmet.tsx +91 -32
- package/src/components/ModalButtons/PopoverButton.tsx +99 -0
- package/src/components/Tabs/TabsContainer.tsx +3 -0
- package/src/components/index.ts +4 -0
- package/src/config/axios.ts +8 -2
- package/src/constants/UIConstants.ts +27 -0
- package/src/contexts/LoginFormProvider.tsx +2 -7
- package/src/contexts/Providers.tsx +3 -1
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useAuth.ts +58 -2
- package/src/hooks/useExternalScript.ts +38 -0
- package/src/hooks/useFilters.ts +6 -3
- package/src/shared-state/PermissionsStore.ts +937 -130
- package/src/theme/muiTheme.ts +6 -4
- package/src/theme/theme.d.ts +2 -0
- package/tsconfig.json +19 -19
|
@@ -2,6 +2,7 @@ import { ReactNode } from 'react'
|
|
|
2
2
|
import { Controller } from 'react-hook-form'
|
|
3
3
|
import { MultiSelect } from '../Input'
|
|
4
4
|
import { IOption } from '../Input/types'
|
|
5
|
+
import { AutocompleteInputChangeReason } from '@mui/material'
|
|
5
6
|
|
|
6
7
|
interface MultiSelectProps {
|
|
7
8
|
control: any
|
|
@@ -10,6 +11,11 @@ interface MultiSelectProps {
|
|
|
10
11
|
options: IOption[]
|
|
11
12
|
placeholder?: string
|
|
12
13
|
loading?: boolean
|
|
14
|
+
onInputChange?: (
|
|
15
|
+
event: React.SyntheticEvent,
|
|
16
|
+
value: string,
|
|
17
|
+
reason: AutocompleteInputChangeReason,
|
|
18
|
+
) => void
|
|
13
19
|
required?: boolean
|
|
14
20
|
value?: IOption[] | IOption
|
|
15
21
|
onChange?: (value: IOption[] | IOption) => void
|
|
@@ -24,6 +30,7 @@ export default function FormMultiSelect({
|
|
|
24
30
|
loading,
|
|
25
31
|
required,
|
|
26
32
|
multiple = true,
|
|
33
|
+
onInputChange,
|
|
27
34
|
...props
|
|
28
35
|
}: MultiSelectProps) {
|
|
29
36
|
return (
|
|
@@ -39,6 +46,7 @@ export default function FormMultiSelect({
|
|
|
39
46
|
onChange={(value) => {
|
|
40
47
|
field.onChange(value)
|
|
41
48
|
}}
|
|
49
|
+
onInputChange={onInputChange}
|
|
42
50
|
loading={loading}
|
|
43
51
|
options={options || []}
|
|
44
52
|
error={!!error}
|
|
@@ -3,6 +3,7 @@ import { InputAdornment, TextFieldProps } from '@mui/material'
|
|
|
3
3
|
import 'flatpickr/dist/flatpickr.css'
|
|
4
4
|
import { ReactNode } from 'react'
|
|
5
5
|
import Flatpickr, { DateTimePickerProps } from 'react-flatpickr'
|
|
6
|
+
import monthSelectPlugin from 'flatpickr/dist/plugins/monthSelect'
|
|
6
7
|
import TextField from './TextField'
|
|
7
8
|
|
|
8
9
|
export interface IDatePicker {
|
|
@@ -17,8 +18,17 @@ export interface IDatePicker {
|
|
|
17
18
|
placeholder?: string
|
|
18
19
|
inputProps?: TextFieldProps
|
|
19
20
|
size?: 'medium' | 'small'
|
|
21
|
+
monthSelect?: boolean
|
|
20
22
|
}
|
|
21
23
|
|
|
24
|
+
const plugins = [
|
|
25
|
+
monthSelectPlugin({
|
|
26
|
+
shorthand: true, //defaults to false
|
|
27
|
+
dateFormat: 'm.y', //defaults to "F Y"
|
|
28
|
+
altFormat: 'F Y', //defaults to "F Y"
|
|
29
|
+
}),
|
|
30
|
+
]
|
|
31
|
+
|
|
22
32
|
export default function FormDatePicker({
|
|
23
33
|
name,
|
|
24
34
|
label,
|
|
@@ -29,6 +39,7 @@ export default function FormDatePicker({
|
|
|
29
39
|
placeholder,
|
|
30
40
|
size = 'medium',
|
|
31
41
|
required = false,
|
|
42
|
+
monthSelect,
|
|
32
43
|
...rest
|
|
33
44
|
}: IDatePicker) {
|
|
34
45
|
return (
|
|
@@ -2,6 +2,7 @@ import { Close, KeyboardArrowDown } from '@mui/icons-material'
|
|
|
2
2
|
import {
|
|
3
3
|
alpha,
|
|
4
4
|
Autocomplete,
|
|
5
|
+
AutocompleteInputChangeReason,
|
|
5
6
|
Checkbox,
|
|
6
7
|
CircularProgress,
|
|
7
8
|
Popper,
|
|
@@ -76,10 +77,16 @@ interface MultiSelectProps {
|
|
|
76
77
|
loading?: boolean
|
|
77
78
|
value: IOption[] | IOption
|
|
78
79
|
onChange: (value: IOption[] | IOption) => void
|
|
80
|
+
onInputChange?: (
|
|
81
|
+
event: React.SyntheticEvent,
|
|
82
|
+
value: string,
|
|
83
|
+
reason: AutocompleteInputChangeReason,
|
|
84
|
+
) => void
|
|
79
85
|
required?: boolean
|
|
80
86
|
error?: boolean
|
|
81
87
|
helperText?: string
|
|
82
88
|
multiple?: boolean
|
|
89
|
+
limitTags?: number
|
|
83
90
|
}
|
|
84
91
|
|
|
85
92
|
export default function MultiSelect({
|
|
@@ -89,10 +96,12 @@ export default function MultiSelect({
|
|
|
89
96
|
loading,
|
|
90
97
|
value,
|
|
91
98
|
onChange,
|
|
99
|
+
onInputChange,
|
|
92
100
|
required,
|
|
93
101
|
error,
|
|
94
102
|
helperText,
|
|
95
103
|
multiple = true,
|
|
104
|
+
limitTags = -1,
|
|
96
105
|
...props
|
|
97
106
|
}: MultiSelectProps) {
|
|
98
107
|
return (
|
|
@@ -107,6 +116,8 @@ export default function MultiSelect({
|
|
|
107
116
|
if (!onChange) return
|
|
108
117
|
onChange(value)
|
|
109
118
|
}}
|
|
119
|
+
onInputChange={onInputChange}
|
|
120
|
+
limitTags={limitTags}
|
|
110
121
|
isOptionEqualToValue={(option: any, value: any) =>
|
|
111
122
|
option?.value === value?.value
|
|
112
123
|
}
|
|
@@ -79,7 +79,8 @@ export default function AppHeader({
|
|
|
79
79
|
const AppLogo = ({ clientLogo }) => {
|
|
80
80
|
const originSubdomain = window.location.host.split('.')?.slice(-3)[0] ?? 'ums'
|
|
81
81
|
const currentApp =
|
|
82
|
-
applications.find((item) => item.
|
|
82
|
+
applications.find((item) => item.domainName === originSubdomain)
|
|
83
|
+
?.domainName ?? 'campx'
|
|
83
84
|
|
|
84
85
|
return (
|
|
85
86
|
<StyledRouterLink to={'/'}>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Box, Menu, Typography } from '@mui/material'
|
|
1
|
+
import { Box, Menu, Typography, styled } from '@mui/material'
|
|
2
2
|
import Cookies from 'js-cookie'
|
|
3
3
|
import { useState } from 'react'
|
|
4
4
|
import { applications } from './applications'
|
|
@@ -11,12 +11,17 @@ import {
|
|
|
11
11
|
StyledLink,
|
|
12
12
|
StyledImageBox,
|
|
13
13
|
} from './styles'
|
|
14
|
-
|
|
14
|
+
import { PermissionsStore } from '../../../shared-state'
|
|
15
|
+
import AppsOutageIcon from '@mui/icons-material/AppsOutage'
|
|
15
16
|
export const campxTenantKey = Cookies.get('campx_tenant')
|
|
16
17
|
|
|
17
18
|
const AppsMenu = () => {
|
|
19
|
+
const permissionState = PermissionsStore.useState((s) => s)
|
|
18
20
|
const [anchorEl, setAnchorEl] = useState<any>(null)
|
|
19
21
|
const open = Boolean(anchorEl)
|
|
22
|
+
const applicationList = applications?.filter((item) =>
|
|
23
|
+
permissionState.applications.includes(item.key),
|
|
24
|
+
)
|
|
20
25
|
|
|
21
26
|
const handleClick = (event) => {
|
|
22
27
|
setAnchorEl(event.currentTarget)
|
|
@@ -60,27 +65,40 @@ const AppsMenu = () => {
|
|
|
60
65
|
},
|
|
61
66
|
}}
|
|
62
67
|
>
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
<
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
68
|
+
{applicationList.length != 0 ? (
|
|
69
|
+
<>
|
|
70
|
+
<Box sx={{ padding: '0.3rem 1rem' }}>
|
|
71
|
+
<Typography variant="body2">Switch to</Typography>
|
|
72
|
+
</Box>
|
|
73
|
+
<Box>
|
|
74
|
+
{applicationList.map((item, index) => {
|
|
75
|
+
return (
|
|
76
|
+
<StyledLink
|
|
77
|
+
href={item.path + `/${campxTenantKey ?? ''}`}
|
|
78
|
+
key={index}
|
|
79
|
+
>
|
|
80
|
+
<StyledMenuItemContainer
|
|
81
|
+
key={index}
|
|
82
|
+
onClick={() => {
|
|
83
|
+
window.location.href = item.path
|
|
84
|
+
handleClose()
|
|
85
|
+
}}
|
|
86
|
+
>
|
|
87
|
+
<MenuItem data={item} />
|
|
88
|
+
</StyledMenuItemContainer>
|
|
89
|
+
</StyledLink>
|
|
90
|
+
)
|
|
91
|
+
})}
|
|
92
|
+
</Box>
|
|
93
|
+
</>
|
|
94
|
+
) : (
|
|
95
|
+
<StyledNoAppContainer>
|
|
96
|
+
<AppsOutageIcon sx={{ width: '40px', height: '40px' }} />
|
|
97
|
+
<Typography variant="subtitle1">
|
|
98
|
+
No Application have been assigned
|
|
99
|
+
</Typography>
|
|
100
|
+
</StyledNoAppContainer>
|
|
101
|
+
)}
|
|
84
102
|
</Menu>
|
|
85
103
|
</>
|
|
86
104
|
)
|
|
@@ -103,3 +121,13 @@ const MenuItem = ({ data }) => {
|
|
|
103
121
|
</StyledMenuItem>
|
|
104
122
|
)
|
|
105
123
|
}
|
|
124
|
+
|
|
125
|
+
const StyledNoAppContainer = styled(Box)({
|
|
126
|
+
width: '300px',
|
|
127
|
+
height: '300px',
|
|
128
|
+
display: 'flex',
|
|
129
|
+
alignItems: 'center',
|
|
130
|
+
flexDirection: 'column',
|
|
131
|
+
justifyContent: 'center',
|
|
132
|
+
gap: '10px',
|
|
133
|
+
})
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
import { useState } from 'react'
|
|
3
|
+
import { UserStore } from '../../../../shared-state'
|
|
4
|
+
import { chatWithUs } from '../assets'
|
|
5
|
+
import { Box, styled } from '@mui/material'
|
|
6
|
+
|
|
7
|
+
export default function FreshChatButton() {
|
|
8
|
+
const _window = window as any
|
|
9
|
+
const { user } = UserStore.useState()
|
|
10
|
+
|
|
11
|
+
var openWidget = function () {
|
|
12
|
+
const el = document.getElementById('fc_frame')
|
|
13
|
+
if (el) {
|
|
14
|
+
el.style.visibility = 'visible'
|
|
15
|
+
}
|
|
16
|
+
_window.fcWidget.open()
|
|
17
|
+
initEvents()
|
|
18
|
+
}
|
|
19
|
+
var initEvents = function () {
|
|
20
|
+
const el = document.getElementById('custom_fc_button')
|
|
21
|
+
_window.fcWidget.on('widget:opened', function (resp) {
|
|
22
|
+
if (el) {
|
|
23
|
+
el.style.visibility = 'hidden'
|
|
24
|
+
}
|
|
25
|
+
})
|
|
26
|
+
_window.fcWidget.on('widget:closed', function (resp) {
|
|
27
|
+
if (el) {
|
|
28
|
+
el.style.visibility = 'visible'
|
|
29
|
+
}
|
|
30
|
+
})
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (!user) return null
|
|
34
|
+
return (
|
|
35
|
+
<Box
|
|
36
|
+
id="custom_fc_button"
|
|
37
|
+
sx={{
|
|
38
|
+
position: 'fixed',
|
|
39
|
+
right: 0,
|
|
40
|
+
bottom: '18px',
|
|
41
|
+
cursor: 'pointer',
|
|
42
|
+
'@media print': {
|
|
43
|
+
display: 'none',
|
|
44
|
+
},
|
|
45
|
+
}}
|
|
46
|
+
>
|
|
47
|
+
<a id="open_fc_widget" onClick={openWidget} style={{ cursor: 'pointer' }}>
|
|
48
|
+
<StyledImg src={chatWithUs} />
|
|
49
|
+
</a>
|
|
50
|
+
</Box>
|
|
51
|
+
)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const StyledImg = styled('img')(({ theme }) => ({
|
|
55
|
+
width: '35px',
|
|
56
|
+
height: 'auto',
|
|
57
|
+
'&:hover': {
|
|
58
|
+
width: '50px',
|
|
59
|
+
},
|
|
60
|
+
transition: 'width 0.3s',
|
|
61
|
+
}))
|
|
@@ -1,21 +1,50 @@
|
|
|
1
1
|
import { HelpOutline } from '@mui/icons-material'
|
|
2
2
|
import { Button } from '@mui/material'
|
|
3
|
+
import { UserStore } from '../../../../shared-state'
|
|
3
4
|
|
|
4
5
|
export default function FreshDeskHelpButton() {
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
const { user } = UserStore.useState()
|
|
7
|
+
|
|
8
|
+
// const handleOpenFreshDeskWidget = () => {
|
|
9
|
+
// try {
|
|
10
|
+
// ;(window as any)?.openFreshDeskWidget()
|
|
11
|
+
// } catch (error) {
|
|
12
|
+
// // eslint-disable-next-line no-console
|
|
13
|
+
// console.error('Error launching Freshdesk')
|
|
14
|
+
// }
|
|
15
|
+
// }
|
|
16
|
+
|
|
17
|
+
const _window = window as any
|
|
18
|
+
|
|
19
|
+
var openWidget = function () {
|
|
20
|
+
const el = document.getElementById('fc_frame')
|
|
21
|
+
if (el) {
|
|
22
|
+
el.style.visibility = 'visible'
|
|
11
23
|
}
|
|
24
|
+
_window.fcWidget.open()
|
|
25
|
+
initEvents()
|
|
12
26
|
}
|
|
27
|
+
var initEvents = function () {
|
|
28
|
+
const el = document.getElementById('custom_fc_button')
|
|
29
|
+
_window.fcWidget.on('widget:opened', function (resp) {
|
|
30
|
+
if (el) {
|
|
31
|
+
el.style.visibility = 'hidden'
|
|
32
|
+
}
|
|
33
|
+
})
|
|
34
|
+
_window.fcWidget.on('widget:closed', function (resp) {
|
|
35
|
+
if (el) {
|
|
36
|
+
el.style.visibility = 'visible'
|
|
37
|
+
}
|
|
38
|
+
})
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (!user) return null
|
|
13
42
|
return (
|
|
14
43
|
<Button
|
|
15
44
|
variant="text"
|
|
16
45
|
color="secondary"
|
|
46
|
+
onClick={openWidget}
|
|
17
47
|
startIcon={<HelpOutline />}
|
|
18
|
-
onClick={handleOpenFreshDeskWidget}
|
|
19
48
|
sx={{ padding: '20px' }}
|
|
20
49
|
>
|
|
21
50
|
Help
|
|
@@ -2,6 +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 SchoolSwitch from '../SchoolSwitch/SchoolSwitch'
|
|
5
6
|
|
|
6
7
|
export default function HeaderActions({
|
|
7
8
|
cogWheelMenu,
|
|
@@ -10,6 +11,7 @@ export default function HeaderActions({
|
|
|
10
11
|
}) {
|
|
11
12
|
return (
|
|
12
13
|
<>
|
|
14
|
+
{/* <SchoolSwitch /> */}
|
|
13
15
|
<FreshDeskHelpButton />
|
|
14
16
|
{cogWheelMenu?.length ? <CogWheelMenu menu={cogWheelMenu} /> : null}
|
|
15
17
|
<UserBox fullName={fullName} actions={userBoxActions} />
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { useState } from 'react'
|
|
2
|
+
import { FormSingleSelect } from '../../../HookForm'
|
|
3
|
+
import { SingleSelect } from '../../../Input'
|
|
4
|
+
|
|
5
|
+
export default function SchoolSwitch() {
|
|
6
|
+
const [state, setStatr] = useState()
|
|
7
|
+
|
|
8
|
+
return (
|
|
9
|
+
<SingleSelect
|
|
10
|
+
containerProps={{
|
|
11
|
+
sx: {
|
|
12
|
+
width: '200px',
|
|
13
|
+
},
|
|
14
|
+
}}
|
|
15
|
+
options={[
|
|
16
|
+
{
|
|
17
|
+
label: 'School 1',
|
|
18
|
+
value: 'school1',
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
label: 'School 2',
|
|
22
|
+
value: 'school2',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
label: 'School 3',
|
|
26
|
+
value: 'school3',
|
|
27
|
+
},
|
|
28
|
+
]}
|
|
29
|
+
value={state}
|
|
30
|
+
onChange={(e) => setStatr(e.target.value)}
|
|
31
|
+
/>
|
|
32
|
+
)
|
|
33
|
+
}
|
|
@@ -45,12 +45,14 @@ export const applications = [
|
|
|
45
45
|
title: 'CollegeX',
|
|
46
46
|
path: isDevelopment ? origins.ums.dev : origins.ums.prod,
|
|
47
47
|
icon: campxSquareSmall,
|
|
48
|
-
key: '
|
|
48
|
+
key: 'square',
|
|
49
|
+
domainName: 'ums',
|
|
49
50
|
description: 'Manage Complete Campus Activities',
|
|
50
51
|
},
|
|
51
52
|
{
|
|
52
53
|
title: 'ExamX',
|
|
53
54
|
key: 'exams',
|
|
55
|
+
domainName: 'exams',
|
|
54
56
|
path: isDevelopment ? origins.exams.dev : origins.exams.prod,
|
|
55
57
|
icon: examsSmall,
|
|
56
58
|
description: 'Manage all Examinations in the Campus',
|
|
@@ -58,20 +60,23 @@ export const applications = [
|
|
|
58
60
|
{
|
|
59
61
|
title: 'PayX',
|
|
60
62
|
key: 'payments',
|
|
63
|
+
domainName: 'payments',
|
|
61
64
|
path: isDevelopment ? origins.payments.dev : origins.payments.prod,
|
|
62
65
|
icon: paySmall,
|
|
63
66
|
description: 'Manage Payments in the Campus',
|
|
64
67
|
},
|
|
65
68
|
{
|
|
66
69
|
title: 'EnrollX',
|
|
67
|
-
key: '
|
|
70
|
+
key: 'enroll_x',
|
|
71
|
+
domainName: 'enroll',
|
|
68
72
|
path: isDevelopment ? origins.enroll.dev : origins.enroll.prod,
|
|
69
73
|
icon: enrollSmall,
|
|
70
74
|
description: 'Manage Admissions in the Campus',
|
|
71
75
|
},
|
|
72
76
|
{
|
|
73
77
|
title: 'HostelX',
|
|
74
|
-
key: '
|
|
78
|
+
key: 'hostels',
|
|
79
|
+
domainName: 'hostel',
|
|
75
80
|
path: isDevelopment ? origins.hostel.dev : origins.hostel.prod,
|
|
76
81
|
icon: hostelSmall,
|
|
77
82
|
description: 'Manage Hostels in the Campus',
|
|
@@ -94,10 +99,4 @@ export const applications = [
|
|
|
94
99
|
},
|
|
95
100
|
]
|
|
96
101
|
: []),
|
|
97
|
-
// {
|
|
98
|
-
// title: 'EnrollX',
|
|
99
|
-
// path: '/hostel',
|
|
100
|
-
// icon: enrollHeaderLogo,
|
|
101
|
-
// // description: 'Manage Admissions in the Campus',
|
|
102
|
-
// },
|
|
103
102
|
]
|
|
Binary file
|
|
@@ -14,6 +14,7 @@ import commuteSmall from './commutexSmall.svg'
|
|
|
14
14
|
import commutex from './commutex.png'
|
|
15
15
|
import hostelx from './hostelx.png'
|
|
16
16
|
import enrollSmall from './enroll_logo.svg'
|
|
17
|
+
import chatWithUs from './chat_with_us.png'
|
|
17
18
|
|
|
18
19
|
export {
|
|
19
20
|
collegex,
|
|
@@ -32,4 +33,5 @@ export {
|
|
|
32
33
|
commutex,
|
|
33
34
|
commuteSmall,
|
|
34
35
|
enrollSmall,
|
|
36
|
+
chatWithUs,
|
|
35
37
|
}
|
|
@@ -1,49 +1,108 @@
|
|
|
1
|
+
import { ReactNode } from 'react'
|
|
1
2
|
import { Helmet as ReactHelmet } from 'react-helmet'
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
4
|
+
const isLocalHost = process.env.NODE_ENV === 'development'
|
|
5
|
+
|
|
6
|
+
const freshDeskInnerHtml = `
|
|
7
|
+
window.fwSettings = {
|
|
8
|
+
widget_id: 85000000149,
|
|
9
|
+
}
|
|
10
|
+
!(function () {
|
|
11
|
+
window.openFreshDeskWidget = function openFreshDeskWidget() {
|
|
12
|
+
FreshworksWidget('open', 'ticketForm')
|
|
13
|
+
}
|
|
14
|
+
if ('function' != typeof window.FreshworksWidget) {
|
|
15
|
+
var n = function () {
|
|
16
|
+
n.q.push(arguments)
|
|
17
|
+
}
|
|
18
|
+
;(n.q = []), (window.FreshworksWidget = n)
|
|
19
|
+
}
|
|
20
|
+
FreshworksWidget('hide', 'launcher')
|
|
21
|
+
})()
|
|
22
|
+
|
|
23
|
+
`
|
|
24
|
+
|
|
25
|
+
const getInnerHtml = (user: any) => {
|
|
26
|
+
if (isLocalHost) {
|
|
27
|
+
return ''
|
|
28
|
+
}
|
|
29
|
+
const fcWidgetMessengerConfig = {
|
|
30
|
+
config: {
|
|
31
|
+
headerProperty: {
|
|
32
|
+
hideChatButton: true,
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const phone = user?.mobile?.substring(user?.mobile?.length - 10)
|
|
38
|
+
|
|
39
|
+
return `
|
|
40
|
+
window.fcWidgetMessengerConfig = ${JSON.stringify(fcWidgetMessengerConfig)}
|
|
41
|
+
window.fcSettings = {
|
|
42
|
+
onInit: function() {
|
|
43
|
+
console.log('Fresh Chat Init')
|
|
44
|
+
window.fcWidget.setExternalId('${user?.email}')
|
|
45
|
+
window.fcWidget.user.setFirstName('${user?.fullName}')
|
|
46
|
+
window.fcWidget.user.setEmail('${user?.email}')
|
|
47
|
+
window.fcWidget.user.setPhone('${phone}')
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
`
|
|
52
|
+
}
|
|
5
53
|
|
|
6
54
|
interface IHelmetProps {
|
|
7
55
|
appTitle: string
|
|
8
56
|
favicon: string
|
|
9
57
|
description?: string
|
|
10
|
-
|
|
11
|
-
|
|
58
|
+
user: any
|
|
59
|
+
extraMetaTags?: ReactNode
|
|
12
60
|
}
|
|
13
61
|
|
|
14
62
|
export default function Helmet({
|
|
15
63
|
appTitle,
|
|
16
64
|
favicon,
|
|
17
65
|
description,
|
|
18
|
-
|
|
19
|
-
|
|
66
|
+
user,
|
|
67
|
+
extraMetaTags,
|
|
20
68
|
}: IHelmetProps) {
|
|
21
69
|
return (
|
|
22
|
-
<ReactHelmet
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
meta={
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
70
|
+
<ReactHelmet htmlAttributes={{ lang: 'en' }}>
|
|
71
|
+
<title>{appTitle}</title>
|
|
72
|
+
<meta charSet="utf-8" />
|
|
73
|
+
<meta name="description" content={description} />
|
|
74
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
75
|
+
{extraMetaTags}
|
|
76
|
+
<link rel="icon" href={favicon} />
|
|
77
|
+
<link rel="apple-touch-icon" href={favicon} />
|
|
78
|
+
{!isLocalHost && (
|
|
79
|
+
<script
|
|
80
|
+
type="text/javascript"
|
|
81
|
+
src="//in.fw-cdn.com/30814322/430238.js"
|
|
82
|
+
defer
|
|
83
|
+
/>
|
|
84
|
+
)}
|
|
85
|
+
{!isLocalHost && <script defer>{getInnerHtml(user)}</script>}
|
|
86
|
+
{/* {!isLocalHost && (
|
|
87
|
+
<script async defer>
|
|
88
|
+
{freshDeskInnerHtml}
|
|
89
|
+
</script>
|
|
90
|
+
)} */}
|
|
91
|
+
{/* {!isLocalHost && (
|
|
92
|
+
<script
|
|
93
|
+
type="text/javascript"
|
|
94
|
+
src="https://ind-widget.freshworks.com/widgets/85000000149.js"
|
|
95
|
+
defer
|
|
96
|
+
></script>
|
|
97
|
+
)} */}
|
|
98
|
+
<style type="text/css">
|
|
99
|
+
{`
|
|
100
|
+
#fc_frame {
|
|
101
|
+
bottom: 0 !important;
|
|
102
|
+
right: 0 !important;
|
|
103
|
+
}
|
|
104
|
+
`}
|
|
105
|
+
</style>
|
|
106
|
+
</ReactHelmet>
|
|
48
107
|
)
|
|
49
108
|
}
|