@campxdev/react-blueprint 0.1.53 → 0.1.55
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 +2 -2
- package/src/App.tsx +1 -0
- package/src/components/Feedback/Tutorial/Tutorial.tsx +1 -1
- package/src/components/Image/Image.tsx +45 -0
- package/src/components/Layout/AppHeader/AppHeader.tsx +12 -6
- package/src/components/Layout/AppHeader/AppHeaderActions/SwitchInstitution.tsx +100 -0
- package/src/components/Layout/AppHeader/AppHeaderActions/UserBox.tsx +97 -64
- package/src/utils/constants.ts +1 -4
- package/src/utils/logout.ts +22 -0
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@campxdev/react-blueprint",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.55",
|
|
4
4
|
"main": "./export.ts",
|
|
5
5
|
"private": false,
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@campxdev/campx-web-utils": "
|
|
7
|
+
"@campxdev/campx-web-utils": "0.1.5",
|
|
8
8
|
"@emotion/react": "^11.11.4",
|
|
9
9
|
"@emotion/styled": "^11.11.5",
|
|
10
10
|
"@mui/icons-material": "^5.15.20",
|
package/src/App.tsx
CHANGED
|
@@ -68,7 +68,7 @@ export const Tutorial = ({
|
|
|
68
68
|
JSON.stringify([...JSON.parse(userTours), tourName])
|
|
69
69
|
);
|
|
70
70
|
}
|
|
71
|
-
await axios.post("/square/tours/complete", {
|
|
71
|
+
await axios.post("/square/tours/complete", { reqData });
|
|
72
72
|
} catch (error) {
|
|
73
73
|
console.error("Error completing the tour:", error);
|
|
74
74
|
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Box } from "@mui/material";
|
|
2
|
+
// const brokenImage = require("./broken-image.png");
|
|
3
|
+
|
|
4
|
+
interface ImageProps {
|
|
5
|
+
src: string;
|
|
6
|
+
alt: string;
|
|
7
|
+
height: string | number;
|
|
8
|
+
width: string | number;
|
|
9
|
+
fit?: "cover" | "contain" | "fill";
|
|
10
|
+
radius?: string | number;
|
|
11
|
+
defaultImage?: any;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export default function Image({
|
|
15
|
+
src,
|
|
16
|
+
alt,
|
|
17
|
+
height,
|
|
18
|
+
width,
|
|
19
|
+
fit = "contain",
|
|
20
|
+
radius = "10px",
|
|
21
|
+
defaultImage = null,
|
|
22
|
+
}: ImageProps) {
|
|
23
|
+
return (
|
|
24
|
+
<Box
|
|
25
|
+
sx={{
|
|
26
|
+
height: height,
|
|
27
|
+
width: width,
|
|
28
|
+
"& > img": {
|
|
29
|
+
borderRadius: radius,
|
|
30
|
+
width: "100%",
|
|
31
|
+
height: "100%",
|
|
32
|
+
objectFit: fit,
|
|
33
|
+
},
|
|
34
|
+
}}
|
|
35
|
+
>
|
|
36
|
+
<img
|
|
37
|
+
src={src || defaultImage}
|
|
38
|
+
alt={alt}
|
|
39
|
+
onError={(e: any) => {
|
|
40
|
+
e.target.src = defaultImage ? defaultImage : "";
|
|
41
|
+
}}
|
|
42
|
+
/>
|
|
43
|
+
</Box>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
@@ -14,6 +14,7 @@ export interface AppHeaderProps {
|
|
|
14
14
|
userFullName: string;
|
|
15
15
|
designation?: string;
|
|
16
16
|
collapsed: boolean;
|
|
17
|
+
institutionsData?: any[];
|
|
17
18
|
profileSx?: any;
|
|
18
19
|
showActiveDevices?: boolean;
|
|
19
20
|
}
|
|
@@ -26,22 +27,27 @@ export const AppHeader = ({
|
|
|
26
27
|
clientName,
|
|
27
28
|
userFullName,
|
|
28
29
|
collapsed,
|
|
30
|
+
institutionsData,
|
|
29
31
|
showActiveDevices = true,
|
|
30
32
|
}: AppHeaderProps) => {
|
|
31
33
|
return (
|
|
32
34
|
<StyledHeader collapsed={collapsed} className="appHeader">
|
|
33
35
|
<Typography variant={"subtitle2"}>{clientName}</Typography>
|
|
34
36
|
<Stack alignItems={"center"} gap={"12px"} flexDirection={"row"}>
|
|
35
|
-
<StyledIconButton
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
37
|
+
<StyledIconButton>
|
|
38
|
+
<a
|
|
39
|
+
href={"https://campx.atlassian.net/servicedesk/customer/portal/2"}
|
|
40
|
+
target="_blank"
|
|
41
|
+
rel="noreferrer"
|
|
42
|
+
style={{ textDecoration: "none" }}
|
|
43
|
+
>
|
|
44
|
+
<HelpIcon size={20} />
|
|
45
|
+
</a>
|
|
41
46
|
</StyledIconButton>
|
|
42
47
|
<UserBox
|
|
43
48
|
fullName={userFullName}
|
|
44
49
|
actions={[]}
|
|
50
|
+
institutionsData={institutionsData}
|
|
45
51
|
profileSx={profileSx}
|
|
46
52
|
designation={designation}
|
|
47
53
|
showActiveDevices={showActiveDevices}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { Box, Stack, TextField, Typography, styled } from "@mui/material";
|
|
2
|
+
import Cookies from "js-cookie";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { isDevelopment } from "../../../../utils/constants";
|
|
5
|
+
import Image from "../../../Image/Image";
|
|
6
|
+
|
|
7
|
+
const SwitchInstitution = ({ close, institutions }: any) => {
|
|
8
|
+
const [searchText, setSearchText] = useState<string>("");
|
|
9
|
+
|
|
10
|
+
const filteredInstitutions = institutions?.filter((item: any) =>
|
|
11
|
+
item.name.toLowerCase().includes(searchText.toLowerCase())
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<Box sx={{ padding: "20px" }}>
|
|
16
|
+
<Stack>
|
|
17
|
+
<Typography variant="subtitle3" textAlign={"center"}>
|
|
18
|
+
Select an Institution
|
|
19
|
+
</Typography>
|
|
20
|
+
|
|
21
|
+
<TextField
|
|
22
|
+
label="Search Institution"
|
|
23
|
+
variant="outlined"
|
|
24
|
+
value={searchText}
|
|
25
|
+
sx={{
|
|
26
|
+
display: "flex",
|
|
27
|
+
alignItems: "center",
|
|
28
|
+
}}
|
|
29
|
+
fullWidth
|
|
30
|
+
onChange={(e) => setSearchText(e.target.value)}
|
|
31
|
+
/>
|
|
32
|
+
</Stack>
|
|
33
|
+
<StyledInstitutionContainer>
|
|
34
|
+
{filteredInstitutions?.map((item: any, index: number) => (
|
|
35
|
+
<InstitutionCard institution={item} key={index} />
|
|
36
|
+
))}
|
|
37
|
+
</StyledInstitutionContainer>
|
|
38
|
+
</Box>
|
|
39
|
+
);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const InstitutionCard = ({ institution }: any) => {
|
|
43
|
+
const handleClick = () => {
|
|
44
|
+
if (isDevelopment) {
|
|
45
|
+
Cookies.set("campx_institution", institution?.code);
|
|
46
|
+
} else {
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
window.location.replace(`${window.location.origin}/${institution?.code}`);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
return (
|
|
53
|
+
<StyledInstitutionCard onClick={handleClick}>
|
|
54
|
+
<Image
|
|
55
|
+
alt="logo"
|
|
56
|
+
height={"100px"}
|
|
57
|
+
width="100%"
|
|
58
|
+
src={institution?.imageSquare?.url}
|
|
59
|
+
/>
|
|
60
|
+
<Typography variant="body2">{institution?.name}</Typography>
|
|
61
|
+
</StyledInstitutionCard>
|
|
62
|
+
);
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const StyledInstitutionCard = styled(Box)(({ theme }) => ({
|
|
66
|
+
display: "flex",
|
|
67
|
+
flexDirection: "column",
|
|
68
|
+
alignItems: "center",
|
|
69
|
+
gap: "20px",
|
|
70
|
+
padding: "14px",
|
|
71
|
+
border: "1px solid black",
|
|
72
|
+
borderRadius: "10px",
|
|
73
|
+
cursor: "pointer",
|
|
74
|
+
width: "200px",
|
|
75
|
+
flexShrink: 0,
|
|
76
|
+
}));
|
|
77
|
+
|
|
78
|
+
export const StyledInstitutionContainer = styled(Box)(({ theme }) => ({
|
|
79
|
+
marginTop: "20px",
|
|
80
|
+
display: "flex",
|
|
81
|
+
justifyContent: "center",
|
|
82
|
+
padding: "20px",
|
|
83
|
+
flexWrap: "wrap",
|
|
84
|
+
gap: "20px",
|
|
85
|
+
"&::-webkit-scrollbar": {
|
|
86
|
+
width: "0.5em",
|
|
87
|
+
height: "0.5em",
|
|
88
|
+
backgroundColor: "rgba(0, 0, 0, 0.1)",
|
|
89
|
+
},
|
|
90
|
+
"&::-webkit-scrollbar-thumb": {
|
|
91
|
+
backgroundColor: "rgba(0, 0, 0, 0.2)",
|
|
92
|
+
borderRadius: "3px",
|
|
93
|
+
|
|
94
|
+
"&:hover": {
|
|
95
|
+
background: "rgba(0, 0, 0, 0.3)",
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
}));
|
|
99
|
+
|
|
100
|
+
export default SwitchInstitution;
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
import { Avatar, Stack, Typography, useTheme } from "@mui/material";
|
|
1
|
+
import { Avatar, Box, Stack, Typography, useTheme } from "@mui/material";
|
|
2
2
|
import { ReactNode } from "react";
|
|
3
|
+
import logout from "../../../../utils/logout";
|
|
4
|
+
import DialogButton from "../../../Navigation/DialogButton/DialogButton";
|
|
3
5
|
import { DropdownMenu } from "../../../Navigation/DropDownMenu/DropDownMenu";
|
|
4
6
|
import { DropdownMenuItem } from "../../../Navigation/DropDownMenu/DropdownMenuItem";
|
|
7
|
+
import { StyledMenuItem } from "../../../Navigation/DropDownMenu/styles";
|
|
5
8
|
import { Icons } from "../../../export";
|
|
9
|
+
import SwitchInstitution from "./SwitchInstitution";
|
|
6
10
|
|
|
7
11
|
const getStartingLetters = (text: string) => {
|
|
8
12
|
if (!text) return "";
|
|
@@ -18,12 +22,14 @@ export default function UserBox({
|
|
|
18
22
|
actions,
|
|
19
23
|
profileUrl,
|
|
20
24
|
profileSx = {},
|
|
25
|
+
institutionsData,
|
|
21
26
|
avatar = true, // Make avatar optional, default to true
|
|
22
27
|
navigationIcon = true, // Make navigationIcon optional, default to true
|
|
23
28
|
showActiveDevices = true, // Make active devices optional, default to true
|
|
24
29
|
}: {
|
|
25
30
|
fullName: string;
|
|
26
31
|
designation?: string;
|
|
32
|
+
institutionsData?: any[];
|
|
27
33
|
actions: {
|
|
28
34
|
label: ReactNode;
|
|
29
35
|
icon?: ReactNode;
|
|
@@ -39,75 +45,102 @@ export default function UserBox({
|
|
|
39
45
|
const theme = useTheme();
|
|
40
46
|
|
|
41
47
|
return (
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
{
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
<
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
<
|
|
67
|
-
{
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
<Stack>
|
|
71
|
-
<
|
|
72
|
-
|
|
48
|
+
<>
|
|
49
|
+
<DropdownMenu
|
|
50
|
+
anchor={({ open }) => (
|
|
51
|
+
<Avatar src={profileUrl ?? ""} onClick={open} sx={profileSx}>
|
|
52
|
+
{getStartingLetters(fullName)}
|
|
53
|
+
</Avatar>
|
|
54
|
+
)}
|
|
55
|
+
menuListProps={{
|
|
56
|
+
sx: {
|
|
57
|
+
width: "300px",
|
|
58
|
+
borderRadius: "5px",
|
|
59
|
+
},
|
|
60
|
+
}}
|
|
61
|
+
menu={[
|
|
62
|
+
<DropdownMenuItem
|
|
63
|
+
label={
|
|
64
|
+
<Stack gap={0.5} sx={{ width: "100%" }}>
|
|
65
|
+
<Typography variant="subtitle3">Account</Typography>
|
|
66
|
+
<Stack
|
|
67
|
+
direction={"row"}
|
|
68
|
+
alignItems={"center"}
|
|
69
|
+
justifyContent={"space-between"}
|
|
70
|
+
>
|
|
71
|
+
{avatar && (
|
|
72
|
+
<Stack direction={"row"} gap={1}>
|
|
73
|
+
<Avatar src={profileUrl ?? ""} sx={profileSx}>
|
|
74
|
+
{getStartingLetters(fullName)}
|
|
75
|
+
</Avatar>
|
|
76
|
+
<Stack direction={"row"} justifyContent={"space-between"}>
|
|
77
|
+
<Stack>
|
|
78
|
+
<Typography variant="subtitle3">
|
|
79
|
+
{fullName}
|
|
80
|
+
</Typography>
|
|
81
|
+
<Typography variant="caption">
|
|
82
|
+
{designation}
|
|
83
|
+
</Typography>
|
|
84
|
+
</Stack>
|
|
73
85
|
</Stack>
|
|
74
86
|
</Stack>
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
87
|
+
)}
|
|
88
|
+
{navigationIcon && <Icons.NavigationIcon />}
|
|
89
|
+
</Stack>
|
|
78
90
|
</Stack>
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
91
|
+
}
|
|
92
|
+
onClick={() => console.log("Action 1 clicked")}
|
|
93
|
+
/>,
|
|
94
|
+
showActiveDevices && (
|
|
95
|
+
<DropdownMenuItem
|
|
96
|
+
label={
|
|
97
|
+
<Stack gap={0.5}>
|
|
98
|
+
<Typography variant="subtitle3">Active Devices</Typography>
|
|
99
|
+
</Stack>
|
|
100
|
+
}
|
|
101
|
+
onClick={() => alert("Action 1 clicked")}
|
|
102
|
+
/>
|
|
103
|
+
),
|
|
104
|
+
<Box>
|
|
105
|
+
<DialogButton
|
|
106
|
+
anchor={({ open }) => (
|
|
107
|
+
<StyledMenuItem
|
|
108
|
+
onClick={() => {
|
|
109
|
+
open();
|
|
110
|
+
}}
|
|
111
|
+
>
|
|
112
|
+
Change Institution
|
|
113
|
+
</StyledMenuItem>
|
|
114
|
+
)}
|
|
115
|
+
content={({ close }) => (
|
|
116
|
+
<SwitchInstitution
|
|
117
|
+
close={close}
|
|
118
|
+
institutions={institutionsData}
|
|
119
|
+
/>
|
|
120
|
+
)}
|
|
121
|
+
title=""
|
|
122
|
+
/>
|
|
123
|
+
</Box>,
|
|
124
|
+
|
|
84
125
|
<DropdownMenuItem
|
|
85
126
|
label={
|
|
86
|
-
<Stack
|
|
87
|
-
|
|
127
|
+
<Stack
|
|
128
|
+
gap={0.5}
|
|
129
|
+
direction={"row"}
|
|
130
|
+
justifyContent={"space-between"}
|
|
131
|
+
width={"100%"}
|
|
132
|
+
>
|
|
133
|
+
<Typography variant="subtitle3">Logout</Typography>
|
|
134
|
+
<Icons.LogoutIcon
|
|
135
|
+
hoverColor={theme.palette.tertiary.main}
|
|
136
|
+
size={20}
|
|
137
|
+
/>
|
|
88
138
|
</Stack>
|
|
89
139
|
}
|
|
90
|
-
onClick={
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
<Stack
|
|
96
|
-
gap={0.5}
|
|
97
|
-
direction={"row"}
|
|
98
|
-
justifyContent={"space-between"}
|
|
99
|
-
width={"100%"}
|
|
100
|
-
>
|
|
101
|
-
<Typography variant="subtitle3">Logout</Typography>
|
|
102
|
-
<Icons.LogoutIcon
|
|
103
|
-
hoverColor={theme.palette.tertiary.main}
|
|
104
|
-
size={20}
|
|
105
|
-
/>
|
|
106
|
-
</Stack>
|
|
107
|
-
}
|
|
108
|
-
onClick={() => alert("Action 1 clicked")}
|
|
109
|
-
/>,
|
|
110
|
-
]}
|
|
111
|
-
/>
|
|
140
|
+
onClick={logout}
|
|
141
|
+
/>,
|
|
142
|
+
]}
|
|
143
|
+
/>
|
|
144
|
+
</>
|
|
112
145
|
);
|
|
113
146
|
}
|
package/src/utils/constants.ts
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import Cookies from "js-cookie";
|
|
2
2
|
|
|
3
|
-
export const isDevelopment: boolean =
|
|
4
|
-
process.env.NODE_ENV === "development" ||
|
|
5
|
-
window.location.origin.split("campx")[1] === ".dev";
|
|
6
|
-
|
|
3
|
+
export const isDevelopment: boolean = process.env.NODE_ENV === "development";
|
|
7
4
|
export const urlTenantKey = window.location.pathname.split("/")[1];
|
|
8
5
|
export const institutionKey = window.location.pathname.split("/")[2];
|
|
9
6
|
export const sessionKey = Cookies.get("campx_session_key");
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// import axios, {
|
|
2
|
+
// axiosErrorToast,
|
|
3
|
+
// } from "@campxdev/campx-web-utils/src/config/axios";
|
|
4
|
+
import { axios } from "@campxdev/campx-web-utils";
|
|
5
|
+
import Cookies from "js-cookie";
|
|
6
|
+
|
|
7
|
+
export default function logout() {
|
|
8
|
+
axios({
|
|
9
|
+
method: "POST",
|
|
10
|
+
baseURL: process.env.REACT_APP_API_HOST,
|
|
11
|
+
url: "/auth-server/auth/logout",
|
|
12
|
+
})
|
|
13
|
+
.then((res) => {
|
|
14
|
+
Cookies.remove("campx_tenant");
|
|
15
|
+
Cookies.remove("campx_session_key");
|
|
16
|
+
Cookies.remove("campx_institution");
|
|
17
|
+
window.location.href = "/";
|
|
18
|
+
})
|
|
19
|
+
.catch((err) => {
|
|
20
|
+
// toast("Unable To Logout.");
|
|
21
|
+
});
|
|
22
|
+
}
|