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;