add init version of server page layout

This commit is contained in:
Dawid Wysokiński 2020-11-11 12:47:19 +01:00
parent 95f8534824
commit 05b19413e1
37 changed files with 1282 additions and 20 deletions

View File

@ -14,6 +14,7 @@
"@types/node": "^12.0.0",
"@types/react": "^16.9.53",
"@types/react-dom": "^16.9.8",
"clsx": "^1.1.1",
"date-fns": "^2.16.1",
"graphql": "^15.4.0",
"i18next": "^19.8.3",

View File

@ -19,12 +19,30 @@ const CustomizedRRDLink = forwardRef(
)
);
function Link({ children, ...props }: Props) {
return (
<MUILink {...props} component={CustomizedRRDLink}>
{children}
</MUILink>
);
}
const Link = forwardRef(
(
{ children, ...props }: Props,
ref:
| ((instance: HTMLAnchorElement | null) => void)
| RefObject<HTMLAnchorElement>
| null
| undefined
) => {
return (
<MUILink {...props} ref={ref} component={CustomizedRRDLink}>
{children}
</MUILink>
);
}
);
// function Link({ children, ...props }: Props) {
// return ;
// }
Link.defaultProps = {
color: 'secondary',
underline: 'none',
};
export default Link;

View File

@ -0,0 +1,44 @@
import React from 'react';
import {
Box,
Typography,
CircularProgress,
BoxProps,
TypographyProps,
} from '@material-ui/core';
export interface Props {
size?: number;
containerProps?: BoxProps;
typographyProps?: TypographyProps;
description?: string;
}
function Spinner({
size,
containerProps,
typographyProps,
description,
}: Props) {
return (
<Box {...containerProps}>
<Box mb={description ? 1 : 0}>
<CircularProgress size={size} />
</Box>
{description && (
<Typography {...typographyProps}>{description}</Typography>
)}
</Box>
);
}
Spinner.defaultProps = {
size: 200,
containerProps: {} as BoxProps,
typographyProps: {
variant: 'h3',
} as TypographyProps,
description: '',
} as Props;
export default Spinner;

View File

@ -2,9 +2,11 @@ export const DEFAULT_LANGUAGE = process.env.DEFAULT_LANGUAGE ?? 'en';
export const NAME = 'TWHelp';
export type ServerStatus = 'open' | 'closed';
export const SERVER_STATUS = {
CLOSED: 'closed',
OPEN: 'open',
CLOSED: 'closed' as ServerStatus,
OPEN: 'open' as ServerStatus,
};
export const TWHELP = process.env.TWHelp ?? 'https://tribalwarshelp.com';

View File

@ -1,3 +1,7 @@
export const COMMON = 'common';
export const INDEX_PAGE = 'index-page';
export const NOT_FOUND_PAGE = 'not-found-page';
export const SERVER_PAGE = {
COMMON: 'server-page/common',
INDEX_PAGE: 'server-page/index-page',
};

View File

@ -1 +1,7 @@
export const INDEX_PAGE = '/';
export const SERVER_PAGE = {
BASE: '/server',
get INDEX_PAGE() {
return this.BASE + '/:key';
},
};

View File

