frontend: Add footer, improve menu, add links to privacy policy and imprint

This commit is contained in:
Paul Bienkowski 2021-05-09 15:38:09 +02:00
parent c380b0d1fb
commit a4756873e5
8 changed files with 186 additions and 110 deletions

View file

@ -1,8 +1,9 @@
import React from 'react'
import {connect} from 'react-redux'
import {Image, Icon, Button} from 'semantic-ui-react'
import {List, Grid, Container, Menu, Icon, Button, Header} from 'semantic-ui-react'
import {BrowserRouter as Router, Switch, Route, Link} from 'react-router-dom'
import config from 'config.json'
import styles from './App.module.scss'
import {
@ -21,96 +22,137 @@ import {Avatar, LoginButton} from 'components'
const App = connect((state) => ({login: state.login}))(function App({login}) {
return (
<Router basename={process.env.PUBLIC_URL || '/'}>
<div className={styles.App}>
<header className={styles.headline}>
<div className={styles.header}>
<div className={styles.pageTitle}>
<Link to="/">OpenBikeSensor</Link>
</div>
<nav className={styles.menu}>
<ul>
{login && (
<li>
<Link to="/upload">
<Button compact primary>
<Icon name="cloud upload" />
Upload
</Button>
</Link>
</li>
)}
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/tracks">Tracks</Link>
</li>
<li>
<a href="https://openbikesensor.org/" target="_blank" rel="noreferrer">
About
</a>
</li>
{login ? (
<>
<li>
<Link to="/settings">
<Avatar user={login} className={styles.avatar} />
</Link>
</li>
<li>
<Button as={Link} to="/logout" compact>
Logout
</Button>
</li>
</>
) : (
<>
<li>
<LoginButton as="a" compact />
</li>
</>
)}
</ul>
</nav>
</div>
</header>
<Menu fixed="top">
<Container>
<Menu.Item header className={styles.pageTitle}>
<Link to="/">OpenBikeSensor</Link>
</Menu.Item>
<Switch>
<Route path="/" exact>
<HomePage />
</Route>
<Route path="/tracks" exact>
<TracksPage />
</Route>
<Route path="/my/tracks" exact>
<TracksPage privateTracks />
</Route>
<Route path={`/tracks/:slug`} exact>
<TrackPage />
</Route>
<Route path={`/tracks/:slug/edit`} exact>
<TrackEditor />
</Route>
<Route path="/redirect" exact>
<LoginRedirectPage />
</Route>
<Route path="/logout" exact>
<LogoutPage />
</Route>
{login && (
<>
<Route path="/upload" exact>
<UploadPage />
</Route>
<Route path="/settings" exact>
<SettingsPage />
</Route>
</>
<Link component={Menu.Item} to="/tracks">
Tracks
</Link>
{login ? (
<Menu.Menu position="right">
<Link to="/upload" component={Menu.Item}>
<Button compact primary>
<Icon name="cloud upload" />
Upload
</Button>
</Link>
<Link to="/settings" component={Menu.Item}>
<Avatar user={login} className={styles.avatar} />
</Link>
<Link component={Menu.Item} to="/logout">
<Button compact>Logout</Button>
</Link>
</Menu.Menu>
) : (
<Menu.Menu>
<Menu.Item>
<LoginButton as="a" compact />
</Menu.Item>
</Menu.Menu>
)}
<Route>
<NotFoundPage />
</Route>
</Switch>
</Container>
</Menu>
<Switch>
<Route path="/" exact>
<HomePage />
</Route>
<Route path="/tracks" exact>
<TracksPage />
</Route>
<Route path="/my/tracks" exact>
<TracksPage privateTracks />
</Route>
<Route path={`/tracks/:slug`} exact>
<TrackPage />
</Route>
<Route path={`/tracks/:slug/edit`} exact>
<TrackEditor />
</Route>
<Route path="/redirect" exact>
<LoginRedirectPage />
</Route>
<Route path="/logout" exact>
<LogoutPage />
</Route>
{login && (
<>
<Route path="/upload" exact>
<UploadPage />
</Route>
<Route path="/settings" exact>
<SettingsPage />
</Route>
</>
)}
<Route>
<NotFoundPage />
</Route>
</Switch>
<div className={styles.footer}>
<Container>
<Grid columns={4} stackable>
<Grid.Row>
<Grid.Column>
<Header as='h5'>About the project</Header>
<List>
<List.Item>
<a href="https://openbikesensor.org/" target="_blank" rel="noreferrer">
openbikesensor.org
</a>
</List.Item>
</List>
</Grid.Column>
<Grid.Column>
<Header as='h5'>Get involved</Header>
<List>
<List.Item>
<a href="https://openbikesensor.org/slack" target="_blank" rel="noreferrer">
Slack
</a>
</List.Item>
<List.Item>
<a href="https://github.com/openbikesensor/portal/issues/new" target="_blank" rel="noreferrer">
Report an issue
</a>
</List.Item>
<List.Item>
<a href="https://github.com/openbikesensor/portal" target="_blank" rel="noreferrer">
Development
</a>
</List.Item>
</List>
</Grid.Column>
<Grid.Column>
<Header as='h5'>This installation</Header>
<List>
<List.Item>
<a href={config.privacyPolicyUrl} target="_blank" rel="noreferrer">
Privacy policy
</a>
</List.Item>
<List.Item>
<a href={config.imprintUrl} target="_blank" rel="noreferrer">
Imprint
</a>
</List.Item>
</List>
</Grid.Column>
<Grid.Column>
</Grid.Column>
</Grid.Row>
</Grid>
</Container>
</div>
</Router>
)

View file

@ -1,14 +1,40 @@
@import 'styles.scss';
.App {
:global(#root) {
padding-top: 60px;
display: flex;
flex-direction: column;
justify-content: stretch;
html, body, & {
min-height: 100%;
}
}
.header {
@include container;
height: 56px;
display: flex;
align-items: center;
.footer {
margin-top: auto;
min-height: 12rem;
padding: 2rem 0;
background: $obsColorB4;
color: $obsColorW;
h1, h2, h3, h4, h5, h6 {
&:global(.ui.header) {
color: inherit;
}
}
a {
&, &:hover {
color: inherit;
}
&:hover {
text-decoration: underline;
}
}
}
.avatar {
@ -36,12 +62,12 @@
box-shadow: 0 0 10px -6px black;
}
.pageTitle {
.pageTitle a {
font-family: 'Open Sans Condensed';
font-weight: 600;
font-size: 18pt;
&, a, a:hover {
&, &:hover {
color: $obsColorB4;
}
}

View file

@ -1,7 +1,6 @@
@import '../../styles.scss';
.page {
@include container;
margin-top: 32px;
margin-bottom: 32px;
}

View file

@ -1,8 +0,0 @@
import React from 'react'
import classnames from 'classnames'
import styles from './Page.module.scss'
export default function Page({small, children}) {
return <main className={classnames(styles.page, small && styles.small)}>{children}</main>
}

View file

@ -0,0 +1,13 @@
import React from 'react'
import classnames from 'classnames'
import {Container} from 'semantic-ui-react'
import styles from './Page.module.scss'
export default function Page({small, children}: {small?: boolean, children: ReactNode}) {
return (
<main className={classnames(styles.page, small && styles.small)}>
<Container>{children}</Container>
</main>
)
}

View file

@ -5,5 +5,7 @@
"clientId": "b730f8d2-d93c-4c68-9ff0-dfac8da76ee2",
"scope": "*",
"redirectUri": "http://localhost:3001/redirect"
}
},
"imprintUrl": "https://example.com/imprint",
"privacyPolicyUrl": "https://example.com/privacy"
}

View file

@ -5,5 +5,7 @@
"clientId": "CHANGEME",
"scope": "*",
"redirectUri": "https://example.com/redirect"
}
},
"imprintUrl": "https://example.com/imprint",
"privacyPolicyUrl": "https://example.com/privacy"
}

View file

@ -1,9 +1,9 @@
.welcomeMap {
height: 60rem;
max-height: 80vh;
max-height: 70vh;
@media screen and (max-width: 767px) {
margin: -35px -32px 0 -32px;
max-height: 70vh;
max-height: 70vh;
}
}