mirror of
https://github.com/RoboSats/robosats.git
synced 2024-12-14 03:16:24 +00:00
Add sliding pages
This commit is contained in:
parent
6dd90aa118
commit
da8b70091b
@ -2,7 +2,6 @@ import React, { useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Button, Typography, Grid, ButtonGroup, Dialog, Box } from '@mui/material';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import currencyDict from '../../../static/assets/currencies.json';
|
||||
import DepthChart from '../../components/Charts/DepthChart';
|
||||
|
||||
import { Book, Favorites, LimitList, Maker } from '../../models';
|
||||
@ -47,25 +46,6 @@ const BookPage = ({
|
||||
const maxBookTableWidth = 85;
|
||||
const chartWidthEm = width - maxBookTableWidth;
|
||||
|
||||
const defaultMaker: Maker = {
|
||||
isExplicit: false,
|
||||
amount: '',
|
||||
paymentMethods: [],
|
||||
paymentMethodsText: 'not specified',
|
||||
badPaymentMethod: false,
|
||||
premium: '',
|
||||
satoshis: '',
|
||||
publicExpiryTime: new Date(0, 0, 0, 23, 59),
|
||||
publicDuration: 86340,
|
||||
escrowExpiryTime: new Date(0, 0, 0, 3, 0),
|
||||
escrowDuration: 10800,
|
||||
bondSize: 3,
|
||||
minAmount: '',
|
||||
maxAmount: '',
|
||||
badPremiumText: '',
|
||||
badSatoshisText: '',
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (book.orders.length < 1) {
|
||||
fetchBook(true, false);
|
||||
@ -87,7 +67,7 @@ const BookPage = ({
|
||||
return (
|
||||
<ButtonGroup variant='contained' color='inherit'>
|
||||
<Button color='primary' onClick={() => setOpenMaker(true)}>
|
||||
{t('Create Order')}
|
||||
{t('Create')}
|
||||
</Button>
|
||||
{doubleView ? (
|
||||
<></>
|
||||
@ -108,9 +88,6 @@ const BookPage = ({
|
||||
)}
|
||||
</Button>
|
||||
)}
|
||||
<Button color='secondary' onClick={() => history.push('/')}>
|
||||
{t('Back')}
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
);
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { HashRouter, BrowserRouter, Switch, Route, useHistory } from 'react-router-dom';
|
||||
import { useTheme, IconButton } from '@mui/material';
|
||||
import { useTheme, IconButton, Box, Slide } from '@mui/material';
|
||||
|
||||
import UserGenPage from './UserGenPage';
|
||||
import MakerPage from './MakerPage';
|
||||
@ -39,18 +39,18 @@ const getWindowSize = function (fontSize: number) {
|
||||
};
|
||||
};
|
||||
|
||||
type Page = 'robot' | 'order' | 'create' | 'offers' | 'settings' | 'none';
|
||||
interface SlideDirection {
|
||||
in: 'left' | 'right' | undefined;
|
||||
out: 'left' | 'right' | undefined;
|
||||
}
|
||||
|
||||
interface MainProps {
|
||||
settings: Settings;
|
||||
setSettings: (state: Settings) => void;
|
||||
}
|
||||
|
||||
const Main = ({ settings, setSettings }: MainProps): JSX.Element => {
|
||||
const theme = useTheme();
|
||||
const history = useHistory();
|
||||
const Router = window.NativeRobosats != null ? HashRouter : BrowserRouter;
|
||||
const basename = window.NativeRobosats != null ? window.location.pathname : '';
|
||||
const [openLearn, setOpenLearn] = useState<boolean>(false);
|
||||
|
||||
// All app data structured
|
||||
const [book, setBook] = useState<Book>({ orders: [], loading: true });
|
||||
const [limits, setLimits] = useState<{ list: LimitList; loading: boolean }>({
|
||||
@ -62,6 +62,19 @@ const Main = ({ settings, setSettings }: MainProps): JSX.Element => {
|
||||
const [info, setInfo] = useState<Info>(defaultInfo);
|
||||
const [fav, setFav] = useState<Favorites>({ type: null, currency: 0 });
|
||||
|
||||
const theme = useTheme();
|
||||
const history = useHistory();
|
||||
const Router = window.NativeRobosats != null ? HashRouter : BrowserRouter;
|
||||
const basename = window.NativeRobosats != null ? window.location.pathname : '';
|
||||
const [page, setPage] = useState<Page>(window.location.pathname.split('/')[1]);
|
||||
const [slideDirection, setSlideDirection] = useState<SlideDirection>({
|
||||
in: undefined,
|
||||
out: undefined,
|
||||
});
|
||||
|
||||
const navbarHeight = 2.5;
|
||||
const [openLearn, setOpenLearn] = useState<boolean>(false);
|
||||
|
||||
const [windowSize, setWindowSize] = useState<{ width: number; height: number }>(
|
||||
getWindowSize(theme.typography.fontSize),
|
||||
);
|
||||
@ -130,6 +143,7 @@ const Main = ({ settings, setSettings }: MainProps): JSX.Element => {
|
||||
});
|
||||
};
|
||||
|
||||
console.log(page, slideDirection);
|
||||
return (
|
||||
<Router basename={basename}>
|
||||
<div className='temporaryUpperIcons'>
|
||||
@ -141,17 +155,15 @@ const Main = ({ settings, setSettings }: MainProps): JSX.Element => {
|
||||
>
|
||||
<SchoolIcon />
|
||||
</IconButton>
|
||||
<IconButton
|
||||
color='inherit'
|
||||
sx={{ position: 'fixed', right: '0px', color: 'text.secondary' }}
|
||||
onClick={() =>
|
||||
setSettings({ ...settings, mode: settings.mode === 'dark' ? 'light' : 'dark' })
|
||||
}
|
||||
>
|
||||
{theme.palette.mode === 'dark' ? <LightModeIcon /> : <DarkModeIcon />}
|
||||
</IconButton>
|
||||
</div>
|
||||
<div className='appCenter'>
|
||||
<Box
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: '50%',
|
||||
left: '50%',
|
||||
transform: `translate(-50%, -50%) translate(0, -${navbarHeight / 2}em`,
|
||||
}}
|
||||
>
|
||||
<Switch>
|
||||
<Route
|
||||
exact
|
||||
@ -161,29 +173,19 @@ const Main = ({ settings, setSettings }: MainProps): JSX.Element => {
|
||||
)}
|
||||
/>
|
||||
<Route
|
||||
path='/ref/:refCode'
|
||||
path='/robot/:refCode?'
|
||||
render={(props: any) => (
|
||||
<UserGenPage match={props.match} theme={theme} robot={robot} setRobot={setRobot} />
|
||||
)}
|
||||
/>
|
||||
<Route
|
||||
path='/make'
|
||||
render={() => (
|
||||
<MakerPage
|
||||
book={book}
|
||||
limits={limits}
|
||||
fetchLimits={fetchLimits}
|
||||
maker={maker}
|
||||
setMaker={setMaker}
|
||||
fav={fav}
|
||||
setFav={setFav}
|
||||
windowSize={windowSize}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<Route
|
||||
path='/book'
|
||||
render={() => (
|
||||
|
||||
<Route path='/offers'>
|
||||
<Slide
|
||||
direction={page === 'offers' ? slideDirection.in : slideDirection.out}
|
||||
in={page === 'offers'}
|
||||
appear={slideDirection.in != undefined}
|
||||
>
|
||||
<div>
|
||||
<BookPage
|
||||
book={book}
|
||||
fetchBook={fetchBook}
|
||||
@ -196,34 +198,66 @@ const Main = ({ settings, setSettings }: MainProps): JSX.Element => {
|
||||
lastDayPremium={info.last_day_nonkyc_btc_premium}
|
||||
windowSize={windowSize}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</Slide>
|
||||
</Route>
|
||||
|
||||
<Route path='/create'>
|
||||
<Slide
|
||||
direction={page === 'create' ? slideDirection.in : slideDirection.out}
|
||||
in={page === 'create'}
|
||||
appear={slideDirection.in != undefined}
|
||||
>
|
||||
<div>
|
||||
<MakerPage
|
||||
book={book}
|
||||
limits={limits}
|
||||
fetchLimits={fetchLimits}
|
||||
maker={maker}
|
||||
setMaker={setMaker}
|
||||
fav={fav}
|
||||
setFav={setFav}
|
||||
windowSize={{ ...windowSize, height: windowSize.height - navbarHeight }}
|
||||
/>
|
||||
</div>
|
||||
</Slide>
|
||||
</Route>
|
||||
|
||||
<Route
|
||||
path='/order/:orderId'
|
||||
render={(props: any) => <OrderPage theme={theme} history={history} {...props} />}
|
||||
/>
|
||||
<Route
|
||||
path='/settings'
|
||||
render={(props: any) => <SettingsPage settings={settings} setSettings={setSettings} />}
|
||||
/>
|
||||
</Switch>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
height: '2.5em',
|
||||
position: 'fixed',
|
||||
bottom: 0,
|
||||
}}
|
||||
|
||||
<Route path='/settings'>
|
||||
<Slide
|
||||
direction={page === 'settings' ? slideDirection.in : slideDirection.out}
|
||||
in={page === 'settings'}
|
||||
appear={slideDirection.in != undefined}
|
||||
mountOnEnter
|
||||
>
|
||||
<div>
|
||||
<SettingsPage
|
||||
settings={settings}
|
||||
setSettings={setSettings}
|
||||
windowSize={{ ...windowSize, height: windowSize.height - navbarHeight }}
|
||||
/>
|
||||
</div>
|
||||
</Slide>
|
||||
</Route>
|
||||
</Switch>
|
||||
</Box>
|
||||
<NavBar
|
||||
width={windowSize.width}
|
||||
height={navbarHeight}
|
||||
page={page}
|
||||
setPage={setPage}
|
||||
setSlideDirection={setSlideDirection}
|
||||
robot={robot}
|
||||
setRobot={setRobot}
|
||||
info={info}
|
||||
setInfo={setInfo}
|
||||
fetchInfo={fetchInfo}
|
||||
/>
|
||||
</div>
|
||||
</Router>
|
||||
);
|
||||
};
|
||||
|
@ -1,6 +1,5 @@
|
||||
import React, { useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { Button, Grid, Paper, Collapse, Typography } from '@mui/material';
|
||||
|
||||
import { LimitList, Maker, Book, Favorites } from '../../models';
|
||||
@ -32,9 +31,8 @@ const MakerPage = ({
|
||||
windowSize,
|
||||
}: MakerPageProps): JSX.Element => {
|
||||
const { t } = useTranslation();
|
||||
const history = useHistory();
|
||||
|
||||
const maxHeight = windowSize.height * 0.85 - 7;
|
||||
const maxHeight = windowSize.height * 0.85 - 3;
|
||||
const [showMatches, setShowMatches] = useState<boolean>(false);
|
||||
|
||||
const matches = filterOrders({
|
||||
@ -96,11 +94,6 @@ const MakerPage = ({
|
||||
/>
|
||||
</Paper>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<Button color='secondary' variant='contained' onClick={() => history.push('/')}>
|
||||
{t('Back')}
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
@ -1,52 +1,137 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import {
|
||||
Badge,
|
||||
Tooltip,
|
||||
ListItemAvatar,
|
||||
Paper,
|
||||
Button,
|
||||
Grid,
|
||||
IconButton,
|
||||
Select,
|
||||
MenuItem,
|
||||
ListItemText,
|
||||
ListItem,
|
||||
ListItemIcon,
|
||||
ListItemButton,
|
||||
useTheme,
|
||||
} from '@mui/material';
|
||||
import { Link as LinkRouter } from 'react-router-dom';
|
||||
import { apiClient } from '../../services/api';
|
||||
import { systemClient } from '../../services/System';
|
||||
import { Tabs, Tab, Paper, Button, useTheme } from '@mui/material';
|
||||
import RobotAvatar from '../../components/RobotAvatar';
|
||||
|
||||
import {
|
||||
SettingsApplications,
|
||||
SmartToy,
|
||||
Storefront,
|
||||
AddBox,
|
||||
Assignment,
|
||||
MoreHoriz,
|
||||
} from '@mui/icons-material';
|
||||
|
||||
type Page = 'robot' | 'offers' | 'create' | 'order' | 'settings' | 'none';
|
||||
type Direction = 'left' | 'right' | 'none';
|
||||
|
||||
interface NavBarProps {
|
||||
page: Page;
|
||||
setPage: (state: Page) => void;
|
||||
slideDirection: { in: Direction; out: Direction };
|
||||
setSlideDirection: (state: { in: Direction; out: Direction }) => void;
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
||||
type Page = 'robot' | 'order' | 'make' | 'book' | 'settings';
|
||||
|
||||
const NavBar = ({ width }: NavBarProps): JSX.Element => {
|
||||
const NavBar = ({
|
||||
page,
|
||||
setPage,
|
||||
slideDirection,
|
||||
setSlideDirection,
|
||||
width,
|
||||
height,
|
||||
}: NavBarProps): JSX.Element => {
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
const history = useHistory();
|
||||
const { pathname } = history.location;
|
||||
const smallBar = width < 50;
|
||||
const tabWidth = smallBar ? 1 : 1;
|
||||
|
||||
const [page, setPage] = useState<Page>(history.location.pathname.split('/'));
|
||||
const [showMore, setShowMore] = useState<boolean>(false);
|
||||
const [newPage, setNewPage] = useState<Page>(history.location.pathname.split('/')[1]);
|
||||
|
||||
const changePage = function (newPage: Page) {
|
||||
setPage(newPage);
|
||||
history.push(`/${newPage}`);
|
||||
const pagesPosition = {
|
||||
robot: 1,
|
||||
offers: 2,
|
||||
create: 3,
|
||||
order: 4,
|
||||
settings: 5,
|
||||
};
|
||||
const handleSlideDirection = function (oldPage: Page, newPage: Page) {
|
||||
const oldPos: number = pagesPosition[oldPage];
|
||||
const newPos: number = pagesPosition[newPage];
|
||||
setSlideDirection(
|
||||
newPos > oldPos ? { in: 'left', out: 'right' } : { in: 'right', out: 'left' },
|
||||
);
|
||||
};
|
||||
|
||||
const changePage = function (mouseEvent: any, newPage: Page) {
|
||||
if (newPage === 'none') {
|
||||
return null;
|
||||
} else {
|
||||
handleSlideDirection(page, newPage);
|
||||
setNewPage(newPage);
|
||||
setTimeout(() => history.push(`/${newPage}`), theme.transitions.duration.leavingScreen * 3);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setPage(newPage);
|
||||
}, [slideDirection, newPage]);
|
||||
|
||||
return (
|
||||
<Paper elevation={6} style={{ height: '2.5em', width: `${width * 0.9}em` }}>
|
||||
{page}
|
||||
<Button onClick={() => changePage('robot')}>ROBOT</Button>
|
||||
<Button onClick={() => changePage('book')}>BOOK</Button>
|
||||
<Button onClick={() => changePage('make')}>MAKER</Button>
|
||||
<Button onClick={() => changePage('order/1')}>ORDER</Button>
|
||||
<Button onClick={() => changePage('settings')}>SETTINGS</Button>
|
||||
<Paper
|
||||
elevation={6}
|
||||
sx={{ height: `${height}em`, width: `${width * 0.9}em`, position: 'fixed', bottom: 0 }}
|
||||
>
|
||||
<Tabs
|
||||
TabIndicatorProps={{ sx: { height: '0.3em', position: 'absolute', top: 0 } }}
|
||||
variant={smallBar ? 'scrollable' : 'fullWidth'}
|
||||
centered={!smallBar}
|
||||
allowScrollButtonsMobile
|
||||
scrollButtons={smallBar}
|
||||
value={page}
|
||||
onChange={changePage}
|
||||
aria-label='navigation bar'
|
||||
>
|
||||
<Tab
|
||||
sx={{ maxWidth: `${tabWidth}em` }}
|
||||
label={smallBar ? undefined : t('Robot')}
|
||||
value='robot'
|
||||
icon={<SmartToy />}
|
||||
iconPosition='start'
|
||||
/>
|
||||
<Tab
|
||||
sx={{ maxWidth: `${tabWidth}em` }}
|
||||
label={smallBar ? undefined : t('Offers')}
|
||||
value='offers'
|
||||
icon={<Storefront />}
|
||||
iconPosition='start'
|
||||
/>
|
||||
<Tab
|
||||
sx={{ maxWidth: `${tabWidth}em` }}
|
||||
label={smallBar ? undefined : t('Create')}
|
||||
value='create'
|
||||
icon={<AddBox />}
|
||||
iconPosition='start'
|
||||
/>
|
||||
<Tab
|
||||
sx={{ maxWidth: `${tabWidth}em` }}
|
||||
label={smallBar ? undefined : t('Order')}
|
||||
value='order/1'
|
||||
icon={<Assignment />}
|
||||
iconPosition='start'
|
||||
/>
|
||||
<Tab
|
||||
sx={{ maxWidth: `${tabWidth}em` }}
|
||||
label={smallBar ? undefined : t('Settings')}
|
||||
value='settings'
|
||||
icon={<SettingsApplications />}
|
||||
iconPosition='start'
|
||||
/>
|
||||
<Tab
|
||||
sx={{ maxWidth: `${tabWidth}em` }}
|
||||
label={smallBar ? undefined : t('More')}
|
||||
value={'none'}
|
||||
onClick={() => {
|
||||
setShowMore(!showMore);
|
||||
}}
|
||||
icon={<MoreHoriz />}
|
||||
iconPosition='start'
|
||||
/>
|
||||
</Tabs>
|
||||
</Paper>
|
||||
);
|
||||
};
|
||||
|
@ -1,21 +1,30 @@
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Paper, useTheme } from '@mui/material';
|
||||
import { Grid, Paper, useTheme } from '@mui/material';
|
||||
import SettingsForm from '../../components/SettingsForm';
|
||||
import { Settings } from '../../models';
|
||||
|
||||
interface SettingsPageProps {
|
||||
settings: Settings;
|
||||
setSettings: (state: Settings) => void;
|
||||
windowSize: { width: number; height: number };
|
||||
}
|
||||
|
||||
const SettingsPage = ({ settings, setSettings }: SettingsPageProps): JSX.Element => {
|
||||
const SettingsPage = ({ settings, setSettings, windowSize }: SettingsPageProps): JSX.Element => {
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
const maxHeight = windowSize.height * 0.85 - 3;
|
||||
|
||||
return (
|
||||
<Paper elevation={12} sx={{ padding: '0.6em', width: '12em', height: '12em' }}>
|
||||
<Paper
|
||||
elevation={12}
|
||||
sx={{ padding: '0.6em', width: '17.25em', maxHeight: `${maxHeight}em`, overflow: 'auto' }}
|
||||
>
|
||||
<Grid container>
|
||||
<Grid item>
|
||||
<SettingsForm settings={settings} setSettings={setSettings} />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Paper>
|
||||
);
|
||||
};
|
||||
|
@ -28,6 +28,7 @@ interface SelectLanguageProps {
|
||||
language: Language;
|
||||
setLanguage: (lang: Language) => void;
|
||||
}
|
||||
|
||||
const SelectLanguage = ({ language, setLanguage }: SelectLanguageProps): JSX.Element => {
|
||||
const theme = useTheme();
|
||||
const { t, i18n } = useTranslation();
|
||||
@ -42,10 +43,9 @@ const SelectLanguage = ({ language, setLanguage }: SelectLanguageProps): JSX.Ele
|
||||
i18n.changeLanguage(e.target.value);
|
||||
};
|
||||
|
||||
console.log(language);
|
||||
return (
|
||||
<Select
|
||||
autoWidth={true}
|
||||
fullWidth={true}
|
||||
value={language}
|
||||
inputProps={{
|
||||
style: { textAlign: 'center' },
|
||||
|
@ -1,25 +1,87 @@
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Grid, useTheme } from '@mui/material';
|
||||
import {
|
||||
Grid,
|
||||
Paper,
|
||||
Switch,
|
||||
useTheme,
|
||||
FormControlLabel,
|
||||
List,
|
||||
ListItem,
|
||||
ListItemIcon,
|
||||
} from '@mui/material';
|
||||
import { Settings } from '../../models';
|
||||
import SelectLanguage from './SelectLanguage';
|
||||
import { Language, Palette, LightMode, DarkMode } from '@mui/icons-material';
|
||||
|
||||
interface SettingsFormProps {
|
||||
dense?: boolean;
|
||||
settings: Settings;
|
||||
setSettings: (state: Settings) => void;
|
||||
}
|
||||
|
||||
const SettingsForm = ({ settings, setSettings }: SettingsFormProps): JSX.Element => {
|
||||
const SettingsForm = ({ dense = false, settings, setSettings }: SettingsFormProps): JSX.Element => {
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<Grid container>
|
||||
<Grid container spacing={1}>
|
||||
<Grid item>
|
||||
<List dense={dense}>
|
||||
<ListItem>
|
||||
<ListItemIcon>
|
||||
<Language />
|
||||
</ListItemIcon>
|
||||
<SelectLanguage
|
||||
language={settings.language}
|
||||
setLanguage={(language) => setSettings({ ...settings, language })}
|
||||
/>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<ListItemIcon>
|
||||
<Palette />
|
||||
</ListItemIcon>
|
||||
<FormControlLabel
|
||||
labelPlacement='end'
|
||||
label={settings.mode === 'dark' ? t('Dark') : t('Light')}
|
||||
control={
|
||||
<Switch
|
||||
checked={settings.mode === 'dark'}
|
||||
checkedIcon={
|
||||
<Paper
|
||||
elevation={3}
|
||||
sx={{
|
||||
width: '1.2em',
|
||||
height: '1.2em',
|
||||
borderRadius: '0.4em',
|
||||
backgroundColor: 'white',
|
||||
}}
|
||||
>
|
||||
<DarkMode sx={{ width: '0.8em', height: '0.8em', color: '#666' }} />
|
||||
</Paper>
|
||||
}
|
||||
icon={
|
||||
<Paper
|
||||
elevation={3}
|
||||
sx={{
|
||||
width: '1.2em',
|
||||
height: '1.2em',
|
||||
borderRadius: '0.4em',
|
||||
backgroundColor: 'white',
|
||||
padding: '0.07em',
|
||||
}}
|
||||
>
|
||||
<LightMode sx={{ width: '0.7em', height: '0.7em', color: '#666' }} />
|
||||
</Paper>
|
||||
}
|
||||
onChange={(e) =>
|
||||
setSettings({ ...settings, mode: e.target.checked ? 'dark' : 'light' })
|
||||
}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</ListItem>
|
||||
</List>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
|
@ -46,13 +46,6 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
.appCenter {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%) translate(0, -20px);
|
||||
}
|
||||
|
||||
.alertUnsafe {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
|
@ -4,13 +4,12 @@ from .views import basic, pro
|
||||
|
||||
urlpatterns = [
|
||||
path("", basic),
|
||||
path("make/", basic),
|
||||
path("create/", basic),
|
||||
path("robot/", basic),
|
||||
path("ref/<refCode>", basic),
|
||||
path("book/", basic),
|
||||
path("robot/<refCode>", basic),
|
||||
path("offers/", basic),
|
||||
path("order/<int:orderId>", basic),
|
||||
path("settings/", basic),
|
||||
path("", basic),
|
||||
path("ref/<refCode>", basic),
|
||||
path("pro/", pro),
|
||||
]
|
||||
|
Loading…
Reference in New Issue
Block a user