@ -6,6 +6,7 @@ import { CssBaseline } from '@material-ui/core';
import IndexPage from './IndexPage/IndexPage';
import NotFoundPage from './NotFoundPage/NotFoundPage';
import ServerPage from './ServerPage/ServerPage';
function App() {
return (
@ -14,6 +15,9 @@ function App() {
<Route path={ROUTES.INDEX_PAGE} exact>
<IndexPage />
</Route>
<Route path={ROUTES.SERVER_PAGE.BASE}>
<ServerPage />
</Route>
<Route>
<NotFoundPage />
</Route>

View File

@ -8,7 +8,7 @@ export default function Header() {
const classes = useStyles();
return (
<AppBar position="static" component="footer">
<AppBar position="static" component="footer" elevation={0}>
<Container>
<Toolbar disableGutters className={classes.toolbar}>
<Typography align="center" className={classes.copyright}>

View File

@ -31,7 +31,7 @@ export default function Header() {
const classes = useStyles();
return (
<AppBar position="fixed">
<AppBar position="fixed" elevation={0}>
<Container>
<Toolbar disableGutters className={classes.toolbar}>
<div className={classes.searchInputWrapper}>

View File

@ -7,6 +7,8 @@ import {
withDefault,
} from 'use-query-params';
import { useTranslation } from 'react-i18next';
import { generatePath } from 'react-router';
import * as ROUTES from '@config/routes';
import * as NAMESPACES from '@config/namespaces';
import { SERVER_STATUS } from '@config/app';
import { ServerList } from './types';
@ -26,6 +28,7 @@ import { ExpandMore as ExpandMoreIcon } from '@material-ui/icons';
import Pagination, {
Props as PaginationProps,
} from '@common/Pagination/Pagination';
import Link from '@common/Link/Link';
const PER_PAGE = 48;
const arr = new Array(PER_PAGE).fill(0);
@ -102,13 +105,19 @@ export default function ServerSelection() {
<Accordion>
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
<Typography variant="h5">
{server.key}{' '}
{SERVER_STATUS.CLOSED === server.status
? `(${t(
NAMESPACES.COMMON +
`:serverStatus.${server.status}`
).toLowerCase()})`
: ''}
<Link
to={generatePath(ROUTES.SERVER_PAGE.INDEX_PAGE, {
key: server.key,
})}
>
{server.key}{' '}
{SERVER_STATUS.CLOSED === server.status
? `(${t(
NAMESPACES.COMMON +
`:serverStatus.${server.status}`
).toLowerCase()})`
: ''}
</Link>
</Typography>
</AccordionSummary>
<AccordionDetails>

View File

@ -1,8 +1,9 @@
import { List } from '@libs/graphql/types';
import { ServerStatus } from '@config/app';
export type Server = {
key: string;
status: string;
status: ServerStatus;
numberOfPlayers: number;
numberOfTribes: number;
numberOfVillages: number;

View File

@ -0,0 +1,21 @@
import React from 'react';
import { SERVER_PAGE } from '@config/routes';
import { Switch, Route } from 'react-router-dom';
import IndexPage from './features/IndexPage/IndexPage';
import NotFoundPage from '../NotFoundPage/NotFoundPage';
function ServerPage() {
return (
<Switch>
<Route path={SERVER_PAGE.INDEX_PAGE}>
<IndexPage />
</Route>
<Route path="*">
<NotFoundPage />
</Route>
</Switch>
);
}
export default ServerPage;

View File

@ -0,0 +1,75 @@
import React, { useState } from 'react';
import clsx from 'clsx';
import { useTranslation } from 'react-i18next';
import { SERVER_PAGE } from '@config/namespaces';
import { DRAWER_WIDTH } from './components/Sidebar/contants';
import { makeStyles, useTheme } from '@material-ui/core/styles';
import { useMediaQuery, Toolbar } from '@material-ui/core';
import ServerProvider from '@features/ServerPage/libs/ServerContext/Provider';
import Sidebar from './components/Sidebar/Sidebar';
import TopBar from './components/TopBar/TopBar';
export interface Props {
children: React.ReactNode;
}
const useStyles = makeStyles(theme => ({
root: {
paddingTop: 56,
height: '100%',
[theme.breakpoints.up('sm')]: {
paddingTop: 64,
},
},
shiftContent: {
paddingLeft: DRAWER_WIDTH,
},
content: {
height: '100%',
padding: theme.spacing(2),
},
}));
function PageLayout({ children }: Props) {
const [open, setOpen] = useState(false);
const classes = useStyles();
const theme = useTheme();
const isDesktop = useMediaQuery(theme.breakpoints.up('lg'), {
defaultMatches: true,
});
const { t } = useTranslation(SERVER_PAGE.COMMON);
const shouldOpenSidebar = isDesktop ? true : open;
const openSidebar = () => {
setOpen(true);
};
const closeSidebar = () => {
setOpen(false);
};
return (
<ServerProvider>
<div
className={clsx({
[classes.shiftContent]: isDesktop,
})}
>
<TopBar openSidebar={openSidebar} t={t} />
<Toolbar />
<Sidebar
onClose={closeSidebar}
open={shouldOpenSidebar}
variant={isDesktop ? 'persistent' : 'temporary'}
t={t}
onOpen={openSidebar}
/>
<main className={classes.content}>{children}</main>
</div>
</ServerProvider>
);
}
export default PageLayout;

View File

@ -0,0 +1,58 @@
import React from 'react';
import clsx from 'clsx';
import { generatePath } from 'react-router';
import { TFunction } from 'i18next';
import useServer from '@features/ServerPage/libs/ServerContext/useServer';
import useStyles from './useStyles';
import * as ROUTES from '@config/routes';
import { Route } from './components/Nav/types';
import { Divider, SwipeableDrawer, DrawerProps } from '@material-ui/core';
import DashboardIcon from '@material-ui/icons/Dashboard';
import Nav from './components/Nav/Nav';
import ServerInfo from './components/ServerInfo/ServerInfo';
export interface Props {
t: TFunction;
className?: string;
open: boolean;
onClose: React.ReactEventHandler<{}>;
onOpen: React.ReactEventHandler<{}>;
variant?: DrawerProps['variant'];
}
const Sidebar = ({ t, className, open, variant, onClose, onOpen }: Props) => {
const classes = useStyles();
const { key } = useServer();
const routes: Route[] = [
{
name: t('pageLayout.sidebar.routes.dashboard'),
to: generatePath(ROUTES.SERVER_PAGE.INDEX_PAGE, {
key: key,
}),
Icon: <DashboardIcon />,
},
];
return (
<SwipeableDrawer
anchor="left"
classes={{ paper: classes.drawer }}
onClose={onClose}
onOpen={onOpen}
open={open}
variant={variant}
disableBackdropTransition
>
<div className={clsx(classes.root, className)}>
<ServerInfo t={t} />
<Divider />
<Nav routes={routes} />
</div>
</SwipeableDrawer>
);
};
export default Sidebar;

View File

@ -0,0 +1,80 @@
import React, { Fragment, useState } from 'react';
import { Route } from './types';
import { makeStyles } from '@material-ui/core/styles';
import {
ListItem as MUIListItem,
ListItemIcon,
ListItemText,
Collapse,
List,
Box,
} from '@material-ui/core';
import { ExpandLess, ExpandMore } from '@material-ui/icons';
import Link from '@common/Link/Link';
export interface Props {
route: Route;
nestedLevel: number;
}
const useStyles = makeStyles(theme => ({
link: {
display: 'block',
width: '100%',
},
}));
function ListItem({ route, nestedLevel }: Props) {
const [open, setOpen] = useState(false);
const classes = useStyles();
const hasNested = Array.isArray(route.nested) && route.nested.length > 0;
const getItem = () => {
return (
<MUIListItem
onClick={hasNested ? () => setOpen(!open) : undefined}
disableGutters
button
component={Box}
pl={nestedLevel}
dense
>
<ListItemIcon>{route.Icon}</ListItemIcon>
<ListItemText primary={route.name} />
{hasNested && (
<Fragment>{open ? <ExpandLess /> : <ExpandMore />}</Fragment>
)}
</MUIListItem>
);
};
return (
<Fragment>
{!hasNested ? (
<Link to={route.to} className={classes.link} color="inherit">
{getItem()}
</Link>
) : (
getItem()
)}
{hasNested && (
<Collapse in={open} timeout="auto">
<List component="div" disablePadding>
{route.nested?.map(route => {
return (
<ListItem
route={route}
nestedLevel={nestedLevel + 1}
key={route.name}
/>
);
})}
</List>
</Collapse>
)}
</Fragment>
);
}
export default ListItem;

View File

@ -0,0 +1,28 @@
import React from 'react';
import { Route } from './types';
import { makeStyles } from '@material-ui/core/styles';
import { List } from '@material-ui/core';
import ListItem from './ListItem';
export interface Props {
routes: Route[];
}
const useStyles = makeStyles(theme => ({
root: {},
}));
const Nav = ({ routes }: Props) => {
const classes = useStyles();
return (
<List className={classes.root}>
{routes.map(route => (
<ListItem nestedLevel={1} route={route} key={route.name} />
))}
</List>
);
};
export default Nav;

View File

@ -0,0 +1,6 @@
export interface Route {
name: string;
to: string;
Icon: React.ReactElement;
nested?: Route[];
}

View File

@ -0,0 +1,59 @@
import React from 'react';
import { TFunction } from 'i18next';
import useServer from '@features/ServerPage/libs/ServerContext/useServer';
import useStyles from './useStyles';
import formatDistanceToNow from '@libs/date/formatDistanceToNow';
import { Locale } from '@libs/date/locales';
import extractVersionCodeFromHostname from '@utils/extractVersionCodeFromHostname';
import { Typography } from '@material-ui/core';
export interface Props {
t: TFunction;
}
const ServerInfo = ({ t }: Props) => {
const {
numberOfPlayers,
numberOfTribes,
dataUpdatedAt,
numberOfVillages,
} = useServer();
const classes = useStyles();
return (
<div className={classes.root}>
<Typography>
{t('pageLayout.sidebar.serverInfo.numberOfPlayers', {
num: numberOfPlayers.toLocaleString(),
count: numberOfPlayers,
})}
</Typography>
<Typography>
{t('pageLayout.sidebar.serverInfo.numberOfTribes', {
num: numberOfTribes.toLocaleString(),
count: numberOfTribes,
})}
</Typography>
<Typography>
{t('pageLayout.sidebar.serverInfo.numberOfVillages', {
num: numberOfVillages.toLocaleString(),
count: numberOfVillages,
})}
</Typography>
<Typography>
{t('pageLayout.sidebar.serverInfo.dataUpdatedAt', {
date: formatDistanceToNow(new Date(dataUpdatedAt), {
locale: extractVersionCodeFromHostname(
window.location.hostname
) as Locale,
addSuffix: true,
}),
})}
</Typography>
</div>
);
};
export default ServerInfo;

View File

@ -0,0 +1,20 @@
import { makeStyles } from '@material-ui/core/styles';
const useStyles = makeStyles(theme => ({
root: {
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
minHeight: 'fit-content',
textAlign: 'center',
padding: theme.spacing(1),
'& > *:not(:last-child)': {
marginBottom: theme.spacing(0.5),
},
},
status: {
marginBottom: theme.spacing(1),
},
}));
export default useStyles;

View File

@ -0,0 +1 @@
export const DRAWER_WIDTH = 250;

View File

@ -0,0 +1,19 @@
import { makeStyles } from '@material-ui/core/styles';
import { DRAWER_WIDTH } from './contants';
const useStyles = makeStyles(theme => ({
drawer: {
width: DRAWER_WIDTH,
[theme.breakpoints.up('lg')]: {
marginTop: 64,
height: 'calc(100% - 64px) !important',
},
},
root: {
backgroundColor: theme.palette.background.paper,
display: 'flex',
flexDirection: 'column',
height: '100%',
},
}));
export default useStyles;

View File

@ -0,0 +1,28 @@
import React from 'react';
import clsx from 'clsx';
import { TFunction } from 'i18next';
import { AppBar, Toolbar, Hidden, IconButton } from '@material-ui/core';
import MenuIcon from '@material-ui/icons/Menu';
export interface Props {
className?: string;
t: TFunction;
openSidebar?: () => void;
}
const TopBar = ({ className, openSidebar }: Props) => {
return (
<AppBar className={clsx(className)} elevation={0}>
<Toolbar>
<Hidden lgUp>
<IconButton color="inherit" onClick={openSidebar}>
<MenuIcon />
</IconButton>
</Hidden>
</Toolbar>
</AppBar>
);
};
export default TopBar;

View File

@ -0,0 +1,580 @@
import React from 'react';
import PageLayout from '@features/ServerPage/common/PageLayout/PageLayout';
function IndexPage() {
return (
<PageLayout>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Doloremque vel,
sequi laborum fugit et libero facilis officiis, fuga dolorem iste ea in
iusto at, repellendus facere. Facilis voluptatibus error illum? Lorem
ipsum dolor sit amet consectetur, adipisicing elit. Officiis eveniet,
facilis aut neque, aliquam ullam amet consequuntur numquam asperiores
ducimus ab, explicabo iure? Aliquid numquam ab excepturi facere dolores
illum. Lorem ipsum dolor sit, amet consectetur adipisicing elit. Fugit,
quae consequuntur? Unde dicta, non inventore magni at rem, debitis et
molestiae officia obcaecati expedita suscipit est fugiat deserunt,
beatae hic? Lorem ipsum dolor sit amet consectetur adipisicing elit.
Molestiae recusandae facilis iure, ipsum excepturi voluptates amet
libero explicabo! Mollitia magni consequuntur perspiciatis consectetur
officiis cum. Illum exercitationem eveniet dolorum maiores. Lorem ipsum
dolor sit amet, consectetur adipisicing elit. Amet commodi molestiae
veritatis ad suscipit at, eos sapiente illum laborum ipsum, unde
reiciendis, praesentium temporibus officia optio nemo dolorum magni
tempora. Lorem ipsum dolor sit amet consectetur adipisicing elit. Fuga,
consectetur laborum? Impedit deserunt dolor qui eligendi aspernatur
magnam ratione at inventore, placeat est. Commodi nobis tenetur suscipit
cupiditate ipsum excepturi. Lorem ipsum dolor sit amet consectetur
adipisicing elit. Vitae illum, explicabo maxime placeat aliquam quos,
harum aliquid aspernatur officia ullam voluptatum beatae? Fugit laborum
in recusandae eius tempore ab quasi. Lorem ipsum dolor sit amet
consectetur adipisicing elit. Doloremque vel, sequi laborum fugit et
libero facilis officiis, fuga dolorem iste ea in iusto at, repellendus
facere. Facilis voluptatibus error illum? Lorem ipsum dolor sit amet
consectetur, adipisicing elit. Officiis eveniet, facilis aut neque,
aliquam ullam amet consequuntur numquam asperiores ducimus ab, explicabo
iure? Aliquid numquam ab excepturi facere dolores illum. Lorem ipsum
dolor sit, amet consectetur adipisicing elit. Fugit, quae consequuntur?
Unde dicta, non inventore magni at rem, debitis et molestiae officia
obcaecati expedita suscipit est fugiat deserunt, beatae hic? Lorem ipsum
dolor sit amet consectetur adipisicing elit. Molestiae recusandae
facilis iure, ipsum excepturi voluptates amet libero explicabo! Mollitia
magni consequuntur perspiciatis consectetur officiis cum. Illum
exercitationem eveniet dolorum maiores. Lorem ipsum dolor sit amet,
consectetur adipisicing elit. Amet commodi molestiae veritatis ad
suscipit at, eos sapiente illum laborum ipsum, unde reiciendis,
praesentium temporibus officia optio nemo dolorum magni tempora. Lorem
ipsum dolor sit amet consectetur adipisicing elit. Fuga, consectetur
laborum? Impedit deserunt dolor qui eligendi aspernatur magnam ratione
at inventore, placeat est. Commodi nobis tenetur suscipit cupiditate
ipsum excepturi. Lorem ipsum dolor sit amet consectetur adipisicing
elit. Vitae illum, explicabo maxime placeat aliquam quos, harum aliquid
aspernatur officia ullam voluptatum beatae? Fugit laborum in recusandae
eius tempore ab quasi. Lorem ipsum dolor sit amet consectetur
adipisicing elit. Doloremque vel, sequi laborum fugit et libero facilis
officiis, fuga dolorem iste ea in iusto at, repellendus facere. Facilis
voluptatibus error illum? Lorem ipsum dolor sit amet consectetur,
adipisicing elit. Officiis eveniet, facilis aut neque, aliquam ullam
amet consequuntur numquam asperiores ducimus ab, explicabo iure? Aliquid
numquam ab excepturi facere dolores illum. Lorem ipsum dolor sit, amet
consectetur adipisicing elit. Fugit, quae consequuntur? Unde dicta, non
inventore magni at rem, debitis et molestiae officia obcaecati expedita
suscipit est fugiat deserunt, beatae hic? Lorem ipsum dolor sit amet
consectetur adipisicing elit. Molestiae recusandae facilis iure, ipsum
excepturi voluptates amet libero explicabo! Mollitia magni consequuntur
perspiciatis consectetur officiis cum. Illum exercitationem eveniet
dolorum maiores. Lorem ipsum dolor sit amet, consectetur adipisicing
elit. Amet commodi molestiae veritatis ad suscipit at, eos sapiente
illum laborum ipsum, unde reiciendis, praesentium temporibus officia
optio nemo dolorum magni tempora. Lorem ipsum dolor sit amet consectetur
adipisicing elit. Fuga, consectetur laborum? Impedit deserunt dolor qui
eligendi aspernatur magnam ratione at inventore, placeat est. Commodi
nobis tenetur suscipit cupiditate ipsum excepturi. Lorem ipsum dolor sit
amet consectetur adipisicing elit. Vitae illum, explicabo maxime placeat
aliquam quos, harum aliquid aspernatur officia ullam voluptatum beatae?
Fugit laborum in recusandae eius tempore ab quasi. Lorem ipsum dolor sit
amet consectetur adipisicing elit. Doloremque vel, sequi laborum fugit
et libero facilis officiis, fuga dolorem iste ea in iusto at,
repellendus facere. Facilis voluptatibus error illum? Lorem ipsum dolor
sit amet consectetur, adipisicing elit. Officiis eveniet, facilis aut
neque, aliquam ullam amet consequuntur numquam asperiores ducimus ab,
explicabo iure? Aliquid numquam ab excepturi facere dolores illum. Lorem
ipsum dolor sit, amet consectetur adipisicing elit. Fugit, quae
consequuntur? Unde dicta, non inventore magni at rem, debitis et
molestiae officia obcaecati expedita suscipit est fugiat deserunt,
beatae hic? Lorem ipsum dolor sit amet consectetur adipisicing elit.
Molestiae recusandae facilis iure, ipsum excepturi voluptates amet
libero explicabo! Mollitia magni consequuntur perspiciatis consectetur
officiis cum. Illum exercitationem eveniet dolorum maiores. Lorem ipsum
dolor sit amet, consectetur adipisicing elit. Amet commodi molestiae
veritatis ad suscipit at, eos sapiente illum laborum ipsum, unde
reiciendis, praesentium temporibus officia optio nemo dolorum magni
tempora. Lorem ipsum dolor sit amet consectetur adipisicing elit. Fuga,
consectetur laborum? Impedit deserunt dolor qui eligendi aspernatur
magnam ratione at inventore, placeat est. Commodi nobis tenetur suscipit
cupiditate ipsum excepturi. Lorem ipsum dolor sit amet consectetur
adipisicing elit. Vitae illum, explicabo maxime placeat aliquam quos,
harum aliquid aspernatur officia ullam voluptatum beatae? Fugit laborum
in recusandae eius tempore ab quasi. Lorem ipsum dolor sit amet
consectetur adipisicing elit. Doloremque vel, sequi laborum fugit et
libero facilis officiis, fuga dolorem iste ea in iusto at, repellendus
facere. Facilis voluptatibus error illum? Lorem ipsum dolor sit amet
consectetur, adipisicing elit. Officiis eveniet, facilis aut neque,
aliquam ullam amet consequuntur numquam asperiores ducimus ab, explicabo
iure? Aliquid numquam ab excepturi facere dolores illum. Lorem ipsum
dolor sit, amet consectetur adipisicing elit. Fugit, quae consequuntur?
Unde dicta, non inventore magni at rem, debitis et molestiae officia
obcaecati expedita suscipit est fugiat deserunt, beatae hic? Lorem ipsum
dolor sit amet consectetur adipisicing elit. Molestiae recusandae
facilis iure, ipsum excepturi voluptates amet libero explicabo! Mollitia
magni consequuntur perspiciatis consectetur officiis cum. Illum
exercitationem eveniet dolorum maiores. Lorem ipsum dolor sit amet,
consectetur adipisicing elit. Amet commodi molestiae veritatis ad
suscipit at, eos sapiente illum laborum ipsum, unde reiciendis,
praesentium temporibus officia optio nemo dolorum magni tempora. Lorem
ipsum dolor sit amet consectetur adipisicing elit. Fuga, consectetur
laborum? Impedit deserunt dolor qui eligendi aspernatur magnam ratione
at inventore, placeat est. Commodi nobis tenetur suscipit cupiditate
ipsum excepturi. Lorem ipsum dolor sit amet consectetur adipisicing
elit. Vitae illum, explicabo maxime placeat aliquam quos, harum aliquid
aspernatur officia ullam voluptatum beatae? Fugit laborum in recusandae
eius tempore ab quasi. Lorem ipsum dolor sit amet consectetur
adipisicing elit. Doloremque vel, sequi laborum fugit et libero facilis
officiis, fuga dolorem iste ea in iusto at, repellendus facere. Facilis
voluptatibus error illum? Lorem ipsum dolor sit amet consectetur,
adipisicing elit. Officiis eveniet, facilis aut neque, aliquam ullam
amet consequuntur numquam asperiores ducimus ab, explicabo iure? Aliquid
numquam ab excepturi facere dolores illum. Lorem ipsum dolor sit, amet
consectetur adipisicing elit. Fugit, quae consequuntur? Unde dicta, non
inventore magni at rem, debitis et molestiae officia obcaecati expedita
suscipit est fugiat deserunt, beatae hic? Lorem ipsum dolor sit amet
consectetur adipisicing elit. Molestiae recusandae facilis iure, ipsum
excepturi voluptates amet libero explicabo! Mollitia magni consequuntur
perspiciatis consectetur officiis cum. Illum exercitationem eveniet
dolorum maiores. Lorem ipsum dolor sit amet, consectetur adipisicing
elit. Amet commodi molestiae veritatis ad suscipit at, eos sapiente
illum laborum ipsum, unde reiciendis, praesentium temporibus officia
optio nemo dolorum magni tempora. Lorem ipsum dolor sit amet consectetur
adipisicing elit. Fuga, consectetur laborum? Impedit deserunt dolor qui
eligendi aspernatur magnam ratione at inventore, placeat est. Commodi
nobis tenetur suscipit cupiditate ipsum excepturi. Lorem ipsum dolor sit
amet consectetur adipisicing elit. Vitae illum, explicabo maxime placeat
aliquam quos, harum aliquid aspernatur officia ullam voluptatum beatae?
Fugit laborum in recusandae eius tempore ab quasi. Lorem ipsum dolor sit
amet consectetur adipisicing elit. Doloremque vel, sequi laborum fugit
et libero facilis officiis, fuga dolorem iste ea in iusto at,
repellendus facere. Facilis voluptatibus error illum? Lorem ipsum dolor
sit amet consectetur, adipisicing elit. Officiis eveniet, facilis aut
neque, aliquam ullam amet consequuntur numquam asperiores ducimus ab,
explicabo iure? Aliquid numquam ab excepturi facere dolores illum. Lorem
ipsum dolor sit, amet consectetur adipisicing elit. Fugit, quae
consequuntur? Unde dicta, non inventore magni at rem, debitis et
molestiae officia obcaecati expedita suscipit est fugiat deserunt,
beatae hic? Lorem ipsum dolor sit amet consectetur adipisicing elit.
Molestiae recusandae facilis iure, ipsum excepturi voluptates amet
libero explicabo! Mollitia magni consequuntur perspiciatis consectetur
officiis cum. Illum exercitationem eveniet dolorum maiores. Lorem ipsum
dolor sit amet, consectetur adipisicing elit. Amet commodi molestiae
veritatis ad suscipit at, eos sapiente illum laborum ipsum, unde
reiciendis, praesentium temporibus officia optio nemo dolorum magni
tempora. Lorem ipsum dolor sit amet consectetur adipisicing elit. Fuga,
consectetur laborum? Impedit deserunt dolor qui eligendi aspernatur
magnam ratione at inventore, placeat est. Commodi nobis tenetur suscipit
cupiditate ipsum excepturi. Lorem ipsum dolor sit amet consectetur
adipisicing elit. Vitae illum, explicabo maxime placeat aliquam quos,
harum aliquid aspernatur officia ullam voluptatum beatae? Fugit laborum
in recusandae eius tempore ab quasi. Lorem ipsum dolor sit amet
consectetur adipisicing elit. Doloremque vel, sequi laborum fugit et
libero facilis officiis, fuga dolorem iste ea in iusto at, repellendus
facere. Facilis voluptatibus error illum? Lorem ipsum dolor sit amet
consectetur, adipisicing elit. Officiis eveniet, facilis aut neque,
aliquam ullam amet consequuntur numquam asperiores ducimus ab, explicabo
iure? Aliquid numquam ab excepturi facere dolores illum. Lorem ipsum
dolor sit, amet consectetur adipisicing elit. Fugit, quae consequuntur?
Unde dicta, non inventore magni at rem, debitis et molestiae officia
obcaecati expedita suscipit est fugiat deserunt, beatae hic? Lorem ipsum
dolor sit amet consectetur adipisicing elit. Molestiae recusandae
facilis iure, ipsum excepturi voluptates amet libero explicabo! Mollitia
magni consequuntur perspiciatis consectetur officiis cum. Illum
exercitationem eveniet dolorum maiores. Lorem ipsum dolor sit amet,
consectetur adipisicing elit. Amet commodi molestiae veritatis ad
suscipit at, eos sapiente illum laborum ipsum, unde reiciendis,
praesentium temporibus officia optio nemo dolorum magni tempora. Lorem
ipsum dolor sit amet consectetur adipisicing elit. Fuga, consectetur
laborum? Impedit deserunt dolor qui eligendi aspernatur magnam ratione
at inventore, placeat est. Commodi nobis tenetur suscipit cupiditate
ipsum excepturi. Lorem ipsum dolor sit amet consectetur adipisicing
elit. Vitae illum, explicabo maxime placeat aliquam quos, harum aliquid
aspernatur officia ullam voluptatum beatae? Fugit laborum in recusandae
eius tempore ab quasi. Lorem ipsum dolor sit amet consectetur
adipisicing elit. Doloremque vel, sequi laborum fugit et libero facilis
officiis, fuga dolorem iste ea in iusto at, repellendus facere. Facilis
voluptatibus error illum? Lorem ipsum dolor sit amet consectetur,
adipisicing elit. Officiis eveniet, facilis aut neque, aliquam ullam
amet consequuntur numquam asperiores ducimus ab, explicabo iure? Aliquid
numquam ab excepturi facere dolores illum. Lorem ipsum dolor sit, amet
consectetur adipisicing elit. Fugit, quae consequuntur? Unde dicta, non
inventore magni at rem, debitis et molestiae officia obcaecati expedita
suscipit est fugiat deserunt, beatae hic? Lorem ipsum dolor sit amet
consectetur adipisicing elit. Molestiae recusandae facilis iure, ipsum
excepturi voluptates amet libero explicabo! Mollitia magni consequuntur
perspiciatis consectetur officiis cum. Illum exercitationem eveniet
dolorum maiores. Lorem ipsum dolor sit amet, consectetur adipisicing
elit. Amet commodi molestiae veritatis ad suscipit at, eos sapiente
illum laborum ipsum, unde reiciendis, praesentium temporibus officia
optio nemo dolorum magni tempora. Lorem ipsum dolor sit amet consectetur
adipisicing elit. Fuga, consectetur laborum? Impedit deserunt dolor qui
eligendi aspernatur magnam ratione at inventore, placeat est. Commodi
nobis tenetur suscipit cupiditate ipsum excepturi. Lorem ipsum dolor sit
amet consectetur adipisicing elit. Vitae illum, explicabo maxime placeat
aliquam quos, harum aliquid aspernatur officia ullam voluptatum beatae?
Fugit laborum in recusandae eius tempore ab quasi. Lorem ipsum dolor sit
amet consectetur adipisicing elit. Doloremque vel, sequi laborum fugit
et libero facilis officiis, fuga dolorem iste ea in iusto at,
repellendus facere. Facilis voluptatibus error illum? Lorem ipsum dolor
sit amet consectetur, adipisicing elit. Officiis eveniet, facilis aut
neque, aliquam ullam amet consequuntur numquam asperiores ducimus ab,
explicabo iure? Aliquid numquam ab excepturi facere dolores illum. Lorem
ipsum dolor sit, amet consectetur adipisicing elit. Fugit, quae
consequuntur? Unde dicta, non inventore magni at rem, debitis et
molestiae officia obcaecati expedita suscipit est fugiat deserunt,
beatae hic? Lorem ipsum dolor sit amet consectetur adipisicing elit.
Molestiae recusandae facilis iure, ipsum excepturi voluptates amet
libero explicabo! Mollitia magni consequuntur perspiciatis consectetur
officiis cum. Illum exercitationem eveniet dolorum maiores. Lorem ipsum
dolor sit amet, consectetur adipisicing elit. Amet commodi molestiae
veritatis ad suscipit at, eos sapiente illum laborum ipsum, unde
reiciendis, praesentium temporibus officia optio nemo dolorum magni
tempora. Lorem ipsum dolor sit amet consectetur adipisicing elit. Fuga,
consectetur laborum? Impedit deserunt dolor qui eligendi aspernatur
magnam ratione at inventore, placeat est. Commodi nobis tenetur suscipit
cupiditate ipsum excepturi. Lorem ipsum dolor sit amet consectetur
adipisicing elit. Vitae illum, explicabo maxime placeat aliquam quos,
harum aliquid aspernatur officia ullam voluptatum beatae? Fugit laborum
in recusandae eius tempore ab quasi. Lorem ipsum dolor sit amet
consectetur adipisicing elit. Doloremque vel, sequi laborum fugit et
libero facilis officiis, fuga dolorem iste ea in iusto at, repellendus
facere. Facilis voluptatibus error illum? Lorem ipsum dolor sit amet
consectetur, adipisicing elit. Officiis eveniet, facilis aut neque,
aliquam ullam amet consequuntur numquam asperiores ducimus ab, explicabo
iure? Aliquid numquam ab excepturi facere dolores illum. Lorem ipsum
dolor sit, amet consectetur adipisicing elit. Fugit, quae consequuntur?
Unde dicta, non inventore magni at rem, debitis et molestiae officia
obcaecati expedita suscipit est fugiat deserunt, beatae hic? Lorem ipsum
dolor sit amet consectetur adipisicing elit. Molestiae recusandae
facilis iure, ipsum excepturi voluptates amet libero explicabo! Mollitia
magni consequuntur perspiciatis consectetur officiis cum. Illum
exercitationem eveniet dolorum maiores. Lorem ipsum dolor sit amet,
consectetur adipisicing elit. Amet commodi molestiae veritatis ad
suscipit at, eos sapiente illum laborum ipsum, unde reiciendis,
praesentium temporibus officia optio nemo dolorum magni tempora. Lorem
ipsum dolor sit amet consectetur adipisicing elit. Fuga, consectetur
laborum? Impedit deserunt dolor qui eligendi aspernatur magnam ratione
at inventore, placeat est. Commodi nobis tenetur suscipit cupiditate
ipsum excepturi. Lorem ipsum dolor sit amet consectetur adipisicing
elit. Vitae illum, explicabo maxime placeat aliquam quos, harum aliquid
aspernatur officia ullam voluptatum beatae? Fugit laborum in recusandae
eius tempore ab quasi. Lorem ipsum dolor sit amet consectetur
adipisicing elit. Doloremque vel, sequi laborum fugit et libero facilis
officiis, fuga dolorem iste ea in iusto at, repellendus facere. Facilis
voluptatibus error illum? Lorem ipsum dolor sit amet consectetur,
adipisicing elit. Officiis eveniet, facilis aut neque, aliquam ullam
amet consequuntur numquam asperiores ducimus ab, explicabo iure? Aliquid
numquam ab excepturi facere dolores illum. Lorem ipsum dolor sit, amet
consectetur adipisicing elit. Fugit, quae consequuntur? Unde dicta, non
inventore magni at rem, debitis et molestiae officia obcaecati expedita
suscipit est fugiat deserunt, beatae hic? Lorem ipsum dolor sit amet
consectetur adipisicing elit. Molestiae recusandae facilis iure, ipsum
excepturi voluptates amet libero explicabo! Mollitia magni consequuntur
perspiciatis consectetur officiis cum. Illum exercitationem eveniet
dolorum maiores. Lorem ipsum dolor sit amet, consectetur adipisicing
elit. Amet commodi molestiae veritatis ad suscipit at, eos sapiente
illum laborum ipsum, unde reiciendis, praesentium temporibus officia
optio nemo dolorum magni tempora. Lorem ipsum dolor sit amet consectetur
adipisicing elit. Fuga, consectetur laborum? Impedit deserunt dolor qui
eligendi aspernatur magnam ratione at inventore, placeat est. Commodi
nobis tenetur suscipit cupiditate ipsum excepturi. Lorem ipsum dolor sit
amet consectetur adipisicing elit. Vitae illum, explicabo maxime placeat
aliquam quos, harum aliquid aspernatur officia ullam voluptatum beatae?
Fugit laborum in recusandae eius tempore ab quasi. Lorem ipsum dolor sit
amet consectetur adipisicing elit. Doloremque vel, sequi laborum fugit
et libero facilis officiis, fuga dolorem iste ea in iusto at,
repellendus facere. Facilis voluptatibus error illum? Lorem ipsum dolor
sit amet consectetur, adipisicing elit. Officiis eveniet, facilis aut
neque, aliquam ullam amet consequuntur numquam asperiores ducimus ab,
explicabo iure? Aliquid numquam ab excepturi facere dolores illum. Lorem
ipsum dolor sit, amet consectetur adipisicing elit. Fugit, quae
consequuntur? Unde dicta, non inventore magni at rem, debitis et
molestiae officia obcaecati expedita suscipit est fugiat deserunt,
beatae hic? Lorem ipsum dolor sit amet consectetur adipisicing elit.
Molestiae recusandae facilis iure, ipsum excepturi voluptates amet
libero explicabo! Mollitia magni consequuntur perspiciatis consectetur
officiis cum. Illum exercitationem eveniet dolorum maiores. Lorem ipsum
dolor sit amet, consectetur adipisicing elit. Amet commodi molestiae
veritatis ad suscipit at, eos sapiente illum laborum ipsum, unde
reiciendis, praesentium temporibus officia optio nemo dolorum magni
tempora. Lorem ipsum dolor sit amet consectetur adipisicing elit. Fuga,
consectetur laborum? Impedit deserunt dolor qui eligendi aspernatur
magnam ratione at inventore, placeat est. Commodi nobis tenetur suscipit
cupiditate ipsum excepturi. Lorem ipsum dolor sit amet consectetur
adipisicing elit. Vitae illum, explicabo maxime placeat aliquam quos,
harum aliquid aspernatur officia ullam voluptatum beatae? Fugit laborum
in recusandae eius tempore ab quasi. Lorem ipsum dolor sit amet
consectetur adipisicing elit. Doloremque vel, sequi laborum fugit et
libero facilis officiis, fuga dolorem iste ea in iusto at, repellendus
facere. Facilis voluptatibus error illum? Lorem ipsum dolor sit amet
consectetur, adipisicing elit. Officiis eveniet, facilis aut neque,
aliquam ullam amet consequuntur numquam asperiores ducimus ab, explicabo
iure? Aliquid numquam ab excepturi facere dolores illum. Lorem ipsum
dolor sit, amet consectetur adipisicing elit. Fugit, quae consequuntur?
Unde dicta, non inventore magni at rem, debitis et molestiae officia
obcaecati expedita suscipit est fugiat deserunt, beatae hic? Lorem ipsum
dolor sit amet consectetur adipisicing elit. Molestiae recusandae
facilis iure, ipsum excepturi voluptates amet libero explicabo! Mollitia
magni consequuntur perspiciatis consectetur officiis cum. Illum
exercitationem eveniet dolorum maiores. Lorem ipsum dolor sit amet,
consectetur adipisicing elit. Amet commodi molestiae veritatis ad
suscipit at, eos sapiente illum laborum ipsum, unde reiciendis,
praesentium temporibus officia optio nemo dolorum magni tempora. Lorem
ipsum dolor sit amet consectetur adipisicing elit. Fuga, consectetur
laborum? Impedit deserunt dolor qui eligendi aspernatur magnam ratione
at inventore, placeat est. Commodi nobis tenetur suscipit cupiditate
ipsum excepturi. Lorem ipsum dolor sit amet consectetur adipisicing
elit. Vitae illum, explicabo maxime placeat aliquam quos, harum aliquid
aspernatur officia ullam voluptatum beatae? Fugit laborum in recusandae
eius tempore ab quasi. Lorem ipsum dolor sit amet consectetur
adipisicing elit. Doloremque vel, sequi laborum fugit et libero facilis
officiis, fuga dolorem iste ea in iusto at, repellendus facere. Facilis
voluptatibus error illum? Lorem ipsum dolor sit amet consectetur,
adipisicing elit. Officiis eveniet, facilis aut neque, aliquam ullam
amet consequuntur numquam asperiores ducimus ab, explicabo iure? Aliquid
numquam ab excepturi facere dolores illum. Lorem ipsum dolor sit, amet
consectetur adipisicing elit. Fugit, quae consequuntur? Unde dicta, non
inventore magni at rem, debitis et molestiae officia obcaecati expedita
suscipit est fugiat deserunt, beatae hic? Lorem ipsum dolor sit amet
consectetur adipisicing elit. Molestiae recusandae facilis iure, ipsum
excepturi voluptates amet libero explicabo! Mollitia magni consequuntur
perspiciatis consectetur officiis cum. Illum exercitationem eveniet
dolorum maiores. Lorem ipsum dolor sit amet, consectetur adipisicing
elit. Amet commodi molestiae veritatis ad suscipit at, eos sapiente
illum laborum ipsum, unde reiciendis, praesentium temporibus officia
optio nemo dolorum magni tempora. Lorem ipsum dolor sit amet consectetur
adipisicing elit. Fuga, consectetur laborum? Impedit deserunt dolor qui
eligendi aspernatur magnam ratione at inventore, placeat est. Commodi
nobis tenetur suscipit cupiditate ipsum excepturi. Lorem ipsum dolor sit
amet consectetur adipisicing elit. Vitae illum, explicabo maxime placeat
aliquam quos, harum aliquid aspernatur officia ullam voluptatum beatae?
Fugit laborum in recusandae eius tempore ab quasi. Lorem ipsum dolor sit
amet consectetur adipisicing elit. Doloremque vel, sequi laborum fugit
et libero facilis officiis, fuga dolorem iste ea in iusto at,
repellendus facere. Facilis voluptatibus error illum? Lorem ipsum dolor
sit amet consectetur, adipisicing elit. Officiis eveniet, facilis aut
neque, aliquam ullam amet consequuntur numquam asperiores ducimus ab,
explicabo iure? Aliquid numquam ab excepturi facere dolores illum. Lorem
ipsum dolor sit, amet consectetur adipisicing elit. Fugit, quae
consequuntur? Unde dicta, non inventore magni at rem, debitis et
molestiae officia obcaecati expedita suscipit est fugiat deserunt,
beatae hic? Lorem ipsum dolor sit amet consectetur adipisicing elit.
Molestiae recusandae facilis iure, ipsum excepturi voluptates amet
libero explicabo! Mollitia magni consequuntur perspiciatis consectetur
officiis cum. Illum exercitationem eveniet dolorum maiores. Lorem ipsum
dolor sit amet, consectetur adipisicing elit. Amet commodi molestiae
veritatis ad suscipit at, eos sapiente illum laborum ipsum, unde
reiciendis, praesentium temporibus officia optio nemo dolorum magni
tempora. Lorem ipsum dolor sit amet consectetur adipisicing elit. Fuga,
consectetur laborum? Impedit deserunt dolor qui eligendi aspernatur
magnam ratione at inventore, placeat est. Commodi nobis tenetur suscipit
cupiditate ipsum excepturi. Lorem ipsum dolor sit amet consectetur
adipisicing elit. Vitae illum, explicabo maxime placeat aliquam quos,
harum aliquid aspernatur officia ullam voluptatum beatae? Fugit laborum
in recusandae eius tempore ab quasi. Lorem ipsum dolor sit amet
consectetur adipisicing elit. Doloremque vel, sequi laborum fugit et
libero facilis officiis, fuga dolorem iste ea in iusto at, repellendus
facere. Facilis voluptatibus error illum? Lorem ipsum dolor sit amet
consectetur, adipisicing elit. Officiis eveniet, facilis aut neque,
aliquam ullam amet consequuntur numquam asperiores ducimus ab, explicabo
iure? Aliquid numquam ab excepturi facere dolores illum. Lorem ipsum
dolor sit, amet consectetur adipisicing elit. Fugit, quae consequuntur?
Unde dicta, non inventore magni at rem, debitis et molestiae officia
obcaecati expedita suscipit est fugiat deserunt, beatae hic? Lorem ipsum
dolor sit amet consectetur adipisicing elit. Molestiae recusandae
facilis iure, ipsum excepturi voluptates amet libero explicabo! Mollitia
magni consequuntur perspiciatis consectetur officiis cum. Illum
exercitationem eveniet dolorum maiores. Lorem ipsum dolor sit amet,
consectetur adipisicing elit. Amet commodi molestiae veritatis ad
suscipit at, eos sapiente illum laborum ipsum, unde reiciendis,
praesentium temporibus officia optio nemo dolorum magni tempora. Lorem
ipsum dolor sit amet consectetur adipisicing elit. Fuga, consectetur
laborum? Impedit deserunt dolor qui eligendi aspernatur magnam ratione
at inventore, placeat est. Commodi nobis tenetur suscipit cupiditate
ipsum excepturi. Lorem ipsum dolor sit amet consectetur adipisicing
elit. Vitae illum, explicabo maxime placeat aliquam quos, harum aliquid
aspernatur officia ullam voluptatum beatae? Fugit laborum in recusandae
eius tempore ab quasi. Lorem ipsum dolor sit amet consectetur
adipisicing elit. Doloremque vel, sequi laborum fugit et libero facilis
officiis, fuga dolorem iste ea in iusto at, repellendus facere. Facilis
voluptatibus error illum? Lorem ipsum dolor sit amet consectetur,
adipisicing elit. Officiis eveniet, facilis aut neque, aliquam ullam
amet consequuntur numquam asperiores ducimus ab, explicabo iure? Aliquid
numquam ab excepturi facere dolores illum. Lorem ipsum dolor sit, amet
consectetur adipisicing elit. Fugit, quae consequuntur? Unde dicta, non
inventore magni at rem, debitis et molestiae officia obcaecati expedita
suscipit est fugiat deserunt, beatae hic? Lorem ipsum dolor sit amet
consectetur adipisicing elit. Molestiae recusandae facilis iure, ipsum
excepturi voluptates amet libero explicabo! Mollitia magni consequuntur
perspiciatis consectetur officiis cum. Illum exercitationem eveniet
dolorum maiores. Lorem ipsum dolor sit amet, consectetur adipisicing
elit. Amet commodi molestiae veritatis ad suscipit at, eos sapiente
illum laborum ipsum, unde reiciendis, praesentium temporibus officia
optio nemo dolorum magni tempora. Lorem ipsum dolor sit amet consectetur
adipisicing elit. Fuga, consectetur laborum? Impedit deserunt dolor qui
eligendi aspernatur magnam ratione at inventore, placeat est. Commodi
nobis tenetur suscipit cupiditate ipsum excepturi. Lorem ipsum dolor sit
amet consectetur adipisicing elit. Vitae illum, explicabo maxime placeat
aliquam quos, harum aliquid aspernatur officia ullam voluptatum beatae?
Fugit laborum in recusandae eius tempore ab quasi. Lorem ipsum dolor sit
amet consectetur adipisicing elit. Doloremque vel, sequi laborum fugit
et libero facilis officiis, fuga dolorem iste ea in iusto at,
repellendus facere. Facilis voluptatibus error illum? Lorem ipsum dolor
sit amet consectetur, adipisicing elit. Officiis eveniet, facilis aut
neque, aliquam ullam amet consequuntur numquam asperiores ducimus ab,
explicabo iure? Aliquid numquam ab excepturi facere dolores illum. Lorem
ipsum dolor sit, amet consectetur adipisicing elit. Fugit, quae
consequuntur? Unde dicta, non inventore magni at rem, debitis et
molestiae officia obcaecati expedita suscipit est fugiat deserunt,
beatae hic? Lorem ipsum dolor sit amet consectetur adipisicing elit.
Molestiae recusandae facilis iure, ipsum excepturi voluptates amet
libero explicabo! Mollitia magni consequuntur perspiciatis consectetur
officiis cum. Illum exercitationem eveniet dolorum maiores. Lorem ipsum
dolor sit amet, consectetur adipisicing elit. Amet commodi molestiae
veritatis ad suscipit at, eos sapiente illum laborum ipsum, unde
reiciendis, praesentium temporibus officia optio nemo dolorum magni
tempora. Lorem ipsum dolor sit amet consectetur adipisicing elit. Fuga,
consectetur laborum? Impedit deserunt dolor qui eligendi aspernatur
magnam ratione at inventore, placeat est. Commodi nobis tenetur suscipit
cupiditate ipsum excepturi. Lorem ipsum dolor sit amet consectetur
adipisicing elit. Vitae illum, explicabo maxime placeat aliquam quos,
harum aliquid aspernatur officia ullam voluptatum beatae? Fugit laborum
in recusandae eius tempore ab quasi. Lorem ipsum dolor sit amet
consectetur adipisicing elit. Doloremque vel, sequi laborum fugit et
libero facilis officiis, fuga dolorem iste ea in iusto at, repellendus
facere. Facilis voluptatibus error illum? Lorem ipsum dolor sit amet
consectetur, adipisicing elit. Officiis eveniet, facilis aut neque,
aliquam ullam amet consequuntur numquam asperiores ducimus ab, explicabo
iure? Aliquid numquam ab excepturi facere dolores illum. Lorem ipsum
dolor sit, amet consectetur adipisicing elit. Fugit, quae consequuntur?
Unde dicta, non inventore magni at rem, debitis et molestiae officia
obcaecati expedita suscipit est fugiat deserunt, beatae hic? Lorem ipsum
dolor sit amet consectetur adipisicing elit. Molestiae recusandae
facilis iure, ipsum excepturi voluptates amet libero explicabo! Mollitia
magni consequuntur perspiciatis consectetur officiis cum. Illum
exercitationem eveniet dolorum maiores. Lorem ipsum dolor sit amet,
consectetur adipisicing elit. Amet commodi molestiae veritatis ad
suscipit at, eos sapiente illum laborum ipsum, unde reiciendis,
praesentium temporibus officia optio nemo dolorum magni tempora. Lorem
ipsum dolor sit amet consectetur adipisicing elit. Fuga, consectetur
laborum? Impedit deserunt dolor qui eligendi aspernatur magnam ratione
at inventore, placeat est. Commodi nobis tenetur suscipit cupiditate
ipsum excepturi. Lorem ipsum dolor sit amet consectetur adipisicing
elit. Vitae illum, explicabo maxime placeat aliquam quos, harum aliquid
aspernatur officia ullam voluptatum beatae? Fugit laborum in recusandae
eius tempore ab quasi. Lorem ipsum dolor sit amet consectetur
adipisicing elit. Doloremque vel, sequi laborum fugit et libero facilis
officiis, fuga dolorem iste ea in iusto at, repellendus facere. Facilis
voluptatibus error illum? Lorem ipsum dolor sit amet consectetur,
adipisicing elit. Officiis eveniet, facilis aut neque, aliquam ullam
amet consequuntur numquam asperiores ducimus ab, explicabo iure? Aliquid
numquam ab excepturi facere dolores illum. Lorem ipsum dolor sit, amet
consectetur adipisicing elit. Fugit, quae consequuntur? Unde dicta, non
inventore magni at rem, debitis et molestiae officia obcaecati expedita
suscipit est fugiat deserunt, beatae hic? Lorem ipsum dolor sit amet
consectetur adipisicing elit. Molestiae recusandae facilis iure, ipsum
excepturi voluptates amet libero explicabo! Mollitia magni consequuntur
perspiciatis consectetur officiis cum. Illum exercitationem eveniet
dolorum maiores. Lorem ipsum dolor sit amet, consectetur adipisicing
elit. Amet commodi molestiae veritatis ad suscipit at, eos sapiente
illum laborum ipsum, unde reiciendis, praesentium temporibus officia
optio nemo dolorum magni tempora. Lorem ipsum dolor sit amet consectetur
adipisicing elit. Fuga, consectetur laborum? Impedit deserunt dolor qui
eligendi aspernatur magnam ratione at inventore, placeat est. Commodi
nobis tenetur suscipit cupiditate ipsum excepturi. Lorem ipsum dolor sit
amet consectetur adipisicing elit. Vitae illum, explicabo maxime placeat
aliquam quos, harum aliquid aspernatur officia ullam voluptatum beatae?
Fugit laborum in recusandae eius tempore ab quasi. Lorem ipsum dolor sit
amet consectetur adipisicing elit. Doloremque vel, sequi laborum fugit
et libero facilis officiis, fuga dolorem iste ea in iusto at,
repellendus facere. Facilis voluptatibus error illum? Lorem ipsum dolor
sit amet consectetur, adipisicing elit. Officiis eveniet, facilis aut
neque, aliquam ullam amet consequuntur numquam asperiores ducimus ab,
explicabo iure? Aliquid numquam ab excepturi facere dolores illum. Lorem
ipsum dolor sit, amet consectetur adipisicing elit. Fugit, quae
consequuntur? Unde dicta, non inventore magni at rem, debitis et
molestiae officia obcaecati expedita suscipit est fugiat deserunt,
beatae hic? Lorem ipsum dolor sit amet consectetur adipisicing elit.
Molestiae recusandae facilis iure, ipsum excepturi voluptates amet
libero explicabo! Mollitia magni consequuntur perspiciatis consectetur
officiis cum. Illum exercitationem eveniet dolorum maiores. Lorem ipsum
dolor sit amet, consectetur adipisicing elit. Amet commodi molestiae
veritatis ad suscipit at, eos sapiente illum laborum ipsum, unde
reiciendis, praesentium temporibus officia optio nemo dolorum magni
tempora. Lorem ipsum dolor sit amet consectetur adipisicing elit. Fuga,
consectetur laborum? Impedit deserunt dolor qui eligendi aspernatur
magnam ratione at inventore, placeat est. Commodi nobis tenetur suscipit
cupiditate ipsum excepturi. Lorem ipsum dolor sit amet consectetur
adipisicing elit. Vitae illum, explicabo maxime placeat aliquam quos,
harum aliquid aspernatur officia ullam voluptatum beatae? Fugit laborum
in recusandae eius tempore ab quasi. Lorem ipsum dolor sit amet
consectetur adipisicing elit. Doloremque vel, sequi laborum fugit et
libero facilis officiis, fuga dolorem iste ea in iusto at, repellendus
facere. Facilis voluptatibus error illum? Lorem ipsum dolor sit amet
consectetur, adipisicing elit. Officiis eveniet, facilis aut neque,
aliquam ullam amet consequuntur numquam asperiores ducimus ab, explicabo
iure? Aliquid numquam ab excepturi facere dolores illum. Lorem ipsum
dolor sit, amet consectetur adipisicing elit. Fugit, quae consequuntur?
Unde dicta, non inventore magni at rem, debitis et molestiae officia
obcaecati expedita suscipit est fugiat deserunt, beatae hic? Lorem ipsum
dolor sit amet consectetur adipisicing elit. Molestiae recusandae
facilis iure, ipsum excepturi voluptates amet libero explicabo! Mollitia
magni consequuntur perspiciatis consectetur officiis cum. Illum
exercitationem eveniet dolorum maiores. Lorem ipsum dolor sit amet,
consectetur adipisicing elit. Amet commodi molestiae veritatis ad
suscipit at, eos sapiente illum laborum ipsum, unde reiciendis,
praesentium temporibus officia optio nemo dolorum magni tempora. Lorem
ipsum dolor sit amet consectetur adipisicing elit. Fuga, consectetur
laborum? Impedit deserunt dolor qui eligendi aspernatur magnam ratione
at inventore, placeat est. Commodi nobis tenetur suscipit cupiditate
ipsum excepturi. Lorem ipsum dolor sit amet consectetur adipisicing
elit. Vitae illum, explicabo maxime placeat aliquam quos, harum aliquid
aspernatur officia ullam voluptatum beatae? Fugit laborum in recusandae
eius tempore ab quasi. Lorem ipsum dolor sit amet consectetur
adipisicing elit. Doloremque vel, sequi laborum fugit et libero facilis
officiis, fuga dolorem iste ea in iusto at, repellendus facere. Facilis
voluptatibus error illum? Lorem ipsum dolor sit amet consectetur,
adipisicing elit. Officiis eveniet, facilis aut neque, aliquam ullam
amet consequuntur numquam asperiores ducimus ab, explicabo iure? Aliquid
numquam ab excepturi facere dolores illum. Lorem ipsum dolor sit, amet
consectetur adipisicing elit. Fugit, quae consequuntur? Unde dicta, non
inventore magni at rem, debitis et molestiae officia obcaecati expedita
suscipit est fugiat deserunt, beatae hic? Lorem ipsum dolor sit amet
consectetur adipisicing elit. Molestiae recusandae facilis iure, ipsum
excepturi voluptates amet libero explicabo! Mollitia magni consequuntur
perspiciatis consectetur officiis cum. Illum exercitationem eveniet
dolorum maiores. Lorem ipsum dolor sit amet, consectetur adipisicing
elit. Amet commodi molestiae veritatis ad suscipit at, eos sapiente
illum laborum ipsum, unde reiciendis, praesentium temporibus officia
optio nemo dolorum magni tempora. Lorem ipsum dolor sit amet consectetur
adipisicing elit. Fuga, consectetur laborum? Impedit deserunt dolor qui
eligendi aspernatur magnam ratione at inventore, placeat est. Commodi
nobis tenetur suscipit cupiditate ipsum excepturi. Lorem ipsum dolor sit
amet consectetur adipisicing elit. Vitae illum, explicabo maxime placeat
aliquam quos, harum aliquid aspernatur officia ullam voluptatum beatae?
Fugit laborum in recusandae eius tempore ab quasi. Lorem ipsum dolor sit
amet consectetur adipisicing elit. Doloremque vel, sequi laborum fugit
et libero facilis officiis, fuga dolorem iste ea in iusto at,
repellendus facere. Facilis voluptatibus error illum? Lorem ipsum dolor
sit amet consectetur, adipisicing elit. Officiis eveniet, facilis aut
neque, aliquam ullam amet consequuntur numquam asperiores ducimus ab,
explicabo iure? Aliquid numquam ab excepturi facere dolores illum. Lorem
ipsum dolor sit, amet consectetur adipisicing elit. Fugit, quae
consequuntur? Unde dicta, non inventore magni at rem, debitis et
molestiae officia obcaecati expedita suscipit est fugiat deserunt,
beatae hic? Lorem ipsum dolor sit amet consectetur adipisicing elit.
Molestiae recusandae facilis iure, ipsum excepturi voluptates amet
libero explicabo! Mollitia magni consequuntur perspiciatis consectetur
officiis cum. Illum exercitationem eveniet dolorum maiores. Lorem ipsum
dolor sit amet, consectetur adipisicing elit. Amet commodi molestiae
veritatis ad suscipit at, eos sapiente illum laborum ipsum, unde
reiciendis, praesentium temporibus officia optio nemo dolorum magni
tempora. Lorem ipsum dolor sit amet consectetur adipisicing elit. Fuga,
consectetur laborum? Impedit deserunt dolor qui eligendi aspernatur
magnam ratione at inventore, placeat est. Commodi nobis tenetur suscipit
cupiditate ipsum excepturi. Lorem ipsum dolor sit amet consectetur
adipisicing elit. Vitae illum, explicabo maxime placeat aliquam quos,
harum aliquid aspernatur officia ullam voluptatum beatae? Fugit laborum
in recusandae eius tempore ab quasi.
</p>
</PageLayout>
);
}
export default IndexPage;

View File

@ -0,0 +1,57 @@
import React from 'react';
import { useParams } from 'react-router-dom';
import { useQuery } from '@apollo/client';
import { SERVERS } from './queries';
import Context from './context';
import extractVersionCodeFromHostname from '@utils/extractVersionCodeFromHostname';
import { Params, ServerList } from './types';
import NotFoundPage from '@features/NotFoundPage/NotFoundPage';
import Spinner from '@common/Spinner/Spinner';
export interface Props {
children: React.ReactNode;
}
function Provider({ children }: Props) {
const { key } = useParams<Params>();
const { loading: loadingServers, data } = useQuery<ServerList>(SERVERS, {
fetchPolicy: 'cache-first',
variables: {
filter: {
limit: 1,
versionCode: [extractVersionCodeFromHostname(window.location.hostname)],
key: [key],
},
},
});
const server =
data?.servers?.items && data.servers.items.length > 0
? data.servers.items[0]
: undefined;
const loading = loadingServers && !server;
if (loading) {
return (
<Spinner
containerProps={{
width: '100%',
height: '100vh',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
}}
description="Loading server..."
/>
);
}
if (!server) {
return <NotFoundPage />;
}
return <Context.Provider value={server}>{children}</Context.Provider>;
}
export default Provider;

View File

@ -0,0 +1,16 @@
import { createContext } from 'react';
import { SERVER_STATUS } from '@config/app';
import { Server } from './types';
const ctx = createContext<Server>({
key: '',
numberOfPlayers: 0,
numberOfTribes: 0,
numberOfVillages: 0,
dataUpdatedAt: new Date(0),
historyUpdatedAt: new Date(0),
statsUpdatedAt: new Date(0),
status: SERVER_STATUS.OPEN,
});
export default ctx;

View File

@ -0,0 +1,19 @@
import { gql } from '@apollo/client';
export const SERVERS = gql`
query servers($filter: ServerFilter) {
servers(filter: $filter) {
total
items {
key
numberOfPlayers
numberOfTribes
numberOfVillages
status
dataUpdatedAt
historyUpdatedAt
statsUpdatedAt
}
}
}
`;

View File

@ -0,0 +1,21 @@
import { List } from '@libs/graphql/types';
import { ServerStatus } from '@config/app';
export type Server = {
key: string;
status: ServerStatus;
numberOfPlayers: number;
numberOfTribes: number;
numberOfVillages: number;
dataUpdatedAt: string | Date;
historyUpdatedAt: string | Date;
statsUpdatedAt: string | Date;
};
export type ServerList = {
servers?: List<Server[]>;
};
export type Params = {
key: string;
};

View File

@ -0,0 +1,9 @@
import { useContext } from 'react';
import ctx from './context';
import { Server } from './types';
const useServer = (): Server => {
return useContext(ctx);
};
export default useServer;

12
src/libs/date/format.ts Normal file
View File

@ -0,0 +1,12 @@
const format = (d: Date) => {
return d.toLocaleString(undefined, {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
});
};
export default format;

View File

@ -2,11 +2,13 @@ import * as NAMESPACES from '@config/namespaces';
import common from './common';
import indexPage from './index-page';
import notFoundPage from './not-found-page';
import serverPage from './server-page';
const translations = {
[NAMESPACES.COMMON]: common,
[NAMESPACES.INDEX_PAGE]: indexPage,
[NAMESPACES.NOT_FOUND_PAGE]: notFoundPage,
...serverPage,
};
export default translations;

View File

@ -0,0 +1,20 @@
const translations = {
pageLayout: {
sidebar: {
routes: {
dashboard: 'Dashboard',
},
serverInfo: {
numberOfPlayers: '{{num}} player',
numberOfPlayers_plural: '{{num}} players',
numberOfTribes: '{{num}} tribe',
numberOfTribes_plural: '{{num}} tribes',
numberOfVillages: '{{num}} village',
numberOfVillages_plural: '{{num}} villages',
dataUpdatedAt: 'The server data was updated {{date}}',
},
},
},
};
export default translations;

View File

@ -0,0 +1,8 @@
import * as NAMESPACES from '@config/namespaces';
import common from './common';
const translations = {
[NAMESPACES.SERVER_PAGE.COMMON]: common,
};
export default translations;

View File

@ -2,11 +2,13 @@ import * as NAMESPACES from '@config/namespaces';
import common from './common';
import indexPage from './index-page';
import notFoundPage from './not-found-page';
import serverPage from './server-page';
const translations = {
[NAMESPACES.COMMON]: common,
[NAMESPACES.INDEX_PAGE]: indexPage,
[NAMESPACES.NOT_FOUND_PAGE]: notFoundPage,
...serverPage,
};
export default translations;

View File

@ -0,0 +1,23 @@
const translations = {
pageLayout: {
sidebar: {
routes: {
dashboard: 'Dashboard',
},
serverInfo: {
numberOfPlayers_0: '{{num}} gracz',
numberOfPlayers_1: '{{num}} graczy',
numberOfPlayers_2: '{{num}} graczy',
numberOfTribes_0: '{{num}} plemię',
numberOfTribes_1: '{{num}} plemiona',
numberOfTribes_2: '{{num}} plemion',
numberOfVillages_0: '{{num}} wioska',
numberOfVillages_1: '{{num}} wioski',
numberOfVillages_2: '{{num}} wiosek',
dataUpdatedAt: 'Dane ostatnio zaktualizowane {{date}}',
},
},
},
};
export default translations;

View File

@ -0,0 +1,8 @@
import * as NAMESPACES from '@config/namespaces';
import common from './common';
const translations = {
[NAMESPACES.SERVER_PAGE.COMMON]: common,
};
export default translations;

View File

@ -21,6 +21,7 @@ const createTheme = (): Theme => {
},
MuiAppBar: {
color: 'default',
elevation: 0,
},
},
})

View File

@ -3321,7 +3321,7 @@ clone-deep@^4.0.1:
kind-of "^6.0.2"
shallow-clone "^3.0.0"
clsx@^1.0.4:
clsx@^1.0.4, clsx@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188"
integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==