display account information

This commit is contained in:
Delucse 2020-12-07 20:12:33 +01:00
parent 80fd3b83a9
commit 646254017c
4 changed files with 180 additions and 9 deletions

34
src/components/Alert.js Normal file
View File

@ -0,0 +1,34 @@
import React, { Component } from 'react';
import { withStyles } from '@material-ui/core/styles';
import { fade } from '@material-ui/core/styles/colorManipulator';
import Typography from '@material-ui/core/Typography';
const styles = (theme) => ({
alert: {
marginBottom: '20px',
border: `1px solid ${theme.palette.primary.main}`,
padding: '10px 20px',
borderRadius: '4px',
background: fade(theme.palette.primary.main, 0.3),
color: 'rgb(70,70,70)'
}
});
export class Alert extends Component {
render(){
return(
<div className={this.props.classes.alert}>
<Typography>
{this.props.children}
</Typography>
</div>
);
}
}
export default withStyles(styles, { withTheme: true })(Alert);

View File

@ -20,6 +20,7 @@ import Settings from '../Settings/Settings';
import Impressum from '../Impressum'; import Impressum from '../Impressum';
import Privacy from '../Privacy'; import Privacy from '../Privacy';
import Login from '../User/Login'; import Login from '../User/Login';
import Account from '../User/Account';
class Routes extends Component { class Routes extends Component {
@ -33,34 +34,37 @@ class Routes extends Component {
<div style={{ margin: '0 22px' }}> <div style={{ margin: '0 22px' }}>
<Switch> <Switch>
<Route path="/" exact component={Home} /> <Route path="/" exact component={Home} />
// Tutorials {/* Tutorials */}
<Route path="/tutorial" exact component={TutorialHome} /> <Route path="/tutorial" exact component={TutorialHome} />
<PrivateRouteCreator path="/tutorial/builder" exact> <PrivateRouteCreator path="/tutorial/builder" exact>
<Builder/> <Builder/>
</PrivateRouteCreator> </PrivateRouteCreator>
<Route path="/tutorial/:tutorialId" exact component={Tutorial} /> <Route path="/tutorial/:tutorialId" exact component={Tutorial} />
// Sharing {/* Sharing */}
<Route path="/share/:shareId" exact component={Project} /> <Route path="/share/:shareId" exact component={Project} />
// Gallery-Projects {/* Gallery-Projects */}
<Route path="/gallery" exact component={ProjectHome} /> <Route path="/gallery" exact component={ProjectHome} />
<Route path="/gallery/:galleryId" exact component={Project} /> <Route path="/gallery/:galleryId" exact component={Project} />
// User-Projects {/* User-Projects */}
<PrivateRoute path="/project" exact> <PrivateRoute path="/project" exact>
<ProjectHome/> <ProjectHome/>
</PrivateRoute> </PrivateRoute>
<PrivateRoute path="/project/:projectId" exact> <PrivateRoute path="/project/:projectId" exact>
<Project/> <Project/>
</PrivateRoute> </PrivateRoute>
// User {/* User */}
<IsLoggedRoute path="/user/login" exact> <IsLoggedRoute path="/user/login" exact>
<Login /> <Login />
</IsLoggedRoute> </IsLoggedRoute>
// settings <PrivateRoute path="/user" exact>
<Account/>
</PrivateRoute>
{/* settings */}
<Route path="/settings" exact component={Settings} /> <Route path="/settings" exact component={Settings} />
// privacy {/* privacy */}
<Route path="/impressum" exact component={Impressum} /> <Route path="/impressum" exact component={Impressum} />
<Route path="/privacy" exact component={Privacy} /> <Route path="/privacy" exact component={Privacy} />
// Not Found {/* Not Found */}
<Route component={NotFound} /> <Route component={NotFound} />
</Switch> </Switch>
</div> </div>

View File

@ -0,0 +1,129 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import Breadcrumbs from '../Breadcrumbs';
import Alert from '../Alert';
import Grid from '@material-ui/core/Grid';
import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
import ListItemIcon from '@material-ui/core/ListItemIcon';
import ListItemText from '@material-ui/core/ListItemText';
import Divider from '@material-ui/core/Divider';
import Paper from '@material-ui/core/Paper';
import Link from '@material-ui/core/Link';
import Typography from '@material-ui/core/Typography';
import Tooltip from '@material-ui/core/Tooltip';
import { faUser, faAt, faMapMarkerAlt, faCloudSunRain, faBox } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
export class Account extends Component {
render(){
const {user} = this.props;
return(
<div>
<Breadcrumbs content={[{ link: '/user', title: 'Account' }]} />
<h1>Account</h1>
<Alert>
Alle Angaben stammen von <Link color='primary' rel="noreferrer" target="_blank" href={'https://opensensemap.org/'}>openSenseMap</Link> und können dort verwaltet werden.
</Alert>
<Paper style={{width: 'max-content', maxWidth: '100%'}}>
<List>
<ListItem>
<Tooltip title='Nutzername'>
<ListItemIcon>
<FontAwesomeIcon icon={faUser} />
</ListItemIcon>
</Tooltip>
<ListItemText primary={user.name} />
</ListItem>
<ListItem>
<Tooltip title='Email'>
<ListItemIcon>
<FontAwesomeIcon icon={faAt} />
</ListItemIcon>
</Tooltip>
<ListItemText primary={user.email} />
</ListItem>
</List>
</Paper>
<Divider style={{marginBottom: '16px', marginTop: '16px'}}/>
<div style={{marginBottom: '8px'}}>
{this.props.user.boxes.length < 1 ?
<Typography>
Du hast noch keine senseBox registriert. Besuche <Link color='primary' rel="noreferrer" target="_blank" href={'https://opensensemap.org/'}>openSenseMap</Link> um eine senseBox zu registrieren.
</Typography>
: <Typography style={{fontWeight: 'bold', fontSize: '1.1rem'}}>
Du hast {this.props.user.boxes.length} {this.props.user.boxes.length === 1 ? 'senseBox' : 'senseBoxen'} registriert:
</Typography>}
</div>
<Grid container spacing={2}>
{this.props.user.boxes.map((box, i) => {
var sensors = box.sensors.map(sensor => sensor.title );
return (
<Grid item xs={12} sm={6} md={4} xl={3} key={i}>
<Link rel="noreferrer" target="_blank" href={`https://opensensemap.org/explore/${box._id}`} color="primary" style={{ textDecoration: 'none', color: 'inherit' }}>
<Paper>
<List>
<ListItem>
<Typography style={{fontWeight: 'bold', fontSize: '1.6rem'}}>{box.name}</Typography>
</ListItem>
<ListItem>
<Tooltip title='Modell'>
<ListItemIcon>
<FontAwesomeIcon icon={faBox} />
</ListItemIcon>
</Tooltip>
<div>
<Typography style={{fontWeight: 'bold', marginRight: '4px'}}>Modell: </Typography>
<Typography>{box.model}</Typography>
</div>
</ListItem>
<ListItem>
<Tooltip title='Standort'>
<ListItemIcon>
<FontAwesomeIcon icon={faMapMarkerAlt} />
</ListItemIcon>
</Tooltip>
<div>
<Typography style={{fontWeight: 'bold', marginRight: '4px'}}>Standort: </Typography>
<Typography>{`${box.exposure} (lon: ${box.currentLocation.coordinates[0]}, lat: ${box.currentLocation.coordinates[1]})`}</Typography>
</div>
</ListItem>
<ListItem>
<Tooltip title='Sensoren'>
<ListItemIcon>
<FontAwesomeIcon icon={faCloudSunRain} />
</ListItemIcon>
</Tooltip>
<div>
<Typography style={{fontWeight: 'bold', marginRight: '4px'}}>Sensoren: </Typography>
<Typography>{sensors.join(', ')}</Typography>
</div>
</ListItem>
</List>
</Paper>
</Link>
</Grid>
)
})}
</Grid>
</div>
);
}
}
Account.propTypes = {
user: PropTypes.object.isRequired
};
const mapStateToProps = state => ({
user: state.auth.user
});
export default connect(mapStateToProps, null)(Account);

View File

@ -7,6 +7,7 @@ import { clearMessages } from '../../actions/messageActions'
import { withRouter } from 'react-router-dom'; import { withRouter } from 'react-router-dom';
import Snackbar from '../Snackbar'; import Snackbar from '../Snackbar';
import Alert from '../Alert';
import Breadcrumbs from '../Breadcrumbs'; import Breadcrumbs from '../Breadcrumbs';
import Button from '@material-ui/core/Button'; import Button from '@material-ui/core/Button';
@ -89,6 +90,9 @@ export class Login extends Component {
<div style={{maxWidth: '500px', marginLeft: 'auto', marginRight: 'auto'}}> <div style={{maxWidth: '500px', marginLeft: 'auto', marginRight: 'auto'}}>
<h1>Anmelden</h1> <h1>Anmelden</h1>
<Alert>
Zur Anmeldung ist ein Konto auf <Link color='primary' rel="noreferrer" target="_blank" href={'https://opensensemap.org/'}>openSenseMap</Link> Voraussetzung.
</Alert>
<Snackbar <Snackbar
open={this.state.snackbar} open={this.state.snackbar}
message={this.state.message} message={this.state.message}
@ -140,7 +144,7 @@ export class Login extends Component {
</p> </p>
<Divider variant='fullWidth'/> <Divider variant='fullWidth'/>
<p style={{textAlign: 'center', paddingRight: "34px", paddingLeft: "34px"}}> <p style={{textAlign: 'center', paddingRight: "34px", paddingLeft: "34px"}}>
Du hast noch kein Konto? <Link rel="noreferrer" target="_blank" href={'https://opensensemap.org/'}>Registrieren</Link> Du hast noch kein Konto? Registriere dich auf <Link rel="noreferrer" target="_blank" href={'https://opensensemap.org/'}>openSenseMap</Link>.
</p> </p>
</div> </div>
</div> </div>