diff --git a/frontend/src/basic/RobotPage/Onboarding.tsx b/frontend/src/basic/RobotPage/Onboarding.tsx
index 1d6d2fad..f0e209dd 100644
--- a/frontend/src/basic/RobotPage/Onboarding.tsx
+++ b/frontend/src/basic/RobotPage/Onboarding.tsx
@@ -11,28 +11,117 @@ import {
LinearProgress,
Link,
Typography,
- Accordion,
- AccordionSummary,
- AccordionDetails,
+ Stepper,
+ Step,
+ StepLabel,
+ StepConnector,
+ styled,
+ stepConnectorClasses,
+ Paper,
+ useTheme,
+ useMediaQuery,
+ IconButton,
} from '@mui/material';
-import { type Robot } from '../../models';
-import { Casino, Bolt, Check, Storefront, AddBox, School } from '@mui/icons-material';
+import {
+ Check,
+ Casino,
+ SmartToy,
+ Storefront,
+ AddBox,
+ School,
+ ContentCopy,
+} from '@mui/icons-material';
import RobotAvatar from '../../components/RobotAvatar';
import TokenInput from './TokenInput';
import { genBase62Token } from '../../utils';
-import { NewTabIcon } from '../../components/Icons';
import { AppContext, type UseAppStoreType } from '../../contexts/AppContext';
import { GarageContext, type UseGarageStoreType } from '../../contexts/GarageContext';
-interface OnboardingProps {
- setView: (state: 'welcome' | 'onboarding' | 'recovery' | 'profile') => void;
- robot: Robot;
- setRobot: (state: Robot) => void;
- inputToken: string;
- setInputToken: (state: string) => void;
- getGenerateRobot: (token: string) => void;
- badToken: string;
- baseUrl: string;
+const StyledPaper = styled(Paper)(({ theme }) => ({
+ backgroundColor: theme.palette.background.paper,
+ boxShadow: '8px 8px 0px 0px rgba(0, 0, 0, 0.2)',
+ borderRadius: '16px',
+ border: '2px solid #000',
+ padding: theme.spacing(2),
+ color: theme.palette.text.primary,
+ width: '100%',
+ maxWidth: '500px',
+ margin: '0 auto',
+}));
+
+const StyledButton = styled(Button)(({ theme }) => ({
+ justifyContent: 'center',
+ textAlign: 'center',
+ padding: theme.spacing(1),
+ borderRadius: '8px',
+ border: '2px solid #000',
+ boxShadow: '4px 4px 0px 0px rgba(0, 0, 0, 0.2)',
+ textTransform: 'none',
+ fontWeight: 'bold',
+ width: '100%',
+ '&:hover': {
+ boxShadow: '6px 6px 0px 0px rgba(0, 0, 0, 0.3)',
+ },
+}));
+
+const StyledStepConnector = styled(StepConnector)(({ theme }) => ({
+ [`&.${stepConnectorClasses.alternativeLabel}`]: {
+ top: 22,
+ left: 'calc(-50% + 20px)',
+ right: 'calc(50% + 20px)',
+ },
+ [`&.${stepConnectorClasses.active}`]: {
+ [`& .${stepConnectorClasses.line}`]: {
+ borderColor: theme.palette.primary.main,
+ },
+ },
+ [`&.${stepConnectorClasses.completed}`]: {
+ [`& .${stepConnectorClasses.line}`]: {
+ borderColor: theme.palette.primary.main,
+ },
+ },
+ [`& .${stepConnectorClasses.line}`]: {
+ borderColor: theme.palette.mode === 'dark' ? theme.palette.grey[800] : '#eaeaf0',
+ borderTopWidth: 3,
+ borderRadius: 1,
+ },
+}));
+
+const StyledStepIconRoot = styled('div')<{ ownerState: { active?: boolean; completed?: boolean } }>(
+ ({ theme, ownerState }) => ({
+ backgroundColor: theme.palette.mode === 'dark' ? theme.palette.grey[700] : '#ccc',
+ zIndex: 1,
+ color: '#fff',
+ width: 44,
+ height: 44,
+ display: 'flex',
+ borderRadius: '50%',
+ justifyContent: 'center',
+ alignItems: 'center',
+ ...(ownerState.active && {
+ backgroundColor: theme.palette.primary.main,
+ boxShadow: '0 4px 10px 0 rgba(0,0,0,.25)',
+ }),
+ ...(ownerState.completed && {
+ backgroundColor: theme.palette.primary.main,
+ }),
+ }),
+);
+
+function StyledStepIcon(props: StepIconProps) {
+ const { active, completed, className } = props;
+
+ const icons: { [index: string]: React.ReactElement } = {
+ 1: ,
+ 2: ,
+ 3: ,
+ };
+
+ return (
+
+ {icons[String(props.icon)]}
+
+ );
}
const Onboarding = ({
@@ -44,6 +133,8 @@ const Onboarding = ({
}: OnboardingProps): JSX.Element => {
const { t } = useTranslation();
const navigate = useNavigate();
+ const theme = useTheme();
+ const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
const { setPage } = useContext(AppContext);
const { garage } = useContext(GarageContext);
@@ -63,43 +154,77 @@ const Onboarding = ({
const slot = garage.getSlot();
+ const steps = [
+ t('1. Generate a token'),
+ t('2. Meet your robot identity'),
+ t('3. Browse or create an order'),
+ ];
+
return (
-
-
-
-
- {t('1. Generate a token')}
-
-
-
-
-
-
- {t(
- 'This temporary key gives you access to a unique and private robot identity for your trade.',
- )}
-
-
+
+ }
+ sx={{ width: '100%', mb: 3 }}
+ >
+ {steps.map((label) => (
+
+ {isMobile ? null : label}
+
+ ))}
+
+
+
+ {step === '1' && (
+ <>
+
+ {t('1. Generate a token')}
+
+
+ {t(
+ 'This temporary key gives you access to a unique and private robot identity for your trade.',
+ )}
+
{!generatedToken ? (
-
-
-
+
+
+ {t('Generate Token')}
+
+
) : (
-
-
-
-
-
- {`${t('Store it somewhere safe!')} `}
+
+
+
+
+
+ {t('Store it somewhere safe!')}
+
+
{t(
- `This token is the one and only key to your robot and trade. You will need it later to recover your order or check its status.`,
+ 'This token is the one and only key to your robot and trade. You will need it later to recover your order or check its status.',
)}
-
-
-
+
+
+
+
+
null}
+ sx={{ flexGrow: 1 }}
/>
-
-
-
- {t('You can also add your own random characters into the token or')}
-
-
-
-
-
-
+
+
+
+ {
setStep('2');
getGenerateRobot(inputToken);
}}
variant='contained'
size='large'
+ startIcon={}
+ fullWidth={false}
>
-
{t('Continue')}
-
-
+
+
-
-
+
+
)}
-
-
-
+ >
+ )}
-
-
-
- {t('2. Meet your robot identity')}
-
-
-
-
-
-
- {slot?.hashId ? (
- t('This is your trading avatar')
- ) : (
- <>
- {t('Building your robot!')}
-
- >
- )}
-
-
-
-
+ {step === '2' && (
+ <>
+
+ {t('2. Meet your robot identity')}
+
+
+ {slot?.hashId ? t('This is your trading avatar') : t('Building your robot!')}
+
+ {!slot?.hashId && }
+
-
-
- {slot?.nickname ? (
-
- {t('Hi! My name is')}
-
-
-
- {slot?.nickname}
-
-
+
+ {slot?.nickname && (
+ <>
+
+ {t('Hi! My name is')}
-
- ) : null}
-
-
-
-
-
-
-
-
+
+
+
+ {slot.nickname}
+
+
+
+ >
+ )}
+
+ setStep('3')}
+ variant='contained'
+ size='large'
+ startIcon={}
+ disabled={!slot?.hashId}
+ fullWidth={false}
+ >
+ {t('Continue')}
+
+
+ >
+ )}
-
-
-
- {t('3. Browse or create an order')}
-
-
-
-
-
-
- {t(
- 'RoboSats is a peer-to-peer marketplace. You can browse the public offers or create a new one.',
- )}
-
-
-
-
-
-
-
+
-
-
-
-
- {`${t('If you need help on your RoboSats journey join our public support')} `}
-
- {t('Telegram group')}
-
- {`, ${t('or visit the robot school for documentation.')} `}
-
-
-
-
-
- {
- setView('profile');
- }}
- >
- {t('See profile')}
-
-
-
-
-
+
+ >
+ )}
+
);
};