diff --git a/frontend/src/assets/img/demo_qr.png b/frontend/src/assets/img/demo_qr.png new file mode 100644 index 0000000000..d6f8b3b215 Binary files /dev/null and b/frontend/src/assets/img/demo_qr.png differ diff --git a/frontend/src/component/demo/Demo.tsx b/frontend/src/component/demo/Demo.tsx index 83ca3e9ad5..33f779f473 100644 --- a/frontend/src/component/demo/Demo.tsx +++ b/frontend/src/component/demo/Demo.tsx @@ -5,10 +5,12 @@ import { DemoSteps } from './DemoSteps/DemoSteps'; import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { createLocalStorage } from 'utils/createLocalStorage'; import { TOPICS } from './demo-topics'; +import { DemoDialogWelcome } from './DemoDialog/DemoDialogWelcome/DemoDialogWelcome'; const defaultProgress = { + welcomeOpen: true, expanded: true, - run: false, + active: false, topic: 0, steps: [0], }; @@ -18,34 +20,47 @@ const { value: storedProgress, setValue: setStoredProgress } = export const Demo = () => { const { uiConfig } = useUiConfig(); - const [loaded, setLoaded] = useState(false); + const [welcomeOpen, setWelcomeOpen] = useState( + storedProgress.welcomeOpen ?? true + ); + const [active, setActive] = useState(false); const [expanded, setExpanded] = useState(storedProgress.expanded ?? true); - const [run, setRun] = useState(false); const [topic, setTopic] = useState(storedProgress.topic ?? 0); const [steps, setSteps] = useState(storedProgress.steps ?? [0]); useEffect(() => { - setTimeout(() => { - setLoaded(true); - if (storedProgress.run) { - setRun(true); - } - }, 1000); + if (storedProgress.active) { + setTimeout(() => { + setActive(true); + }, 1000); + } }, []); useEffect(() => { setStoredProgress({ + welcomeOpen, expanded, - run, + active, topic, steps, }); - }, [expanded, run, topic, steps]); + }, [welcomeOpen, expanded, active, topic, steps]); if (!uiConfig.flags.demo) return null; return ( <> + { + setWelcomeOpen(false); + setExpanded(false); + }} + onStart={() => { + setWelcomeOpen(false); + setActive(true); + }} + /> { }); }} topics={TOPICS} + onShowWelcome={() => setWelcomeOpen(true)} /> ({ + '& .MuiDialog-paper': { + borderRadius: theme.shape.borderRadiusExtraLarge, + maxWidth: theme.spacing(90), + padding: theme.spacing(7.5), + textAlign: 'center', + }, +})); + +const StyledCloseButton = styled(IconButton)(({ theme }) => ({ + position: 'absolute', + right: theme.spacing(2), + top: theme.spacing(2), + color: theme.palette.neutral.main, +})); + +const StyledHeader = styled(Typography)(({ theme }) => ({ + fontSize: theme.fontSizes.largeHeader, + fontWeight: theme.fontWeight.bold, +})); + +interface IDemoDialogProps { + open: boolean; + onClose: () => void; + children: React.ReactNode; +} + +export const DemoDialog = ({ open, onClose, children }: IDemoDialogProps) => ( + + + + + {children} + +); + +DemoDialog.Header = StyledHeader; diff --git a/frontend/src/component/demo/DemoDialog/DemoDialogWelcome/DemoDialogWelcome.tsx b/frontend/src/component/demo/DemoDialog/DemoDialogWelcome/DemoDialogWelcome.tsx new file mode 100644 index 0000000000..16763ec99c --- /dev/null +++ b/frontend/src/component/demo/DemoDialog/DemoDialogWelcome/DemoDialogWelcome.tsx @@ -0,0 +1,93 @@ +import { Button, Divider, Typography, styled } from '@mui/material'; +import qrImage from 'assets/img/demo_qr.png'; +import { formatAssetPath } from 'utils/formatPath'; +import { Launch } from '@mui/icons-material'; +import { DemoDialog } from '../DemoDialog'; + +const StyledDemoPane = styled('div')(({ theme }) => ({ + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + backgroundColor: theme.palette.neutral.light, + borderRadius: theme.shape.borderRadiusLarge, + padding: theme.spacing(4), + margin: theme.spacing(4, 0), +})); + +const StyledScanMessage = styled(Typography)(({ theme }) => ({ + fontSize: theme.fontSizes.mainHeader, + fontWeight: theme.fontWeight.bold, + marginBottom: theme.spacing(2), +})); + +const StyledQRCode = styled('img')(({ theme }) => ({ + width: theme.spacing(20), + height: theme.spacing(20), +})); + +const StyledDivider = styled(Divider)(({ theme }) => ({ + margin: theme.spacing(4, 0), + padding: theme.spacing(0, 4), + width: '100%', + color: theme.palette.text.secondary, +})); + +const StyledLink = styled('a')(({ theme }) => ({ + display: 'inline-flex', + alignItems: 'center', + gap: theme.spacing(0.5), + '& > svg': { + fontSize: theme.fontSizes.bodySize, + }, +})); + +const StyledStartButton = styled(Button)(({ theme }) => ({ + height: theme.spacing(7), +})); + +interface IDemoDialogWelcomeProps { + open: boolean; + onClose: () => void; + onStart: () => void; +} + +export const DemoDialogWelcome = ({ + open, + onClose, + onStart, +}: IDemoDialogWelcomeProps) => ( + + Explore Unleash + + You can explore Unleash on your own, however for the best experience + it's recommended you follow our interactive tutorial. To get + started, you will need to open the demo website below. + + + + Scan the QR code with your phone + + + OR + + Open demo website in another tab:{' '} + + demo.unleash-hosted.com + + + + (we recommend you keep the pages open side by side) + + + + Start Unleash tutorial + + +); diff --git a/frontend/src/component/demo/DemoSteps/DemoSteps.tsx b/frontend/src/component/demo/DemoSteps/DemoSteps.tsx index 8eabe169fe..88158d3b1e 100644 --- a/frontend/src/component/demo/DemoSteps/DemoSteps.tsx +++ b/frontend/src/component/demo/DemoSteps/DemoSteps.tsx @@ -44,8 +44,6 @@ const StyledTooltipPrimaryActions = styled('div')(({ theme }) => ({ })); interface IDemoStepsProps { - run: boolean; - setRun: React.Dispatch>; setExpanded: React.Dispatch>; steps: number[]; setSteps: React.Dispatch>; @@ -55,8 +53,6 @@ interface IDemoStepsProps { } export const DemoSteps = ({ - run, - setRun, setExpanded, steps, setSteps, @@ -67,6 +63,7 @@ export const DemoSteps = ({ const theme = useTheme(); const navigate = useNavigate(); const location = useLocation(); + const [run, setRun] = useState(false); const [flow, setFlow] = useState<'next' | 'back'>('next'); const abortController = new AbortController(); diff --git a/frontend/src/component/demo/DemoTopics/DemoTopics.tsx b/frontend/src/component/demo/DemoTopics/DemoTopics.tsx index 27159dfaf7..b9a33ffd46 100644 --- a/frontend/src/component/demo/DemoTopics/DemoTopics.tsx +++ b/frontend/src/component/demo/DemoTopics/DemoTopics.tsx @@ -138,6 +138,7 @@ interface IDemoTopicsProps { currentTopic: number; setCurrentTopic: (topic: number) => void; topics: ITutorialTopic[]; + onShowWelcome: () => void; } export const DemoTopics = ({ @@ -147,6 +148,7 @@ export const DemoTopics = ({ currentTopic, setCurrentTopic, topics, + onShowWelcome, }: IDemoTopicsProps) => { const completedSteps = steps.reduce((acc, step) => acc + (step || 0), 0); const totalSteps = topics.flatMap(({ steps }) => steps).length; @@ -201,7 +203,7 @@ export const DemoTopics = ({ ); })} - + View demo link again