diff --git a/src/features/ServerPage/features/IndexPage/IndexPage.tsx b/src/features/ServerPage/features/IndexPage/IndexPage.tsx index 25e51de..5db1c7f 100644 --- a/src/features/ServerPage/features/IndexPage/IndexPage.tsx +++ b/src/features/ServerPage/features/IndexPage/IndexPage.tsx @@ -6,6 +6,7 @@ import { SERVER_PAGE } from '@config/namespaces'; import { Container, Grid } from '@material-ui/core'; import PageLayout from '@features/ServerPage/common/PageLayout/PageLayout'; import TodaysBestStatsPlayers from './components/TodaysBestStatsPlayers/TodaysBestStatsPlayers'; +import TodaysBestStatsTribes from './components/TodaysBestStatsTribes/TodaysBestStatsTribes'; import RecentlyDeletedPlayers from './components/RecentlyDeletedPlayers/RecentlyDeletedPlayers'; import RecentlyDeletedTribes from './components/RecentlyDeletedTribes/RecentlyDeletedTribes'; @@ -19,6 +20,9 @@ function IndexPage() { + + + diff --git a/src/features/ServerPage/features/IndexPage/components/TodaysBestStatsTribes/TodaysBestStatsTribes.tsx b/src/features/ServerPage/features/IndexPage/components/TodaysBestStatsTribes/TodaysBestStatsTribes.tsx new file mode 100644 index 0000000..5c40be6 --- /dev/null +++ b/src/features/ServerPage/features/IndexPage/components/TodaysBestStatsTribes/TodaysBestStatsTribes.tsx @@ -0,0 +1,127 @@ +import React, { useRef, useState } from 'react'; +import { subHours } from 'date-fns'; +import { useQuery } from '@apollo/client'; +import { SERVER_PAGE } from '@config/routes'; +import { DAILY_TRIBE_STATS } from './queries'; +import { COLUMNS, LIMIT } from './constants'; + +import { Typography } from '@material-ui/core'; +import TableToolbar from '@common/Table/TableToolbar'; +import Table from '@common/Table/Table'; +import Link from '@common/Link/Link'; +import Paper from '../Paper/Paper'; +import ModeSelector from '../ModeSelector/ModeSelector'; + +import { TFunction } from 'i18next'; +import { DailyTribeStatsQueryVariables } from '@libs/graphql/types'; +import { DailyTribeStatsList, DailyTribeStatsRecord, Mode } from './types'; + +export interface Props { + server: string; + t: TFunction; +} + +function TodaysBestStatsTribes({ server, t }: Props) { + const createDateGT = useRef(subHours(new Date(), 30)); + const [mode, setMode] = useState('scoreAtt'); + const { loading: loadingData, data } = useQuery< + DailyTribeStatsList, + DailyTribeStatsQueryVariables + >(DAILY_TRIBE_STATS, { + fetchPolicy: 'cache-and-network', + variables: { + limit: LIMIT, + sort: [mode + ' DESC'], + filter: { + createDateGT: createDateGT.current, + }, + server, + }, + }); + const records = data?.dailyTribeStats?.items ?? []; + const loading = loadingData && records.length === 0; + + return ( + + + + + {t('todaysBestStatsTribes.title')} + + + + setMode(m.name as Mode)} + modes={[ + { + name: 'scoreAtt', + label: t('todaysBestStatsTribes.modes.scoreAtt'), + get selected() { + return this.name === mode; + }, + }, + { + name: 'scoreDef', + label: t('todaysBestStatsTribes.modes.scoreDef'), + get selected() { + return this.name === mode; + }, + }, + { + name: 'scoreTotal', + label: t('todaysBestStatsTribes.modes.scoreTotal'), + get selected() { + return this.name === mode; + }, + }, + { + name: 'points', + label: t('todaysBestStatsTribes.modes.points'), + get selected() { + return this.name === mode; + }, + }, + { + name: 'villages', + label: t('todaysBestStatsTribes.modes.villages'), + get selected() { + return this.name === mode; + }, + }, + ]} + /> + ({ + ...column, + valueFormatter: + index === 0 + ? (record: DailyTribeStatsRecord) => ( + + {record.tribe.tag} + + ) + : index === 1 + ? (record: DailyTribeStatsRecord) => record[mode].toLocaleString() + : column.valueFormatter, + label: column.label ? t(column.label) : '', + }))} + loading={loading} + data={records} + size="small" + hideFooter + footerProps={{ rowsPerPage: LIMIT, rowsPerPageOptions: [LIMIT] }} + /> + + ); +} + +export default TodaysBestStatsTribes; diff --git a/src/features/ServerPage/features/IndexPage/components/TodaysBestStatsTribes/constants.ts b/src/features/ServerPage/features/IndexPage/components/TodaysBestStatsTribes/constants.ts new file mode 100644 index 0000000..53f3047 --- /dev/null +++ b/src/features/ServerPage/features/IndexPage/components/TodaysBestStatsTribes/constants.ts @@ -0,0 +1,23 @@ +import { Column } from '@common/Table/types'; +import { DailyTribeStatsRecord } from './types'; + +export const COLUMNS: Column[] = [ + { + field: 'name', + label: 'todaysBestStatsTribes.columns.name', + sortable: false, + }, + { + field: 'score', + label: 'todaysBestStatsTribes.columns.score', + sortable: false, + }, + { + field: 'createDate', + label: 'todaysBestStatsTribes.columns.createDate', + sortable: false, + type: 'date', + }, +]; + +export const LIMIT = 5; diff --git a/src/features/ServerPage/features/IndexPage/components/TodaysBestStatsTribes/queries.ts b/src/features/ServerPage/features/IndexPage/components/TodaysBestStatsTribes/queries.ts new file mode 100644 index 0000000..7182e44 --- /dev/null +++ b/src/features/ServerPage/features/IndexPage/components/TodaysBestStatsTribes/queries.ts @@ -0,0 +1,32 @@ +import { gql } from '@apollo/client'; + +export const DAILY_TRIBE_STATS = gql` + query dailyTribeStats( + $server: String! + $filter: DailyTribeStatsFilter + $sort: [String!] + $limit: Int + $offset: Int + ) { + dailyTribeStats( + server: $server + filter: $filter + sort: $sort + limit: $limit + offset: $offset + ) { + items { + tribe { + id + tag + } + scoreAtt + scoreDef + scoreTotal + points + villages + createDate + } + } + } +`; diff --git a/src/features/ServerPage/features/IndexPage/components/TodaysBestStatsTribes/types.ts b/src/features/ServerPage/features/IndexPage/components/TodaysBestStatsTribes/types.ts new file mode 100644 index 0000000..45b0793 --- /dev/null +++ b/src/features/ServerPage/features/IndexPage/components/TodaysBestStatsTribes/types.ts @@ -0,0 +1,28 @@ +import { List } from '@libs/graphql/types'; + +export type Tribe = { + id: number; + tag: string; +}; + +export type DailyTribeStatsRecord = { + scoreAtt: number; + scoreDef: number; + scoreSup: number; + scoreTotal: number; + points: number; + villages: number; + createDate: string; + tribe: Tribe; +}; + +export type DailyTribeStatsList = { + dailyTribeStats?: List; +}; + +export type Mode = + | 'scoreAtt' + | 'scoreDef' + | 'scoreTotal' + | 'points' + | 'villages'; diff --git a/src/libs/graphql/types.ts b/src/libs/graphql/types.ts index 6d9410e..5f402cb 100644 --- a/src/libs/graphql/types.ts +++ b/src/libs/graphql/types.ts @@ -67,3 +67,15 @@ export type DailyPlayerStatsQueryVariables = { offset?: number; filter?: DailyPlayerStatsFilter; }; + +export type DailyTribeStatsFilter = { + createDateGT?: Date | 'string'; +}; + +export type DailyTribeStatsQueryVariables = { + server: string; + sort?: string[]; + limit?: number; + offset?: number; + filter?: DailyTribeStatsFilter; +}; diff --git a/src/libs/i18n/en/server-page/index-page.ts b/src/libs/i18n/en/server-page/index-page.ts index 715bf52..fe319cf 100644 --- a/src/libs/i18n/en/server-page/index-page.ts +++ b/src/libs/i18n/en/server-page/index-page.ts @@ -31,6 +31,22 @@ const translations = { createDate: 'Date', }, }, + todaysBestStatsTribes: { + title: `Today's best stats - tribes`, + modes: { + scoreAtt: 'ODA', + scoreDef: 'ODD', + scoreTotal: 'OD', + points: 'Points', + villages: 'Villages', + members: 'Members', + }, + columns: { + name: 'Name', + score: 'Score', + createDate: 'Date', + }, + }, }; export default translations; diff --git a/src/libs/i18n/pl/server-page/index-page.ts b/src/libs/i18n/pl/server-page/index-page.ts index 5ec483e..e4dd38d 100644 --- a/src/libs/i18n/pl/server-page/index-page.ts +++ b/src/libs/i18n/pl/server-page/index-page.ts @@ -31,6 +31,22 @@ const translations = { createDate: 'Data', }, }, + todaysBestStatsTribes: { + title: `Dzisiejsze najlepsze statystyki - plemiona`, + modes: { + scoreAtt: 'ODA', + scoreDef: 'ODD', + scoreTotal: 'OD', + points: 'Punkty', + villages: 'Wioski', + members: 'Członkowie', + }, + columns: { + name: 'Nazwa', + score: 'Wynik', + createDate: 'Data', + }, + }, }; export default translations;