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 {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,59 +22,42 @@ 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}>
|
||||
<Menu fixed="top">
|
||||
<Container>
|
||||
<Menu.Item header className={styles.pageTitle}>
|
||||
<Link to="/">OpenBikeSensor</Link>
|
||||
</div>
|
||||
<nav className={styles.menu}>
|
||||
<ul>
|
||||
{login && (
|
||||
<li>
|
||||
<Link to="/upload">
|
||||
</Menu.Item>
|
||||
|
||||
<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>
|
||||
</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">
|
||||
|
||||
<Link to="/settings" component={Menu.Item}>
|
||||
<Avatar user={login} className={styles.avatar} />
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Button as={Link} to="/logout" compact>
|
||||
Logout
|
||||
</Button>
|
||||
</li>
|
||||
</>
|
||||
|
||||
<Link component={Menu.Item} to="/logout">
|
||||
<Button compact>Logout</Button>
|
||||
</Link>
|
||||
</Menu.Menu>
|
||||
) : (
|
||||
<>
|
||||
<li>
|
||||
<Menu.Menu>
|
||||
<Menu.Item>
|
||||
<LoginButton as="a" compact />
|
||||
</li>
|
||||
</>
|
||||
</Menu.Item>
|
||||
</Menu.Menu>
|
||||
)}
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
</Container>
|
||||
</Menu>
|
||||
|
||||
<Switch>
|
||||
<Route path="/" exact>
|
||||
|
@ -111,6 +95,64 @@ const App = connect((state) => ({login: state.login}))(function App({login}) {
|
|||
<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>
|
||||
)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
@import '../../styles.scss';
|
||||
|
||||
.page {
|
||||
@include container;
|
||||
margin-top: 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",
|
||||
"scope": "*",
|
||||
"redirectUri": "http://localhost:3001/redirect"
|
||||
}
|
||||
},
|
||||
"imprintUrl": "https://example.com/imprint",
|
||||
"privacyPolicyUrl": "https://example.com/privacy"
|
||||
}
|
||||
|
|
|
@ -5,5 +5,7 @@
|
|||
"clientId": "CHANGEME",
|
||||
"scope": "*",
|
||||
"redirectUri": "https://example.com/redirect"
|
||||
}
|
||||
},
|
||||
"imprintUrl": "https://example.com/imprint",
|
||||
"privacyPolicyUrl": "https://example.com/privacy"
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
.welcomeMap {
|
||||
height: 60rem;
|
||||
max-height: 80vh;
|
||||
max-height: 70vh;
|
||||
|
||||
@media screen and (max-width: 767px) {
|
||||
margin: -35px -32px 0 -32px;
|
||||
|
|
Loading…
Reference in a new issue