Skip to content

Commit

Permalink
Merge pull request #74 from nachtm/submit-button
Browse files Browse the repository at this point in the history
Fix form usability issues
  • Loading branch information
sayas01 authored Aug 9, 2019
2 parents 36580be + f116704 commit 64d6b8f
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 112 deletions.
5 changes: 5 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 8 additions & 3 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,17 @@ class App extends Component {
};

render() {
const {isMobile} = this.props;
const {isMobile, history} = this.props;
// If we are on the mobile create reports page, show nothing. Otherwise, show either the mobile header or the
// desktop header.
const header = isMobile && history.location.pathname === '/reports/create' ? null : isMobile ? <Header/> : <DesktopHeader/>;
// If we are on mobile, and not on the create reports page, show a footer.
const footer = isMobile && history.location.pathname !== '/reports/create' ? <Footer/> : null;
return (
<div className="App">
{isMobile ? <Header/> : <DesktopHeader/>}
{header}
<Main/>
{isMobile ? <Footer/> : null}
{footer}
</div>
);
}
Expand Down
69 changes: 4 additions & 65 deletions src/components/Footer.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
import React, { Component } from 'react';
import AddIcon from '@material-ui/icons/Add';
import ClearIcon from '@material-ui/icons/Clear';
import MapIcon from '@material-ui/icons/Map';
import SettingsIcon from '@material-ui/icons/Settings';
import Button from '@material-ui/core/Button';
import Fab from '@material-ui/core/Fab';
import Drawer from '@material-ui/core/Drawer';
import { withStyles } from '@material-ui/core/styles';
import { setOnExplore } from '../store/actions';

import Form from './Form';
import { withRouter } from "react-router";
import {connect} from "react-redux";

