IndexPage/Pagination/VersionSelector are now translated into Polish and English
This commit is contained in:
parent
cde80bd092
commit
7360dc9554
|
@ -1,4 +1,6 @@
|
|||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { COMMON } from '@config/namespaces';
|
||||
|
||||
import {
|
||||
Pagination as MaterialUIPagination,
|
||||
|
@ -11,10 +13,31 @@ export type Props = PaginationProps & {
|
|||
};
|
||||
|
||||
function Pagination({ total, perPage, ...rest }: Props) {
|
||||
const { t } = useTranslation(COMMON);
|
||||
|
||||
const getItemAriaLabel = (
|
||||
type: 'page' | 'first' | 'last' | 'next' | 'previous',
|
||||
page: number
|
||||
): string => {
|
||||
switch (type) {
|
||||
case 'page':
|
||||
return `${t<string>('pagination.page')} ${page}`;
|
||||
case 'first':
|
||||
return t<string>('pagination.first');
|
||||
case 'last':
|
||||
return t<string>('pagination.last');
|
||||
case 'next':
|
||||
return t<string>('pagination.next');
|
||||
case 'previous':
|
||||
return t<string>('pagination.previous');
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
if (total && perPage) {
|
||||
rest.count = total > 0 ? Math.ceil(total / perPage) : 1;
|
||||
}
|
||||
return <MaterialUIPagination {...rest} />;
|
||||
return <MaterialUIPagination {...rest} getItemAriaLabel={getItemAriaLabel} />;
|
||||
}
|
||||
|
||||
export default Pagination;
|
||||
|
|
|
@ -1,22 +1,24 @@
|
|||
import React, { useState } from 'react';
|
||||
import { useQuery } from '@apollo/client';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { COMMON } from '@config/namespaces';
|
||||
import { LANG_VERSIONS } from './queries';
|
||||
import { LangVersionList } from './types';
|
||||
import extractLangTagFromHostname from '@utils/extractLangTagFromHostname';
|
||||
|
||||
import useStyles from './styles';
|
||||
import { Button, Menu, MenuItem, Link } from '@material-ui/core';
|
||||
import { Button, Menu, MenuItem, Link, Tooltip } from '@material-ui/core';
|
||||
import { Language as LanguageIcon } from '@material-ui/icons';
|
||||
|
||||
function VersionSelector() {
|
||||
const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null);
|
||||
const { t } = useTranslation(COMMON);
|
||||
const langTag = extractLangTagFromHostname(window.location.hostname);
|
||||
const classes = useStyles();
|
||||
const { data, loading } = useQuery<LangVersionList>(LANG_VERSIONS, {
|
||||
fetchPolicy: 'cache-first',
|
||||
variables: {
|
||||
filter: {
|
||||
sort: 'tag ASC',
|
||||
tagNEQ: [langTag],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
@ -41,12 +43,17 @@ function VersionSelector() {
|
|||
|
||||
return (
|
||||
<div>
|
||||
<Tooltip
|
||||
title={t<string>('versionSelector.changeVersion')}
|
||||
placement="bottom"
|
||||
>
|
||||
<Button
|
||||
startIcon={<LanguageIcon />}
|
||||
onClick={loading ? undefined : handleClick}
|
||||
>
|
||||
{langTag}
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Menu
|
||||
anchorEl={anchorEl}
|
||||
keepMounted
|
||||
|
@ -58,11 +65,11 @@ function VersionSelector() {
|
|||
<MenuItem
|
||||
component={Link}
|
||||
href={buildLink(lv.tag)}
|
||||
className={classes.menuItem}
|
||||
underline="none"
|
||||
key={lv.tag}
|
||||
title={lv.host}
|
||||
>
|
||||
{lv.tag}
|
||||
{lv.host}
|
||||
</MenuItem>
|
||||
);
|
||||
})}
|
||||
|
|
|
@ -5,6 +5,7 @@ export const LANG_VERSIONS = gql`
|
|||
langVersions(filter: $filter) {
|
||||
items {
|
||||
tag
|
||||
host
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ import { List } from '@libs/graphql/types';
|
|||
|
||||
export type LangVersion = {
|
||||
tag: string;
|
||||
host: string;
|
||||
};
|
||||
|
||||
export type LangVersionList = {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
export const DEFAULT_LANGUAGE = 'en';
|
||||
export const DEFAULT_LANGUAGE = process.env.DEFAULT_LANGUAGE ?? 'en';
|
||||
|
||||
export const SERVER_STATUS = {
|
||||
CLOSED: 'closed',
|
||||
|
|
2
src/config/namespaces.ts
Normal file
2
src/config/namespaces.ts
Normal file
|
@ -0,0 +1,2 @@
|
|||
export const COMMON = 'common';
|
||||
export const INDEX_PAGE = 'index-page';
|
|
@ -1,7 +1,9 @@
|
|||
import React from 'react';
|
||||
import { useQueryParams, StringParam, withDefault } from 'use-query-params';
|
||||
import { useDebouncedCallback } from 'use-debounce';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { TWHELP } from '@config/app';
|
||||
import * as NAMESPACES from '@config/namespaces';
|
||||
|
||||
import useStyles from './styles';
|
||||
import {
|
||||
|
@ -25,6 +27,7 @@ export default function Header() {
|
|||
value => setQuery({ q: value }),
|
||||
1000
|
||||
);
|
||||
const { t } = useTranslation(NAMESPACES.INDEX_PAGE);
|
||||
const classes = useStyles();
|
||||
|
||||
return (
|
||||
|
@ -35,7 +38,7 @@ export default function Header() {
|
|||
<TextField
|
||||
fullWidth
|
||||
variant="outlined"
|
||||
placeholder="Search"
|
||||
placeholder={t<string>('header.search')}
|
||||
defaultValue={query.q}
|
||||
size="small"
|
||||
onChange={e => {
|
||||
|
|
|
@ -6,10 +6,12 @@ import {
|
|||
NumberParam,
|
||||
withDefault,
|
||||
} from 'use-query-params';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import formatDistanceToNow from '@libs/date/formatDistanceToNow';
|
||||
import { Locale } from '@libs/date/locales';
|
||||
import useLanguage from '@libs/i18n/useLanguage';
|
||||
import { SERVER_STATUS } from '@config/app';
|
||||
import * as NAMESPACES from '@config/namespaces';
|
||||
import { ServerList } from './types';
|
||||
import { SERVERS } from './queries';
|
||||
import extractLangTagFromHostname from '@utils/extractLangTagFromHostname';
|
||||
|
@ -28,6 +30,7 @@ export default function ServerSelection() {
|
|||
page: withDefault(NumberParam, 1),
|
||||
q: withDefault(StringParam, ''),
|
||||
});
|
||||
const { t } = useTranslation(NAMESPACES.INDEX_PAGE);
|
||||
const lang = useLanguage();
|
||||
const { data, loading: loadingServers } = useQuery<ServerList>(SERVERS, {
|
||||
fetchPolicy: 'cache-and-network',
|
||||
|
@ -97,18 +100,30 @@ export default function ServerSelection() {
|
|||
<CardHeader
|
||||
title={`${server.key}${
|
||||
SERVER_STATUS.CLOSED === server.status
|
||||
? ' (closed)'
|
||||
? ` (${t(
|
||||
NAMESPACES.COMMON +
|
||||
`:serverStatus.${server.status}`
|
||||
)})`.toLowerCase()
|
||||
: ''
|
||||
}`}
|
||||
subheader={
|
||||
<span>
|
||||
{server.numberOfPlayers.toLocaleString()} players
|
||||
{t('serverSelection.numberOfPlayers', {
|
||||
count: server.numberOfPlayers,
|
||||
num: server.numberOfPlayers.toLocaleString(),
|
||||
})}
|
||||
<br />
|
||||
{server.numberOfTribes.toLocaleString()} tribes
|
||||
{t('serverSelection.numberOfTribes', {
|
||||
count: server.numberOfTribes,
|
||||
num: server.numberOfTribes.toLocaleString(),
|
||||
})}
|
||||
<br />
|
||||
{server.numberOfVillages.toLocaleString()} villages
|
||||
{t('serverSelection.numberOfVillages', {
|
||||
count: server.numberOfVillages,
|
||||
num: server.numberOfVillages.toLocaleString(),
|
||||
})}
|
||||
<br />
|
||||
Updated{' '}
|
||||
{t('serverSelection.updated')}{' '}
|
||||
{formatDistanceToNow(new Date(server.dataUpdatedAt), {
|
||||
locale: lang as Locale,
|
||||
addSuffix: true,
|
||||
|
|
18
src/libs/i18n/en/common.ts
Normal file
18
src/libs/i18n/en/common.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
const translations = {
|
||||
versionSelector: {
|
||||
changeVersion: 'Change version',
|
||||
},
|
||||
pagination: {
|
||||
page: 'Page',
|
||||
first: 'Go to first page',
|
||||
last: 'Go to last page',
|
||||
next: 'Go to next page',
|
||||
previous: 'Go to previous page',
|
||||
},
|
||||
serverStatus: {
|
||||
closed: 'Closed',
|
||||
open: 'Open',
|
||||
},
|
||||
};
|
||||
|
||||
export default translations;
|
16
src/libs/i18n/en/index-page.ts
Normal file
16
src/libs/i18n/en/index-page.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
const translations = {
|
||||
header: {
|
||||
search: 'Search',
|
||||
},
|
||||
serverSelection: {
|
||||
numberOfPlayers: '{{num}} player',
|
||||
numberOfPlayers_plural: '{{num}} players',
|
||||
numberOfTribes: '{{num}} tribe',
|
||||
numberOfTribes_plural: '{{num}} tribes',
|
||||
numberOfVillages: '{{num}} village',
|
||||
numberOfVillages_plural: '{{num}} villages',
|
||||
updated: 'Updated',
|
||||
},
|
||||
};
|
||||
|
||||
export default translations;
|
|
@ -1 +1,10 @@
|
|||
export default {};
|
||||
import * as NAMESPACES from '@config/namespaces';
|
||||
import common from './common';
|
||||
import indexPage from './index-page';
|
||||
|
||||
const translations = {
|
||||
[NAMESPACES.COMMON]: common,
|
||||
[NAMESPACES.INDEX_PAGE]: indexPage,
|
||||
};
|
||||
|
||||
export default translations;
|
||||
|
|
|
@ -4,6 +4,7 @@ import LanguageDetector from 'i18next-browser-languagedetector';
|
|||
import pl from './pl';
|
||||
import en from './en';
|
||||
import { DEFAULT_LANGUAGE } from '@config/app';
|
||||
import { COMMON } from '@config/namespaces';
|
||||
|
||||
const init = (): i18nT => {
|
||||
i18n
|
||||
|
@ -20,7 +21,7 @@ const init = (): i18nT => {
|
|||
en,
|
||||
pl,
|
||||
},
|
||||
defaultNS: 'common',
|
||||
defaultNS: COMMON,
|
||||
react: {
|
||||
useSuspense: false,
|
||||
},
|
||||
|
|
18
src/libs/i18n/pl/common.ts
Normal file
18
src/libs/i18n/pl/common.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
const translations = {
|
||||
versionSelector: {
|
||||
changeVersion: 'Zmień wersję',
|
||||
},
|
||||
pagination: {
|
||||
page: 'Strona',
|
||||
first: 'Przejdź do pierwszej strony',
|
||||
last: 'Przejdź do ostatniej strony',
|
||||
next: 'Przejdź do następnej strony',
|
||||
previous: 'Przejdź do poprzedniej strony',
|
||||
},
|
||||
serverStatus: {
|
||||
closed: 'Zamknięty',
|
||||
open: 'Otwarty',
|
||||
},
|
||||
};
|
||||
|
||||
export default translations;
|
19
src/libs/i18n/pl/index-page.ts
Normal file
19
src/libs/i18n/pl/index-page.ts
Normal file
|
@ -0,0 +1,19 @@
|
|||
const translations = {
|
||||
header: {
|
||||
search: 'Szukaj',
|
||||
},
|
||||
serverSelection: {
|
||||
numberOfPlayers_0: '{{num}} gracz',
|
||||
numberOfPlayers_1: '{{num}} graczy',
|
||||
numberOfPlayers_2: '{{num}} graczy',
|
||||
numberOfTribes_0: '{{num}} plemię',
|
||||
numberOfTribes_1: '{{num}} plemiona',
|
||||
numberOfTribes_2: '{{num}} plemion',
|
||||
numberOfVillages_0: '{{num}} wioska',
|
||||
numberOfVillages_1: '{{num}} wioski',
|
||||
numberOfVillages_2: '{{num}} wiosek',
|
||||
updated: 'Zaktualizowany',
|
||||
},
|
||||
};
|
||||
|
||||
export default translations;
|
|
@ -1 +1,10 @@
|
|||
export default {};
|
||||
import * as NAMESPACES from '@config/namespaces';
|
||||
import common from './common';
|
||||
import indexPage from './index-page';
|
||||
|
||||
const translations = {
|
||||
[NAMESPACES.COMMON]: common,
|
||||
[NAMESPACES.INDEX_PAGE]: indexPage,
|
||||
};
|
||||
|
||||
export default translations;
|
||||
|
|
Reference in New Issue
Block a user