change how we render layouts

This commit is contained in:
Dawid Wysokiński 2021-01-02 00:43:20 +12:00
parent ea71ef5e0b
commit 3e87c42e0b
29 changed files with 592 additions and 634 deletions

View File

@ -4,25 +4,44 @@ import { heights } from '@theme/toolbar';
import { makeStyles } from '@material-ui/core/styles'; import { makeStyles } from '@material-ui/core/styles';
export interface Props extends React.HTMLProps<HTMLElement> { export interface Props extends React.HTMLAttributes<HTMLOrSVGElement> {
footer?: boolean; footer?: boolean;
component?: keyof JSX.IntrinsicElements;
minHeight?: boolean;
} }
interface MakeStylesProps { interface MakeStylesProps {
footer?: boolean; footer?: boolean;
} }
function Content({ className, footer = false, ...props }: Props) { function Content({
className,
footer = false,
component: Wrapper = 'main',
minHeight = true,
...props
}: Props) {
const classes = useStyles({ footer }); const classes = useStyles({ footer });
return <main className={clsx(classes.main, className)} {...props} />; return (
<Wrapper
className={clsx(
{ [classes.minHeight]: minHeight },
classes.padding,
className
)}
{...props}
/>
);
} }
const useStyles = makeStyles(theme => { const useStyles = makeStyles(theme => {
return { return {
main: ({ footer }: MakeStylesProps) => { padding: {
padding: theme.spacing(3, 0),
},
minHeight: ({ footer }: MakeStylesProps) => {
const multiplier = footer ? 2 : 1; const multiplier = footer ? 2 : 1;
return { return {
padding: theme.spacing(3, 0),
minHeight: `calc(100vh - ${heights.tabletDesktop * multiplier}px)`, minHeight: `calc(100vh - ${heights.tabletDesktop * multiplier}px)`,
[`${theme.breakpoints.down('xs')} and (orientation: landscape)`]: { [`${theme.breakpoints.down('xs')} and (orientation: landscape)`]: {
minHeight: `calc(100vh - ${heights.mobileLandscape * multiplier}px)`, minHeight: `calc(100vh - ${heights.mobileLandscape * multiplier}px)`,

View File

@ -1,5 +1,7 @@
import React from 'react'; import React from 'react';
import { StringParam, useQueryParam, withDefault } from 'use-query-params';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useLocation } from 'react-router-dom';
import { TWHELP, NAME } from '@config/app'; import { TWHELP, NAME } from '@config/app';
import * as ROUTES from '@config/routes'; import * as ROUTES from '@config/routes';
import * as NAMESPACES from '@config/namespaces'; import * as NAMESPACES from '@config/namespaces';
@ -21,20 +23,14 @@ import VersionSelector from '@common/VersionSelector/VersionSelector';
import SearchInput from './SearchInput'; import SearchInput from './SearchInput';
export interface Props { export interface Props {
showLinkToHomePage?: boolean;
hideVersionSelectorOnMobile?: boolean;
defaultQ?: string;
appBarProps?: AppBarProps; appBarProps?: AppBarProps;
} }
export default function Header({ export default function Header({ appBarProps = {} }: Props) {
showLinkToHomePage = true,
hideVersionSelectorOnMobile = false,
defaultQ = '',
appBarProps = {},
}: Props) {
const { t } = useTranslation(NAMESPACES.COMMON); const { t } = useTranslation(NAMESPACES.COMMON);
const location = useLocation();
const classes = useStyles(); const classes = useStyles();
const [q] = useQueryParam('q', withDefault(StringParam, ''));
const versionSelector = ( const versionSelector = (
<div> <div>
@ -46,9 +42,11 @@ export default function Header({
<Container> <Container>
<Toolbar disableGutters className={classes.toolbar}> <Toolbar disableGutters className={classes.toolbar}>
<form className={classes.form}> <form className={classes.form}>
<SearchInput defaultQ={defaultQ} /> <SearchInput
defaultQ={location.pathname === ROUTES.SEARCH_PAGE ? q : ''}
/>
</form> </form>
{showLinkToHomePage && ( {location.pathname !== ROUTES.INDEX_PAGE && (
<Link to={ROUTES.INDEX_PAGE}> <Link to={ROUTES.INDEX_PAGE}>
<Hidden xsDown implementation="css"> <Hidden xsDown implementation="css">
<Button startIcon={<InputIcon />}> <Button startIcon={<InputIcon />}>
@ -62,7 +60,7 @@ export default function Header({
</Hidden> </Hidden>
</Link> </Link>
)} )}
{hideVersionSelectorOnMobile ? ( {location.pathname !== ROUTES.INDEX_PAGE ? (
<Hidden xsDown implementation="css"> <Hidden xsDown implementation="css">
{versionSelector} {versionSelector}
</Hidden> </Hidden>

View File

@ -7,6 +7,7 @@ import ScrollToTop from '@common/ScrollToTop/ScrollToTop';
import VersionProvider from '../libs/VersionContext/Provider'; import VersionProvider from '../libs/VersionContext/Provider';
import DateUtilsProvider from '../libs/date/DateUtilsProvider'; import DateUtilsProvider from '../libs/date/DateUtilsProvider';
import MainLayout from '../common/MainLayout/MainLayout';
import IndexPage from './IndexPage/IndexPage'; import IndexPage from './IndexPage/IndexPage';
import NotFoundPage from './NotFoundPage/NotFoundPage'; import NotFoundPage from './NotFoundPage/NotFoundPage';
import SearchPage from './SearchPage/SearchPage'; import SearchPage from './SearchPage/SearchPage';
@ -17,6 +18,9 @@ function App() {
<Fragment> <Fragment>
<VersionProvider> <VersionProvider>
<DateUtilsProvider> <DateUtilsProvider>
<Switch>
<Route path={[ROUTES.INDEX_PAGE, ROUTES.SEARCH_PAGE]} exact>
<MainLayout>
<Switch> <Switch>
<Route path={ROUTES.INDEX_PAGE} exact> <Route path={ROUTES.INDEX_PAGE} exact>
<IndexPage /> <IndexPage />
@ -24,6 +28,9 @@ function App() {
<Route path={ROUTES.SEARCH_PAGE} exact> <Route path={ROUTES.SEARCH_PAGE} exact>
<SearchPage /> <SearchPage />
</Route> </Route>
</Switch>
</MainLayout>
</Route>
<Route path={ROUTES.SERVER_PAGE.INDEX_PAGE}> <Route path={ROUTES.SERVER_PAGE.INDEX_PAGE}>
<ServerPage /> <ServerPage />
</Route> </Route>

View File

@ -4,7 +4,6 @@ import useTitle from '@libs/useTitle';
import { INDEX_PAGE } from '@config/namespaces'; import { INDEX_PAGE } from '@config/namespaces';
import { Container, Box } from '@material-ui/core'; import { Container, Box } from '@material-ui/core';
import MainLayout from '@common/MainLayout/MainLayout';
import DevNote from '@common/DevNote/DevNote'; import DevNote from '@common/DevNote/DevNote';
import ServerSelection from './components/ServerSelection/ServerSelection'; import ServerSelection from './components/ServerSelection/ServerSelection';
@ -12,18 +11,11 @@ export default function IndexPage() {
const { t } = useTranslation(INDEX_PAGE); const { t } = useTranslation(INDEX_PAGE);
useTitle(t('title')); useTitle(t('title'));
return ( return (
<MainLayout
headerProps={{
showLinkToHomePage: false,
hideVersionSelectorOnMobile: false,
}}
>
<Container> <Container>
<Box mb={3}> <Box mb={3}>
<DevNote /> <DevNote />
</Box> </Box>
<ServerSelection /> <ServerSelection />
</Container> </Container>
</MainLayout>
); );
} }

View File

@ -1,4 +1,4 @@
import React, { useRef } from 'react'; import React, { useRef, useState } from 'react';
import formatNumber from '@utils/formatNumber'; import formatNumber from '@utils/formatNumber';
import * as ROUTES from '@config/routes'; import * as ROUTES from '@config/routes';
import * as NAMESPACES from '@config/namespaces'; import * as NAMESPACES from '@config/namespaces';
@ -31,7 +31,7 @@ export interface Props {
function GridItem({ t, server, hideTooltip = true }: Props) { function GridItem({ t, server, hideTooltip = true }: Props) {
const classes = useStyles(); const classes = useStyles();
const [expanded, setExpanded] = React.useState<boolean>(false); const [expanded, setExpanded] = useState<boolean>(false);
const accordion = useRef<HTMLDivElement | null>(null); const accordion = useRef<HTMLDivElement | null>(null);
const handleClick = (e: React.ChangeEvent<{}>, expanded: boolean) => { const handleClick = (e: React.ChangeEvent<{}>, expanded: boolean) => {

View File

@ -14,7 +14,6 @@ import { SEARCH_PAGE } from '@config/namespaces';
import { MODES, LIMIT } from './constants'; import { MODES, LIMIT } from './constants';
import { Container, Paper } from '@material-ui/core'; import { Container, Paper } from '@material-ui/core';
import MainLayout from '@common/MainLayout/MainLayout';
import ModeSelector from '@common/ModeSelector/ModeSelector'; import ModeSelector from '@common/ModeSelector/ModeSelector';
import PlayerTable from './components/PlayerTable/PlayerTable'; import PlayerTable from './components/PlayerTable/PlayerTable';
import TribeTable from './components/TribeTable/TribeTable'; import TribeTable from './components/TribeTable/TribeTable';
@ -55,9 +54,6 @@ function SearchPage() {
}; };
return ( return (
<MainLayout
headerProps={{ hideVersionSelectorOnMobile: true, defaultQ: query.q }}
>
<Container> <Container>
<Paper> <Paper>
<ModeSelector <ModeSelector
@ -87,7 +83,6 @@ function SearchPage() {
)} )}
</Paper> </Paper>
</Container> </Container>
</MainLayout>
); );
} }

View File

@ -3,6 +3,7 @@ import { SERVER_PAGE } from '@config/routes';
import { Switch, Route } from 'react-router-dom'; import { Switch, Route } from 'react-router-dom';
import ServerProvider from './libs/ServerContext/Provider'; import ServerProvider from './libs/ServerContext/Provider';
import PageLayout from './common/PageLayout/PageLayout';
import IndexPage from './features/IndexPage/IndexPage'; import IndexPage from './features/IndexPage/IndexPage';
import PlayerPage from './features/PlayerPage/PlayerPage'; import PlayerPage from './features/PlayerPage/PlayerPage';
import TribePage from './features/TribePage/TribePage'; import TribePage from './features/TribePage/TribePage';
@ -16,6 +17,7 @@ import NotFoundPage from './features/NotFoundPage/NotFoundPage';
function ServerPage() { function ServerPage() {
return ( return (
<ServerProvider> <ServerProvider>
<PageLayout>
<Switch> <Switch>
<Route exact path={SERVER_PAGE.INDEX_PAGE}> <Route exact path={SERVER_PAGE.INDEX_PAGE}>
<IndexPage /> <IndexPage />
@ -45,6 +47,7 @@ function ServerPage() {
<NotFoundPage /> <NotFoundPage />
</Route> </Route>
</Switch> </Switch>
</PageLayout>
</ServerProvider> </ServerProvider>
); );
} }

View File

@ -7,23 +7,15 @@ import { DRAWER_WIDTH } from './components/Sidebar/contants';
import { makeStyles, useTheme } from '@material-ui/core/styles'; import { makeStyles, useTheme } from '@material-ui/core/styles';
import { useMediaQuery, Toolbar } from '@material-ui/core'; import { useMediaQuery, Toolbar } from '@material-ui/core';
import Content, { Props as ContentProps } from '@common/Content/Content'; import Content from '@common/Content/Content';
import Sidebar from './components/Sidebar/Sidebar'; import Sidebar from './components/Sidebar/Sidebar';
import TopBar from './components/TopBar/TopBar'; import TopBar from './components/TopBar/TopBar';
export interface Props { export interface Props {
children?: React.ReactNode; children?: React.ReactNode;
noPadding?: boolean;
contentClassName?: string;
contentStyle?: ContentProps['style'];
} }
function PageLayout({ function PageLayout({ children }: Props) {
children,
noPadding,
contentClassName,
contentStyle,
}: Props) {
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
const classes = useStyles(); const classes = useStyles();
const theme = useTheme(); const theme = useTheme();
@ -56,14 +48,7 @@ function PageLayout({
t={t} t={t}
onOpen={openSidebar} onOpen={openSidebar}
/> />
<Content <Content className={classes.content}>{children}</Content>
className={clsx(classes.content, contentClassName, {
'no-padding': noPadding,
})}
style={contentStyle}
>
{children}
</Content>
</div> </div>
); );
} }
@ -81,10 +66,7 @@ const useStyles = makeStyles(theme => ({
}, },
content: { content: {
height: '100%', height: '100%',
padding: theme.spacing(3, 0), padding: 0,
'&.no-padding': {
padding: '0 0',
},
}, },
})); }));

View File

@ -53,6 +53,7 @@ const Sidebar = ({ t, className, open, variant, onClose, onOpen }: Props) => {
name: t('pageLayout.sidebar.routes.rankings.name'), name: t('pageLayout.sidebar.routes.rankings.name'),
Icon: <GradeIcon color="inherit" />, Icon: <GradeIcon color="inherit" />,
to: ROUTES.SERVER_PAGE.RANKING_PAGE.BASE, to: ROUTES.SERVER_PAGE.RANKING_PAGE.BASE,
isExpandable: true,
nested: [ nested: [
{ {
name: t('pageLayout.sidebar.routes.rankings.player.index'), name: t('pageLayout.sidebar.routes.rankings.player.index'),

View File

@ -1,4 +1,4 @@
import React, { Fragment, useState } from 'react'; import React, { Fragment, useState, memo } from 'react';
import { useLocation, matchPath } from 'react-router-dom'; import { useLocation, matchPath } from 'react-router-dom';
import { Route } from './types'; import { Route } from './types';
@ -26,7 +26,7 @@ function ListItem({ route, nestedLevel }: Props) {
const isActive = const isActive =
!!route.to && !!matchPath(pathname, { path: route.to, exact: route.exact }); !!route.to && !!matchPath(pathname, { path: route.to, exact: route.exact });
const [open, setOpen] = useState( const [open, setOpen] = useState(
(hasNested && isActive) || !route.isExpandable (hasNested && !route.isExpandable) || isActive
); );
const getItem = () => { const getItem = () => {
@ -97,4 +97,4 @@ const useStyles = makeStyles(theme => ({
}, },
})); }));
export default ListItem; export default memo(ListItem);

View File

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

View File

@ -6,7 +6,7 @@ import useServer from '@features/ServerPage/libs/ServerContext/useServer';
import { SERVER_PAGE } from '@config/namespaces'; import { SERVER_PAGE } from '@config/namespaces';
import { Container, Paper } from '@material-ui/core'; import { Container, Paper } from '@material-ui/core';
import ServerPageLayout from '@features/ServerPage/common/PageLayout/PageLayout'; import Content from '@common/Content/Content';
import ModeSelector from '@common/ModeSelector/ModeSelector'; import ModeSelector from '@common/ModeSelector/ModeSelector';
import LiveEnnoblements from './components/LiveEnnoblements/LiveEnnoblements'; import LiveEnnoblements from './components/LiveEnnoblements/LiveEnnoblements';
import LatestSavedEnnoblements from './components/LatestSavedEnnoblements/LatestSavedEnnoblements'; import LatestSavedEnnoblements from './components/LatestSavedEnnoblements/LatestSavedEnnoblements';
@ -22,7 +22,7 @@ function EnnoblementsPage() {
); );
return ( return (
<ServerPageLayout> <Content component="div" minHeight={false}>
<Container> <Container>
<Paper> <Paper>
<ModeSelector <ModeSelector
@ -53,7 +53,7 @@ function EnnoblementsPage() {
)} )}
</Paper> </Paper>
</Container> </Container>
</ServerPageLayout> </Content>
); );
} }

View File

@ -5,7 +5,7 @@ import useServer from '../../libs/ServerContext/useServer';
import { SERVER_PAGE } from '@config/namespaces'; import { SERVER_PAGE } from '@config/namespaces';
import { Container, Grid, Hidden } from '@material-ui/core'; import { Container, Grid, Hidden } from '@material-ui/core';
import PageLayout from '@features/ServerPage/common/PageLayout/PageLayout'; import Content from '@common/Content/Content';
import PlayerStatistics from './components/PlayerStatistics/PlayerStatistics'; import PlayerStatistics from './components/PlayerStatistics/PlayerStatistics';
import TribeStatistics from './components/TribeStatistics/TribeStatistics'; import TribeStatistics from './components/TribeStatistics/TribeStatistics';
import Top5Players from './components/Top5Players/Top5Players'; import Top5Players from './components/Top5Players/Top5Players';
@ -23,7 +23,7 @@ function IndexPage() {
useTitle(t('title', { key })); useTitle(t('title', { key }));
return ( return (
<PageLayout> <Content component="div" minHeight={false}>
<Container> <Container>
<Grid container spacing={2}> <Grid container spacing={2}>
<Grid <Grid
@ -72,7 +72,7 @@ function IndexPage() {
</Grid> </Grid>
</Grid> </Grid>
</Container> </Container>
</PageLayout> </Content>
); );
} }

View File

@ -25,7 +25,7 @@ import {
Checkbox, Checkbox,
FormControlLabel, FormControlLabel,
} from '@material-ui/core'; } from '@material-ui/core';
import ServerPageLayout from '@features/ServerPage/common/PageLayout/PageLayout'; import Content from '@common/Content/Content';
import ColorInput from '@common/Form/ColorInput'; import ColorInput from '@common/Form/ColorInput';
import Spinner from '@common/Spinner/Spinner'; import Spinner from '@common/Spinner/Spinner';
import Map from './components/Map/Map'; import Map from './components/Map/Map';
@ -188,9 +188,8 @@ function MapPage() {
return blacklist.some(id2 => id === id2); return blacklist.some(id2 => id === id2);
}; };
if (loading) {
return ( return (
<ServerPageLayout>
{loading && (
<Spinner <Spinner
containerProps={{ containerProps={{
display: 'flex', display: 'flex',
@ -203,8 +202,11 @@ function MapPage() {
}} }}
description={t('loading')} description={t('loading')}
/> />
)} );
{!loading && ( }
return (
<Content component="div" minHeight={false}>
<Container> <Container>
<form onSubmit={handleSubmit}> <form onSubmit={handleSubmit}>
<Grid container spacing={2}> <Grid container spacing={2}>
@ -269,9 +271,7 @@ function MapPage() {
{ {
name: 'playerVillageColor', name: 'playerVillageColor',
color: query.playerVillageColor, color: query.playerVillageColor,
onChange: createSettingsChangeHandler( onChange: createSettingsChangeHandler('playerVillageColor'),
'playerVillageColor'
),
}, },
{ {
name: 'barbarianVillageColor', name: 'barbarianVillageColor',
@ -406,9 +406,7 @@ function MapPage() {
<MarkerField <MarkerField
key={marker.id} key={marker.id}
onDelete={createDeletePlayerMarkerHandler(marker.id)} onDelete={createDeletePlayerMarkerHandler(marker.id)}
onChange={createUpdatePlayerMarkerItemHandler( onChange={createUpdatePlayerMarkerItemHandler(marker.id)}
marker.id
)}
onChangeColor={createUpdatePlayerMarkerColorHandler( onChangeColor={createUpdatePlayerMarkerColorHandler(
marker.id marker.id
)} )}
@ -455,8 +453,7 @@ function MapPage() {
</Grid> </Grid>
</form> </form>
</Container> </Container>
)} </Content>
</ServerPageLayout>
); );
} }

View File

@ -5,11 +5,10 @@ import { NOT_FOUND_PAGE } from '@config/namespaces';
import { makeStyles } from '@material-ui/core/styles'; import { makeStyles } from '@material-ui/core/styles';
import { Typography } from '@material-ui/core'; import { Typography } from '@material-ui/core';
import PageLayout from '@features/ServerPage/common/PageLayout/PageLayout'; import Content from '@common/Content/Content';
const useStyles = makeStyles(theme => ({ const useStyles = makeStyles(theme => ({
container: { container: {
padding: theme.spacing(3, 0),
width: '100%', width: '100%',
minHeight: 'inherit', minHeight: 'inherit',
display: 'flex', display: 'flex',
@ -24,40 +23,20 @@ const useStyles = makeStyles(theme => ({
export interface Props { export interface Props {
title?: string; title?: string;
description?: string; description?: string;
wrapIntoServerPageLayout?: boolean;
} }
function NotFoundPage({ function NotFoundPage({ title, description }: Props) {
title,
description,
wrapIntoServerPageLayout = true,
}: Props) {
const classes = useStyles(); const classes = useStyles();
const { t } = useTranslation(NOT_FOUND_PAGE); const { t } = useTranslation(NOT_FOUND_PAGE);
useTitle(t('title')); useTitle(t('title'));
const jsx = (
<div className={classes.container}>
<div>
<Typography variant="h1">{title ? title : t('title')}</Typography>
{description && <Typography variant="h4">{description}</Typography>}
</div>
</div>
);
if (!wrapIntoServerPageLayout) {
return jsx;
}
return ( return (
<PageLayout noPadding> <Content component="div" className={classes.container}>
<div className={classes.container}>
<div> <div>
<Typography variant="h1">{title ? title : t('title')}</Typography> <Typography variant="h1">{title ? title : t('title')}</Typography>
{description && <Typography variant="h4">{description}</Typography>} {description && <Typography variant="h4">{description}</Typography>}
</div> </div>
</div> </Content>
</PageLayout>
); );
} }

View File

@ -28,7 +28,7 @@ function PlayerPage() {
<EnnoblementsPage /> <EnnoblementsPage />
</Route> </Route>
<Route path="*"> <Route path="*">
<NotFoundPage wrapIntoServerPageLayout={false} /> <NotFoundPage />
</Route> </Route>
</Switch> </Switch>
</PageLayout> </PageLayout>

View File

@ -11,9 +11,9 @@ import * as ROUTES from '@config/routes';
import { makeStyles } from '@material-ui/core/styles'; import { makeStyles } from '@material-ui/core/styles';
import { Chip, Toolbar, Typography, Tabs, ChipProps } from '@material-ui/core'; import { Chip, Toolbar, Typography, Tabs, ChipProps } from '@material-ui/core';
import Content from '@common/Content/Content';
import Link from '@common/Link/Link'; import Link from '@common/Link/Link';
import TabLink from '@common/Link/TabLink'; import TabLink from '@common/Link/TabLink';
import ServerPageLayout from '@features/ServerPage/common/PageLayout/PageLayout';
import background1 from './backgrounds/bg-1-dark.png'; import background1 from './backgrounds/bg-1-dark.png';
import background2 from './backgrounds/bg-2-dark.jpg'; import background2 from './backgrounds/bg-2-dark.jpg';
@ -37,7 +37,7 @@ function PageLayout({ children }: Props) {
size: 'small', size: 'small',
}; };
return ( return (
<ServerPageLayout noPadding> <div>
<header className={clsx(classes.header, 'bg-' + bg)}> <header className={clsx(classes.header, 'bg-' + bg)}>
<Toolbar className={classes.toolbar}> <Toolbar className={classes.toolbar}>
<div style={{ width: '100%' }}> <div style={{ width: '100%' }}>
@ -124,8 +124,10 @@ function PageLayout({ children }: Props) {
})} })}
</Tabs> </Tabs>
</header> </header>
<div className={classes.content}>{children}</div> <Content component="div" minHeight={false}>
</ServerPageLayout> {children}
</Content>
</div>
); );
} }
@ -181,13 +183,6 @@ const useStyles = makeStyles(theme => ({
margin: theme.spacing(0.5), margin: theme.spacing(0.5),
}, },
}, },
content: {
height: '100%',
padding: theme.spacing(3, 0),
'&.no-padding': {
padding: '0 0',
},
},
})); }));
export default PageLayout; export default PageLayout;

View File

@ -10,7 +10,6 @@ import { PlayerQueryVariables } from '@libs/graphql/types';
import { Params, PlayerQueryResult } from './types'; import { Params, PlayerQueryResult } from './types';
import NotFoundPage from '@features/ServerPage/features/NotFoundPage/NotFoundPage'; import NotFoundPage from '@features/ServerPage/features/NotFoundPage/NotFoundPage';
import PageLayout from '@features/ServerPage/common/PageLayout/PageLayout';
import Spinner from '@common/Spinner/Spinner'; import Spinner from '@common/Spinner/Spinner';
export interface Props { export interface Props {
@ -41,17 +40,15 @@ function Provider({ children }: Props) {
alignItems: 'center', alignItems: 'center',
}; };
return ( return (
<PageLayout noPadding contentStyle={centerFlex as React.CSSProperties}>
<Spinner <Spinner
containerProps={{ containerProps={{
...centerFlex, ...centerFlex,
textAlign: 'center', textAlign: 'center',
height: '100%', minHeight: 'inherit',
paddingY: 5, paddingY: 5,
}} }}
description={t('playerPageContextProvider.loadingPlayer')} description={t('playerPageContextProvider.loadingPlayer')}
/> />
</PageLayout>
); );
} }

View File

@ -18,7 +18,7 @@ function RankingPage() {
<TribePage /> <TribePage />
</Route> </Route>
<Route path="*"> <Route path="*">
<NotFoundPage wrapIntoServerPageLayout={false} /> <NotFoundPage />
</Route> </Route>
</Switch> </Switch>
</PageLayout> </PageLayout>

View File

@ -8,7 +8,7 @@ import { makeStyles } from '@material-ui/core/styles';
import { Tabs } from '@material-ui/core'; import { Tabs } from '@material-ui/core';
import TabLink from '@common/Link/TabLink'; import TabLink from '@common/Link/TabLink';
import ServerPageLayout from '@features/ServerPage/common/PageLayout/PageLayout'; import Content from '@common/Content/Content';
import background from './backgrounds/bg-1-dark.png'; import background from './backgrounds/bg-1-dark.png';
@ -22,7 +22,7 @@ function PageLayout({ children }: Props) {
const { t } = useTranslation(NAMESPACES.SERVER_PAGE.RANKING_PAGE.COMMON); const { t } = useTranslation(NAMESPACES.SERVER_PAGE.RANKING_PAGE.COMMON);
const { currentTab, tabs } = useTabs(t); const { currentTab, tabs } = useTabs(t);
return ( return (
<ServerPageLayout noPadding> <div>
<header className={classes.header}> <header className={classes.header}>
<Tabs variant="scrollable" value={currentTab}> <Tabs variant="scrollable" value={currentTab}>
{tabs.map(({ to, label }) => { {tabs.map(({ to, label }) => {
@ -40,8 +40,10 @@ function PageLayout({ children }: Props) {
})} })}
</Tabs> </Tabs>
</header> </header>
<div className={classes.content}>{children}</div> <Content minHeight={false} component="div">
</ServerPageLayout> {children}
</Content>
</div>
); );
} }
@ -61,15 +63,6 @@ const useStyles = makeStyles(theme => ({
minHeight: theme.spacing(10), minHeight: theme.spacing(10),
}, },
}, },
content: {
padding: theme.spacing(3, 0),
'&.no-padding': {
padding: '0 0',
},
},
tabs: {
overflowX: 'auto',
},
})); }));
export default PageLayout; export default PageLayout;

View File

@ -24,7 +24,7 @@ function PlayerPage() {
<ArchivePage /> <ArchivePage />
</Route> </Route>
<Route path="*"> <Route path="*">
<NotFoundPage wrapIntoServerPageLayout={false} /> <NotFoundPage />
</Route> </Route>
</Switch> </Switch>
); );

View File

@ -24,7 +24,7 @@ function TribePage() {
<ArchivePage /> <ArchivePage />
</Route> </Route>
<Route path="*"> <Route path="*">
<NotFoundPage wrapIntoServerPageLayout={false} /> <NotFoundPage />
</Route> </Route>
</Switch> </Switch>
); );

View File

@ -32,7 +32,7 @@ function TribePage() {
<EnnoblementsPage /> <EnnoblementsPage />
</Route> </Route>
<Route path="*"> <Route path="*">
<NotFoundPage wrapIntoServerPageLayout={false} /> <NotFoundPage />
</Route> </Route>
</Switch> </Switch>
</PageLayout> </PageLayout>

View File

@ -10,8 +10,8 @@ import * as NAMESPACES from '@config/namespaces';
import { makeStyles } from '@material-ui/core/styles'; import { makeStyles } from '@material-ui/core/styles';
import { Chip, Toolbar, Typography, Tabs, ChipProps } from '@material-ui/core'; import { Chip, Toolbar, Typography, Tabs, ChipProps } from '@material-ui/core';
import Content from '@common/Content/Content';
import TabLink from '@common/Link/TabLink'; import TabLink from '@common/Link/TabLink';
import ServerPageLayout from '@features/ServerPage/common/PageLayout/PageLayout';
import background1 from './backgrounds/bg-1-dark.jpg'; import background1 from './backgrounds/bg-1-dark.jpg';
import background2 from './backgrounds/bg-2-dark.jpg'; import background2 from './backgrounds/bg-2-dark.jpg';
@ -35,7 +35,7 @@ function PageLayout({ children }: Props) {
size: 'small', size: 'small',
}; };
return ( return (
<ServerPageLayout noPadding> <div>
<header className={clsx(classes.header, 'bg-' + bg)}> <header className={clsx(classes.header, 'bg-' + bg)}>
<Toolbar className={classes.toolbar}> <Toolbar className={classes.toolbar}>
<div style={{ width: '100%' }}> <div style={{ width: '100%' }}>
@ -105,8 +105,10 @@ function PageLayout({ children }: Props) {
})} })}
</Tabs> </Tabs>
</header> </header>
<div className={classes.content}>{children}</div> <Content minHeight={false} component="div">
</ServerPageLayout> {children}
</Content>
</div>
); );
} }
@ -161,13 +163,6 @@ const useStyles = makeStyles(theme => ({
margin: theme.spacing(0.5), margin: theme.spacing(0.5),
}, },
}, },
content: {
height: '100%',
padding: theme.spacing(3, 0),
'&.no-padding': {
padding: '0 0',
},
},
})); }));
export default PageLayout; export default PageLayout;

