feat: Add optional banner to frontend via config entry (solves #128)

This commit is contained in:
Paul Bienkowski 2021-12-03 17:31:43 +01:00
parent 99f33aa988
commit 09fe1a7ac0
5 changed files with 38 additions and 5 deletions

View file

@ -37,6 +37,7 @@ FRONTEND_CONFIG = {
"imprintUrl": "https://example.com/imprint", "imprintUrl": "https://example.com/imprint",
"privacyPolicyUrl": "https://example.com/privacy", "privacyPolicyUrl": "https://example.com/privacy",
"mapHome": {"zoom": 6, "longitude": 10.2, "latitude": 51.3}, "mapHome": {"zoom": 6, "longitude": 10.2, "latitude": 51.3},
"banner": {"text": "This is a test installation.", "style": "warning"},
} }
# If the API should serve generated tiles, this is the path where the tiles are # If the API should serve generated tiles, this is the path where the tiles are

View file

@ -1,8 +1,6 @@
@import 'styles.less'; @import 'styles.less';
:global(#root) { :global(#root) {
padding-top: @menuHeight;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: stretch; justify-content: stretch;
@ -72,7 +70,10 @@
} }
} }
.menu { .menu.menu {
flex: 0 0 auto;
margin: 0;
> :global(.ui.container) { > :global(.ui.container) {
height: @menuHeight; height: @menuHeight;
align-items: stretch; align-items: stretch;
@ -81,7 +82,10 @@
align-items: center; align-items: center;
justify-content: center; justify-content: center;
color: white; color: white;
flex: 1 0 auto; border-radius: 0;
border-right: 0;
border-left: 0;
border-top: 0;
ul { ul {
margin: 0; margin: 0;
@ -106,3 +110,20 @@
} }
} }
} }
.banner {
padding: 8px;
z-index: 100;
border-bottom: 1px solid #DDD;
&.warning {
background: #FFD54F;
border-color: #FBC02D;
color: #263238;
}
&.info {
background: #4FC3F7;
border-color: #0D47A1;
color: #0D47A1;
}
}

View file

@ -1,4 +1,5 @@
import React from 'react' import React from 'react'
import classnames from 'classnames'
import {connect} from 'react-redux' import {connect} from 'react-redux'
import {List, Grid, Container, Menu, Header, Dropdown} from 'semantic-ui-react' import {List, Grid, Container, Menu, Header, Dropdown} 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'
@ -50,6 +51,10 @@ function DropdownItemForLink({navigate, ...props}) {
) )
} }
function Banner({text, style = 'warning'}: {text: string, style: 'warning' | 'info'}) {
return <div className={classnames(styles.banner, styles[style])}>{text}</div>
}
const App = connect((state) => ({login: state.login}))(function App({login}) { const App = connect((state) => ({login: state.login}))(function App({login}) {
const config = useConfig() const config = useConfig()
const apiVersion = useObservable(() => from(api.get('/info')).pipe(pluck('version'))) const apiVersion = useObservable(() => from(api.get('/info')).pipe(pluck('version')))
@ -60,7 +65,8 @@ const App = connect((state) => ({login: state.login}))(function App({login}) {
return config ? ( return config ? (
<Router basename={config.basename}> <Router basename={config.basename}>
<Menu fixed="top" className={styles.menu}> {config?.banner && <Banner {...config.banner} />}
<Menu className={styles.menu}>
<Container> <Container>
<Link to="/" component={MenuItemForLink} header className={styles.pageTitle}> <Link to="/" component={MenuItemForLink} header className={styles.pageTitle}>
OpenBikeSensor OpenBikeSensor

View file

@ -3,6 +3,7 @@
.page { .page {
margin-top: 32px; margin-top: 32px;
margin-bottom: 32px; margin-bottom: 32px;
flex: 1 0 auto;
} }
.small { .small {

View file

@ -20,6 +20,10 @@ export interface Config {
obsMapSource?: MapSoure obsMapSource?: MapSoure
imprintUrl?: string imprintUrl?: string
privacyPolicyUrl?: string privacyPolicyUrl?: string
banner?: {
text: string
style?: "warning" | "info"
}
} }
async function loadConfig(): Promise<Config> { async function loadConfig(): Promise<Config> {