all repos — caroster @ 01806da3fda7779fff57d70b67c1f6828b033a1e

[Octree] Group carpool to your event https://caroster.io

Fix car creation form accessibility. Autofocus issue (should focus on name and not on phone). Cancel should be out of keyboard flow (ESQ close the form). Form Actions have id. Related to #14
Hadrien Froger hadrien@octree.ch
Thu, 02 Jul 2020 08:51:34 +0100
commit

01806da3fda7779fff57d70b67c1f6828b033a1e

parent

6eb6aa7b98abe986421fe3c6d3416861c9d7f3f5

1 files changed, 121 insertions(+), 112 deletions(-)

jump to
M app/src/containers/NewCarDialog/index.jsapp/src/containers/NewCarDialog/index.js

@@ -1,49 +1,50 @@

-import React, { useState } from "react"; -import Dialog from "@material-ui/core/Dialog"; -import DialogActions from "@material-ui/core/DialogActions"; -import DialogContent from "@material-ui/core/DialogContent"; -import DialogContentText from "@material-ui/core/DialogContentText"; -import DialogTitle from "@material-ui/core/DialogTitle"; -import Button from "@material-ui/core/Button"; -import Slide from "@material-ui/core/Slide"; -import moment from "moment"; -import { useStrapi } from "strapi-react-context"; -import { useTranslation } from "react-i18next"; -import TextField from "@material-ui/core/TextField"; -import Slider from "@material-ui/core/Slider"; -import Typography from "@material-ui/core/Typography"; -import { makeStyles } from "@material-ui/core/styles"; -import { DateTimePicker } from "@material-ui/pickers"; -import { useToast } from "../../contexts/Toast"; -import { useEvent } from "../../contexts/Event"; +import React, {useState} from 'react'; +import Dialog from '@material-ui/core/Dialog'; +import DialogActions from '@material-ui/core/DialogActions'; +import DialogContent from '@material-ui/core/DialogContent'; +import DialogContentText from '@material-ui/core/DialogContentText'; +import DialogTitle from '@material-ui/core/DialogTitle'; +import Button from '@material-ui/core/Button'; +import Slide from '@material-ui/core/Slide'; +import moment from 'moment'; +import {useStrapi} from 'strapi-react-context'; +import {useTranslation} from 'react-i18next'; +import TextField from '@material-ui/core/TextField'; +import Slider from '@material-ui/core/Slider'; +import Typography from '@material-ui/core/Typography'; +import {makeStyles} from '@material-ui/core/styles'; +import {DateTimePicker} from '@material-ui/pickers'; +import {useToast} from '../../contexts/Toast'; +import {useEvent} from '../../contexts/Event'; const Transition = React.forwardRef(function Transition(props, ref) { return <Slide direction="up" ref={ref} {...props} />; }); -const marks = [1, 2, 3, 4, 5, 6, 7, 8].map((value) => ({ +const marks = [1, 2, 3, 4, 5, 6, 7, 8].map(value => ({ value, label: value, })); -const NewCarDialog = ({ open, toggle }) => { +const NewCarDialog = ({open, toggle}) => { const strapi = useStrapi(); - const { t } = useTranslation(); + const {t} = useTranslation(); const classes = useStyles(); - const { addToast } = useToast(); - const { event } = useEvent(); + const {addToast} = useToast(); + const {event} = useEvent(); // States - const [name, setName] = useState(""); + const [name, setName] = useState(''); const [seats, setSeats] = useState(4); - const [meeting, setMeeting] = useState(""); + const [meeting, setMeeting] = useState(''); const [date, setDate] = useState(moment()); - const [phone, setPhone] = useState(""); - const [details, setDetails] = useState(""); + const [phone, setPhone] = useState(''); + const [details, setDetails] = useState(''); const canCreate = !!name && !!seats; - const onCreate = async () => { + const onCreate = async event => { + if (event.preventDefault) event.preventDefault(); try { await strapi.services.cars.create({ name,

@@ -54,14 +55,13 @@ phone_number: phone,

details, event: event.id, }); - addToast(t("car.creation.created")); + addToast(t('car.creation.created')); toggle(); - return true; } catch (error) { console.error(error); - addToast(t("car.errors.cant_create")); - return false; + addToast(t('car.errors.cant_create')); } + return false; }; return (

@@ -72,90 +72,99 @@ onClose={toggle}

fullWidth maxWidth="sm" > - <DialogTitle>{t("car.creation.title")}</DialogTitle> - <DialogContent> - <DialogContentText> - <TextField - className={classes.textField} - label={t("car.creation.name")} - fullWidth - autoFocus - margin="dense" - value={name} - onChange={(e) => setName(e.target.value)} - id="NewCarName" - name="name" - /> - <Typography variant="caption">{t("car.creation.seats")}</Typography> - <Slider - value={seats} - onChange={(e, value) => setSeats(value)} - step={1} - marks={marks} - min={1} - max={marks.length} - valueLabelDisplay="auto" - /> - <TextField - className={classes.textField} - label={t("car.creation.meeting")} - fullWidth - margin="dense" - multiline - rows={2} - value={meeting} - onChange={(e) => setMeeting(e.target.value)} - id="NewCarMeeting" - name="meeting" - /> - <DateTimePicker - label={t("event.creation.date")} - value={date} - onChange={setDate} - className={classes.textField} - fullWidth - format="LLLL" - disablePast - id="NewCarDateTime" - name="date" - /> - <TextField - className={classes.textField} - label={t("car.creation.phone")} - fullWidth - autoFocus - margin="dense" - value={phone} - onChange={(e) => setPhone(e.target.value)} - id="NewCarPhone" - name="phone" - /> - <TextField - className={classes.textField} - label={t("car.creation.notes")} - fullWidth - margin="dense" - multiline - rows={2} - value={details} - onChange={(e) => setDetails(e.target.value)} - id="NewCarDetails" - name="details" - /> - </DialogContentText> - </DialogContent> - <DialogActions> - <Button onClick={toggle}>{t("generic.cancel")}</Button> - <Button variant="contained" onClick={onCreate} disabled={!canCreate}> - {t("generic.create")} - </Button> - </DialogActions> + <form onSubmit={onCreate}> + <DialogTitle>{t('car.creation.title')}</DialogTitle> + <DialogContent> + <DialogContentText> + <TextField + className={classes.textField} + label={t('car.creation.name')} + fullWidth + autoFocus + margin="dense" + value={name} + onChange={e => setName(e.target.value)} + id="NewCarName" + name="name" + /> + <Typography variant="caption">{t('car.creation.seats')}</Typography> + <Slider + value={seats} + onChange={(e, value) => setSeats(value)} + step={1} + marks={marks} + min={1} + max={marks.length} + valueLabelDisplay="auto" + /> + <TextField + className={classes.textField} + label={t('car.creation.meeting')} + fullWidth + margin="dense" + multiline + rows={2} + value={meeting} + onChange={e => setMeeting(e.target.value)} + id="NewCarMeeting" + name="meeting" + /> + <DateTimePicker + label={t('event.creation.date')} + value={date} + onChange={setDate} + className={classes.textField} + fullWidth + format="LLLL" + disablePast + id="NewCarDateTime" + name="date" + /> + <TextField + className={classes.textField} + label={t('car.creation.phone')} + fullWidth + margin="dense" + value={phone} + onChange={e => setPhone(e.target.value)} + id="NewCarPhone" + name="phone" + /> + <TextField + className={classes.textField} + label={t('car.creation.notes')} + fullWidth + margin="dense" + multiline + rows={2} + value={details} + onChange={e => setDetails(e.target.value)} + id="NewCarDetails" + name="details" + /> + </DialogContentText> + </DialogContent> + <DialogActions> + <Button id="NewCarCancel" onClick={toggle} tabIndex={-1}> + {t('generic.cancel')} + </Button> + <Button + variant="contained" + type="submit" + disabled={!canCreate} + aria-disabled={!canCreate} + id="NewCarSubmit" + > + {t('generic.create')} + </Button> + </DialogActions> + </form> </Dialog> ); }; -const useStyles = makeStyles((theme) => ({ - textField: { marginBottom: theme.spacing(2) }, +const useStyles = makeStyles(theme => ({ + textField: {marginBottom: theme.spacing(2)}, })); export default NewCarDialog;