2021-05-14 20:44:36 +02:00
|
|
|
import React from 'react'
|
|
|
|
import {Link} from 'react-router-dom'
|
|
|
|
import {Message, Grid, Loader, Header, Item} from 'semantic-ui-react'
|
|
|
|
import {useObservable} from 'rxjs-hooks'
|
|
|
|
import {of, from} from 'rxjs'
|
|
|
|
import {map, switchMap} from 'rxjs/operators'
|
|
|
|
|
|
|
|
import api from 'api'
|
2021-10-10 12:32:28 +02:00
|
|
|
import {Stats, Page} from 'components'
|
2021-11-16 21:59:37 +01:00
|
|
|
import {useConfig, MapSource} from 'config'
|
2021-05-14 20:44:36 +02:00
|
|
|
|
|
|
|
import {TrackListItem} from './TracksPage'
|
|
|
|
import styles from './HomePage.module.scss'
|
|
|
|
|
2021-10-27 17:32:07 +02:00
|
|
|
import 'ol/ol.css'
|
2021-10-10 12:32:28 +02:00
|
|
|
import {obsRoads} from '../mapstyles'
|
|
|
|
import ReactMapGl from 'react-map-gl'
|
|
|
|
|
2021-11-16 21:59:37 +01:00
|
|
|
function WelcomeMap({mapSource}: {mapSource: MapSource}) {
|
2021-10-27 17:32:07 +02:00
|
|
|
const mapStyle = React.useMemo(() => obsRoads(mapSource), [mapSource])
|
2021-10-10 12:32:28 +02:00
|
|
|
const config = useConfig()
|
|
|
|
const [viewport, setViewport] = React.useState({
|
|
|
|
longitude: 0,
|
|
|
|
latitude: 0,
|
|
|
|
zoom: 0,
|
2021-10-27 17:32:07 +02:00
|
|
|
})
|
2021-10-10 12:32:28 +02:00
|
|
|
|
|
|
|
React.useEffect(() => {
|
2021-10-27 17:32:07 +02:00
|
|
|
if (config?.mapHome) {
|
|
|
|
setViewport(config.mapHome)
|
2021-10-10 12:32:28 +02:00
|
|
|
}
|
|
|
|
}, [config])
|
|
|
|
|
2021-05-14 20:44:36 +02:00
|
|
|
return (
|
2021-10-10 12:32:28 +02:00
|
|
|
<div className={styles.welcomeMap}>
|
2021-10-27 17:32:07 +02:00
|
|
|
<ReactMapGl mapStyle={mapStyle} width="100%" height="100%" onViewportChange={setViewport} {...viewport} />
|
2021-10-10 12:32:28 +02:00
|
|
|
</div>
|
2021-05-14 20:44:36 +02:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
function MostRecentTrack() {
|
|
|
|
const track: Track | null = useObservable(
|
|
|
|
() =>
|
|
|
|
of(null).pipe(
|
|
|
|
switchMap(() => from(api.fetch('/tracks?limit=1'))),
|
|
|
|
map((response) => response?.tracks?.[0])
|
|
|
|
),
|
|
|
|
null,
|
|
|
|
[]
|
|
|
|
)
|
|
|
|
|
|
|
|
return (
|
|
|
|
<>
|
|
|
|
<Header as="h2">Most recent track</Header>
|
|
|
|
<Loader active={track === null} />
|
|
|
|
{track === undefined ? (
|
|
|
|
<Message>
|
|
|
|
No public tracks yet. <Link to="/upload">Upload the first!</Link>
|
|
|
|
</Message>
|
|
|
|
) : track ? (
|
|
|
|
<Item.Group>
|
|
|
|
<TrackListItem track={track} />
|
|
|
|
</Item.Group>
|
|
|
|
) : null}
|
|
|
|
</>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
export default function HomePage() {
|
2021-10-27 17:32:07 +02:00
|
|
|
const {obsMapSource: mapSource} = useConfig() || {}
|
|
|
|
|
2021-05-14 20:44:36 +02:00
|
|
|
return (
|
|
|
|
<Page>
|
|
|
|
<Grid stackable>
|
|
|
|
<Grid.Row>
|
|
|
|
<Grid.Column width={10}>
|
2021-10-27 17:32:07 +02:00
|
|
|
{mapSource ? <WelcomeMap {...{mapSource}} /> : null}
|
2021-05-14 20:44:36 +02:00
|
|
|
</Grid.Column>
|
|
|
|
<Grid.Column width={6}>
|
|
|
|
<Stats />
|
|
|
|
<MostRecentTrack />
|
|
|
|
</Grid.Column>
|
|
|
|
</Grid.Row>
|
|
|
|
</Grid>
|
|
|
|
</Page>
|
|
|
|
)
|
|
|
|
}
|