I have an array of football matches that I'll like users to enter their predictions. The issue I'm facing is that I'm unable to get save this form into an array.
Here is the visual look of the form.
Current form output
Here's my react code
import React, { useEffect, useState } from 'react';
import { Row, Col } from 'antd';
import moment from 'moment';
import { PredictTag, PotTitle, AmountInput } from '../../styles/styling';
import { Form, Container } from 'react-bootstrap';
import { produce } from "immer";
const StakeForm = (props) => {
const { potter } = props;
const [inputList, setInputList] = useState([
]);
const pots = potter.pot.findPot.pot;
useEffect(() => {
pots.slice(0, 4).map(() => {
setInputList(currentInput => [{
pot: {home_score: '', away_score: ''}
}
]);
})
},[]);
return (
<Container>
<Row justify="space-around" align="middle">
<Col span={12}><PotTitle>{potter.pot.findPot.pot_name}</PotTitle></Col>
<Col span={12} className="mt-2">
<PredictTag>Home</PredictTag>
<PredictTag>Away</PredictTag>
</Col>
</Row>
<Form>
{pots.map(({_id, home_team, away_team, date, time}) => (
<Row justify="space-around" align="middle" key={_id}>
<Col span={12}>
<h6>{home_team} vs {away_team}</h6>
<p>{moment(date).format("MMM Do, YYYY")} | {moment(time).format('LT')}</p>
</Col>
<Col span={12}>
{inputList.map((item, index) => (
<Container key={index}>
<Row>
<Col span={12}>
<Form.Group controlId="home" style={{ width: 100, }}>
<Form.Control as="select"
onChange={(e) => {
const home_score = e.target.value;
setInputList((currentInput) =>
produce(currentInput, (v) => {
v[index].pot.home_score = home_score;
})
)}}
>
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
</Form.Control>
</Form.Group>
</Col>
<Col span={12}>
<Form.Group controlId="away" style={{ width: 100, float: 'left' }}>
<Form.Control as="select"
onChange={(e) => {
const away_score = e.target.value;
setInputList((currentInput) =>
produce(currentInput, (v) => {
v[index].pot.away_score = away_score;
})
)}}
>
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
</Form.Control>
</Form.Group>
</Col>
</Row>
</Container>
))}
</Col>
</Row>
))}
<pre>{JSON.stringify(inputList, null, 2)}</pre>
</Form>
</Container>
);
};
export default StakeForm;
Currently, all home_score and away_score fields only return a single output rather than creating an object for each of the matches. Please do help me on this.
Related
I want to save the progress state of Mobile Stepper, so that when user logged out, the user can resume from the place where he left. If progress bar is filled 2% then when next time the user login he should resume from 2% not from 0.
Here is the code:
import React, { useState, useReducer, useEffect } from "react";
import { Button, Typography, Grid, CircularProgress, Paper } from '#mui/material/';
import guardianOptions from '../../../constants/guardianOptions.js';
import studentClasses from '../../../constants/studentClasses.js';
import Stepper from '#mui/material/Stepper';
import Step from '#mui/material/Step';
import StepLabel from '#mui/material/StepLabel';
import MobileStepper from '#mui/material/MobileStepper';
import StepContent from '#mui/material/StepContent';
import { makeStyles, withStyles, createStyles } from '#mui/styles';
import { purple } from '#mui/material/colors';
import TextField from '#mui/material/TextField';
import useStyles from './styles';
import InputLabel from '#mui/material/InputLabel';
import MenuItem from '#mui/material/MenuItem';
import FormHelperText from '#mui/material/FormHelperText';
import FormControl from '#mui/material/FormControl';
import Select from '#mui/material/Select';
const User= (props) => {
const { activeStep: lastActiveStep, userId } = props;
const classes = useStyles();
const [guardianType, setGuardianType] = useState(0);
const [activeStep, setActiveStep] = useState(lastActiveStep || 0);
const [guardianRelationOptions, setGuardianRelationOptions] = useState(0);
const [guardianDetailsForm, setGuardianDetailsForm] = useReducer(
(state, newState) => ({ ...state, ...newState }),
{}
);
const [studentDetailsForm, setStudentDetailsForm] = useReducer(
(state, newState) => ({ ...state, ...newState }),
{ s_firstName: '', s_lastName: '', s_age: '', s_class: '' }
);
React.useEffect(() => {
async function updateActiveStep() {
// this is just pseudo code - whatever your endpoint looks like
await window.fetch('http://localhost:8080/api/user/:userId', {
method: 'PUT',
body: JSON.stringify({activeStep})
})
}
updateActiveStep()
}, [activeStep]);
function getSteps(){
return [<b style={{color:'purple'}}>'Personal Details'</b>,
<b style={{color:'purple'}}>'Relation'</b>,
<b style={{color:'purple'}}>'Guardian Details'</b>];
}
const steps = getSteps();
function onGuardianTypeChangeChange(event) {
// setAge(event.target.value);
setGuardianType(event.target.value);
let _guardianRelationOptions = guardianOptions.find(options => options.value === event.target.value);
setGuardianRelationOptions(_guardianRelationOptions.relationships);
}
const handleGuardianDeatilsInput = evt => {
const name = evt.target.name;
const newValue = evt.target.value;
setGuardianDetailsForm({ [name]: newValue });
};
const handleGuardianDetailsSubmit = evt => {
evt.preventDefault();
let data = { guardianDetailsForm };
props.onGuardianDetails(guardianDetailsForm)
console.log(data + "new user");
// console.log( props.onGuardianDetails(guardianDetailsForm) + "gana bajao");
setActiveStep((prevActiveStep) => prevActiveStep+1);
setGuardianDetailsForm();
}
function getStepContent(step) {
switch (step) {
case 0: if (!props.user.s_firstName) {
return (<div>
<form id ="form-step0" className={classes.root} onSubmit={handleGuardianDetailsSubmit} noValidate autoComplete="off">
<TextField
id="outlined-basic"
name="s_firstName"
label="First Name"
variant="outlined"
defaultValue={guardianDetailsForm.s_firstName}
onChange={handleGuardianDeatilsInput} />
<TextField
id="outlined-basic"
name="s_lastName"
label="Last Name"
variant="outlined"
defaultValue={guardianDetailsForm.s_lastName}
onChange={handleGuardianDeatilsInput} />
<TextField
id="outlined-number"
label="Age"
name="s_age"
defaultValue={guardianDetailsForm.s_age}
type="number"
InputLabelProps={{
shrink: true,
}}
onChange={handleGuardianDeatilsInput}
variant="outlined"
/>
<FormControl variant="outlined" className={classes.formControl}
sx={{ m: 1, minWidth: 120 }}>
<InputLabel id="demo-simple-select-outlined-label">Class</InputLabel>
<Select
labelId="demo-simple-select-outlined-label"
id="demo-simple-select-outlined"
value={guardianDetailsForm.s_class}
onChange={handleGuardianDeatilsInput}
label="Class"
name="s_class"
>
{studentClasses.map(c =>
<MenuItem key={c.value} value={c.value}>{c.name}</MenuItem>
)}
</Select>
{/* <Button variant="contained" type="submit" color="primary" >NEXT</Button> */}
</FormControl>
</form>
</div> )}
;
case 1: if (!props.user.g_relationship) {
return ( <div>
<form id="form-step1" className={classes.root} onSubmit={handleGuardianDetailsSubmit} noValidate autoComplete="off">
<FormControl variant="outlined" className={classes.formControl}
sx={{ m: 1, minWidth: 120 }}>
<InputLabel id="demo-simple-select-outlined-label">Relationship</InputLabel>
<Select
labelId="demo-simple-select-outlined-label"
id="demo-simple-select-outlined"
onChange={onGuardianTypeChangeChange}
label="Relationship"
>
{guardianOptions.map(type =>
<MenuItem key={type.value} value={type.value}>{type.name}</MenuItem>
)}
</Select>
</FormControl>
{guardianRelationOptions ?
<FormControl variant="outlined" className={classes.formControl}
sx={{ m: 1, minWidth: 120 }}>
<InputLabel id="demo-simple-select-outlined-label">Relation</InputLabel>
<Select
labelId="demo-simple-select-outlined-label"
id="demo-simple-select-outlined"
// value={age}
name="g_relationship"
value={guardianDetailsForm.g_relationship}
onChange={handleGuardianDeatilsInput}
label="Relation"
>
{guardianRelationOptions.map(type =>
<MenuItem key={type.value} value={type.value}>{type.name}</MenuItem>
)}
</Select>
</FormControl> : null
}
{!g_relationship} onClick={() => props.onGuardianDetails({g_relationship})}>NEXT</Button> */}
{/* <Button variant="contained" color="primary" type="submit">NEXT</Button> */}
</form>
</div> )}
;
case 2:
return ( <div>
<form id="form-step2" className={classes.root} onSubmit={handleGuardianDetailsSubmit} noValidate autoComplete="off">
<TextField
id="outlined-basic"
name="g_firstName"
label="First Name"
variant="outlined"
defaultValue={guardianDetailsForm.g_firstName}
onChange={handleGuardianDeatilsInput} />
<TextField
id="outlined-basic"
name="g_lastName"
label="Last Name"
variant="outlined"
defaultValue={guardianDetailsForm.g_lastName}
onChange={handleGuardianDeatilsInput} />
<TextField
id="outlined-number"
label="Age"
name="g_age"
defaultValue={guardianDetailsForm.g_age}
type="number"
InputLabelProps={{
shrink: true,
}}
onChange={handleGuardianDeatilsInput}
variant="outlined"
/>
</form>
</div>)
;
default:
return 'welcome lets fill the progress.' ;
}
}
return (
<div className={classes.root} align="center">
<div className = {classes.actionsContainer}>
<Paper square elevation={0}>
<Typography>{getStepContent(activeStep)}</Typography>
</Paper>
<MobileStepper
variant="progress"
steps= {4}
position="bottom"
activeStep={activeStep}
sx={{ minWidth: 400, flexGrow: 1 }}
nextButton={
<>
<Button size="small" onClick={handleGuardianDetailsSubmit} type="submit"
form={`form-step${activeStep}`}>
{activeStep === steps.length-1? 'Finish' : 'Next'}
</Button>
</>
}
/>
</div>
</div>
);
}
export default User;
If user refreshes or reload the page, he should see the progress from where he has left.
#Tanya
So you are saying that your user can authorize. When this happens do you receive any data about the user? Can you update the user data via POST or PUT request? If so, I'd store the active step with this data.
Assuming you have some user data that you receive when the user signs in:
// user - user data
export default function BuildAdStepper({user}) {
const { activeStep: lastActiveStep, userId } = user
const classes = useStyles();
const theme = useTheme();
const [activeStep, setActiveStep] = React.useState(lastActiveStep || 0);
React.useEffect(() => {
async function updateActiveStep() {
// this is just pseudo code - whatever your endpoint looks like
await window.fetch('/yourEndpoint/:userId', {
method: 'PUT',
body: JSON.stringify({activeStep})
})
}
updateActiveStep()
}, [activeStep])
/* ... rest of your component * /
}
Is there any way to use mobile image different from the desktop mode in react slick slider? I can use display none for breakpoints but what I want to learn, Is there any different way to do it?
const Hero = () => {
const classes = useStyle();
const { push } = useRouter();
const [sliderState, setSliderState] = useState(heroSliderData);
const [my_swiper, set_my_swiper] = useState({});
return (
<section className={classes.section}>
<Grid style={{ width:"100%", padding: "0px" }}>
<Swiper
loop={true}
navigation={true}
onInit={(ev) => {
set_my_swiper(ev);
}}
>
{sliderState.map(({ id, mainheading, mainheading2, subheading, subheading2, buttontext, image }) => (
<SwiperSlide key={id}>
<Grid item className={classes.hero}>
<img className={classes.heroimg} src={image} style={{ position:"relative"}} />
<Grid item xs={12} style={{ position:"absolute", top:"30%", left:"0", right:"0", textAlign: "center" }}>
<Typography variant="h1" className={classes.h1}>
{mainheading}<br />
{mainheading2}
</Typography>
</Grid>
<Grid item xs={12} style={{ position:"absolute", top:"42%", left:"0", right:"0", textAlign: "center" }}>
<Typography variant="h2" className={classes.h2}>
{subheading}
<br/>
{subheading2}
</Typography>
</Grid>
<Grid item xs={12} style={{ position:"absolute", top:"52%", left:"0", right:"0", textAlign: "center" }}>
<Button
variant="contained"
onClick={() => push("/teklif-al")}
className={classes.teklifal}
>
{buttontext}
</Button>
</Grid>
</Grid>
</SwiperSlide>
))}
</Swiper>
</Grid>
</section>
);
};
This is my code that I am working on it
Have you tried to use an IF clause to show and hide images?
See docs of React Slick.
import React, { Component } from "react";
import Slider from "react-slick";
export default class MultipleItems extends Component {
render() {
const settings = {
dots: true,
infinite: true,
speed: 500,
slidesToShow: 3,
slidesToScroll: 3
};
return (
<div>
<h2> Multiple items </h2>
<Slider {...settings}>
<div>
<h3>1</h3>
</div>
<div>
<h3>2</h3>
</div>
<div>
<h3>3</h3>
</div>
<div>
<h3>4</h3>
</div>
<div>
<h3>5</h3>
</div>
<div>
<h3>6</h3>
</div>
<div>
<h3>7</h3>
</div>
<div>
<h3>8</h3>
</div>
<div>
<h3>9</h3>
</div>
</Slider>
</div>
);
}
}
And modify like this:
import React, { Component } from "react";
import Slider from "react-slick";
export default class MultipleItems extends Component {
const showOnMobile = document.innerWidth < 769;
render() {
const settings = {
dots: true,
infinite: true,
speed: 500,
slidesToShow: 3,
slidesToScroll: 3
};
return (
<div>
<h2> Multiple items </h2>
<Slider {...settings}>
{showOnMobile &&
<div>
<h3>1</h3>
</div>
}
<div>
<h3>2</h3>
</div>
<div>
<h3>3</h3>
</div>
<div>
<h3>4</h3>
</div>
<div>
<h3>5</h3>
</div>
<div>
<h3>6</h3>
</div>
<div>
<h3>7</h3>
</div>
<div>
<h3>8</h3>
</div>
<div>
<h3>9</h3>
</div>
</Slider>
</div>
);
}
}
Below is my code, my problem is, the results are displaying at the bottom one by one like this:
1
2
3
I want to display each output result as follows? as 3 column
1 2 3
4 5 so on......
I have used https://react-bootstrap.github.io/components/cards/ component to display the database output
{Mylist.length && Mylist.map((item, index) => {
return (
<Card key={index} style={{ width: '18rem' }}>
<Card.Body>
<Card.Subtitle className="mb-2 text-muted">{moment(item.date_time).format('LLL')}</Card.Subtitle>
<Card.Text>{item.content}</Card.Text>
<Button variant="danger" size="sm" data-id={item.id} onClick={() => remove(item.id)} >Delete</Button>{' '}
</Card.Body>
</Card>
)
})}
Try the following approach, see more at https://react-bootstrap.netlify.app/components/cards/#card-groups
<Row xs={1} md={2} className="g-3">
{Mylist.length && Mylist.map((item, index) => {
return (
<Col key={index}>
<Card style={{ width: '18rem' }}>
<Card.Body>
<Card.Subtitle className="mb-2 text-muted">{moment(item.date_time).format('LLL')}</Card.Subtitle>
<Card.Text>{item.content}</Card.Text>
<Button variant="danger" size="sm" data-id={item.id} onClick={() => remove(item.id)} >Delete</Button>{' '}
</Card.Body>
</Card>
</Col>
)
})}
</Row>
I want to make it necessary to mark the React js checkbox component. I want to show warning icon when Checkbox is not selected. How can I do that? I shared the component I wrote below.
React checkbox component
const CheckBox = ({
question,
formKey,
valid = true,
validationError = 'Field is required',
}) => {
const dispatch = useDispatch()
const reduxValue = useSelector(state => state.app.forms.f3[formKey].value)
const isSaved = useSelector(state => state.app.forms.f3[formKey].saved)
const [input, setInput] = useState({
value: reduxValue,
valid: true,
})
return (
<>
<Row>
<Col className="col-1">
<label className="orange-checkbox-container">
<input
type="checkbox"
name={formKey}
onChange={(e) => changeSelected(e)}
checked={input.value}
/>
<span className="checkmark"></span>
</label>
</Col>
<Col className="col-11">
<p>{question}</p>
</Col>
</Row>
<div
className="invalid-feedback"
style={{
width: '8rem',
}}
>
{validationError}
</div>
</>
);
}
I will improve on Han's answer. You should hide the whole div if there the checkbox was selected. I improved how the onChange works and separated states. Using hooks you can separate your state values rather than the approach used in classes where you have 1 object this.state = {} to manage the whole state of that component.
const CheckBox = ({
question,
formKey,
// valid = true,
validationError = 'Field is required',
}) => {
const dispatch = useDispatch();
const reduxValue = useSelector(state => state.app.forms.f3[formKey].value);
const isSaved = useSelector(state => state.app.forms.f3[formKey].saved);
const [checked, setChecked] = useState(reduxValue);
const [valid, setValid] = useState(true);
const handleCheckedChange = event => {
setChecked(event.target.checked);
}
return (
<>
<Row>
<Col className="col-1">
<label className="orange-checkbox-container">
<input
type="checkbox"
name={formKey}
onChange={handleCheckedChange}
checked={checked}
/>
<span className="checkmark"></span>
</label>
</Col>
<Col className="col-11">
<p>{question}</p>
</Col>
</Row>
{!checked &&
<div
className="invalid-feedback"
style={{
width: '8rem',
}}
>
{validationError}
</div>
}
</>
);
}
First you should declare the initial state of valid to false and display validationError if input.value is false I assume your onChange is changing the input.value.
const [input, setInput] = useState({
value: reduxValue,
valid: false,
})
<div
className='invalid-feedback'
style={{
width: '8rem',
}}
>
{!input.value && validationError}
</div>
I recently started learning about the Material UI. To develop a basic website structure while checking the basic template code.
However, certain items in the menu bar are not on the right side as in the example. I have taken most of the code as is and merged it, and I wonder why it doesn't move to the right.
CodeSandBox URL
Here's my full code but it seems quite long so I also add codesandbox URL
Full Code
import React from "react";
import clsx from "clsx";
import { makeStyles, useTheme } from "#material-ui/core/styles";
import Drawer from "#material-ui/core/Drawer";
import CssBaseline from "#material-ui/core/CssBaseline";
import AppBar from "#material-ui/core/AppBar";
import Toolbar from "#material-ui/core/Toolbar";
import List from "#material-ui/core/List";
import Typography from "#material-ui/core/Typography";
import Divider from "#material-ui/core/Divider";
import IconButton from "#material-ui/core/IconButton";
import MenuIcon from "#material-ui/icons/Menu";
import ChevronLeftIcon from "#material-ui/icons/ChevronLeft";
import ChevronRightIcon from "#material-ui/icons/ChevronRight";
import ListItem from "#material-ui/core/ListItem";
import ListItemIcon from "#material-ui/core/ListItemIcon";
import ListItemText from "#material-ui/core/ListItemText";
import InboxIcon from "#material-ui/icons/MoveToInbox";
import MailIcon from "#material-ui/icons/Mail";
import Badge from "#material-ui/core/Badge";
import Menu from "#material-ui/core/Menu";
import MenuItem from "#material-ui/core/MenuItem";
import NotificationsIcon from "#material-ui/icons/Notifications";
import AccountCircle from "#material-ui/icons/AccountCircle";
import MoreIcon from "#material-ui/icons/MoreVert";
const drawerWidth = 240;
const useStyles = makeStyles(theme => ({
root: {
display: "flex"
},
appBar: {
transition: theme.transitions.create(["margin", "width"], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen
})
},
appBarShift: {
width: `calc(100% - ${drawerWidth}px)`,
marginLeft: drawerWidth,
transition: theme.transitions.create(["margin", "width"], {
easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.enteringScreen
})
},
menuButton: {
marginRight: theme.spacing(2)
},
hide: {
display: "none"
},
drawer: {
width: drawerWidth,
flexShrink: 0
},
drawerPaper: {
width: drawerWidth
},
drawerHeader: {
display: "flex",
alignItems: "center",
padding: theme.spacing(0, 1),
...theme.mixins.toolbar,
justifyContent: "flex-end"
},
content: {
flexGrow: 1,
padding: theme.spacing(3),
transition: theme.transitions.create("margin", {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen
}),
marginLeft: -drawerWidth
},
contentShift: {
transition: theme.transitions.create("margin", {
easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.enteringScreen
}),
marginLeft: 0
}
}));
export default function User() {
const classes = useStyles();
const theme = useTheme();
const [open, setOpen] = React.useState(false);
const handleDrawerOpen = () => {
setOpen(true);
};
const handleDrawerClose = () => {
setOpen(false);
};
// TEST
const [anchorEl, setAnchorEl] = React.useState(null);
const [mobileMoreAnchorEl, setMobileMoreAnchorEl] = React.useState(null);
const isMenuOpen = Boolean(anchorEl);
const isMobileMenuOpen = Boolean(mobileMoreAnchorEl);
const handleProfileMenuOpen = event => {
setAnchorEl(event.currentTarget);
};
const handleMobileMenuClose = () => {
setMobileMoreAnchorEl(null);
};
const handleMenuClose = () => {
setAnchorEl(null);
handleMobileMenuClose();
};
const handleMobileMenuOpen = event => {
setMobileMoreAnchorEl(event.currentTarget);
};
const menuId = "primary-search-account-menu";
const renderMenu = (
<Menu
anchorEl={anchorEl}
anchorOrigin={{ vertical: "top", horizontal: "right" }}
id={menuId}
keepMounted
transformOrigin={{ vertical: "top", horizontal: "right" }}
open={isMenuOpen}
onClose={handleMenuClose}
>
<MenuItem onClick={handleMenuClose}>Profile</MenuItem>
<MenuItem onClick={handleMenuClose}>My account</MenuItem>
</Menu>
);
const mobileMenuId = "primary-search-account-menu-mobile";
const renderMobileMenu = (
<Menu
anchorEl={mobileMoreAnchorEl}
anchorOrigin={{ vertical: "top", horizontal: "right" }}
id={mobileMenuId}
keepMounted
transformOrigin={{ vertical: "top", horizontal: "right" }}
open={isMobileMenuOpen}
onClose={handleMobileMenuClose}
>
<MenuItem>
<IconButton aria-label="show 4 new mails" color="inherit">
<Badge badgeContent={4} color="secondary">
<MailIcon />
</Badge>
</IconButton>
<p>Messages</p>
</MenuItem>
<MenuItem>
<IconButton aria-label="show 11 new notifications" color="inherit">
<Badge badgeContent={11} color="secondary">
<NotificationsIcon />
</Badge>
</IconButton>
<p>Notifications</p>
</MenuItem>
<MenuItem onClick={handleProfileMenuOpen}>
<IconButton
aria-label="account of current user"
aria-controls="primary-search-account-menu"
aria-haspopup="true"
color="inherit"
>
<AccountCircle />
</IconButton>
<p>Profile</p>
</MenuItem>
</Menu>
);
return (
<div className={classes.root}>
<CssBaseline />
<AppBar
position="fixed"
className={clsx(classes.appBar, {
[classes.appBarShift]: open
})}
>
<Toolbar>
<IconButton
color="inherit"
aria-label="open drawer"
onClick={handleDrawerOpen}
edge="start"
className={clsx(classes.menuButton, open && classes.hide)}
>
<MenuIcon />
</IconButton>
<Typography variant="h6" noWrap>
LiveToday
</Typography>
<div className={classes.grow} />
<div className={classes.sectionDesktop}>
<IconButton aria-label="show 4 new mails" color="inherit">
<Badge badgeContent={4} color="secondary">
<MailIcon />
</Badge>
</IconButton>
<IconButton aria-label="show 17 new notifications" color="inherit">
<Badge badgeContent={17} color="secondary">
<NotificationsIcon />
</Badge>
</IconButton>
<IconButton
edge="end"
aria-label="account of current user"
aria-controls={menuId}
aria-haspopup="true"
onClick={handleProfileMenuOpen}
color="inherit"
>
<AccountCircle />
</IconButton>
</div>
<div className={classes.sectionMobile}>
<IconButton
aria-label="show more"
aria-controls={mobileMenuId}
aria-haspopup="true"
onClick={handleMobileMenuOpen}
color="inherit"
>
<MoreIcon />
</IconButton>
</div>
</Toolbar>
</AppBar>
<Drawer
className={classes.drawer}
variant="persistent"
anchor="left"
open={open}
classes={{
paper: classes.drawerPaper
}}
>
<div className={classes.drawerHeader}>
<IconButton onClick={handleDrawerClose}>
{theme.direction === "ltr" ? (
<ChevronLeftIcon />
) : (
<ChevronRightIcon />
)}
</IconButton>
</div>
<Divider />
<List>
{["Inbox", "Starred", "Send email", "Drafts"].map((text, index) => (
<ListItem button key={text}>
<ListItemIcon>
{index % 2 === 0 ? <InboxIcon /> : <MailIcon />}
</ListItemIcon>
<ListItemText primary={text} />
</ListItem>
))}
</List>
<Divider />
<List>
{["All mail", "Trash", "Spam"].map((text, index) => (
<ListItem button key={text}>
<ListItemIcon>
{index % 2 === 0 ? <InboxIcon /> : <MailIcon />}
</ListItemIcon>
<ListItemText primary={text} />
</ListItem>
))}
</List>
</Drawer>
<main
className={clsx(classes.content, {
[classes.contentShift]: open
})}
>
<div className={classes.drawerHeader} />
</main>
{renderMobileMenu}
{renderMenu}
</div>
);
}
The div which is responsible for pushing icons to the right is using className={classes.grow}, but you haven't defined grow anywhere.
Add the following code to your makeStyles function:
grow: {
flexGrow: 1
}