View File

@ -10,7 +10,6 @@ import { TribeQueryVariables } from '@libs/graphql/types';
import { Params, TribeQueryResult } from './types'; import { Params, TribeQueryResult } from './types';
import NotFoundPage from '@features/ServerPage/features/NotFoundPage/NotFoundPage'; import NotFoundPage from '@features/ServerPage/features/NotFoundPage/NotFoundPage';
import PageLayout from '@features/ServerPage/common/PageLayout/PageLayout';
import Spinner from '@common/Spinner/Spinner'; import Spinner from '@common/Spinner/Spinner';
export interface Props { export interface Props {
@ -41,17 +40,16 @@ function Provider({ children }: Props) {
alignItems: 'center', alignItems: 'center',
}; };
return ( return (
<PageLayout noPadding contentStyle={centerFlex as React.CSSProperties}>
<Spinner <Spinner
containerProps={{ containerProps={{
...centerFlex, ...centerFlex,
textAlign: 'center', textAlign: 'center',
minHeight: 'inherit',
height: '100%', height: '100%',
paddingY: 5, paddingY: 5,
}} }}
description={t('tribePageContextProvider.loadingTribe')} description={t('tribePageContextProvider.loadingTribe')}
/> />
</PageLayout>
); );
} }

View File

@ -7,7 +7,6 @@ import { SERVER_PAGE } from '@config/namespaces';
import { Container } from '@material-ui/core'; import { Container } from '@material-ui/core';
import NotFoundPage from '@features/ServerPage/features/NotFoundPage/NotFoundPage'; import NotFoundPage from '@features/ServerPage/features/NotFoundPage/NotFoundPage';
import ServerPageLayout from '@features/ServerPage/common/PageLayout/PageLayout';
import Spinner from '@common/Spinner/Spinner'; import Spinner from '@common/Spinner/Spinner';
import PageLayout from './components/PageLayout/PageLayout'; import PageLayout from './components/PageLayout/PageLayout';
import Ennoblements from './components/Ennoblements/Ennoblements'; import Ennoblements from './components/Ennoblements/Ennoblements';
@ -28,20 +27,15 @@ function VillagePage() {
alignItems: 'center', alignItems: 'center',
}; };
return ( return (
<ServerPageLayout
noPadding
contentStyle={centerFlex as React.CSSProperties}
>
<Spinner <Spinner
containerProps={{ containerProps={{
...centerFlex, ...centerFlex,
textAlign: 'center', textAlign: 'center',
height: '100%', minHeight: 'inherit',
paddingY: 5, paddingY: 5,
}} }}
description={t('loadingVillage')} description={t('loadingVillage')}
/> />
</ServerPageLayout>
); );
} }

