[WIP]: /server/:key/ranking/player
- add PageLayout
This commit is contained in:
parent
5f6e9eb363
commit
6df12861bf
|
@ -24,4 +24,7 @@ export const SERVER_PAGE = {
|
|||
VILLAGE_PAGE: {
|
||||
INDEX_PAGE: 'server-page/village-page/index-page',
|
||||
},
|
||||
RANKING_PAGE: {
|
||||
COMMON: 'server-page/ranking-page/common',
|
||||
},
|
||||
};
|
||||
|
|
|
@ -20,6 +20,7 @@ export const SERVER_PAGE = {
|
|||
INDEX_PAGE: '/server/:key/village/:id',
|
||||
},
|
||||
RANKING_PAGE: {
|
||||
BASE: '/server/:key/ranking',
|
||||
PLAYER_PAGE: {
|
||||
INDEX_PAGE: '/server/:key/ranking/player',
|
||||
OD_PAGE: '/server/:key/ranking/player/od',
|
||||
|
|
|
@ -7,6 +7,7 @@ import IndexPage from './features/IndexPage/IndexPage';
|
|||
import PlayerPage from './features/PlayerPage/PlayerPage';
|
||||
import TribePage from './features/TribePage/TribePage';
|
||||
import VillagePage from './features/VillagePage/VillagePage';
|
||||
import RankingPage from './features/RankingPage/RankingPage';
|
||||
import NotFoundPage from '../NotFoundPage/NotFoundPage';
|
||||
|
||||
const EnhancedRoute = ({ children, ...rest }: RouteProps) => {
|
||||
|
@ -32,6 +33,9 @@ function ServerPage() {
|
|||
<EnhancedRoute exact path={SERVER_PAGE.VILLAGE_PAGE.INDEX_PAGE}>
|
||||
<VillagePage />
|
||||
</EnhancedRoute>
|
||||
<EnhancedRoute path={SERVER_PAGE.RANKING_PAGE.BASE}>
|
||||
<RankingPage />
|
||||
</EnhancedRoute>
|
||||
<Route path="*">
|
||||
<NotFoundPage />
|
||||
</Route>
|
||||
|
|
|
@ -43,46 +43,54 @@ const Sidebar = ({ t, className, open, variant, onClose, onOpen }: Props) => {
|
|||
to: ROUTES.SERVER_PAGE.INDEX_PAGE,
|
||||
params: { key },
|
||||
Icon: <DashboardIcon color="inherit" />,
|
||||
exact: true,
|
||||
},
|
||||
{
|
||||
name: t('pageLayout.sidebar.routes.rankings.name'),
|
||||
Icon: <GradeIcon color="inherit" />,
|
||||
to: ROUTES.SERVER_PAGE.RANKING_PAGE.BASE,
|
||||
nested: [
|
||||
{
|
||||
name: t('pageLayout.sidebar.routes.rankings.player.index'),
|
||||
to: ROUTES.SERVER_PAGE.RANKING_PAGE.PLAYER_PAGE.INDEX_PAGE,
|
||||
params: { key },
|
||||
Icon: <GradeIcon color="inherit" />,
|
||||
exact: true,
|
||||
},
|
||||
{
|
||||
name: t('pageLayout.sidebar.routes.rankings.player.od'),
|
||||
to: ROUTES.SERVER_PAGE.RANKING_PAGE.PLAYER_PAGE.OD_PAGE,
|
||||
params: { key },
|
||||
Icon: <GradeIcon color="inherit" />,
|
||||
exact: true,
|
||||
},
|
||||
{
|
||||
name: t('pageLayout.sidebar.routes.rankings.player.archive'),
|
||||
to: ROUTES.SERVER_PAGE.RANKING_PAGE.PLAYER_PAGE.ARCHIVE_PAGE,
|
||||
params: { key },
|
||||
Icon: <GradeIcon color="inherit" />,
|
||||
exact: true,
|
||||
},
|
||||
{
|
||||
name: t('pageLayout.sidebar.routes.rankings.tribe.index'),
|
||||
to: ROUTES.SERVER_PAGE.RANKING_PAGE.TRIBE_PAGE.INDEX_PAGE,
|
||||
params: { key },
|
||||
Icon: <GradeIcon color="inherit" />,
|
||||
exact: true,
|
||||
},
|
||||
{
|
||||
name: t('pageLayout.sidebar.routes.rankings.tribe.od'),
|
||||
to: ROUTES.SERVER_PAGE.RANKING_PAGE.TRIBE_PAGE.OD_PAGE,
|
||||
params: { key },
|
||||
Icon: <GradeIcon color="inherit" />,
|
||||
exact: true,
|
||||
},
|
||||
{
|
||||
name: t('pageLayout.sidebar.routes.rankings.tribe.archive'),
|
||||
to: ROUTES.SERVER_PAGE.RANKING_PAGE.TRIBE_PAGE.ARCHIVE_PAGE,
|
||||
params: { key },
|
||||
Icon: <GradeIcon color="inherit" />,
|
||||
exact: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -91,12 +99,14 @@ const Sidebar = ({ t, className, open, variant, onClose, onOpen }: Props) => {
|
|||
to: ROUTES.SERVER_PAGE.ENNOBLEMENTS_PAGE,
|
||||
params: { key },
|
||||
Icon: <BeenhereIcon color="inherit" />,
|
||||
exact: true,
|
||||
},
|
||||
{
|
||||
name: t('pageLayout.sidebar.routes.map'),
|
||||
to: ROUTES.SERVER_PAGE.MAP_PAGE,
|
||||
params: { key },
|
||||
Icon: <MapIcon color="inherit" />,
|
||||
exact: true,
|
||||
},
|
||||
];
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React, { Fragment, useState } from 'react';
|
||||
import { useLocation, generatePath } from 'react-router-dom';
|
||||
import { useLocation, generatePath, matchPath } from 'react-router-dom';
|
||||
import { Route } from './types';
|
||||
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
|
@ -25,12 +25,8 @@ function ListItem({ route, nestedLevel }: Props) {
|
|||
const classes = useStyles();
|
||||
const { pathname } = useLocation();
|
||||
const hasNested = Array.isArray(route.nested) && route.nested.length > 0;
|
||||
const generatedPath =
|
||||
route.to && route.params
|
||||
? generatePath(route.to, route.params)
|
||||
: route.to
|
||||
? route.to
|
||||
: '';
|
||||
const isActive =
|
||||
route.to && matchPath(pathname, { path: route.to, exact: route.exact });
|
||||
|
||||
const getItem = () => {
|
||||
return (
|
||||
|
@ -43,12 +39,17 @@ function ListItem({ route, nestedLevel }: Props) {
|
|||
>
|
||||
<ListItemIcon
|
||||
className={clsx({
|
||||
[classes.activeLink]: generatedPath === pathname,
|
||||
[classes.activeLink]: isActive,
|
||||
})}
|
||||
>
|
||||
{route.Icon}
|
||||
</ListItemIcon>
|
||||
<ListItemText primary={route.name} />
|
||||
<ListItemText
|
||||
className={clsx({
|
||||
[classes.activeLink]: isActive,
|
||||
})}
|
||||
primary={route.name}
|
||||
/>
|
||||
{hasNested && (
|
||||
<Fragment>{open ? <ExpandLess /> : <ExpandMore />}</Fragment>
|
||||
)}
|
||||
|
@ -59,14 +60,7 @@ function ListItem({ route, nestedLevel }: Props) {
|
|||
return (
|
||||
<Fragment>
|
||||
{!hasNested && route.to ? (
|
||||
<Link
|
||||
to={route.to}
|
||||
params={route.params}
|
||||
className={clsx(classes.link, {
|
||||
[classes.activeLink]: generatedPath === pathname,
|
||||
})}
|
||||
color="inherit"
|
||||
>
|
||||
<Link to={route.to} params={route.params} color="inherit">
|
||||
{getItem()}
|
||||
</Link>
|
||||
) : (
|
||||
|
|
|
@ -3,6 +3,7 @@ import { Props } from '@common/Link/Link';
|
|||
export interface Route {
|
||||
name: string;
|
||||
to?: string;
|
||||
exact?: boolean;
|
||||
params?: Props['params'];
|
||||
Icon: React.ReactElement;
|
||||
nested?: Route[];
|
||||
|
|
21
src/features/ServerPage/features/RankingPage/RankingPage.tsx
Normal file
21
src/features/ServerPage/features/RankingPage/RankingPage.tsx
Normal file
|
@ -0,0 +1,21 @@
|
|||
import React from 'react';
|
||||
import { SERVER_PAGE } from '@config/routes';
|
||||
|
||||
import { Switch, Route } from 'react-router-dom';
|
||||
import PlayerPage from './features/PlayerPage/PlayerPage';
|
||||
import NotFoundPage from '../../../NotFoundPage/NotFoundPage';
|
||||
|
||||
function RankingPage() {
|
||||
return (
|
||||
<Switch>
|
||||
<Route path={SERVER_PAGE.RANKING_PAGE.PLAYER_PAGE.INDEX_PAGE}>
|
||||
<PlayerPage />
|
||||
</Route>
|
||||
<Route path="*">
|
||||
<NotFoundPage />
|
||||
</Route>
|
||||
</Switch>
|
||||
);
|
||||
}
|
||||
|
||||
export default RankingPage;
|
|
@ -0,0 +1,78 @@
|
|||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import useServer from '@features/ServerPage/libs/ServerContext/useServer';
|
||||
import useTabs from './useTabs';
|
||||
import * as NAMESPACES from '@config/namespaces';
|
||||
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
|
||||
import { Tabs, Tab } from '@material-ui/core';
|
||||
import Link from '@common/Link/Link';
|
||||
import ServerPageLayout from '@features/ServerPage/common/PageLayout/PageLayout';
|
||||
|
||||
import background from './backgrounds/bg-1-dark.png';
|
||||
|
||||
export interface Props {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
function PageLayout({ children }: Props) {
|
||||
const classes = useStyles();
|
||||
const server = useServer();
|
||||
const { t } = useTranslation(NAMESPACES.SERVER_PAGE.RANKING_PAGE.COMMON);
|
||||
const { currentTab, tabs } = useTabs(t);
|
||||
return (
|
||||
<ServerPageLayout noPadding>
|
||||
<header className={classes.header}>
|
||||
<Tabs
|
||||
variant="scrollable"
|
||||
value={currentTab}
|
||||
selectionFollowsFocus={false}
|
||||
>
|
||||
{tabs.map(({ to, label }) => {
|
||||
return (
|
||||
<Tab
|
||||
key={to}
|
||||
label={
|
||||
<Link
|
||||
to={to}
|
||||
color="inherit"
|
||||
params={{ key: server.key }}
|
||||
style={{ width: '100%', height: '100%' }}
|
||||
>
|
||||
{label}
|
||||
</Link>
|
||||
}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</Tabs>
|
||||
</header>
|
||||
<div className={classes.content}>{children}</div>
|
||||
</ServerPageLayout>
|
||||
);
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(theme => ({
|
||||
header: {
|
||||
width: '100%',
|
||||
minHeight: theme.spacing(30),
|
||||
backgroundPosition: 'center',
|
||||
backgroundSize: 'cover',
|
||||
backgroundRepeat: 'no-repeat',
|
||||
display: 'flex',
|
||||
justifyContent: 'flex-end',
|
||||
flexDirection: 'column',
|
||||
backgroundImage: `url(${background})`,
|
||||
boxShadow: theme.shadows[4],
|
||||
},
|
||||
content: {
|
||||
height: '100%',
|
||||
padding: theme.spacing(3, 0),
|
||||
'&.no-padding': {
|
||||
padding: '0 0',
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
export default PageLayout;
|
Binary file not shown.
After Width: | Height: | Size: 1.6 MiB |
|
@ -0,0 +1,58 @@
|
|||
import { useMemo } from 'react';
|
||||
import { matchPath, useLocation } from 'react-router-dom';
|
||||
import * as ROUTES from '@config/routes';
|
||||
|
||||
import { TFunction } from 'i18next';
|
||||
|
||||
const useTabs = (t: TFunction) => {
|
||||
const loc = useLocation();
|
||||
const tabs = useMemo(() => {
|
||||
return [
|
||||
{
|
||||
to: ROUTES.SERVER_PAGE.RANKING_PAGE.PLAYER_PAGE.INDEX_PAGE,
|
||||
label: t('pageLayout.tabs.playerPage.indexPage'),
|
||||
},
|
||||
{
|
||||
to: ROUTES.SERVER_PAGE.RANKING_PAGE.PLAYER_PAGE.OD_PAGE,
|
||||
label: t('pageLayout.tabs.playerPage.odPage'),
|
||||
},
|
||||
{
|
||||
to: ROUTES.SERVER_PAGE.RANKING_PAGE.PLAYER_PAGE.DAILY_PAGE,
|
||||
label: t('pageLayout.tabs.playerPage.dailyPage'),
|
||||
},
|
||||
{
|
||||
to: ROUTES.SERVER_PAGE.RANKING_PAGE.PLAYER_PAGE.ARCHIVE_PAGE,
|
||||
label: t('pageLayout.tabs.playerPage.archivePage'),
|
||||
},
|
||||
{
|
||||
to: ROUTES.SERVER_PAGE.RANKING_PAGE.TRIBE_PAGE.INDEX_PAGE,
|
||||
label: t('pageLayout.tabs.tribePage.indexPage'),
|
||||
},
|
||||
{
|
||||
to: ROUTES.SERVER_PAGE.RANKING_PAGE.TRIBE_PAGE.OD_PAGE,
|
||||
label: t('pageLayout.tabs.tribePage.odPage'),
|
||||
},
|
||||
{
|
||||
to: ROUTES.SERVER_PAGE.RANKING_PAGE.TRIBE_PAGE.DAILY_PAGE,
|
||||
label: t('pageLayout.tabs.tribePage.dailyPage'),
|
||||
},
|
||||
{
|
||||
to: ROUTES.SERVER_PAGE.RANKING_PAGE.TRIBE_PAGE.ARCHIVE_PAGE,
|
||||
label: t('pageLayout.tabs.tribePage.archivePage'),
|
||||
},
|
||||
];
|
||||
}, [t]);
|
||||
const currentTab = useMemo(
|
||||
() =>
|
||||
tabs.findIndex(({ to }) => {
|
||||
return matchPath(loc.pathname, { exact: true, path: to });
|
||||
}),
|
||||
[loc.pathname, tabs]
|
||||
);
|
||||
return {
|
||||
tabs,
|
||||
currentTab,
|
||||
};
|
||||
};
|
||||
|
||||
export default useTabs;
|
|
@ -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 PlayerPage() {
|
||||
return (
|
||||
<Switch>
|
||||
<Route exact path={SERVER_PAGE.RANKING_PAGE.PLAYER_PAGE.INDEX_PAGE}>
|
||||
<IndexPage />
|
||||
</Route>
|
||||
<Route path="*">
|
||||
<NotFoundPage />
|
||||
</Route>
|
||||
</Switch>
|
||||
);
|
||||
}
|
||||
|
||||
export default PlayerPage;
|
|
@ -0,0 +1,9 @@
|
|||
import React from 'react';
|
||||
|
||||
import PageLayout from '@features/ServerPage/features/RankingPage/common/PageLayout/PageLayout';
|
||||
|
||||
function IndexPage() {
|
||||
return <PageLayout>elo</PageLayout>;
|
||||
}
|
||||
|
||||
export default IndexPage;
|
|
@ -4,6 +4,7 @@ import indexPage from './index-page';
|
|||
import playerPage from './player-page';
|
||||
import tribePage from './tribe-page';
|
||||
import villagePage from './village-page';
|
||||
import rankingPage from './ranking-page';
|
||||
|
||||
const translations = {
|
||||
[NAMESPACES.SERVER_PAGE.COMMON]: common,
|
||||
|
@ -11,6 +12,7 @@ const translations = {
|
|||
[NAMESPACES.SERVER_PAGE.VILLAGE_PAGE.INDEX_PAGE]: villagePage,
|
||||
...playerPage,
|
||||
...tribePage,
|
||||
...rankingPage,
|
||||
};
|
||||
|
||||
export default translations;
|
||||
|
|
20
src/libs/i18n/en/server-page/ranking-page/common.ts
Normal file
20
src/libs/i18n/en/server-page/ranking-page/common.ts
Normal file
|
@ -0,0 +1,20 @@
|
|||
const translations = {
|
||||
pageLayout: {
|
||||
tabs: {
|
||||
playerPage: {
|
||||
indexPage: 'Players',
|
||||
odPage: 'Players OD',
|
||||
dailyPage: 'Players daily',
|
||||
archivePage: 'Past players',
|
||||
},
|
||||
tribePage: {
|
||||
indexPage: 'Tribes',
|
||||
odPage: 'Tribes OD',
|
||||
dailyPage: 'Tribes daily',
|
||||
archivePage: 'Past tribes',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default translations;
|
8
src/libs/i18n/en/server-page/ranking-page/index.ts
Normal file
8
src/libs/i18n/en/server-page/ranking-page/index.ts
Normal file
|
@ -0,0 +1,8 @@
|
|||
import * as NAMESPACES from '@config/namespaces';
|
||||
import common from './common';
|
||||
|
||||
const translations = {
|
||||
[NAMESPACES.SERVER_PAGE.RANKING_PAGE.COMMON]: common,
|
||||
};
|
||||
|
||||
export default translations;
|
|
@ -4,11 +4,13 @@ import indexPage from './index-page';
|
|||
import notFoundPage from './not-found-page';
|
||||
import serverPage from './server-page';
|
||||
import table from './table';
|
||||
import lineChart from './line-chart';
|
||||
|
||||
const translations = {
|
||||
[NAMESPACES.COMMON]: common,
|
||||
[NAMESPACES.INDEX_PAGE]: indexPage,
|
||||
[NAMESPACES.NOT_FOUND_PAGE]: notFoundPage,
|
||||
[NAMESPACES.LINE_CHART]: lineChart,
|
||||
[NAMESPACES.TABLE]: table,
|
||||
...serverPage,
|
||||
};
|
||||
|
|
|
@ -4,6 +4,7 @@ import indexPage from './index-page';
|
|||
import playerPage from './player-page';
|
||||
import tribePage from './tribe-page';
|
||||
import villagePage from './village-page';
|
||||
import rankingPage from './ranking-page';
|
||||
|
||||
const translations = {
|
||||
[NAMESPACES.SERVER_PAGE.COMMON]: common,
|
||||
|
@ -11,6 +12,7 @@ const translations = {
|
|||
[NAMESPACES.SERVER_PAGE.VILLAGE_PAGE.INDEX_PAGE]: villagePage,
|
||||
...playerPage,
|
||||
...tribePage,
|
||||
...rankingPage,
|
||||
};
|
||||
|
||||
export default translations;
|
||||
|
|
20
src/libs/i18n/pl/server-page/ranking-page/common.ts
Normal file
20
src/libs/i18n/pl/server-page/ranking-page/common.ts
Normal file
|
@ -0,0 +1,20 @@
|
|||
const translations = {
|
||||
pageLayout: {
|
||||
tabs: {
|
||||
playerPage: {
|
||||
indexPage: 'Gracze',
|
||||
odPage: 'Gracze OD',
|
||||
dailyPage: 'Gracze dzienne',
|
||||
archivePage: 'Byli gracze',
|
||||
},
|
||||
tribePage: {
|
||||
indexPage: 'Plemiona',
|
||||
odPage: 'Plemiona OD',
|
||||
dailyPage: 'Plemiona dzienne',
|
||||
archivePage: 'Byłe plemiona',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default translations;
|
8
src/libs/i18n/pl/server-page/ranking-page/index.ts
Normal file
8
src/libs/i18n/pl/server-page/ranking-page/index.ts
Normal file
|
@ -0,0 +1,8 @@
|
|||
import * as NAMESPACES from '@config/namespaces';
|
||||
import common from './common';
|
||||
|
||||
const translations = {
|
||||
[NAMESPACES.SERVER_PAGE.RANKING_PAGE.COMMON]: common,
|
||||
};
|
||||
|
||||
export default translations;
|
Reference in New Issue
Block a user