diff --git a/src/common/Table/Table.tsx b/src/common/Table/Table.tsx index 7f89a08..cd1574f 100644 --- a/src/common/Table/Table.tsx +++ b/src/common/Table/Table.tsx @@ -108,6 +108,7 @@ function Table({ ? item[idFieldName] + '' : index } + index={index} row={item} actions={actions} selected={isSelected(item)} diff --git a/src/common/Table/TableRow.tsx b/src/common/Table/TableRow.tsx index 074169f..a5563bd 100644 --- a/src/common/Table/TableRow.tsx +++ b/src/common/Table/TableRow.tsx @@ -14,6 +14,7 @@ export interface Props { selection: boolean; selected: boolean; size?: 'small' | 'medium'; + index: number; onSelect?: (row: T) => void; } @@ -25,6 +26,7 @@ function EnhancedTableRow({ selected = false, onSelect, size = 'medium', + index, }: Props) { const handleSelect = () => { if (onSelect) { @@ -65,7 +67,7 @@ function EnhancedTableRow({ align={col.align ? col.align : 'left'} > {col.valueFormatter - ? col.valueFormatter(row) + ? col.valueFormatter(row, index) : col.type ? formatValue(val, col.type) : val} diff --git a/src/common/Table/types.ts b/src/common/Table/types.ts index c07d70d..e0fe049 100644 --- a/src/common/Table/types.ts +++ b/src/common/Table/types.ts @@ -7,7 +7,7 @@ export type Column = { field: string; label?: string; sortable?: boolean; - valueFormatter?: (v: T) => React.ReactNode; + valueFormatter?: (v: T, i: number) => React.ReactNode; disablePadding?: boolean; type?: 'normal' | 'datetime' | 'date'; align?: 'left' | 'right' | 'center'; diff --git a/src/config/app.ts b/src/config/app.ts index eeda5f3..daefcd0 100644 --- a/src/config/app.ts +++ b/src/config/app.ts @@ -1,4 +1,4 @@ -export const DEFAULT_LANGUAGE = process.env.REACT_APP_DEFAULT_LANGUAGE ?? 'pl'; +export const DEFAULT_LANGUAGE = process.env.REACT_APP_DEFAULT_LANGUAGE ?? 'en'; export const NAME = 'TWHelp'; @@ -9,7 +9,8 @@ export const SERVER_STATUS = { OPEN: 'open' as ServerStatus, }; -export const TWHELP = process.env.TWHelp ?? 'https://tribalwarshelp.com'; +export const TWHELP = + process.env.REACT_APP_TWHELP ?? 'https://tribalwarshelp.com'; export const AUTHOR = 'Dawid WysokiƄski'; diff --git a/src/features/ServerPage/features/TribePage/TribePage.tsx b/src/features/ServerPage/features/TribePage/TribePage.tsx index c2bac72..57a46cc 100644 --- a/src/features/ServerPage/features/TribePage/TribePage.tsx +++ b/src/features/ServerPage/features/TribePage/TribePage.tsx @@ -4,6 +4,7 @@ import { SERVER_PAGE } from '@config/routes'; import { Switch, Route, RouteProps } from 'react-router-dom'; import TribeProvider from './libs/TribePageContext/Provider'; import IndexPage from './features/IndexPage/IndexPage'; +import MembersPage from './features/MembersPage/MembersPage'; import HistoryPage from './features/HistoryPage/HistoryPage'; import EnnoblementsPage from './features/EnnoblementsPage/EnnoblementsPage'; import TribeChangesPage from './features/TribeChangesPage/TribeChangesPage'; @@ -23,6 +24,9 @@ function TribePage() { + + + diff --git a/src/features/ServerPage/features/TribePage/features/MembersPage/MembersPage.tsx b/src/features/ServerPage/features/TribePage/features/MembersPage/MembersPage.tsx new file mode 100644 index 0000000..ddebf50 --- /dev/null +++ b/src/features/ServerPage/features/TribePage/features/MembersPage/MembersPage.tsx @@ -0,0 +1,26 @@ +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import useTitle from '@libs/useTitle'; +import useServer from '@features/ServerPage/libs/ServerContext/useServer'; +import useTribe from '../../libs/TribePageContext/useTribe'; +import { SERVER_PAGE } from '@config/namespaces'; + +import { Container } from '@material-ui/core'; +import PageLayout from '../../common/PageLayout/PageLayout'; +import Members from './components/Members/Members'; + +function MembersPage() { + const { key } = useServer(); + const tribe = useTribe(); + const { t } = useTranslation(SERVER_PAGE.TRIBE_PAGE.MEMBERS_PAGE); + useTitle(t('title', { key, tag: tribe.tag })); + return ( + + + + + + ); +} + +export default MembersPage; diff --git a/src/features/ServerPage/features/TribePage/features/MembersPage/components/Members/Members.tsx b/src/features/ServerPage/features/TribePage/features/MembersPage/components/Members/Members.tsx new file mode 100644 index 0000000..1e90efe --- /dev/null +++ b/src/features/ServerPage/features/TribePage/features/MembersPage/components/Members/Members.tsx @@ -0,0 +1,82 @@ +import React from 'react'; +import { useQuery } from '@apollo/client'; +import { PLAYERS } from './queries'; + +import { Paper } from '@material-ui/core'; +import Table from '@common/Table/Table'; +import PlayerProfileLink from '@features/ServerPage/common/PlayerProfileLink/PlayerProfileLink'; + +import { TFunction } from 'i18next'; +import { PlayersQueryVariables } from '@libs/graphql/types'; +import { PlayersQuery, Player } from './types'; + +export interface Props { + server: string; + tribeID: number; + t: TFunction; +} + +function Members({ t, server, tribeID }: Props) { + const { data: queryData, loading: queryLoading } = useQuery< + PlayersQuery, + PlayersQueryVariables + >(PLAYERS, { + fetchPolicy: 'cache-and-network', + variables: { + sort: ['rank ASC'], + filter: { + tribeID: [tribeID], + }, + server, + }, + }); + const playersItems = queryData?.players?.items ?? []; + const loading = playersItems.length === 0 && queryLoading; + + return ( + + { + return i + 1 + '.'; + }, + }, + { + field: 'name', + label: t('members.columns.name'), + sortable: false, + valueFormatter: (p: Player) => { + return ; + }, + }, + { + field: 'points', + label: t('members.columns.points'), + sortable: false, + valueFormatter: (p: Player) => { + return `${p.points.toLocaleString()} (#${p.rank})`; + }, + }, + { + field: 'totalVillages', + label: t('members.columns.totalVillages'), + sortable: false, + valueFormatter: (p: Player) => { + return p.totalVillages.toLocaleString(); + }, + }, + ]} + loading={loading} + data={playersItems} + size="small" + hideFooter + /> + + ); +} + +export default Members; diff --git a/src/features/ServerPage/features/TribePage/features/MembersPage/components/Members/queries.ts b/src/features/ServerPage/features/TribePage/features/MembersPage/components/Members/queries.ts new file mode 100644 index 0000000..1618193 --- /dev/null +++ b/src/features/ServerPage/features/TribePage/features/MembersPage/components/Members/queries.ts @@ -0,0 +1,28 @@ +import { gql } from '@apollo/client'; + +export const PLAYERS = gql` + query players( + $server: String! + $filter: PlayerFilter + $sort: [String!] + $limit: Int + $offset: Int + ) { + players( + server: $server + filter: $filter + sort: $sort + limit: $limit + offset: $offset + ) { + items { + id + name + rank + points + totalVillages + } + total + } + } +`; diff --git a/src/features/ServerPage/features/TribePage/features/MembersPage/components/Members/types.ts b/src/features/ServerPage/features/TribePage/features/MembersPage/components/Members/types.ts new file mode 100644 index 0000000..6d4bfb4 --- /dev/null +++ b/src/features/ServerPage/features/TribePage/features/MembersPage/components/Members/types.ts @@ -0,0 +1,13 @@ +import { List } from '@libs/graphql/types'; + +export type Player = { + id: number; + name: string; + rank: number; + points: number; + totalVillages: number; +}; + +export type PlayersQuery = { + players?: List; +}; diff --git a/src/libs/graphql/types.ts b/src/libs/graphql/types.ts index e85ceec..6210fff 100644 --- a/src/libs/graphql/types.ts +++ b/src/libs/graphql/types.ts @@ -39,6 +39,7 @@ export type ServerStatsQueryVariables = QueryVariablesWithServer< export type PlayerFilter = { id?: number[]; + tribeID?: number[]; exists?: boolean; tribeFilter?: TribeFilter; deletedAtGT?: Date | string; @@ -100,7 +101,7 @@ export type TribeHistoryQueryVariables = QueryVariablesWithServer< TribeHistoryFilter >; -export type TribeChangesFilter = { +export type TribeChangeFilter = { playerID?: number[]; playerIDNEQ?: number[]; or?: { @@ -110,7 +111,7 @@ export type TribeChangesFilter = { }; export type TribeChangesQueryVariables = QueryVariablesWithServer< - TribeChangesFilter + TribeChangeFilter >; export type EnnoblementFilter = {