View File

@ -6,7 +6,7 @@ import { Village } from '../../types';
import { makeStyles } from '@material-ui/core/styles'; import { makeStyles } from '@material-ui/core/styles';
import { Toolbar, Typography } from '@material-ui/core'; import { Toolbar, Typography } from '@material-ui/core';
import ServerPageLayout from '@features/ServerPage/common/PageLayout/PageLayout'; import Content from '@common/Content/Content';
import PlayerProfileLink from '@features/ServerPage/common/PlayerProfileLink/PlayerProfileLink'; import PlayerProfileLink from '@features/ServerPage/common/PlayerProfileLink/PlayerProfileLink';
import background from './backgrounds/bg-1-dark.jpg'; import background from './backgrounds/bg-1-dark.jpg';
@ -21,7 +21,7 @@ export interface Props {
function PageLayout({ children, village, server, t }: Props) { function PageLayout({ children, village, server, t }: Props) {
const classes = useStyles(); const classes = useStyles();
return ( return (
<ServerPageLayout noPadding> <div>
<header className={classes.header}> <header className={classes.header}>
<Toolbar className={classes.toolbar}> <Toolbar className={classes.toolbar}>
<div> <div>
@ -40,8 +40,10 @@ function PageLayout({ children, village, server, t }: Props) {
</div> </div>
</Toolbar> </Toolbar>
</header> </header>
<div className={classes.content}>{children}</div> <Content minHeight={false} component="div">
</ServerPageLayout> {children}
</Content>
</div>
); );
} }
@ -68,13 +70,6 @@ const useStyles = makeStyles(theme => ({
marginBottom: theme.spacing(1), marginBottom: theme.spacing(1),
}, },
}, },
content: {
height: '100%',
padding: theme.spacing(3, 0),
'&.no-padding': {
padding: '0 0',
},
},
})); }));
export default PageLayout; export default PageLayout;

