I am making a pricing calculator on my site with 3 different options for calculation. I'd like the three categories at the top of the screenshot included to show the respective section (and make the others invisible) and turn that specific button black (it currently turns black on hover but not when clicked) and the others back to grey. Also screenshotted is an example of this working on Airtable's product page.
My script is below; I've been trying to make this work with useState
and an onClick
function as this is the recommended solution I've found in my research (linked one example of a few similar answers). However, if there is another more suitable approach I appreciate the advice.
import React, { useState } from 'react';
import { makeStyles } from '@material-ui/core/styles';
import useWindowPosition from '../../hook/useWindowPosition';
import Typography from '@material-ui/core/Typography';
import TextField from '@material-ui/core/TextField';
import Switch from '@material-ui/core/Switch';
const useStyles = makeStyles((theme) => ({
root: {
background: 'white',
paddingTop: '30px',
paddingBottom: '60px',
marginBottom: '-80px',
},
cardRoot: {
width: '90vw',
background: 'white',
marginTop: '20px',
marginBottom: '20px',
},
calculator: {
display: 'flex',
marginLeft: '10vw',
marginTop: '5vh',
[theme.breakpoints.down('md')]: {
flexDirection: 'column',
},
},
spacing: {
marginTop: '10vh',
marginLeft: '10vw',
},
header: {
fontFamily: 'Nunito',
fontWeight: 'bold',
fontSize: '2rem',
color: '#000',
marginRight: '30px',
},
title: {
fontFamily: 'Nunito',
fontWeight: 'regular',
fontSize: '1.5rem',
color: '#000',
marginRight: '30px',
},
price: {
fontFamily: 'Nunito',
fontWeight: 'regular',
fontSize: '2rem',
color: '#000',
marginRight: '30px',
},
liststyle: {
fontFamily: "Nunito",
fontSize: "1rem",
margin: '10px 10px',
},
list: {
display: "flex",
marginLeft: '8vw',
},
sections: {
textDecoration: 'none',
fontWeight: 'bold',
color: '#B6B6B6',
'&:hover': {
backgroundColor: '#fff',
color: '#000',
},
'&:clicked': {
backgroundColor: '#fff',
color: '#000',
},
},
}));
export default function () {
const classes = useStyles();
const [state, setState] = useState({
ImageNumber: '',
checkedA: false,
LabelImagesPrice: '',
AnimalNumber: '',
AnimalNumberPrice: '',
DatasetImageNumber: '',
DatasetAnimalNumber: '',
DatasetModelPrice: '',
});
const [show, setShow] = useState({
LabelImages: true,
CustomModel: false,
DatasetModel: false,
})
const onClick = () => setShow(true)
const handleSwitchChange = (event) => {
setState({ ...state, [event.target.name]: event.target.checked });
};
const handleChange = (event) => {
console.log(event.target.name);
setState({
...state,
[event.target.name]: event.target.value,
});
};
return (
<section id="pricingcalc" data-scroll-id="pricingcalc" backgroundColor="white">
<div className={classes.root}>
<div className={classes.calculator}>
<Typography
gutterBottom
variant="h5"
component="h1"
className={classes.header}
>
Pricing Calculator
</Typography>
</div>
<div>
<ul className={classes.list} style={{ listStyleType: "none" }}>
<li className={classes.liststyle}>
<a className={classes.sections} href="#labelimages" onClick={onClick}>
Label Images
</a>
</li>
<li className={classes.liststyle}>
<a className={classes.sections} href="#custommodel" onClick={onClick}>
Custom Model
</a>
</li>
<li className={classes.liststyle}>
<a className={classes.sections} href="#datasetmodel" onClick={onClick}>
Specialized Model
</a>
</li>
</ul>
</div>
<div className={classes.calculator} name="LabelImages">
<Typography
gutterBottom
variant="h6"
component="h1"
className={classes.title}
>
Number of Images
</Typography>
<TextField label="" name="ImageNumber" type="text" value={state.ImageNumber} variant="outlined" onChange={(e) => handleChange(e)} />
</div>
<div className={classes.calculator}>
<Typography
gutterBottom
variant="h6"
component="h1"
className={classes.title}
>
Human verified?
</Typography>
<Switch checked={state.checkedA} color="primary" onChange={handleSwitchChange} name="checkedA" />
</div>
<div className={classes.calculator}>
<Typography
gutterBottom
variant="h6"
component="h1"
className={classes.price}
>
Price
</Typography>
<TextField label="$ (USD)" name="LabelImagesPrice" type="text" value={state.ImageNumber*10 + state.checkedA*99} disabled variant="outlined" onChange={(e) => handleChange(e)} />
</div>
<div className={classes.calculator} name="CustomModel">
<Typography
gutterBottom
variant="h6"
component="h1"
className={classes.title}
>
Number of Animals in Model
</Typography>
<TextField label="" name="AnimalNumber" type="text" value={state.AnimalNumber} variant="outlined" onChange={(e) => handleChange(e)} />
</div>
<div className={classes.calculator}>
<Typography
gutterBottom
variant="h6"
component="h1"
className={classes.price}
>
Price
</Typography>
<TextField label="$ (USD)" name="AnimalNumberPrice" disabled type="text" value={state.AnimalNumber*15} disabled variant="outlined" onChange={(e) => handleChange(e)} />
</div>
<div className={classes.calculator} name="DatasetModel">
<Typography
gutterBottom
variant="h6"
component="h1"
className={classes.title}
>
Number of Images in Training Dataset
</Typography>
<TextField label="" name="DatasetImageNumber" type="text" value={state.DatasetImageNumber} variant="outlined" onChange={(e) => handleChange(e)} />
</div>
<div className={classes.calculator}>
<Typography
gutterBottom
variant="h6"
component="h1"
className={classes.title}
>
Number of Animals in Model
</Typography>
<TextField label="" name="DatasetAnimalNumber" type="text" value={state.DatasetAnimalNumber} variant="outlined" onChange={(e) => handleChange(e)} />
</div>
<div className={classes.calculator}>
<Typography
gutterBottom
variant="h6"
component="h1"
className={classes.price}
>
Price
</Typography>
<TextField label="$ (USD)" name="DatasetModelPrice" type="text" disabled value={state.DatasetImageNumber*10 + state.DatasetAnimalNumber*2} variant="outlined" onChange={(e) => handleChange(e)} />
</div>
</div>
</section>
);
}
Updated script:
import React, { useState } from 'react';
import { makeStyles } from '@material-ui/core/styles';
import useWindowPosition from '../../hook/useWindowPosition';
import Typography from '@material-ui/core/Typography';
import TextField from '@material-ui/core/TextField';
import Switch from '@material-ui/core/Switch';
const useStyles = makeStyles((theme) => ({
root: {
background: 'white',
paddingTop: '30px',
paddingBottom: '60px',
marginBottom: '-80px',
},
cardRoot: {
width: '90vw',
background: 'white',
marginTop: '20px',
marginBottom: '20px',
},
calculator: {
display: 'flex',
marginLeft: '10vw',
marginTop: '5vh',
[theme.breakpoints.down('md')]: {
flexDirection: 'column',
},
},
spacing: {
marginTop: '10vh',
marginLeft: '10vw',
},
header: {
fontFamily: 'Nunito',
fontWeight: 'bold',
fontSize: '2rem',
color: '#000',
marginRight: '30px',
},
title: {
fontFamily: 'Nunito',
fontWeight: 'regular',
fontSize: '1.5rem',
color: '#000',
marginRight: '30px',
},
price: {
fontFamily: 'Nunito',
fontWeight: 'regular',
fontSize: '2rem',
color: '#000',
marginRight: '30px',
},
liststyle: {
fontFamily: "Nunito",
fontSize: "1rem",
margin: '10px 10px',
},
list: {
display: "flex",
marginLeft: '8vw',
},
sections: {
textDecoration: 'none',
fontWeight: 'bold',
color: '#B6B6B6',
'&:hover': {
backgroundColor: '#fff',
color: '#000',
},
'&:clicked': {
backgroundColor: '#fff',
color: '#000',
},
},
}));
export default function () {
const classes = useStyles();
const checked = useWindowPosition('header');
const [state, setState] = useState({
ImageNumber: '',
checkedA: false,
LabelImagesPrice: '',
AnimalNumber: '',
AnimalNumberPrice: '',
DatasetImageNumber: '',
DatasetAnimalNumber: '',
DatasetModelPrice: '',
});
const [show, setShow] = useState({
LabelImages: true,
CustomModel: false,
DatasetModel: false,
})
const onClick = () => setShow(true)
const handleSwitchChange = (event) => {
setState({ ...state, [event.target.name]: event.target.checked });
};
const handleChange = (event) => {
console.log(event.target.name);
setState({
...state,
[event.target.name]: event.target.value,
});
};
return (
<section id="pricingcalc" data-scroll-id="pricingcalc" backgroundColor="white">
<div className={classes.root}>
<div className={classes.calculator}>
<Typography
gutterBottom
variant="h5"
component="h1"
className={classes.header}
>
Pricing Calculator
</Typography>
</div>
<div>
<ul className={classes.list} style={{ listStyleType: "none" }}>
<li className={classes.liststyle}>
<a
style = {show.labelImages ? {color: 'black'} : {color: 'grey'}}
className={classes.sections}
href="#labelimages"
onClick={onClick}
>
Label Images
</a>
</li>
<li className={classes.liststyle}>
<a
style={show.customModel ? {color: 'black'} : {color: 'grey'}}
className={classes.sections}
href="#customModel"
onClick={onClick}
>
Custom Model
</a>
</li>
<li className={classes.liststyle}>
<a
style={show.datasetModel ? {color: 'black'} : {color: 'grey'}}
className={classes.sections}
href="#datasetModel"
onClick={onClick}
>
Specialized Model
</a>
</li>
</ul>
</div>
{show.labelImages && <div className={classes.calculator} name="CustomModel">
<Typography
gutterBottom
variant="h6"
component="h1"
className={classes.title}
>
Number of Images
</Typography>
<TextField label="" name="ImageNumber" type="text" value={state.ImageNumber} variant="outlined" onChange={(e) => handleChange(e)} />
</div>}
{show.labelImages && <div className={classes.calculator} name="CustomModel">
<Typography
gutterBottom
variant="h6"
component="h1"
className={classes.title}
>
Human verified?
</Typography>
<Switch checked={state.checkedA} color="primary" onChange={handleSwitchChange} name="checkedA" />
</div>}
{show.labelImages && <div className={classes.calculator} name="CustomModel">
<Typography
gutterBottom
variant="h6"
component="h1"
className={classes.price}
>
Price
</Typography>
<TextField label="$ (USD)" name="LabelImagesPrice" type="text" value={state.ImageNumber*10 + state.checkedA*99} disabled variant="outlined" onChange={(e) => handleChange(e)} />
</div>}
{show.customModel && <div className={classes.calculator} name="CustomModel">
<Typography
gutterBottom
variant="h6"
component="h1"
className={classes.title}
>
Number of Animals in Model
</Typography>
<TextField label="" name="AnimalNumber" type="text" value={state.AnimalNumber} variant="outlined" onChange={(e) => handleChange(e)} />
</div>}
{show.customModel && <div className={classes.calculator} name="CustomModel">
<Typography
gutterBottom
variant="h6"
component="h1"
className={classes.price}
>
Price
</Typography>
<TextField label="$ (USD)" name="AnimalNumberPrice" disabled type="text" value={state.AnimalNumber*15} disabled variant="outlined" onChange={(e) => handleChange(e)} />
</div>}
{show.datasetModel && <div className={classes.calculator} name="DatasetModel">
<Typography
gutterBottom
variant="h6"
component="h1"
className={classes.title}
>
Number of Images in Training Dataset
</Typography>
<TextField label="" name="DatasetImageNumber" type="text" value={state.DatasetImageNumber} variant="outlined" onChange={(e) => handleChange(e)} />
</div>}
{show.datasetModel && <div className={classes.calculator} name="DatasetModel">
<Typography
gutterBottom
variant="h6"
component="h1"
className={classes.title}
>
Number of Animals in Model
</Typography>
<TextField label="" name="DatasetAnimalNumber" type="text" value={state.DatasetAnimalNumber} variant="outlined" onChange={(e) => handleChange(e)} />
</div>}
{show.datasetModel && <div className={classes.calculator} name="DatasetModel">
<Typography
gutterBottom
variant="h6"
component="h1"
className={classes.price}
>
Price
</Typography>
<TextField label="$ (USD)" name="DatasetModelPrice" type="text" disabled value={state.DatasetImageNumber*10 + state.DatasetAnimalNumber*2} variant="outlined" onChange={(e) => handleChange(e)} />
</div>}
</div>
</section>
);
}