Translate region frontend

This commit is contained in:
Paul Bienkowski 2023-03-12 12:57:05 +01:00
parent e0070fc794
commit 6d71b88010
6 changed files with 95 additions and 68 deletions

View file

@ -1,46 +1,36 @@
import React, { useState, useCallback } from "react"; import React, {useState, useCallback} from 'react'
import { pickBy } from "lodash"; import {pickBy} from 'lodash'
import { import {Loader, Statistic, Pagination, Segment, Header, Menu, Table, Icon} from 'semantic-ui-react'
Loader, import {useObservable} from 'rxjs-hooks'
Statistic, import {of, from, concat, combineLatest} from 'rxjs'
Pagination, import {map, switchMap, distinctUntilChanged} from 'rxjs/operators'
Segment, import {Duration, DateTime} from 'luxon'
Header,
Menu,
Table,
Icon,
} from "semantic-ui-react";
import { useObservable } from "rxjs-hooks";
import { of, from, concat, combineLatest } from "rxjs";
import { map, switchMap, distinctUntilChanged } from "rxjs/operators";
import { Duration, DateTime } from "luxon";
import api from "api"; import api from 'api'
import {useTranslation} from 'react-i18next'
function formatDuration(seconds) { function formatDuration(seconds) {
return ( return (
Duration.fromMillis((seconds ?? 0) * 1000) Duration.fromMillis((seconds ?? 0) * 1000)
.as("hours") .as('hours')
.toFixed(1) + " h" .toFixed(1) + ' h'
); )
} }
export default function Stats() { export default function Stats() {
const [page, setPage] = useState(1); const {t} = useTranslation()
const PER_PAGE = 10; const [page, setPage] = useState(1)
const PER_PAGE = 10
const stats = useObservable( const stats = useObservable(
() => () => of(null).pipe(switchMap(() => concat(of(null), from(api.get('/stats/regions'))))),
of(null).pipe(
switchMap(() => concat(of(null), from(api.get("/stats/regions"))))
),
null null
); )
const pageCount = stats ? Math.ceil(stats.length / PER_PAGE) : 1; const pageCount = stats ? Math.ceil(stats.length / PER_PAGE) : 1
return ( return (
<> <>
<Header as="h2">Top Regions</Header> <Header as="h2">{t('RegionStats.title')}</Header>
<div> <div>
<Loader active={stats == null} /> <Loader active={stats == null} />
@ -48,36 +38,36 @@ export default function Stats() {
<Table celled> <Table celled>
<Table.Header> <Table.Header>
<Table.Row> <Table.Row>
<Table.HeaderCell>Region name</Table.HeaderCell> <Table.HeaderCell> {t('RegionStats.regionName')}</Table.HeaderCell>
<Table.HeaderCell>Event count</Table.HeaderCell> <Table.HeaderCell>{t('RegionStats.eventCount')}</Table.HeaderCell>
</Table.Row> </Table.Row>
</Table.Header> </Table.Header>
<Table.Body> <Table.Body>
{stats {stats?.slice((page - 1) * PER_PAGE, page * PER_PAGE)?.map((area) => (
?.slice((page - 1) * PER_PAGE, page * PER_PAGE) <Table.Row key={area.id}>
?.map((area) => ( <Table.Cell>{area.name}</Table.Cell>
<Table.Row key={area.id}> <Table.Cell>{area.overtaking_event_count}</Table.Cell>
<Table.Cell>{area.name}</Table.Cell> </Table.Row>
<Table.Cell>{area.overtaking_event_count}</Table.Cell> ))}
</Table.Row>
))}
</Table.Body> </Table.Body>
{pageCount > 1 && <Table.Footer> {pageCount > 1 && (
<Table.Row> <Table.Footer>
<Table.HeaderCell colSpan="2"> <Table.Row>
<Pagination <Table.HeaderCell colSpan="2">
floated="right" <Pagination
activePage={page} floated="right"
totalPages={pageCount} activePage={page}
onPageChange={(e, data) => setPage(data.activePage as number)} totalPages={pageCount}
/> onPageChange={(e, data) => setPage(data.activePage as number)}
</Table.HeaderCell> />
</Table.Row> </Table.HeaderCell>
</Table.Footer>} </Table.Row>
</Table.Footer>
)}
</Table> </Table>
</div> </div>
</> </>
); )
} }

View file

@ -72,12 +72,12 @@ function LayerSidebar({
onChange={() => setMapConfigFlag('obsRegions.show', !showRegions)} onChange={() => setMapConfigFlag('obsRegions.show', !showRegions)}
/> />
<label htmlFor="obsRegions.show"> <label htmlFor="obsRegions.show">
<Header as="h4">Regions</Header> <Header as="h4">{t('MapPage.sidebar.obsRegions.title')}</Header>
</label> </label>
</List.Item> </List.Item>
{showRegions && ( {showRegions && (
<> <>
<List.Item>Color regions based on event count</List.Item> <List.Item>{t('MapPage.sidebar.obsRegions.colorByEventCount')}</List.Item>
<List.Item> <List.Item>
<ColorMapLegend <ColorMapLegend
twoTicks twoTicks

View file

@ -1,15 +1,16 @@
import React, { useState, useCallback } from "react"; import React from 'react'
import { createPortal } from "react-dom"; import {createPortal} from 'react-dom'
import _ from "lodash"; import {useTranslation} from 'react-i18next'
import { List, Header, Icon, Button } from "semantic-ui-react"; import {List, Header, Icon, Button} from 'semantic-ui-react'
import styles from "./styles.module.less"; import styles from './styles.module.less'
export default function RegionInfo({ region, mapInfoPortal, onClose }) { export default function RegionInfo({region, mapInfoPortal, onClose}) {
const {t} = useTranslation()
const content = ( const content = (
<> <>
<div className={styles.closeHeader}> <div className={styles.closeHeader}>
<Header as="h3">{region.properties.name || "Unnamed region"}</Header> <Header as="h3">{region.properties.name || t('MapPage.regionInfo.unnamedRegion')}</Header>
<Button primary icon onClick={onClose}> <Button primary icon onClick={onClose}>
<Icon name="close" /> <Icon name="close" />
</Button> </Button>
@ -17,17 +18,14 @@ export default function RegionInfo({ region, mapInfoPortal, onClose }) {
<List> <List>
<List.Item> <List.Item>
<List.Header>Number of events</List.Header> <List.Header>{t('MapPage.regionInfo.eventCount')}</List.Header>
<List.Content>{region.properties.overtaking_event_count ?? 0}</List.Content> <List.Content>{region.properties.overtaking_event_count ?? 0}</List.Content>
</List.Item> </List.Item>
</List> </List>
</> </>
); )
return content && mapInfoPortal return content && mapInfoPortal
? createPortal( ? createPortal(<div className={styles.mapInfoBox}>{content}</div>, mapInfoPortal)
<div className={styles.mapInfoBox}>{content}</div>, : null
mapInfoPortal
)
: null;
} }

View file

@ -158,6 +158,10 @@ MapPage:
obsEvents: obsEvents:
title: Überholvorgänge title: Überholvorgänge
obsRegions:
title: Regionen
colorByEventCount: Regionen eingefärbt nach Anzahl Überholungen
filters: filters:
title: Filter title: Filter
needsLogin: Filter sind ohne Login nicht verfügbar. needsLogin: Filter sind ohne Login nicht verfügbar.
@ -203,6 +207,10 @@ MapPage:
west: westwärts west: westwärts
northWest: nordwestwärts northWest: nordwestwärts
regionInfo:
unnamedRegion: Unbenannte Region
eventCount: Anzahl Überholungen
SettingsPage: SettingsPage:
title: Einstellungen title: Einstellungen
@ -343,3 +351,8 @@ TrackEditor:
vorhanden bleiben. vorhanden bleiben.
**Nutze diese Funktion mit Bedacht und auf dein eigenes Risiko.** **Nutze diese Funktion mit Bedacht und auf dein eigenes Risiko.**
RegionStats:
title: Top-Regionen
regionName: Region
eventCount: Anzahl Überholungen

View file

@ -164,6 +164,10 @@ MapPage:
obsEvents: obsEvents:
title: Event points title: Event points
obsRegions:
title: Regions
colorByEventCount: Color regions are based on event count
filters: filters:
title: Filters title: Filters
needsLogin: No filters available without login. needsLogin: No filters available without login.
@ -208,6 +212,10 @@ MapPage:
west: west bound west: west bound
northWest: north-west bound northWest: north-west bound
regionInfo:
unnamedRegion: Unnamed region
eventCount: Event count
SettingsPage: SettingsPage:
title: Settings title: Settings
@ -342,3 +350,8 @@ TrackEditor:
later. later.
**Use at your own risk.** **Use at your own risk.**
RegionStats:
title: Top regions
regionName: Region name
eventCount: Event count

View file

@ -164,6 +164,10 @@ MapPage:
obsEvents: obsEvents:
title: Points d'événement title: Points d'événement
obsRegions:
title: Régions
colorByEventCount: Couleurs des régions sont basées sur le nombre d'événements
filters: filters:
title: Filtres title: Filtres
needsLogin: Aucun filtre disponible sans être connecté. needsLogin: Aucun filtre disponible sans être connecté.
@ -208,6 +212,10 @@ MapPage:
west: Ouest west: Ouest
northWest: Nord-Ouest northWest: Nord-Ouest
regionInfo:
unnamedRegion: Région sans nom
eventCount: Nombre de dépassements
SettingsPage: SettingsPage:
title: Paramètres title: Paramètres
@ -343,3 +351,8 @@ TrackEditor:
ou les rendez anonymes plus tard. ou les rendez anonymes plus tard.
**Utilisation à vos risques et périls.** **Utilisation à vos risques et périls.**
RegionStats:
title: Top régions
regionName: Nom de la région
eventCount: Nombre de dépassements