frontend: Add footer, improve menu, add links to privacy policy and imprint
This commit is contained in:
parent
c380b0d1fb
commit
a4756873e5
|
@ -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,59 +22,42 @@ 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>
|
||||||
</div>
|
</Menu.Item>
|
||||||
<nav className={styles.menu}>
|
|
||||||
<ul>
|
<Link component={Menu.Item} to="/tracks">
|
||||||
{login && (
|
Tracks
|
||||||
<li>
|
</Link>
|
||||||
<Link to="/upload">
|
|
||||||
|
{login ? (
|
||||||
|
<Menu.Menu position="right">
|
||||||
|
<Link to="/upload" component={Menu.Item}>
|
||||||
<Button compact primary>
|
<Button compact primary>
|
||||||
<Icon name="cloud upload" />
|
<Icon name="cloud upload" />
|
||||||
Upload
|
Upload
|
||||||
</Button>
|
</Button>
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
|
||||||
)}
|
<Link to="/settings" component={Menu.Item}>
|
||||||
<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} />
|
<Avatar user={login} className={styles.avatar} />
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
|
||||||
<li>
|
<Link component={Menu.Item} to="/logout">
|
||||||
<Button as={Link} to="/logout" compact>
|
<Button compact>Logout</Button>
|
||||||
Logout
|
</Link>
|
||||||
</Button>
|
</Menu.Menu>
|
||||||
</li>
|
|
||||||
</>
|
|
||||||
) : (
|
) : (
|
||||||
<>
|
<Menu.Menu>
|
||||||
<li>
|
<Menu.Item>
|
||||||
<LoginButton as="a" compact />
|
<LoginButton as="a" compact />
|
||||||
</li>
|
</Menu.Item>
|
||||||
</>
|
</Menu.Menu>
|
||||||
)}
|
)}
|
||||||
</ul>
|
</Container>
|
||||||
</nav>
|
</Menu>
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route path="/" exact>
|
<Route path="/" exact>
|
||||||
|
@ -111,6 +95,64 @@ const App = connect((state) => ({login: state.login}))(function App({login}) {
|
||||||
<NotFoundPage />
|
<NotFoundPage />
|
||||||
</Route>
|
</Route>
|
||||||
</Switch>
|
</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>
|
||||||
)
|
)
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
|
||||||
}
|
|
13
frontend/src/components/Page/index.tsx
Normal file
13
frontend/src/components/Page/index.tsx
Normal 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>
|
||||||
|
)
|
||||||
|
}
|
|
@ -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"
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
.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;
|
||||||
|
|
Loading…
Reference in a new issue