2022-07-14 13:36:17 +10:00
|
|
|
|
import { useState, Fragment } from "react";
|
2022-08-15 12:05:54 +02:00
|
|
|
|
import { useAtom, useSetAtom } from "jotai";
|
2022-07-14 13:36:17 +10:00
|
|
|
|
import { useNavigate } from "react-router-dom";
|
|
|
|
|
|
|
|
|
|
|
|
import {
|
|
|
|
|
|
Slide,
|
|
|
|
|
|
Drawer,
|
|
|
|
|
|
Typography,
|
|
|
|
|
|
IconButton,
|
|
|
|
|
|
Box,
|
|
|
|
|
|
Stack,
|
|
|
|
|
|
Button,
|
|
|
|
|
|
} from "@mui/material";
|
|
|
|
|
|
import CloseIcon from "@mui/icons-material/Close";
|
|
|
|
|
|
import ArrowForwardIcon from "@mui/icons-material/ArrowForward";
|
|
|
|
|
|
|
|
|
|
|
|
import StepsProgress from "@src/components/StepsProgress";
|
|
|
|
|
|
import { TUTORIAL_STEPS } from "./Steps";
|
|
|
|
|
|
|
2022-08-15 12:05:54 +02:00
|
|
|
|
import {
|
|
|
|
|
|
projectScope,
|
|
|
|
|
|
confirmDialogAtom,
|
|
|
|
|
|
navOpenAtom,
|
2022-08-15 12:45:45 +02:00
|
|
|
|
updateUserSettingsAtom,
|
2022-08-15 12:05:54 +02:00
|
|
|
|
} from "@src/atoms/projectScope";
|
2022-07-14 13:36:17 +10:00
|
|
|
|
import { ROUTES } from "@src/constants/routes";
|
2022-08-15 12:05:54 +02:00
|
|
|
|
import {
|
|
|
|
|
|
NAV_DRAWER_COLLAPSED_WIDTH,
|
|
|
|
|
|
NAV_DRAWER_WIDTH,
|
|
|
|
|
|
} from "@src/layouts/Navigation/NavDrawer";
|
2022-07-14 13:36:17 +10:00
|
|
|
|
|
|
|
|
|
|
export default function TableTutorial() {
|
2022-08-15 12:05:54 +02:00
|
|
|
|
const [navOpen] = useAtom(navOpenAtom, projectScope);
|
2022-07-18 14:40:46 +10:00
|
|
|
|
const confirm = useSetAtom(confirmDialogAtom, projectScope);
|
2022-08-15 12:45:45 +02:00
|
|
|
|
const [updateUserSettings] = useAtom(updateUserSettingsAtom, projectScope);
|
2022-07-14 13:36:17 +10:00
|
|
|
|
const navigate = useNavigate();
|
|
|
|
|
|
|
|
|
|
|
|
const [completed, setCompleted] = useState(
|
|
|
|
|
|
new Array(TUTORIAL_STEPS.length).fill(false)
|
|
|
|
|
|
);
|
|
|
|
|
|
const [currentStep, setCurrentStep] = useState(0);
|
|
|
|
|
|
|
2022-08-15 12:45:45 +02:00
|
|
|
|
const stepProps = TUTORIAL_STEPS[currentStep];
|
|
|
|
|
|
const StepComponent = stepProps.StepComponent;
|
|
|
|
|
|
const isFinal = currentStep === TUTORIAL_STEPS.length - 1;
|
|
|
|
|
|
|
2022-07-14 13:36:17 +10:00
|
|
|
|
const handleComplete = (value: boolean) =>
|
|
|
|
|
|
setCompleted((c) => {
|
|
|
|
|
|
if (c[currentStep] === value) return c;
|
|
|
|
|
|
const newCompleted = [...c];
|
|
|
|
|
|
newCompleted[currentStep] = value;
|
|
|
|
|
|
return newCompleted;
|
|
|
|
|
|
});
|
|
|
|
|
|
|
2022-08-15 12:45:45 +02:00
|
|
|
|
const handleNext = () => {
|
|
|
|
|
|
if (isFinal) {
|
|
|
|
|
|
if (updateUserSettings)
|
|
|
|
|
|
updateUserSettings({ tableTutorialComplete: true });
|
2022-07-14 13:36:17 +10:00
|
|
|
|
|
2022-08-15 12:45:45 +02:00
|
|
|
|
navigate(ROUTES.tables);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
setCurrentStep((c) => Math.min(c + 1, TUTORIAL_STEPS.length - 1));
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
2022-07-14 13:36:17 +10:00
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<Slide in direction="up">
|
|
|
|
|
|
<Drawer
|
|
|
|
|
|
variant="permanent"
|
|
|
|
|
|
anchor="bottom"
|
|
|
|
|
|
sx={{
|
|
|
|
|
|
position: "fixed",
|
|
|
|
|
|
top: "auto",
|
|
|
|
|
|
bottom: `env(safe-area-inset-bottom)`,
|
|
|
|
|
|
left: {
|
|
|
|
|
|
xs: `env(safe-area-inset-left)`,
|
2022-08-15 12:45:45 +02:00
|
|
|
|
md: (navOpen ? NAV_DRAWER_WIDTH : NAV_DRAWER_COLLAPSED_WIDTH) + 8,
|
2022-07-14 13:36:17 +10:00
|
|
|
|
},
|
|
|
|
|
|
right: `env(safe-area-inset-right)`,
|
|
|
|
|
|
height: "min(50vh, 440px)",
|
|
|
|
|
|
|
|
|
|
|
|
"& .MuiPaper-root": {
|
|
|
|
|
|
position: "static",
|
|
|
|
|
|
height: "100%",
|
|
|
|
|
|
|
|
|
|
|
|
borderRadius: 2,
|
|
|
|
|
|
borderBottomLeftRadius: 0,
|
|
|
|
|
|
borderBottomRightRadius: 0,
|
|
|
|
|
|
border: "none",
|
|
|
|
|
|
|
|
|
|
|
|
px: { xs: 2, sm: 3, md: 6 },
|
|
|
|
|
|
py: { xs: 3, md: 5 },
|
|
|
|
|
|
pb: (theme) =>
|
|
|
|
|
|
`max(env(safe-area-inset-bottom), ${theme.spacing(5)})`,
|
|
|
|
|
|
overflow: "auto",
|
|
|
|
|
|
|
|
|
|
|
|
display: "flex",
|
|
|
|
|
|
flexDirection: "column",
|
|
|
|
|
|
gap: 2,
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
"& ol": { m: 0, p: 0, listStyle: "none" },
|
|
|
|
|
|
"& p": { maxWidth: "100ch" },
|
|
|
|
|
|
}}
|
|
|
|
|
|
PaperProps={{ elevation: 2 }}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Typography variant="overline" sx={{ mb: -2 }}>
|
|
|
|
|
|
Get started tutorial
|
|
|
|
|
|
</Typography>
|
|
|
|
|
|
|
|
|
|
|
|
<IconButton
|
|
|
|
|
|
aria-label="Close tutorial"
|
|
|
|
|
|
size="medium"
|
|
|
|
|
|
sx={{
|
|
|
|
|
|
marginLeft: "auto",
|
|
|
|
|
|
width: 40,
|
|
|
|
|
|
position: "absolute",
|
|
|
|
|
|
top: 12,
|
|
|
|
|
|
right: 12,
|
|
|
|
|
|
}}
|
|
|
|
|
|
onClick={() =>
|
|
|
|
|
|
confirm({
|
|
|
|
|
|
title: "Close tutorial?",
|
|
|
|
|
|
body: "Your progress will be lost",
|
|
|
|
|
|
handleConfirm: () => navigate(ROUTES.tables),
|
|
|
|
|
|
confirm: "Close tutorial",
|
|
|
|
|
|
cancel: "Continue tutorial",
|
|
|
|
|
|
confirmColor: "error",
|
|
|
|
|
|
buttonLayout: "vertical",
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
>
|
|
|
|
|
|
<CloseIcon />
|
|
|
|
|
|
</IconButton>
|
|
|
|
|
|
|
|
|
|
|
|
<Fragment key={TUTORIAL_STEPS[currentStep].id}>
|
|
|
|
|
|
<header>
|
|
|
|
|
|
<Typography variant="h5" component="h1" gutterBottom>
|
|
|
|
|
|
{stepProps.title}
|
|
|
|
|
|
</Typography>
|
|
|
|
|
|
<Typography variant="body1">{stepProps.description}</Typography>
|
|
|
|
|
|
</header>
|
|
|
|
|
|
|
|
|
|
|
|
<div style={{ flexGrow: 1 }}>
|
|
|
|
|
|
<StepComponent
|
|
|
|
|
|
complete={completed[currentStep]}
|
|
|
|
|
|
setComplete={handleComplete}
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
{stepProps.completeText && (
|
|
|
|
|
|
<Box
|
|
|
|
|
|
sx={{
|
|
|
|
|
|
visibility: completed[currentStep] ? "visible" : "hidden",
|
|
|
|
|
|
opacity: completed[currentStep] ? 1 : 0,
|
|
|
|
|
|
transition: (theme) => theme.transitions.create("opacity"),
|
|
|
|
|
|
}}
|
|
|
|
|
|
>
|
|
|
|
|
|
{stepProps.completeText}
|
|
|
|
|
|
</Box>
|
|
|
|
|
|
)}
|
|
|
|
|
|
</Fragment>
|
|
|
|
|
|
|
|
|
|
|
|
<Stack
|
|
|
|
|
|
direction="row"
|
|
|
|
|
|
justifyContent="flex-end"
|
|
|
|
|
|
alignItems="center"
|
|
|
|
|
|
gap={1}
|
|
|
|
|
|
>
|
|
|
|
|
|
<StepsProgress
|
|
|
|
|
|
steps={TUTORIAL_STEPS.length}
|
|
|
|
|
|
value={completed.filter(Boolean).length}
|
|
|
|
|
|
style={{
|
|
|
|
|
|
flexGrow: 0,
|
|
|
|
|
|
flexShrink: 1,
|
|
|
|
|
|
flexBasis: 200,
|
|
|
|
|
|
marginRight: "auto",
|
|
|
|
|
|
}}
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
|
|
<Button variant="text" style={{ flexShrink: 0 }}>
|
|
|
|
|
|
I’m stuck
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
<Button
|
|
|
|
|
|
variant="contained"
|
|
|
|
|
|
color="primary"
|
|
|
|
|
|
style={{ flexShrink: 0 }}
|
|
|
|
|
|
disabled={!completed[currentStep]}
|
|
|
|
|
|
onClick={handleNext}
|
|
|
|
|
|
endIcon={isFinal ? <ArrowForwardIcon /> : undefined}
|
|
|
|
|
|
>
|
|
|
|
|
|
{isFinal ? "Finish" : "Next"}
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</Stack>
|
|
|
|
|
|
</Drawer>
|
|
|
|
|
|
</Slide>
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|