View File

@ -18,7 +18,7 @@ import {
Button, Button,
} from '@material-ui/core'; } from '@material-ui/core';
import DateTimePicker from '@common/Picker/DateTimePicker'; import DateTimePicker from '@common/Picker/DateTimePicker';
import ServerPageLayout from '@features/ServerPage/common/PageLayout/PageLayout'; import Content from '@common/Content/Content';
import Spinner from '@common/Spinner/Spinner'; import Spinner from '@common/Spinner/Spinner';
import Card from './components/Card/Card'; import Card from './components/Card/Card';
import OneSide from './components/OneSide/OneSide'; import OneSide from './components/OneSide/OneSide';
@ -205,9 +205,8 @@ function WarStatsPage() {
setIsSubmitting(false); setIsSubmitting(false);
}; };
if (loading) {
return ( return (
<ServerPageLayout>
{loading && (
<Spinner <Spinner
containerProps={{ containerProps={{
minHeight: 'inherit', minHeight: 'inherit',
@ -220,8 +219,11 @@ function WarStatsPage() {
}} }}
description={t('loading')} description={t('loading')}
/> />
)} );
{!loading && ( }
return (
<Content component="div" minHeight={false}>
<Container> <Container>
<form onSubmit={handleSubmit}> <form onSubmit={handleSubmit}>
<Grid container spacing={2}> <Grid container spacing={2}>
@ -308,8 +310,7 @@ function WarStatsPage() {
isSubmitting || isSubmitting ||
(sideOnePlayers.length === 0 && (sideOnePlayers.length === 0 &&
sideOneTribes.length === 0) || sideOneTribes.length === 0) ||
(sideTwoPlayers.length === 0 && (sideTwoPlayers.length === 0 && sideTwoTribes.length === 0)
sideTwoTribes.length === 0)
} }
> >
{t('buttons.generateStats')} {t('buttons.generateStats')}
@ -324,8 +325,7 @@ function WarStatsPage() {
</Grid> </Grid>
</form> </form>
</Container> </Container>
)} </Content>
</ServerPageLayout>
); );
} }

View File

@ -0,0 +1,25 @@
export function getEncodedValue(
input: string | (string | null)[] | null | undefined,
allowEmptyString?: boolean
): string | null | undefined {
if (!input) {
return undefined;
}
// '' or []
if (
input.length === 0 &&
(!allowEmptyString || (allowEmptyString && input !== ''))
) {
return null;
}
const str = input instanceof Array ? input[0] : input;
if (str == null) {
return str;
}
if (!allowEmptyString && str === '') {
return null;
}
return str;
}