@campxdev/react-blueprint 0.1.42 → 0.1.43
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 +6 -4
- package/src/components/Assets/Icons/IconComponents/ToursIcon.tsx +68 -0
- package/src/components/Assets/Icons/Icons.tsx +2 -0
- package/src/components/Feedback/Tutorial/Tutorial.tsx +113 -0
- package/src/components/Feedback/exports.ts +1 -0
- package/src/stories/Feedback/Tutorial.stories.tsx +56 -0
- package/src/themes/commonTheme.ts +1 -2
- /package/src/stories/{Layout → Navigation}/FloatingSidebar.stories.tsx +0 -0
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@campxdev/react-blueprint",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.43",
|
|
4
4
|
"main": "./export.ts",
|
|
5
5
|
"private": false,
|
|
6
6
|
"dependencies": {
|
|
7
|
+
"@campxdev/campx-web-utils": "^0.1.3",
|
|
7
8
|
"@emotion/react": "^11.11.4",
|
|
8
9
|
"@emotion/styled": "^11.11.5",
|
|
9
10
|
"@mui/icons-material": "^5.15.20",
|
|
@@ -11,9 +12,6 @@
|
|
|
11
12
|
"@mui/x-data-grid": "^7.5.1",
|
|
12
13
|
"@storybook/addon-backgrounds": "^8.1.5",
|
|
13
14
|
"@storybook/addon-designs": "^8.0.2",
|
|
14
|
-
"axios": "^1.7.2",
|
|
15
|
-
"framer-motion": "^11.2.9",
|
|
16
|
-
"js-cookie": "^3.0.5",
|
|
17
15
|
"@testing-library/jest-dom": "^5.14.1",
|
|
18
16
|
"@testing-library/react": "^13.0.0",
|
|
19
17
|
"@testing-library/user-event": "^13.2.1",
|
|
@@ -22,11 +20,15 @@
|
|
|
22
20
|
"@types/react": "^18.0.0",
|
|
23
21
|
"@types/react-dom": "^18.3.0",
|
|
24
22
|
"@types/react-router-dom": "^5.3.3",
|
|
23
|
+
"axios": "^1.7.2",
|
|
24
|
+
"framer-motion": "^11.2.9",
|
|
25
|
+
"js-cookie": "^3.0.5",
|
|
25
26
|
"lodash": "^4.17.21",
|
|
26
27
|
"pullstate": "^1.24.0",
|
|
27
28
|
"react": "^18.3.1",
|
|
28
29
|
"react-dom": "^18.3.1",
|
|
29
30
|
"react-error-boundary": "^3.1.4",
|
|
31
|
+
"react-joyride": "^2.8.2",
|
|
30
32
|
"react-router-dom": "^6.24.0",
|
|
31
33
|
"react-scripts": "^5.0.1",
|
|
32
34
|
"storybook-dark-mode": "^4.0.1",
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
export const ToursIcon = () => {
|
|
2
|
+
return (
|
|
3
|
+
<svg
|
|
4
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
5
|
+
width="118"
|
|
6
|
+
height="118"
|
|
7
|
+
viewBox="0 0 118 118"
|
|
8
|
+
>
|
|
9
|
+
<defs>
|
|
10
|
+
<filter
|
|
11
|
+
id="Rectangle_24558"
|
|
12
|
+
x="0"
|
|
13
|
+
y="0"
|
|
14
|
+
width="118"
|
|
15
|
+
height="118"
|
|
16
|
+
filterUnits="userSpaceOnUse"
|
|
17
|
+
>
|
|
18
|
+
<feOffset dx="6" dy="6" />
|
|
19
|
+
<feGaussianBlur stdDeviation="8" result="blur" />
|
|
20
|
+
<feFlood flood-opacity="0.059" />
|
|
21
|
+
<feComposite operator="in" in2="blur" />
|
|
22
|
+
<feComposite in="SourceGraphic" />
|
|
23
|
+
</filter>
|
|
24
|
+
</defs>
|
|
25
|
+
<g
|
|
26
|
+
id="Group_9777"
|
|
27
|
+
data-name="Group 9777"
|
|
28
|
+
transform="translate(-1822 -982)"
|
|
29
|
+
>
|
|
30
|
+
<g
|
|
31
|
+
id="Group_9776"
|
|
32
|
+
data-name="Group 9776"
|
|
33
|
+
transform="translate(1840 1000)"
|
|
34
|
+
>
|
|
35
|
+
<g
|
|
36
|
+
transform="matrix(1, 0, 0, 1, -18, -18)"
|
|
37
|
+
filter="url(#Rectangle_24558)"
|
|
38
|
+
>
|
|
39
|
+
<rect
|
|
40
|
+
id="Rectangle_24558-2"
|
|
41
|
+
data-name="Rectangle 24558"
|
|
42
|
+
width="70"
|
|
43
|
+
height="70"
|
|
44
|
+
rx="35"
|
|
45
|
+
transform="translate(18 18)"
|
|
46
|
+
fill="#fff"
|
|
47
|
+
/>
|
|
48
|
+
</g>
|
|
49
|
+
<rect
|
|
50
|
+
id="Rectangle_24559"
|
|
51
|
+
data-name="Rectangle 24559"
|
|
52
|
+
width="54"
|
|
53
|
+
height="54"
|
|
54
|
+
rx="27"
|
|
55
|
+
transform="translate(8 8)"
|
|
56
|
+
fill="#d0d0e3"
|
|
57
|
+
/>
|
|
58
|
+
</g>
|
|
59
|
+
<path
|
|
60
|
+
id="sun"
|
|
61
|
+
d="M4.914,11.712a.971.971,0,0,0-.971-.971H2.971a.971.971,0,0,0,0,1.942h.971A.971.971,0,0,0,4.914,11.712Zm.622,4.856-.69.69a.968.968,0,0,0,1.369,1.369l.69-.69a.971.971,0,0,0-1.369-1.369ZM11.712,4.914a.971.971,0,0,0,.971-.971V2.971a.971.971,0,0,0-1.942,0v.971A.971.971,0,0,0,11.712,4.914Zm5.5,2.273a.971.971,0,0,0,.68-.282l.69-.69a.971.971,0,1,0-1.369-1.369l-.641.69a.967.967,0,0,0,.641,1.651ZM5.555,6.9A.968.968,0,0,0,6.924,5.535l-.69-.69A.975.975,0,0,0,4.846,6.215Zm14.9,3.836h-.971a.971.971,0,0,0,0,1.942h.971a.971.971,0,0,0,0-1.942Zm-2.564,5.827a.971.971,0,0,0-1.321,1.321l.69.69a.968.968,0,1,0,1.369-1.369ZM11.712,6.37a5.342,5.342,0,1,0,5.342,5.342A5.342,5.342,0,0,0,11.712,6.37Zm0,8.741a3.4,3.4,0,1,1,3.4-3.4,3.4,3.4,0,0,1-3.4,3.4Zm0,3.4a.971.971,0,0,0-.971.971v.971a.971.971,0,0,0,1.942,0v-.971A.971.971,0,0,0,11.712,18.51Z"
|
|
62
|
+
transform="translate(1863.288 1023.288)"
|
|
63
|
+
fill="#323167"
|
|
64
|
+
/>
|
|
65
|
+
</g>
|
|
66
|
+
</svg>
|
|
67
|
+
);
|
|
68
|
+
};
|
|
@@ -33,6 +33,7 @@ import { ProductFeaturesIcon } from "./IconComponents/ProductFeaturesIcon";
|
|
|
33
33
|
import { ProfileIcon } from "./IconComponents/ProfileIcon";
|
|
34
34
|
import { RightIcon } from "./IconComponents/RightIcon";
|
|
35
35
|
import { TicketsIcon } from "./IconComponents/TicketsIcon";
|
|
36
|
+
import { ToursIcon } from "./IconComponents/ToursIcon";
|
|
36
37
|
import { UnCheckedCheckboxIcon } from "./IconComponents/UncheckCheckBoxIcon";
|
|
37
38
|
import { UnCheckedRadioIcon } from "./IconComponents/UncheckedRadioIcon";
|
|
38
39
|
import { Union4Icon } from "./IconComponents/Union4Icon";
|
|
@@ -78,4 +79,5 @@ export const Icons = {
|
|
|
78
79
|
ExamxIcon,
|
|
79
80
|
Union4Icon,
|
|
80
81
|
XIcon,
|
|
82
|
+
ToursIcon,
|
|
81
83
|
};
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { axios } from "@campxdev/campx-web-utils";
|
|
2
|
+
import { IconButton } from "@mui/material";
|
|
3
|
+
import { ReactNode, useEffect, useState, useCallback } from "react";
|
|
4
|
+
import ReactJoyride, { Step, CallBackProps, ACTIONS } from "react-joyride";
|
|
5
|
+
import { ToursIcon } from "../../Assets/Icons/IconComponents/ToursIcon";
|
|
6
|
+
import { Tooltip } from "../Tooltip/Tooltip";
|
|
7
|
+
import { Typography } from "../../DataDisplay/Typography/Typography";
|
|
8
|
+
|
|
9
|
+
export interface TutorialProps {
|
|
10
|
+
steps: Step[];
|
|
11
|
+
children?: ReactNode;
|
|
12
|
+
tourName: string;
|
|
13
|
+
iconPosition?: "left" | "right";
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const Tutorial = ({
|
|
17
|
+
steps,
|
|
18
|
+
children,
|
|
19
|
+
tourName,
|
|
20
|
+
iconPosition = "right",
|
|
21
|
+
}: TutorialProps) => {
|
|
22
|
+
const [run, setRun] = useState(false);
|
|
23
|
+
const userTours = localStorage.getItem("userTours") || "[]";
|
|
24
|
+
|
|
25
|
+
const startTour = useCallback(() => {
|
|
26
|
+
setRun(true);
|
|
27
|
+
}, []);
|
|
28
|
+
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
if (userTours && !userTours.includes(tourName)) {
|
|
31
|
+
startTour();
|
|
32
|
+
}
|
|
33
|
+
}, [userTours, tourName, startTour]);
|
|
34
|
+
|
|
35
|
+
const handleJoyrideCallback = (data: CallBackProps) => {
|
|
36
|
+
const { action, status } = data;
|
|
37
|
+
|
|
38
|
+
if (action === ACTIONS.RESET) {
|
|
39
|
+
setRun(false);
|
|
40
|
+
completeTour().catch((err) => {
|
|
41
|
+
console.error("Failed to mark tour as complete:", err);
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const completeTour = async () => {
|
|
47
|
+
try {
|
|
48
|
+
if (!userTours.includes(tourName)) {
|
|
49
|
+
localStorage.setItem(
|
|
50
|
+
"userTours",
|
|
51
|
+
JSON.stringify([...JSON.parse(userTours), tourName])
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
await axios.post("/square/tours/complete", { tourName });
|
|
55
|
+
} catch (error) {
|
|
56
|
+
console.error("Error completing the tour:", error);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<div style={{ textAlign: iconPosition }}>
|
|
62
|
+
<Tooltip
|
|
63
|
+
title={<Typography variant="body1">Start Tour</Typography>}
|
|
64
|
+
placement="left"
|
|
65
|
+
>
|
|
66
|
+
<IconButton
|
|
67
|
+
onClick={startTour}
|
|
68
|
+
style={{ cursor: "pointer" }}
|
|
69
|
+
aria-label={`Start ${tourName} tour`}
|
|
70
|
+
>
|
|
71
|
+
<ToursIcon />
|
|
72
|
+
</IconButton>
|
|
73
|
+
</Tooltip>
|
|
74
|
+
|
|
75
|
+
<ReactJoyride
|
|
76
|
+
callback={handleJoyrideCallback}
|
|
77
|
+
steps={steps}
|
|
78
|
+
continuous={true}
|
|
79
|
+
run={run}
|
|
80
|
+
showSkipButton={true}
|
|
81
|
+
locale={{
|
|
82
|
+
last: "Finish",
|
|
83
|
+
next: "Next",
|
|
84
|
+
skip: "Skip",
|
|
85
|
+
back: "Previous",
|
|
86
|
+
}}
|
|
87
|
+
styles={{
|
|
88
|
+
buttonNext: {
|
|
89
|
+
backgroundColor: "#D27D2D",
|
|
90
|
+
color: "white",
|
|
91
|
+
height: "28px",
|
|
92
|
+
width: "100px",
|
|
93
|
+
padding: "0px",
|
|
94
|
+
fontFamily: "Roboto, sans-serif",
|
|
95
|
+
},
|
|
96
|
+
buttonBack: {
|
|
97
|
+
backgroundColor: "transparent",
|
|
98
|
+
color: "black",
|
|
99
|
+
borderRadius: "4px",
|
|
100
|
+
height: "28px",
|
|
101
|
+
width: "100px",
|
|
102
|
+
gap: "10px",
|
|
103
|
+
marginLeft: "5px",
|
|
104
|
+
padding: "0px",
|
|
105
|
+
border: "1px solid black",
|
|
106
|
+
fontFamily: "Roboto, sans-serif",
|
|
107
|
+
},
|
|
108
|
+
}}
|
|
109
|
+
/>
|
|
110
|
+
{children}
|
|
111
|
+
</div>
|
|
112
|
+
);
|
|
113
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { Tutorial } from "../../components/Feedback/Tutorial/Tutorial";
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: "Feedback/Tutorial",
|
|
6
|
+
component: Tutorial,
|
|
7
|
+
parameters: {
|
|
8
|
+
controls: {
|
|
9
|
+
exclude: ["children"],
|
|
10
|
+
},
|
|
11
|
+
},
|
|
12
|
+
argTypes: {
|
|
13
|
+
iconPosition: {
|
|
14
|
+
control: { type: "radio" },
|
|
15
|
+
options: ["left", "right"],
|
|
16
|
+
defaultValue: "right",
|
|
17
|
+
},
|
|
18
|
+
tourName: { control: "text" },
|
|
19
|
+
steps: { control: "object" },
|
|
20
|
+
},
|
|
21
|
+
} as Meta<typeof Tutorial>;
|
|
22
|
+
|
|
23
|
+
export const PrimaryTutorial: StoryObj<typeof Tutorial> = {
|
|
24
|
+
render: (args) => (
|
|
25
|
+
<div>
|
|
26
|
+
{/* Placeholder elements for the tutorial */}
|
|
27
|
+
<div
|
|
28
|
+
className="tutorial-target"
|
|
29
|
+
style={{ margin: "20px", border: "2px solid blue", padding: "10px" }}
|
|
30
|
+
>
|
|
31
|
+
Target 1: This element is the first target of the tutorial.
|
|
32
|
+
</div>
|
|
33
|
+
<div
|
|
34
|
+
className="next-target"
|
|
35
|
+
style={{ margin: "20px", border: "2px solid green", padding: "10px" }}
|
|
36
|
+
>
|
|
37
|
+
Target 2: This element is the next target of the tutorial.
|
|
38
|
+
</div>
|
|
39
|
+
|
|
40
|
+
<Tutorial {...args} />
|
|
41
|
+
</div>
|
|
42
|
+
),
|
|
43
|
+
args: {
|
|
44
|
+
tourName: "Active Batches",
|
|
45
|
+
steps: [
|
|
46
|
+
{
|
|
47
|
+
target: ".tutorial-target",
|
|
48
|
+
content: "This is my first step",
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
target: ".next-target",
|
|
52
|
+
content: "This is the next step",
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
},
|
|
56
|
+
};
|
|
@@ -187,8 +187,7 @@ export const getCommonTheme = (mode: Theme) => {
|
|
|
187
187
|
styleOverrides: {
|
|
188
188
|
tooltip: {
|
|
189
189
|
backgroundColor: ColorTokens.surface.paperBackground,
|
|
190
|
-
padding: "20px
|
|
191
|
-
minWidth: "300px",
|
|
190
|
+
padding: "20px 20px",
|
|
192
191
|
boxShadow: `0px 2px 5px ${ColorTokens.secondary.main}`,
|
|
193
192
|
border: `1px solid ${ColorTokens.secondary.main}`,
|
|
194
193
|
},
|
|
File without changes
|