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 React from 'react'
import {connect} from 'react-redux' 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 {BrowserRouter as Router, Switch, Route, Link} from 'react-router-dom'
import config from 'config.json'
import styles from './App.module.scss' import styles from './App.module.scss'
import { import {
@ -21,96 +22,137 @@ import {Avatar, LoginButton} from 'components'
const App = connect((state) => ({login: state.login}))(function App({login}) { const App = connect((state) => ({login: state.login}))(function App({login}) {
return ( return (
<Router basename={process.env.PUBLIC_URL || '/'}> <Router basename={process.env.PUBLIC_URL || '/'}>
<div className={styles.App}> <Menu fixed="top">
<header className={styles.headline}> <Container>
<div className={styles.header}> <Menu.Item header className={styles.pageTitle}>
<div className={styles.pageTitle}> <Link to="/">OpenBikeSensor</Link>
<Link to="/">OpenBikeSensor</Link> </Menu.Item>
</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>
<Switch> <Link component={Menu.Item} to="/tracks">
<Route path="/" exact> Tracks
<HomePage /> </Link>
</Route>
<Route path="/tracks" exact> {login ? (
<TracksPage /> <Menu.Menu position="right">
</Route> <Link to="/upload" component={Menu.Item}>
<Route path="/my/tracks" exact> <Button compact primary>
<TracksPage privateTracks /> <Icon name="cloud upload" />
</Route> Upload
<Route path={`/tracks/:slug`} exact> </Button>
<TrackPage /> </Link>
</Route>
<Route path={`/tracks/:slug/edit`} exact> <Link to="/settings" component={Menu.Item}>
<TrackEditor /> <Avatar user={login} className={styles.avatar} />
</Route> </Link>
<Route path="/redirect" exact>
<LoginRedirectPage /> <Link component={Menu.Item} to="/logout">
</Route> <Button compact>Logout</Button>
<Route path="/logout" exact> </Link>
<LogoutPage /> </Menu.Menu>
</Route> ) : (
{login && ( <Menu.Menu>
<> <Menu.Item>
<Route path="/upload" exact> <LoginButton as="a" compact />
<UploadPage /> </Menu.Item>
</Route> </Menu.Menu>
<Route path="/settings" exact>
<SettingsPage />
</Route>
</>
)} )}
<Route> </Container>
<NotFoundPage /> </Menu>
</Route>
</Switch> <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> </div>
</Router> </Router>
) )

View file

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

View file

@ -1,7 +1,6 @@
@import '../../styles.scss'; @import '../../styles.scss';
.page { .page {
@include container;
margin-top: 32px; margin-top: 32px;
margin-bottom: 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", "clientId": "b730f8d2-d93c-4c68-9ff0-dfac8da76ee2",
"scope": "*", "scope": "*",
"redirectUri": "http://localhost:3001/redirect" "redirectUri": "http://localhost:3001/redirect"
} },
"imprintUrl": "https://example.com/imprint",
"privacyPolicyUrl": "https://example.com/privacy"
} }

View file

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

View file

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