fix Tabs component animation

This commit is contained in:
Dawid Wysokiński 2020-12-28 08:41:00 +01:00
parent d0228af0ba
commit 4d64201c51
32 changed files with 450 additions and 474 deletions

View File

@ -3,7 +3,6 @@ export const INDEX_PAGE = '/';
export const SEARCH_PAGE = '/search'; export const SEARCH_PAGE = '/search';
export const SERVER_PAGE = { export const SERVER_PAGE = {
BASE: '/server',
INDEX_PAGE: '/server/:key', INDEX_PAGE: '/server/:key',
TRIBE_PAGE: { TRIBE_PAGE: {
INDEX_PAGE: '/server/:key/tribe/:id', INDEX_PAGE: '/server/:key/tribe/:id',

View File

@ -20,7 +20,7 @@ function App() {
<Route path={ROUTES.SEARCH_PAGE} exact> <Route path={ROUTES.SEARCH_PAGE} exact>
<SearchPage /> <SearchPage />
</Route> </Route>
<Route path={ROUTES.SERVER_PAGE.BASE}> <Route path={ROUTES.SERVER_PAGE.INDEX_PAGE}>
<ServerPage /> <ServerPage />
</Route> </Route>
<Route path="*"> <Route path="*">

View File

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import { SERVER_PAGE } from '@config/routes'; import { SERVER_PAGE } from '@config/routes';
import { Switch, Route, RouteProps } from 'react-router-dom'; import { Switch, Route } from 'react-router-dom';
import ServerProvider from './libs/ServerContext/Provider'; import ServerProvider from './libs/ServerContext/Provider';
import IndexPage from './features/IndexPage/IndexPage'; import IndexPage from './features/IndexPage/IndexPage';
import PlayerPage from './features/PlayerPage/PlayerPage'; import PlayerPage from './features/PlayerPage/PlayerPage';
@ -10,44 +10,38 @@ import VillagePage from './features/VillagePage/VillagePage';
import RankingPage from './features/RankingPage/RankingPage'; import RankingPage from './features/RankingPage/RankingPage';
import MapPage from './features/MapPage/MapPage'; import MapPage from './features/MapPage/MapPage';
import EnnoblementsPage from './features/EnnoblementsPage/EnnoblementsPage'; import EnnoblementsPage from './features/EnnoblementsPage/EnnoblementsPage';
import NotFoundPage from '../NotFoundPage/NotFoundPage'; import NotFoundPage from './features/NotFoundPage/NotFoundPage';
const EnhancedRoute = ({ children, ...rest }: RouteProps) => {
return (
<Route {...rest}>
<ServerProvider>{children}</ServerProvider>
</Route>
);
};
function ServerPage() { function ServerPage() {
return ( return (
<Switch> <ServerProvider>
<EnhancedRoute exact path={SERVER_PAGE.INDEX_PAGE}> <Switch>
<IndexPage /> <Route exact path={SERVER_PAGE.INDEX_PAGE}>
</EnhancedRoute> <IndexPage />
<EnhancedRoute path={SERVER_PAGE.PLAYER_PAGE.INDEX_PAGE}> </Route>
<PlayerPage /> <Route path={SERVER_PAGE.PLAYER_PAGE.INDEX_PAGE}>
</EnhancedRoute> <PlayerPage />
<EnhancedRoute path={SERVER_PAGE.TRIBE_PAGE.INDEX_PAGE}> </Route>
<TribePage /> <Route path={SERVER_PAGE.TRIBE_PAGE.INDEX_PAGE}>
</EnhancedRoute> <TribePage />
<EnhancedRoute exact path={SERVER_PAGE.VILLAGE_PAGE.INDEX_PAGE}> </Route>
<VillagePage /> <Route exact path={SERVER_PAGE.VILLAGE_PAGE.INDEX_PAGE}>
</EnhancedRoute> <VillagePage />
<EnhancedRoute path={SERVER_PAGE.RANKING_PAGE.BASE}> </Route>
<RankingPage /> <Route path={SERVER_PAGE.RANKING_PAGE.BASE}>
</EnhancedRoute> <RankingPage />
<EnhancedRoute path={SERVER_PAGE.MAP_PAGE}> </Route>
<MapPage /> <Route path={SERVER_PAGE.MAP_PAGE}>
</EnhancedRoute> <MapPage />
<EnhancedRoute path={SERVER_PAGE.ENNOBLEMENTS_PAGE}> </Route>
<EnnoblementsPage /> <Route exact path={SERVER_PAGE.ENNOBLEMENTS_PAGE}>
</EnhancedRoute> <EnnoblementsPage />
<Route path="*"> </Route>
<NotFoundPage /> <Route path="*">
</Route> <NotFoundPage />
</Switch> </Route>
</Switch>
</ServerProvider>
); );
} }

View File

@ -1,35 +1,61 @@
import React from 'react'; import React from 'react';
import { useTranslation } from 'react-i18next';
import useTitle from '@libs/useTitle';
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 PageLayout from '@features/ServerPage/common/PageLayout/PageLayout';
const useStyles = makeStyles(theme => ({ const useStyles = makeStyles(theme => ({
container: { container: {
marginTop: theme.spacing(5), padding: theme.spacing(3, 0),
width: '100%',
minHeight: 'inherit',
display: 'flex',
textAlign: 'center', textAlign: 'center',
alignItems: 'center',
'& > div': {
flex: 1,
},
}, },
})); }));
export interface Props { export interface Props {
title?: string; title?: string;
description?: string; description?: string;
wrapIntoServerPageLayout?: boolean;
} }
function NotFoundPage({ title, description }: Props) { function NotFoundPage({
title,
description,
wrapIntoServerPageLayout = true,
}: Props) {
const classes = useStyles(); const classes = useStyles();
const { t } = useTranslation(NOT_FOUND_PAGE);
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> <PageLayout noPadding>
<div className={classes.container}> <div className={classes.container}>
<Typography gutterBottom variant="h1"> <div>
{title ? title : 'Page not found'} <Typography variant="h1">{title ? title : t('title')}</Typography>
</Typography> {description && <Typography variant="h4">{description}</Typography>}
{description && ( </div>
<Typography gutterBottom variant="h4">
{description}
</Typography>
)}
</div> </div>
</PageLayout> </PageLayout>
); );

View File

@ -1,41 +1,38 @@
import React from 'react'; import React from 'react';
import { SERVER_PAGE } from '@config/routes'; import { SERVER_PAGE } from '@config/routes';
import { Switch, Route, RouteProps } from 'react-router-dom'; import { Switch, Route } from 'react-router-dom';
import PlayerProvider from './libs/PlayerPageContext/Provider'; import PlayerProvider from './libs/PlayerPageContext/Provider';
import PageLayout from './common/PageLayout/PageLayout';
import IndexPage from './features/IndexPage/IndexPage'; import IndexPage from './features/IndexPage/IndexPage';
import HistoryPage from './features/HistoryPage/HistoryPage'; import HistoryPage from './features/HistoryPage/HistoryPage';
import EnnoblementsPage from './features/EnnoblementsPage/EnnoblementsPage'; import EnnoblementsPage from './features/EnnoblementsPage/EnnoblementsPage';
import TribeChangesPage from './features/TribeChangesPage/TribeChangesPage'; import TribeChangesPage from './features/TribeChangesPage/TribeChangesPage';
import NotFoundPage from '../NotFoundPage/NotFoundPage'; import NotFoundPage from '../NotFoundPage/NotFoundPage';
const EnhancedRoute = ({ children, ...rest }: RouteProps) => {
return (
<Route {...rest}>
<PlayerProvider>{children}</PlayerProvider>
</Route>
);
};
function PlayerPage() { function PlayerPage() {
return ( return (
<Switch> <PlayerProvider>
<EnhancedRoute exact path={SERVER_PAGE.PLAYER_PAGE.INDEX_PAGE}> <PageLayout>
<IndexPage /> <Switch>
</EnhancedRoute> <Route exact path={SERVER_PAGE.PLAYER_PAGE.INDEX_PAGE}>
<EnhancedRoute exact path={SERVER_PAGE.PLAYER_PAGE.HISTORY_PAGE}> <IndexPage />
<HistoryPage /> </Route>
</EnhancedRoute> <Route exact path={SERVER_PAGE.PLAYER_PAGE.HISTORY_PAGE}>
<EnhancedRoute exact path={SERVER_PAGE.PLAYER_PAGE.TRIBE_CHANGES_PAGE}> <HistoryPage />
<TribeChangesPage /> </Route>
</EnhancedRoute> <Route exact path={SERVER_PAGE.PLAYER_PAGE.TRIBE_CHANGES_PAGE}>
<EnhancedRoute exact path={SERVER_PAGE.PLAYER_PAGE.ENNOBLEMENTS_PAGE}> <TribeChangesPage />
<EnnoblementsPage /> </Route>
</EnhancedRoute> <Route exact path={SERVER_PAGE.PLAYER_PAGE.ENNOBLEMENTS_PAGE}>
<Route path="*"> <EnnoblementsPage />
<NotFoundPage /> </Route>
</Route> <Route path="*">
</Switch> <NotFoundPage wrapIntoServerPageLayout={false} />
</Route>
</Switch>
</PageLayout>
</PlayerProvider>
); );
} }

View File

@ -26,13 +26,16 @@ const useTabs = (t: TFunction) => {
}, },
]; ];
}, [t]); }, [t]);
const currentTab = useMemo( const currentTab = useMemo(() => {
() => const currentTab = tabs.findIndex(({ to }) => {
tabs.findIndex(({ to }) => { return matchPath(loc.pathname, { exact: true, path: to });
return matchPath(loc.pathname, { exact: true, path: to }); });
}), return currentTab === -1
[loc.pathname, tabs] ? process.env.NODE_ENV === 'production'
); ? -1
: 0
: currentTab;
}, [loc.pathname, tabs]);
return { return {
tabs, tabs,
currentTab, currentTab,

View File

@ -6,7 +6,6 @@ import usePlayer from '../../libs/PlayerPageContext/usePlayer';
import { SERVER_PAGE } from '@config/namespaces'; import { SERVER_PAGE } from '@config/namespaces';
import { Container } from '@material-ui/core'; import { Container } from '@material-ui/core';
import PageLayout from '../../common/PageLayout/PageLayout';
import Ennoblements from './components/Ennoblements/Ennoblements'; import Ennoblements from './components/Ennoblements/Ennoblements';
function EnnoblementsPage() { function EnnoblementsPage() {
@ -15,11 +14,9 @@ function EnnoblementsPage() {
const { t } = useTranslation(SERVER_PAGE.PLAYER_PAGE.ENNOBLEMENTS_PAGE); const { t } = useTranslation(SERVER_PAGE.PLAYER_PAGE.ENNOBLEMENTS_PAGE);
useTitle(t('title', { key, name: player.name })); useTitle(t('title', { key, name: player.name }));
return ( return (
<PageLayout> <Container>
<Container> <Ennoblements t={t} server={key} playerID={player.id} />
<Ennoblements t={t} server={key} playerID={player.id} /> </Container>
</Container>
</PageLayout>
); );
} }

View File

@ -6,7 +6,6 @@ import usePlayer from '../../libs/PlayerPageContext/usePlayer';
import { SERVER_PAGE } from '@config/namespaces'; import { SERVER_PAGE } from '@config/namespaces';
import { Container } from '@material-ui/core'; import { Container } from '@material-ui/core';
import PageLayout from '../../common/PageLayout/PageLayout';
import PlayerHistory from './components/PlayerHistory/PlayerHistory'; import PlayerHistory from './components/PlayerHistory/PlayerHistory';
function HistoryPage() { function HistoryPage() {
@ -15,11 +14,9 @@ function HistoryPage() {
const { t } = useTranslation(SERVER_PAGE.PLAYER_PAGE.HISTORY_PAGE); const { t } = useTranslation(SERVER_PAGE.PLAYER_PAGE.HISTORY_PAGE);
useTitle(t('title', { key, name: player.name })); useTitle(t('title', { key, name: player.name }));
return ( return (
<PageLayout> <Container>
<Container> <PlayerHistory t={t} server={key} playerID={player.id} />
<PlayerHistory t={t} server={key} playerID={player.id} /> </Container>
</Container>
</PageLayout>
); );
} }

View File

@ -20,7 +20,6 @@ import {
Chip, Chip,
} from '@material-ui/core'; } from '@material-ui/core';
import Link from '@common/Link/Link'; import Link from '@common/Link/Link';
import PageLayout from '../../common/PageLayout/PageLayout';
import Statistics from './components/Statistics/Statistics'; import Statistics from './components/Statistics/Statistics';
import NameChanges from './components/NameChanges/NameChanges'; import NameChanges from './components/NameChanges/NameChanges';
@ -32,144 +31,140 @@ function IndexPage() {
useTitle(t('title', { key, name: player.name })); useTitle(t('title', { key, name: player.name }));
return ( return (
<PageLayout> <Container>
<Container> <Grid container spacing={2}>
<Grid container spacing={2}> <Grid component={Hidden} xsDown implementation="css" item xs={12}>
<Grid component={Hidden} xsDown implementation="css" item xs={12}> <Statistics server={key} playerID={player.id} t={t} />
<Statistics server={key} playerID={player.id} t={t} />
</Grid>
{[
{
field: 'joinedAt',
value: format(
new Date(player.joinedAt),
DATE_FORMAT.DAY_MONTH_AND_YEAR
),
},
{
field: 'points',
value: `${formatNumber('commas', player.points)} (#${
player.rank
})`,
},
{
field: 'totalVillages',
value: formatNumber('commas', player.totalVillages),
},
{
field: 'dailyGrowth',
value: formatNumber('commas', player.dailyGrowth),
},
{
field: 'scoreAtt',
value: `${formatNumber('commas', player.scoreAtt)} (#${
player.rankAtt
})`,
},
{
field: 'scoreDef',
value: `${formatNumber('commas', player.scoreDef)} (#${
player.rankDef
})`,
},
{
field: 'scoreSup',
value: `${formatNumber('commas', player.scoreSup)} (#${
player.rankSup
})`,
},
{
field: 'scoreTotal',
value: `${formatNumber('commas', player.scoreTotal)} (#${
player.rankTotal
})`,
},
{
field: 'deletedAt',
value: player.deletedAt
? format(
new Date(player.deletedAt),
DATE_FORMAT.DAY_MONTH_AND_YEAR
)
: '-',
},
{
field: 'bestRank',
subtitle: format(
new Date(player.bestRankAt),
DATE_FORMAT.HOUR_MINUTES_DAY_MONTH_AND_YEAR
),
value: player.bestRank,
},
{
field: 'mostPoints',
subtitle: format(
new Date(player.mostPointsAt),
DATE_FORMAT.HOUR_MINUTES_DAY_MONTH_AND_YEAR
),
value: formatNumber('commas', player.mostPoints),
},
{
field: 'mostVillages',
subtitle: format(
new Date(player.mostVillagesAt),
DATE_FORMAT.HOUR_MINUTES_DAY_MONTH_AND_YEAR
),
value: formatNumber('commas', player.mostVillages),
},
].map(({ field, value, subtitle }) => {
return (
<Grid key={field} item xs={12} sm={6} md={4} lg={3}>
<Card className={classes.card}>
<CardContent className={classes.cardContent}>
<Typography gutterBottom variant="h5">
{t('fields.' + field)}
<br />
{subtitle && (
<Typography variant="subtitle2" component="span">
{subtitle}
</Typography>
)}
</Typography>
<Typography variant="h4">{value}</Typography>
</CardContent>
</Card>
</Grid>
);
})}
<Grid item xs={12} md={4}>
<Card>
<CardContent>
<Typography variant="h5" gutterBottom>
{t('fields.servers')}
</Typography>
<div className={classes.serverContainer}>
{[...player.servers].sort().map(server => {
return (
<Link
key={server}
to={ROUTES.SERVER_PAGE.PLAYER_PAGE.INDEX_PAGE}
params={{ key: server, id: player.id }}
>
<Chip
className={classes.chip}
color="secondary"
label={server}
clickable
/>
</Link>
);
})}
</div>
</CardContent>
</Card>
</Grid>
<Grid item xs={12} md={8}>
<NameChanges t={t} nameChanges={player.nameChanges} />
</Grid>
</Grid> </Grid>
</Container> {[
</PageLayout> {
field: 'joinedAt',
value: format(
new Date(player.joinedAt),
DATE_FORMAT.DAY_MONTH_AND_YEAR
),
},
{
field: 'points',
value: `${formatNumber('commas', player.points)} (#${player.rank})`,
},
{
field: 'totalVillages',
value: formatNumber('commas', player.totalVillages),
},
{
field: 'dailyGrowth',
value: formatNumber('commas', player.dailyGrowth),
},
{
field: 'scoreAtt',
value: `${formatNumber('commas', player.scoreAtt)} (#${
player.rankAtt
})`,
},
{
field: 'scoreDef',
value: `${formatNumber('commas', player.scoreDef)} (#${
player.rankDef
})`,
},
{
field: 'scoreSup',
value: `${formatNumber('commas', player.scoreSup)} (#${
player.rankSup
})`,
},
{
field: 'scoreTotal',
value: `${formatNumber('commas', player.scoreTotal)} (#${
player.rankTotal
})`,
},
{
field: 'deletedAt',
value: player.deletedAt
? format(
new Date(player.deletedAt),
DATE_FORMAT.DAY_MONTH_AND_YEAR
)
: '-',
},
{
field: 'bestRank',
subtitle: format(
new Date(player.bestRankAt),
DATE_FORMAT.HOUR_MINUTES_DAY_MONTH_AND_YEAR
),
value: player.bestRank,
},
{
field: 'mostPoints',
subtitle: format(
new Date(player.mostPointsAt),
DATE_FORMAT.HOUR_MINUTES_DAY_MONTH_AND_YEAR
),
value: formatNumber('commas', player.mostPoints),
},
{
field: 'mostVillages',
subtitle: format(
new Date(player.mostVillagesAt),
DATE_FORMAT.HOUR_MINUTES_DAY_MONTH_AND_YEAR
),
value: formatNumber('commas', player.mostVillages),
},
].map(({ field, value, subtitle }) => {
return (
<Grid key={field} item xs={12} sm={6} md={4} lg={3}>
<Card className={classes.card}>
<CardContent className={classes.cardContent}>
<Typography gutterBottom variant="h5">
{t('fields.' + field)}
<br />
{subtitle && (
<Typography variant="subtitle2" component="span">
{subtitle}
</Typography>
)}
</Typography>
<Typography variant="h4">{value}</Typography>
</CardContent>
</Card>
</Grid>
);
})}
<Grid item xs={12} md={4}>
<Card>
<CardContent>
<Typography variant="h5" gutterBottom>
{t('fields.servers')}
</Typography>
<div className={classes.serverContainer}>
{[...player.servers].sort().map(server => {
return (
<Link
key={server}
to={ROUTES.SERVER_PAGE.PLAYER_PAGE.INDEX_PAGE}
params={{ key: server, id: player.id }}
>
<Chip
className={classes.chip}
color="secondary"
label={server}
clickable
/>
</Link>
);
})}
</div>
</CardContent>
</Card>
</Grid>
<Grid item xs={12} md={8}>
<NameChanges t={t} nameChanges={player.nameChanges} />
</Grid>
</Grid>
</Container>
); );
} }

View File

@ -66,6 +66,7 @@ function Statistics({ t, server, playerID }: Props) {
<Paper> <Paper>
<ModeSelector <ModeSelector
onSelect={m => setMode(m.name as Mode)} onSelect={m => setMode(m.name as Mode)}
buttonProps={{ size: 'medium' }}
modes={[ modes={[
{ {
name: 'points', name: 'points',

View File

@ -6,7 +6,6 @@ import usePlayer from '../../libs/PlayerPageContext/usePlayer';
import { SERVER_PAGE } from '@config/namespaces'; import { SERVER_PAGE } from '@config/namespaces';
import { Container } from '@material-ui/core'; import { Container } from '@material-ui/core';
import PageLayout from '../../common/PageLayout/PageLayout';
import TribeChanges from './components/TribeChanges/TribeChanges'; import TribeChanges from './components/TribeChanges/TribeChanges';
function TribeChangesPage() { function TribeChangesPage() {
@ -15,11 +14,9 @@ function TribeChangesPage() {
const { t } = useTranslation(SERVER_PAGE.PLAYER_PAGE.TRIBE_CHANGES_PAGE); const { t } = useTranslation(SERVER_PAGE.PLAYER_PAGE.TRIBE_CHANGES_PAGE);
useTitle(t('title', { key, name: player.name })); useTitle(t('title', { key, name: player.name }));
return ( return (
<PageLayout> <Container>
<Container> <TribeChanges t={t} server={key} playerID={player.id} />
<TribeChanges t={t} server={key} playerID={player.id} /> </Container>
</Container>
</PageLayout>
); );
} }

View File

@ -2,23 +2,26 @@ import React from 'react';
import { SERVER_PAGE } from '@config/routes'; import { SERVER_PAGE } from '@config/routes';
import { Switch, Route } from 'react-router-dom'; import { Switch, Route } from 'react-router-dom';
import PageLayout from './common/PageLayout/PageLayout';
import PlayerPage from './features/PlayerPage/PlayerPage'; import PlayerPage from './features/PlayerPage/PlayerPage';
import TribePage from './features/TribePage/TribePage'; import TribePage from './features/TribePage/TribePage';
import NotFoundPage from '../../../NotFoundPage/NotFoundPage'; import NotFoundPage from '../NotFoundPage/NotFoundPage';
function RankingPage() { function RankingPage() {
return ( return (
<Switch> <PageLayout>
<Route path={SERVER_PAGE.RANKING_PAGE.PLAYER_PAGE.INDEX_PAGE}> <Switch>
<PlayerPage /> <Route path={SERVER_PAGE.RANKING_PAGE.PLAYER_PAGE.INDEX_PAGE}>
</Route> <PlayerPage />
<Route path={SERVER_PAGE.RANKING_PAGE.TRIBE_PAGE.INDEX_PAGE}> </Route>
<TribePage /> <Route path={SERVER_PAGE.RANKING_PAGE.TRIBE_PAGE.INDEX_PAGE}>
</Route> <TribePage />
<Route path="*"> </Route>
<NotFoundPage /> <Route path="*">
</Route> <NotFoundPage wrapIntoServerPageLayout={false} />
</Switch> </Route>
</Switch>
</PageLayout>
); );
} }

View File

@ -59,12 +59,14 @@ const useStyles = makeStyles(theme => ({
boxShadow: theme.shadows[4], boxShadow: theme.shadows[4],
}, },
content: { content: {
height: '100%',
padding: theme.spacing(3, 0), padding: theme.spacing(3, 0),
'&.no-padding': { '&.no-padding': {
padding: '0 0', padding: '0 0',
}, },
}, },
tabs: {
overflowX: 'auto',
},
})); }));
export default PageLayout; export default PageLayout;

View File

@ -42,13 +42,16 @@ const useTabs = (t: TFunction) => {
}, },
]; ];
}, [t]); }, [t]);
const currentTab = useMemo( const currentTab = useMemo(() => {
() => const currentTab = tabs.findIndex(({ to }) => {
tabs.findIndex(({ to }) => { return matchPath(loc.pathname, { exact: true, path: to });
return matchPath(loc.pathname, { exact: true, path: to }); });
}), return currentTab === -1
[loc.pathname, tabs] ? process.env.NODE_ENV === 'production'
); ? -1
: 0
: currentTab;
}, [loc.pathname, tabs]);
return { return {
tabs, tabs,
currentTab, currentTab,

View File

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

View File

@ -5,7 +5,6 @@ import useServer from '@features/ServerPage/libs/ServerContext/useServer';
import { SERVER_PAGE } from '@config/namespaces'; import { SERVER_PAGE } from '@config/namespaces';
import { Container } from '@material-ui/core'; import { Container } from '@material-ui/core';
import PageLayout from '@features/ServerPage/features/RankingPage/common/PageLayout/PageLayout';
import Ranking from './components/Ranking/Ranking'; import Ranking from './components/Ranking/Ranking';
function ArchivePage() { function ArchivePage() {
@ -15,11 +14,9 @@ function ArchivePage() {
); );
useTitle(t('title', { key })); useTitle(t('title', { key }));
return ( return (
<PageLayout> <Container>
<Container> <Ranking t={t} server={key} />
<Ranking t={t} server={key} /> </Container>
</Container>
</PageLayout>
); );
} }

View File

@ -5,7 +5,6 @@ import useServer from '@features/ServerPage/libs/ServerContext/useServer';
import { SERVER_PAGE } from '@config/namespaces'; import { SERVER_PAGE } from '@config/namespaces';
import { Container } from '@material-ui/core'; import { Container } from '@material-ui/core';
import PageLayout from '@features/ServerPage/features/RankingPage/common/PageLayout/PageLayout';
import Ranking from './components/Ranking/Ranking'; import Ranking from './components/Ranking/Ranking';
function DailyPage() { function DailyPage() {
@ -13,11 +12,9 @@ function DailyPage() {
const { t } = useTranslation(SERVER_PAGE.RANKING_PAGE.PLAYER_PAGE.DAILY_PAGE); const { t } = useTranslation(SERVER_PAGE.RANKING_PAGE.PLAYER_PAGE.DAILY_PAGE);
useTitle(t('title', { key })); useTitle(t('title', { key }));
return ( return (
<PageLayout> <Container>
<Container> <Ranking t={t} server={key} />
<Ranking t={t} server={key} /> </Container>
</Container>
</PageLayout>
); );
} }

View File

@ -5,19 +5,16 @@ import useServer from '@features/ServerPage/libs/ServerContext/useServer';
import { SERVER_PAGE } from '@config/namespaces'; import { SERVER_PAGE } from '@config/namespaces';
import { Container } from '@material-ui/core'; import { Container } from '@material-ui/core';
import PageLayout from '@features/ServerPage/features/RankingPage/common/PageLayout/PageLayout'; import Ranking from './components/Ranking/Ranking';
import Ranking from './components/Ranking/Ranking'
function IndexPage() { function IndexPage() {
const { key } = useServer(); const { key } = useServer();
const { t } = useTranslation(SERVER_PAGE.RANKING_PAGE.PLAYER_PAGE.INDEX_PAGE); const { t } = useTranslation(SERVER_PAGE.RANKING_PAGE.PLAYER_PAGE.INDEX_PAGE);
useTitle(t('title', { key })); useTitle(t('title', { key }));
return ( return (
<PageLayout> <Container>
<Container> <Ranking t={t} server={key} />
<Ranking t={t} server={key} /> </Container>
</Container>
</PageLayout>
); );
} }

View File

@ -5,7 +5,6 @@ import useServer from '@features/ServerPage/libs/ServerContext/useServer';
import { SERVER_PAGE } from '@config/namespaces'; import { SERVER_PAGE } from '@config/namespaces';
import { Container } from '@material-ui/core'; import { Container } from '@material-ui/core';
import PageLayout from '@features/ServerPage/features/RankingPage/common/PageLayout/PageLayout';
import Ranking from './components/Ranking/Ranking'; import Ranking from './components/Ranking/Ranking';
function ODPage() { function ODPage() {
@ -13,11 +12,9 @@ function ODPage() {
const { t } = useTranslation(SERVER_PAGE.RANKING_PAGE.PLAYER_PAGE.OD_PAGE); const { t } = useTranslation(SERVER_PAGE.RANKING_PAGE.PLAYER_PAGE.OD_PAGE);
useTitle(t('title', { key })); useTitle(t('title', { key }));
return ( return (
<PageLayout> <Container>
<Container> <Ranking t={t} server={key} />
<Ranking t={t} server={key} /> </Container>
</Container>
</PageLayout>
); );
} }

View File

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

View File

@ -5,7 +5,6 @@ import useServer from '@features/ServerPage/libs/ServerContext/useServer';
import { SERVER_PAGE } from '@config/namespaces'; import { SERVER_PAGE } from '@config/namespaces';
import { Container } from '@material-ui/core'; import { Container } from '@material-ui/core';
import PageLayout from '@features/ServerPage/features/RankingPage/common/PageLayout/PageLayout';
import Ranking from './components/Ranking/Ranking'; import Ranking from './components/Ranking/Ranking';
function ArchivePage() { function ArchivePage() {
@ -15,11 +14,9 @@ function ArchivePage() {
); );
useTitle(t('title', { key })); useTitle(t('title', { key }));
return ( return (
<PageLayout> <Container>
<Container> <Ranking t={t} server={key} />
<Ranking t={t} server={key} /> </Container>
</Container>
</PageLayout>
); );
} }

View File

@ -5,7 +5,6 @@ import useServer from '@features/ServerPage/libs/ServerContext/useServer';
import { SERVER_PAGE } from '@config/namespaces'; import { SERVER_PAGE } from '@config/namespaces';
import { Container } from '@material-ui/core'; import { Container } from '@material-ui/core';
import PageLayout from '@features/ServerPage/features/RankingPage/common/PageLayout/PageLayout';
import Ranking from './components/Ranking/Ranking'; import Ranking from './components/Ranking/Ranking';
function DailyPage() { function DailyPage() {
@ -13,11 +12,9 @@ function DailyPage() {
const { t } = useTranslation(SERVER_PAGE.RANKING_PAGE.TRIBE_PAGE.DAILY_PAGE); const { t } = useTranslation(SERVER_PAGE.RANKING_PAGE.TRIBE_PAGE.DAILY_PAGE);
useTitle(t('title', { key })); useTitle(t('title', { key }));
return ( return (
<PageLayout> <Container>
<Container> <Ranking t={t} server={key} />
<Ranking t={t} server={key} /> </Container>
</Container>
</PageLayout>
); );
} }

View File

@ -5,7 +5,6 @@ import useServer from '@features/ServerPage/libs/ServerContext/useServer';
import { SERVER_PAGE } from '@config/namespaces'; import { SERVER_PAGE } from '@config/namespaces';
import { Container } from '@material-ui/core'; import { Container } from '@material-ui/core';
import PageLayout from '@features/ServerPage/features/RankingPage/common/PageLayout/PageLayout';
import Ranking from './components/Ranking/Ranking'; import Ranking from './components/Ranking/Ranking';
function IndexPage() { function IndexPage() {
@ -13,11 +12,9 @@ function IndexPage() {
const { t } = useTranslation(SERVER_PAGE.RANKING_PAGE.TRIBE_PAGE.INDEX_PAGE); const { t } = useTranslation(SERVER_PAGE.RANKING_PAGE.TRIBE_PAGE.INDEX_PAGE);
useTitle(t('title', { key })); useTitle(t('title', { key }));
return ( return (
<PageLayout> <Container>
<Container> <Ranking t={t} server={key} />
<Ranking t={t} server={key} /> </Container>
</Container>
</PageLayout>
); );
} }

View File

@ -5,7 +5,6 @@ import useServer from '@features/ServerPage/libs/ServerContext/useServer';
import { SERVER_PAGE } from '@config/namespaces'; import { SERVER_PAGE } from '@config/namespaces';
import { Container } from '@material-ui/core'; import { Container } from '@material-ui/core';
import PageLayout from '@features/ServerPage/features/RankingPage/common/PageLayout/PageLayout';
import Ranking from './components/Ranking/Ranking'; import Ranking from './components/Ranking/Ranking';
function ODPage() { function ODPage() {
@ -13,11 +12,9 @@ function ODPage() {
const { t } = useTranslation(SERVER_PAGE.RANKING_PAGE.TRIBE_PAGE.OD_PAGE); const { t } = useTranslation(SERVER_PAGE.RANKING_PAGE.TRIBE_PAGE.OD_PAGE);
useTitle(t('title', { key })); useTitle(t('title', { key }));
return ( return (
<PageLayout> <Container>
<Container> <Ranking t={t} server={key} />
<Ranking t={t} server={key} /> </Container>
</Container>
</PageLayout>
); );
} }

View File

@ -1,8 +1,9 @@
import React from 'react'; import React from 'react';
import { SERVER_PAGE } from '@config/routes'; import { SERVER_PAGE } from '@config/routes';
import { Switch, Route, RouteProps } from 'react-router-dom'; import { Switch, Route } from 'react-router-dom';
import TribeProvider from './libs/TribePageContext/Provider'; import TribeProvider from './libs/TribePageContext/Provider';
import PageLayout from './common/PageLayout/PageLayout';
import IndexPage from './features/IndexPage/IndexPage'; import IndexPage from './features/IndexPage/IndexPage';
import MembersPage from './features/MembersPage/MembersPage'; import MembersPage from './features/MembersPage/MembersPage';
import HistoryPage from './features/HistoryPage/HistoryPage'; import HistoryPage from './features/HistoryPage/HistoryPage';
@ -10,36 +11,32 @@ import EnnoblementsPage from './features/EnnoblementsPage/EnnoblementsPage';
import TribeChangesPage from './features/TribeChangesPage/TribeChangesPage'; import TribeChangesPage from './features/TribeChangesPage/TribeChangesPage';
import NotFoundPage from '../NotFoundPage/NotFoundPage'; import NotFoundPage from '../NotFoundPage/NotFoundPage';
const EnhancedRoute = ({ children, ...rest }: RouteProps) => {
return (
<Route {...rest}>
<TribeProvider>{children}</TribeProvider>
</Route>
);
};
function TribePage() { function TribePage() {
return ( return (
<Switch> <TribeProvider>
<EnhancedRoute exact path={SERVER_PAGE.TRIBE_PAGE.INDEX_PAGE}> <PageLayout>
<IndexPage /> <Switch>
</EnhancedRoute> <Route exact path={SERVER_PAGE.TRIBE_PAGE.INDEX_PAGE}>
<EnhancedRoute exact path={SERVER_PAGE.TRIBE_PAGE.MEMBERS_PAGE}> <IndexPage />
<MembersPage /> </Route>
</EnhancedRoute> <Route exact path={SERVER_PAGE.TRIBE_PAGE.MEMBERS_PAGE}>
<EnhancedRoute exact path={SERVER_PAGE.TRIBE_PAGE.HISTORY_PAGE}> <MembersPage />
<HistoryPage /> </Route>
</EnhancedRoute> <Route exact path={SERVER_PAGE.TRIBE_PAGE.HISTORY_PAGE}>
<EnhancedRoute exact path={SERVER_PAGE.TRIBE_PAGE.TRIBE_CHANGES_PAGE}> <HistoryPage />
<TribeChangesPage /> </Route>
</EnhancedRoute> <Route exact path={SERVER_PAGE.TRIBE_PAGE.TRIBE_CHANGES_PAGE}>
<EnhancedRoute exact path={SERVER_PAGE.TRIBE_PAGE.ENNOBLEMENTS_PAGE}> <TribeChangesPage />
<EnnoblementsPage /> </Route>
</EnhancedRoute> <Route exact path={SERVER_PAGE.TRIBE_PAGE.ENNOBLEMENTS_PAGE}>
<Route path="*"> <EnnoblementsPage />
<NotFoundPage /> </Route>
</Route> <Route path="*">
</Switch> <NotFoundPage wrapIntoServerPageLayout={false} />
</Route>
</Switch>
</PageLayout>
</TribeProvider>
); );
} }

View File

@ -30,13 +30,16 @@ const useTabs = (t: TFunction) => {
}, },
]; ];
}, [t]); }, [t]);
const currentTab = useMemo( const currentTab = useMemo(() => {
() => const currentTab = tabs.findIndex(({ to }) => {
tabs.findIndex(({ to }) => { return matchPath(loc.pathname, { exact: true, path: to });
return matchPath(loc.pathname, { exact: true, path: to }); });
}), return currentTab === -1
[loc.pathname, tabs] ? process.env.NODE_ENV === 'production'
); ? -1
: 0
: currentTab;
}, [loc.pathname, tabs]);
return { return {
tabs, tabs,
currentTab, currentTab,

View File

@ -6,7 +6,6 @@ import useTribe from '../../libs/TribePageContext/useTribe';
import { SERVER_PAGE } from '@config/namespaces'; import { SERVER_PAGE } from '@config/namespaces';
import { Container } from '@material-ui/core'; import { Container } from '@material-ui/core';
import PageLayout from '../../common/PageLayout/PageLayout';
import Ennoblements from './components/Ennoblements/Ennoblements'; import Ennoblements from './components/Ennoblements/Ennoblements';
function EnnoblementsPage() { function EnnoblementsPage() {
@ -15,11 +14,9 @@ function EnnoblementsPage() {
const { t } = useTranslation(SERVER_PAGE.TRIBE_PAGE.ENNOBLEMENTS_PAGE); const { t } = useTranslation(SERVER_PAGE.TRIBE_PAGE.ENNOBLEMENTS_PAGE);
useTitle(t('title', { key, tag: tribe.tag })); useTitle(t('title', { key, tag: tribe.tag }));
return ( return (
<PageLayout> <Container>
<Container> <Ennoblements t={t} server={key} tribeID={tribe.id} />
<Ennoblements t={t} server={key} tribeID={tribe.id} /> </Container>
</Container>
</PageLayout>
); );
} }

View File

@ -6,7 +6,6 @@ import useTribe from '../../libs/TribePageContext/useTribe';
import { SERVER_PAGE } from '@config/namespaces'; import { SERVER_PAGE } from '@config/namespaces';
import { Container } from '@material-ui/core'; import { Container } from '@material-ui/core';
import PageLayout from '../../common/PageLayout/PageLayout';
import TribeHistory from './components/TribeHistory/TribeHistory'; import TribeHistory from './components/TribeHistory/TribeHistory';
function HistoryPage() { function HistoryPage() {
@ -15,11 +14,9 @@ function HistoryPage() {
const { t } = useTranslation(SERVER_PAGE.TRIBE_PAGE.HISTORY_PAGE); const { t } = useTranslation(SERVER_PAGE.TRIBE_PAGE.HISTORY_PAGE);
useTitle(t('title', { key, tag: tribe.tag })); useTitle(t('title', { key, tag: tribe.tag }));
return ( return (
<PageLayout> <Container>
<Container> <TribeHistory t={t} server={key} tribeID={tribe.id} />
<TribeHistory t={t} server={key} tribeID={tribe.id} /> </Container>
</Container>
</PageLayout>
); );
} }

View File

@ -17,7 +17,6 @@ import {
CardContent, CardContent,
Typography, Typography,
} from '@material-ui/core'; } from '@material-ui/core';
import PageLayout from '../../common/PageLayout/PageLayout';
import Statistics from './components/Statistics/Statistics'; import Statistics from './components/Statistics/Statistics';
function IndexPage() { function IndexPage() {
@ -28,110 +27,108 @@ function IndexPage() {
useTitle(t('title', { key, tag: tribe.tag })); useTitle(t('title', { key, tag: tribe.tag }));
return ( return (
<PageLayout> <Container>
<Container> <Grid container spacing={2}>
<Grid container spacing={2}> <Grid component={Hidden} xsDown implementation="css" item xs={12}>
<Grid component={Hidden} xsDown implementation="css" item xs={12}> <Statistics server={key} tribeID={tribe.id} t={t} />
<Statistics server={key} tribeID={tribe.id} t={t} />
</Grid>
{[
{
field: 'createdAt',
value: format(
new Date(tribe.createdAt),
DATE_FORMAT.DAY_MONTH_AND_YEAR
),
},
{
field: 'points',
value: `${formatNumber('commas', tribe.points)} (#${tribe.rank})`,
},
{
field: 'allPoints',
value: formatNumber('commas', tribe.allPoints),
},
{
field: 'totalVillages',
value: formatNumber('commas', tribe.totalVillages),
},
{
field: 'dominance',
value: formatNumber('dominance', tribe.dominance),
},
{
field: 'scoreAtt',
value: `${formatNumber('commas', tribe.scoreAtt)} (#${
tribe.rankAtt
})`,
},
{
field: 'scoreDef',
value: `${formatNumber('commas', tribe.scoreDef)} (#${
tribe.rankDef
})`,
},
{
field: 'scoreTotal',
value: `${formatNumber('commas', tribe.scoreTotal)} (#${
tribe.rankTotal
})`,
},
{
field: 'deletedAt',
value: tribe.deletedAt
? format(
new Date(tribe.deletedAt),
DATE_FORMAT.DAY_MONTH_AND_YEAR
)
: '-',
},
{
field: 'bestRank',
subtitle: format(
new Date(tribe.bestRankAt),
DATE_FORMAT.HOUR_MINUTES_DAY_MONTH_AND_YEAR
),
value: tribe.bestRank,
},
{
field: 'mostPoints',
subtitle: format(
new Date(tribe.mostPointsAt),
DATE_FORMAT.HOUR_MINUTES_DAY_MONTH_AND_YEAR
),
value: formatNumber('commas', tribe.mostPoints),
},
{
field: 'mostVillages',
subtitle: format(
new Date(tribe.mostVillagesAt),
DATE_FORMAT.HOUR_MINUTES_DAY_MONTH_AND_YEAR
),
value: formatNumber('commas', tribe.mostVillages),
},
].map(({ field, value, subtitle }) => {
return (
<Grid key={field} item xs={12} sm={6} md={4} lg={3}>
<Card className={classes.card}>
<CardContent className={classes.cardContent}>
<Typography gutterBottom variant="h5">
{t('fields.' + field)}
<br />
{subtitle && (
<Typography variant="subtitle2" component="span">
{subtitle}
</Typography>
)}
</Typography>
<Typography variant="h4">{value}</Typography>
</CardContent>
</Card>
</Grid>
);
})}
</Grid> </Grid>
</Container> {[
</PageLayout> {
field: 'createdAt',
value: format(
new Date(tribe.createdAt),
DATE_FORMAT.DAY_MONTH_AND_YEAR
),
},
{
field: 'points',
value: `${formatNumber('commas', tribe.points)} (#${tribe.rank})`,
},
{
field: 'allPoints',
value: formatNumber('commas', tribe.allPoints),
},
{
field: 'totalVillages',
value: formatNumber('commas', tribe.totalVillages),
},
{
field: 'dominance',
value: formatNumber('dominance', tribe.dominance),
},
{
field: 'scoreAtt',
value: `${formatNumber('commas', tribe.scoreAtt)} (#${
tribe.rankAtt
})`,
},
{
field: 'scoreDef',
value: `${formatNumber('commas', tribe.scoreDef)} (#${
tribe.rankDef
})`,
},
{
field: 'scoreTotal',
value: `${formatNumber('commas', tribe.scoreTotal)} (#${
tribe.rankTotal
})`,
},
{
field: 'deletedAt',
value: tribe.deletedAt
? format(
new Date(tribe.deletedAt),
DATE_FORMAT.DAY_MONTH_AND_YEAR
)
: '-',
},
{
field: 'bestRank',
subtitle: format(
new Date(tribe.bestRankAt),
DATE_FORMAT.HOUR_MINUTES_DAY_MONTH_AND_YEAR
),
value: tribe.bestRank,
},
{
field: 'mostPoints',
subtitle: format(
new Date(tribe.mostPointsAt),
DATE_FORMAT.HOUR_MINUTES_DAY_MONTH_AND_YEAR
),
value: formatNumber('commas', tribe.mostPoints),
},
{
field: 'mostVillages',
subtitle: format(
new Date(tribe.mostVillagesAt),
DATE_FORMAT.HOUR_MINUTES_DAY_MONTH_AND_YEAR
),
value: formatNumber('commas', tribe.mostVillages),
},
].map(({ field, value, subtitle }) => {
return (
<Grid key={field} item xs={12} sm={6} md={4} lg={3}>
<Card className={classes.card}>
<CardContent className={classes.cardContent}>
<Typography gutterBottom variant="h5">
{t('fields.' + field)}
<br />
{subtitle && (
<Typography variant="subtitle2" component="span">
{subtitle}
</Typography>
)}
</Typography>
<Typography variant="h4">{value}</Typography>
</CardContent>
</Card>
</Grid>
);
})}
</Grid>
</Container>
); );
} }

View File

@ -66,6 +66,7 @@ function Statistics({ t, server, tribeID }: Props) {
<Paper> <Paper>
<ModeSelector <ModeSelector
onSelect={m => setMode(m.name as Mode)} onSelect={m => setMode(m.name as Mode)}
buttonProps={{ size: 'medium' }}
modes={[ modes={[
{ {
name: 'points', name: 'points',

View File

@ -6,7 +6,6 @@ import useTribe from '../../libs/TribePageContext/useTribe';
import { SERVER_PAGE } from '@config/namespaces'; import { SERVER_PAGE } from '@config/namespaces';
import { Container } from '@material-ui/core'; import { Container } from '@material-ui/core';
import PageLayout from '../../common/PageLayout/PageLayout';
import Members from './components/Members/Members'; import Members from './components/Members/Members';
function MembersPage() { function MembersPage() {
@ -15,11 +14,9 @@ function MembersPage() {
const { t } = useTranslation(SERVER_PAGE.TRIBE_PAGE.MEMBERS_PAGE); const { t } = useTranslation(SERVER_PAGE.TRIBE_PAGE.MEMBERS_PAGE);
useTitle(t('title', { key, tag: tribe.tag })); useTitle(t('title', { key, tag: tribe.tag }));
return ( return (
<PageLayout> <Container>
<Container> <Members t={t} server={key} tribeID={tribe.id} />
<Members t={t} server={key} tribeID={tribe.id} /> </Container>
</Container>
</PageLayout>
); );
} }

View File

@ -6,7 +6,6 @@ import useTribe from '../../libs/TribePageContext/useTribe';
import { SERVER_PAGE } from '@config/namespaces'; import { SERVER_PAGE } from '@config/namespaces';
import { Container } from '@material-ui/core'; import { Container } from '@material-ui/core';
import PageLayout from '../../common/PageLayout/PageLayout';
import TribeChanges from './components/TribeChanges/TribeChanges'; import TribeChanges from './components/TribeChanges/TribeChanges';
function TribeChangesPage() { function TribeChangesPage() {
@ -15,11 +14,9 @@ function TribeChangesPage() {
const { t } = useTranslation(SERVER_PAGE.TRIBE_PAGE.TRIBE_CHANGES_PAGE); const { t } = useTranslation(SERVER_PAGE.TRIBE_PAGE.TRIBE_CHANGES_PAGE);
useTitle(t('title', { key, tag: tribe.tag })); useTitle(t('title', { key, tag: tribe.tag }));
return ( return (
<PageLayout> <Container>
<Container> <TribeChanges t={t} server={key} tribeID={tribe.id} />
<TribeChanges t={t} server={key} tribeID={tribe.id} /> </Container>
</Container>
</PageLayout>
); );
} }