delete formatDistanceToNow (it's useless right now), add ServerTable (SearchPage)
This commit is contained in:
parent
5c88ae991c
commit
6288c54057
|
@ -11,17 +11,18 @@ import useTitle from '@libs/useTitle';
|
||||||
import useScrollToElement from '@libs/useScrollToElement';
|
import useScrollToElement from '@libs/useScrollToElement';
|
||||||
import { validateRowsPerPage } from '@common/Table/helpers';
|
import { validateRowsPerPage } from '@common/Table/helpers';
|
||||||
import { SEARCH_PAGE } from '@config/namespaces';
|
import { SEARCH_PAGE } from '@config/namespaces';
|
||||||
import { MODES, LIMIT } from './constants';
|
import { MODE, LIMIT } from './constants';
|
||||||
|
|
||||||
import { Container, Paper } from '@material-ui/core';
|
import { Container, Paper } from '@material-ui/core';
|
||||||
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';
|
||||||
|
import ServerTable from './components/ServerTable/ServerTable';
|
||||||
|
|
||||||
function SearchPage() {
|
function SearchPage() {
|
||||||
const [query, setQuery] = useQueryParams({
|
const [query, setQuery] = useQueryParams({
|
||||||
q: withDefault(StringParam, ''),
|
q: withDefault(StringParam, ''),
|
||||||
mode: withDefault(StringParam, MODES.PLAYER),
|
mode: withDefault(StringParam, MODE.PLAYER),
|
||||||
page: withDefault(NumberParam, 0),
|
page: withDefault(NumberParam, 0),
|
||||||
limit: withDefault(NumberParam, LIMIT),
|
limit: withDefault(NumberParam, LIMIT),
|
||||||
});
|
});
|
||||||
|
@ -43,6 +44,7 @@ function SearchPage() {
|
||||||
setQuery({ limit: rowsPerPage, page: 0 });
|
setQuery({ limit: rowsPerPage, page: 0 });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getTable = () => {
|
||||||
const tableProps = {
|
const tableProps = {
|
||||||
t: t,
|
t: t,
|
||||||
q: query.q,
|
q: query.q,
|
||||||
|
@ -53,6 +55,16 @@ function SearchPage() {
|
||||||
onChangeRowsPerPage: handleRowsPerPageChange,
|
onChangeRowsPerPage: handleRowsPerPageChange,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
switch (query.mode.toLowerCase()) {
|
||||||
|
case MODE.TRIBE:
|
||||||
|
return <TribeTable {...tableProps} />;
|
||||||
|
case MODE.SERVER:
|
||||||
|
return <ServerTable {...tableProps} />;
|
||||||
|
default:
|
||||||
|
return <PlayerTable {...tableProps} />;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
<Paper>
|
<Paper>
|
||||||
|
@ -74,13 +86,16 @@ function SearchPage() {
|
||||||
return this.name === query.mode;
|
return this.name === query.mode;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'server',
|
||||||
|
label: t('modes.server'),
|
||||||
|
get selected() {
|
||||||
|
return this.name === query.mode;
|
||||||
|
},
|
||||||
|
},
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
{query.mode === MODES.TRIBE ? (
|
{getTable()}
|
||||||
<TribeTable {...tableProps} />
|
|
||||||
) : (
|
|
||||||
<PlayerTable {...tableProps} />
|
|
||||||
)}
|
|
||||||
</Paper>
|
</Paper>
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
import React from 'react';
|
||||||
|
import useServers from './useServers';
|
||||||
|
import * as NAMESPACES from '@config/namespaces';
|
||||||
|
import * as ROUTES from '@config/routes';
|
||||||
|
import { COLUMNS } from './constants';
|
||||||
|
|
||||||
|
import Table from '@common/Table/Table';
|
||||||
|
import Link from '@common/Link/Link';
|
||||||
|
import { Props as TableFooterProps } from '@common/Table/TableFooter';
|
||||||
|
|
||||||
|
import { TFunction } from 'i18next';
|
||||||
|
import { Server } from './types';
|
||||||
|
|
||||||
|
export interface Props {
|
||||||
|
t: TFunction;
|
||||||
|
page: number;
|
||||||
|
limit: number;
|
||||||
|
q: string;
|
||||||
|
onChangePage: TableFooterProps['onChangePage'];
|
||||||
|
onChangeRowsPerPage: TableFooterProps['onChangeRowsPerPage'];
|
||||||
|
}
|
||||||
|
|
||||||
|
function ServerTable({
|
||||||
|
t,
|
||||||
|
q,
|
||||||
|
limit,
|
||||||
|
page,
|
||||||
|
onChangePage,
|
||||||
|
onChangeRowsPerPage,
|
||||||
|
}: Props) {
|
||||||
|
const { servers, total, loading } = useServers(page, limit, q);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Table
|
||||||
|
columns={COLUMNS.map((column, index) => {
|
||||||
|
const newCol = {
|
||||||
|
...column,
|
||||||
|
label: column.label ? t<string>(column.label) : '',
|
||||||
|
};
|
||||||
|
switch (index) {
|
||||||
|
case 0:
|
||||||
|
newCol.valueFormatter = (server: Server) => (
|
||||||
|
<span>
|
||||||
|
{t(`${NAMESPACES.COMMON}:serverStatus.` + server.status)}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
newCol.valueFormatter = (server: Server) => (
|
||||||
|
<Link
|
||||||
|
to={ROUTES.SERVER_PAGE.INDEX_PAGE}
|
||||||
|
params={{ key: server.key }}
|
||||||
|
>
|
||||||
|
{server.key}
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return newCol;
|
||||||
|
})}
|
||||||
|
loading={loading}
|
||||||
|
data={servers}
|
||||||
|
size="small"
|
||||||
|
idFieldName="key"
|
||||||
|
footerProps={{
|
||||||
|
page,
|
||||||
|
rowsPerPage: limit,
|
||||||
|
count: total,
|
||||||
|
onChangePage,
|
||||||
|
onChangeRowsPerPage,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ServerTable;
|
39
src/features/SearchPage/components/ServerTable/constants.ts
Normal file
39
src/features/SearchPage/components/ServerTable/constants.ts
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
import formatNumber from '@utils/formatNumber';
|
||||||
|
import { Column } from '@common/Table/types';
|
||||||
|
import { Server } from './types';
|
||||||
|
|
||||||
|
export const COLUMNS: Column<Server>[] = [
|
||||||
|
{
|
||||||
|
field: 'status',
|
||||||
|
label: 'serverTable.columns.status',
|
||||||
|
sortable: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'key',
|
||||||
|
label: 'serverTable.columns.key',
|
||||||
|
sortable: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'numberOfPlayers',
|
||||||
|
label: 'serverTable.columns.numberOfPlayers',
|
||||||
|
sortable: false,
|
||||||
|
valueFormatter: (server: Server) =>
|
||||||
|
formatNumber('commas', server.numberOfPlayers),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'numberOfTribes',
|
||||||
|
label: 'serverTable.columns.numberOfTribes',
|
||||||
|
sortable: false,
|
||||||
|
valueFormatter: (server: Server) =>
|
||||||
|
formatNumber('commas', server.numberOfTribes),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'numberOfVillages',
|
||||||
|
label: 'serverTable.columns.numberOfVillages',
|
||||||
|
sortable: false,
|
||||||
|
valueFormatter: (server: Server) =>
|
||||||
|
formatNumber('commas', server.numberOfVillages),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const LIMIT = 25;
|
21
src/features/SearchPage/components/ServerTable/queries.ts
Normal file
21
src/features/SearchPage/components/ServerTable/queries.ts
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import { gql } from '@apollo/client';
|
||||||
|
|
||||||
|
export const SERVERS = gql`
|
||||||
|
query servers(
|
||||||
|
$filter: ServerFilter
|
||||||
|
$sort: [String!]
|
||||||
|
$limit: Int
|
||||||
|
$offset: Int
|
||||||
|
) {
|
||||||
|
servers(filter: $filter, sort: $sort, limit: $limit, offset: $offset) {
|
||||||
|
items {
|
||||||
|
key
|
||||||
|
status
|
||||||
|
numberOfPlayers
|
||||||
|
numberOfTribes
|
||||||
|
numberOfVillages
|
||||||
|
}
|
||||||
|
total
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
14
src/features/SearchPage/components/ServerTable/types.ts
Normal file
14
src/features/SearchPage/components/ServerTable/types.ts
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
import { List } from '@libs/graphql/types';
|
||||||
|
import { ServerStatus } from '@config/app';
|
||||||
|
|
||||||
|
export type Server = {
|
||||||
|
key: string;
|
||||||
|
status: ServerStatus;
|
||||||
|
numberOfPlayers: number;
|
||||||
|
numberOfTribes: number;
|
||||||
|
numberOfVillages: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ServerList = {
|
||||||
|
servers?: List<Server[]>;
|
||||||
|
};
|
41
src/features/SearchPage/components/ServerTable/useServers.ts
Normal file
41
src/features/SearchPage/components/ServerTable/useServers.ts
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
import { useQuery } from '@apollo/client';
|
||||||
|
import { SERVERS } from './queries';
|
||||||
|
|
||||||
|
import { ServersQueryVariables } from '@libs/graphql/types';
|
||||||
|
import { Server, ServerList } from './types';
|
||||||
|
|
||||||
|
export type QueryResult = {
|
||||||
|
servers: Server[];
|
||||||
|
loading: boolean;
|
||||||
|
total: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
const useServers = (page: number, limit: number, q: string): QueryResult => {
|
||||||
|
const skip = q.trim() === '';
|
||||||
|
const { loading: loadingServers, data } = useQuery<
|
||||||
|
ServerList,
|
||||||
|
ServersQueryVariables
|
||||||
|
>(SERVERS, {
|
||||||
|
fetchPolicy: 'cache-and-network',
|
||||||
|
variables: {
|
||||||
|
limit,
|
||||||
|
offset: page * limit,
|
||||||
|
sort: ['status DESC', 'key ASC'],
|
||||||
|
filter: {
|
||||||
|
keyIEQ: '%' + q + '%',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
skip,
|
||||||
|
});
|
||||||
|
const servers = data?.servers?.items ?? [];
|
||||||
|
const loading = loadingServers && servers.length === 0 && !skip;
|
||||||
|
const total = data?.servers?.total ?? 0;
|
||||||
|
|
||||||
|
return {
|
||||||
|
servers,
|
||||||
|
loading,
|
||||||
|
total,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useServers;
|
|
@ -1,6 +1,7 @@
|
||||||
export const MODES = {
|
export const MODE = {
|
||||||
PLAYER: 'player',
|
PLAYER: 'player',
|
||||||
TRIBE: 'tribe',
|
TRIBE: 'tribe',
|
||||||
|
SERVER: 'server',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const LIMIT = 25;
|
export const LIMIT = 25;
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
import { formatDistanceToNow } from 'date-fns';
|
|
||||||
import locales, { Locale } from './locales';
|
|
||||||
|
|
||||||
export type Options = {
|
|
||||||
includeSeconds?: boolean;
|
|
||||||
addSuffix?: boolean;
|
|
||||||
locale: Locale;
|
|
||||||
};
|
|
||||||
|
|
||||||
const _formatDistanceToNow = (date: Date | number, opts: Options) => {
|
|
||||||
return formatDistanceToNow(date, {
|
|
||||||
...opts,
|
|
||||||
locale: locales[opts.locale] ?? locales.en,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export default _formatDistanceToNow;
|
|
Reference in New Issue
Block a user