const styles = theme => ({
list: {
Expand Down Expand Up @@ -57,42 +52,8 @@ const styles = theme => ({
}
});

class Footer extends Component {
state = {
open: false,
};

componentDidMount() {
const { location } = this.props;
if (window.innerWidth < 768 && location.pathname === '/reports/create') {
this.handleDrawer(true);
}
}

toggleDrawer = drawerState => () => {
const { history } = this.props;
const { open } = this.state;

this.setState({
open: drawerState
}, () => {
if (open) {
history.push('/');
} else {
history.push('/reports/create');
}
});
};

handleDrawer = state => {
this.setState({
open: state
});
};

render() {
const { open } = this.state;
const { classes, history, isOnExplore } = this.props;
const Footer = (props) => {
const { classes, history } = props;

return (
<div className={classes.footerIconDiv}>
Expand All @@ -103,24 +64,9 @@ class Footer extends Component {
</Button>
</div>
<div className={classes.flexColumn}>
<Fab color="primary" aria-label="Add" className={classes.plusButton} size="large" onClick={this.toggleDrawer(!open)}>
<Fab color="primary" aria-label="Add" className={classes.plusButton} size={"large"} onClick={() => history.push('/reports/create')}>
<AddIcon/>
</Fab>
<Drawer
anchor="bottom"
open={open}
onClose={this.toggleDrawer(!open)}
className="formWizard"
>
<div tabIndex={0}>
<div>
<Fab color="primary" aria-label="Add" className={classes.fab}>
<ClearIcon onClick={this.toggleDrawer(!open)}/>
</Fab>
</div>
<Form handleDrawerState={this.handleDrawer} fromDrawer/>
</div>
</Drawer>
</div>
<div className={classes.flexColumn}>
<Button className={classes.footerIcons} style={{ float: 'right', marginRight: '50px', color: history.location.pathname==='/resources'?
Expand All @@ -132,13 +78,6 @@ class Footer extends Component {
</div>
</div>
);
}
}

const mapStateToProps = (state) => {
return {
isOnExplore: state.isOnExplore
};
};

export default withRouter(connect(mapStateToProps)(withStyles(styles)(Footer)));
export default withRouter(withStyles(styles)(Footer));
87 changes: 43 additions & 44 deletions src/components/Form.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ import MediaUpload from './MediaUpload';
import FormMap from './FormMap';
import StaticFormMap from './StaticFormMap'
import MediaDisplay from './MediaDisplay';
import FormRadioButtons from './FormRadioButtons';
import NeighborhoodService from '../services/NeighborhoodService';
import {Collapse, Fab, withStyles} from "@material-ui/core";
import ClearIcon from '@material-ui/icons/Clear';
import "react-responsive-carousel/lib/styles/carousel.min.css";
import { Carousel } from 'react-responsive-carousel';
import Info from '@material-ui/icons/InfoOutlined';
Expand Down Expand Up @@ -59,17 +61,17 @@ const DIALOG_MODES = {
ERROR: 'error',
LARGE_FILES: 'largeFiles',
PERMISSION: 'permission',
CLOSED: 'closed'
CLOSED: 'closed',
MISSING_FIELD: 'missing field',
};

const styles = {
allContent: {
height: '100%',
overflow: 'scroll',
position: 'static',
display: 'flex',
flexDirection: 'column',
backgroundColor: 'white'
overlay: {
height: '100vh',
width: '100vw',
position: 'fixed',
top: 0,
zIndex: 999,
},
header: {
display: 'flex',
Expand Down Expand Up @@ -130,9 +132,8 @@ const styles = {
paddingRight: 35,
},
addButtonContainer: {
position: 'absolute',
left: '34%',
top: '15%',
position: 'relative',
top: -250,
zIndex: 0,
},
doneButtonContainer: {
Expand All @@ -146,7 +147,7 @@ const styles = {
},
interactiveMapInnerContainer: {
flex: 1,
}
},
};

//https://github.com/Hacker0x01/react-datepicker/issues/942#issuecomment-485934975
Expand Down Expand Up @@ -259,10 +260,13 @@ class Form extends Component {
.then(response => {
this.setState({submitting: false});
if (response.status === 200) {
this.setState({dialogMode: DIALOG_MODES.THANKS}); // Open the submission recieved dialog
this.setState({dialogMode: DIALOG_MODES.THANKS}); // Open the submission received dialog
} else {
this.setState({dialogMode: DIALOG_MODES.ERROR});
}
})
.catch(err => {
this.setState({submitting: false, dialogMode: DIALOG_MODES.ERROR});
});
};

Expand Down Expand Up @@ -381,6 +385,11 @@ class Form extends Component {
open={true}
onClose={this.handleClose}
message={THANKS_FOR_SUBMITTING}/>;
case DIALOG_MODES.MISSING_FIELD:
return <FormInfoDialog
open={true}
onClose={() => this.setState({dialogMode: DIALOG_MODES.CLOSED})}
message={"Your report is missing some required fields! Please fill in all required fields and re-submit."}/>;
default:
return null;
}
Expand Down Expand Up @@ -433,16 +442,21 @@ class Form extends Component {
const {
mapLat, mapLng, timestamp, confidence, numberOfAdultSpecies,
numberOfYoungSpecies, numberOfAdults, numberOfChildren, reaction, reactionDescription, numberOfDogs, dogSize,
onLeash, animalBehavior, animalEating, vocalization, vocalizationDesc, carnivoreResponse, carnivoreConflict,
onLeash, animalBehavior, animalEating, vocalization, vocalizationDesc, carnivoreResponse, carnivoreConflict,
conflictDesc, contactName, contactEmail, contactPhone, generalComments, media, submitting,
neighborhood, dialogMode, showObserverDetails, showAnimalBehavior, showContactInformation, spinnerActive, addMode,
imagePaths, audioPaths, videoPaths
imagePaths, audioPaths, videoPaths, species
} = this.state;
const {classes, isMobile} = this.props;
const {classes, isMobile, history} = this.props;
return (
<LoadingOverlay active={submitting} spinner text='Submitting...'>
<>
{submitting ? <LoadingOverlay active={submitting} spinner text='Submitting...' className={classes.overlay} />: null}
{isMobile ?
<Fab color="primary" aria-label="Add" className={classes.fab}>
<ClearIcon onClick={() => history.push('/')}/>
</Fab>: null}
<h2>Report a carnivore sighting</h2>
<ValidatorForm onError={errors => console.log(errors)}
<ValidatorForm onError={() => this.setState({dialogMode: DIALOG_MODES.MISSING_FIELD})}
onSubmit={this.handleSubmit}
className="formWizardBody" autoComplete="off">
{this.renderMap(classes, isMobile,neighborhood, mapLng, mapLat)}
Expand Down Expand Up @@ -514,28 +528,13 @@ class Form extends Component {
</Carousel>
</DialogContent>
</Dialog>
{speciesLst.map((type, idx) =>
<span className={isMobile ? classes.radioButtonContainerMobile : "radioButtonContainer"} key={idx}>
<div >
<label >
<input
type="radio"
name="react-tips"
value={type}
onChange={() => this.setState({species: type})}
/>
{type}
</label>
</div>
<div>
<ResizableIconButton
onClick={() => this.openCarousel(idx)}
backgroundColor={'white'}
color={'#4385E9'}>
<Info />
</ResizableIconButton>
</div>
</span>)}
<FormRadioButtons
species={speciesLst}
onChangeSelection={(species) => () => this.setState({species})}
onClickInfo={(index) => () => this.openCarousel(index)}
validators={['required']}
errorMessages={['This field is required']}
value={species}/>
</div>

<div className="formItem">
Expand Down Expand Up @@ -571,7 +570,7 @@ class Form extends Component {
<hr/>

{/*Observer details*/}
<div className={classes.allContent}>
<div>
{/* Species Identification Tips */}
{this.getCollapse(classes, "Observer Details (Optional)", this.toggleShow('showObserverDetails'), showObserverDetails,
<div>
Expand Down Expand Up @@ -659,7 +658,7 @@ class Form extends Component {
<br/>

{/*Animal behavior*/}
<div className={classes.allContent}>
<div>
{/* Species Identification Tips */}
{this.getCollapse(classes, "Animal Behavior (Optional)", this.toggleShow('showAnimalBehavior'), showAnimalBehavior,
<div>
Expand Down Expand Up @@ -768,7 +767,7 @@ class Form extends Component {
<br/>

{/*Contact*/}
<div className={classes.allContent}>
<div>
{/* Species Identification Tips */}
{this.getCollapse(classes, "Contact Information (Optional)", this.toggleShow('showContactInformation'), showContactInformation,
<div>
Expand Down Expand Up @@ -843,7 +842,7 @@ class Form extends Component {
</Button>
</ValidatorForm>
{this.getDialogFromMode(dialogMode)}
</LoadingOverlay>
</>
);
}
}
Expand Down
77 changes: 77 additions & 0 deletions src/components/FormRadioButtons.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { ValidatorComponent } from 'react-material-ui-form-validator';
import ResizableIconButton from "./ResizableIconButton";
import Info from '@material-ui/icons/InfoOutlined';
import React from "react";
import { withStyles } from "@material-ui/core"
import { connect } from "react-redux";

const styles = (theme) => ({
radioButtonContainerMobile: {
display: 'flex',
alignItems: 'baseline',
flexDirection: 'row',
justifyContent: 'space-between',
position: 'relative',
paddingLeft: 35,
paddingRight: 35,
},
radioButtonContainer: {
display: 'flex',
alignItems: 'baseline',
flexDirection: 'row',
justifyContent: 'spaceBetween',
paddingLeft: '35%',
paddingRight: '35%',
position: 'relative'
}
});

class FormRadioButtons extends ValidatorComponent {

render = () => {
const { species, classes, isMobile, onChangeSelection, onClickInfo } = this.props;
return <div>
{this.errorText()}
{species.map((type, idx) =>
<span className={isMobile ? classes.radioButtonContainerMobile : "radioButtonContainer"} key={idx}>
<div >
<label >
<input
type="radio"
name="react-tips"
value={type}
onChange={onChangeSelection(type)}
/>
{type}
</label>
</div>
<div>
<ResizableIconButton
onClick={onClickInfo(idx)}
backgroundColor={'white'}
color={'#4385E9'}>
<Info />
</ResizableIconButton>
</div>
</span>)}
</div>
};

errorText = () => {
const { isValid } = this.state;
if (isValid) {
return null;
}
return (
<div style={{ color: 'red' }}>
{this.getErrorMessage()}
</div>
);
}
}

const mapStateToProps = (state) => {
return {isMobile: state.isMobile};
};

export default withStyles(styles)(connect(mapStateToProps)(FormRadioButtons));

0 comments on commit 64d6b8f

Please sign in to comment.