Allow simple calculations of skein/cost. Style.

This commit is contained in:
Nicholas Warzin 2020-11-25 09:10:22 -05:00
parent b2ec7b3e50
commit 689c1b4cdf
3 changed files with 63 additions and 46 deletions

View File

@ -1,9 +1,11 @@
{ {
"name": "yarn", "name": "yarn",
"homepage": "/yarn",
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"dependencies": { "dependencies": {
"@material-ui/core": "^4.11.0", "@material-ui/core": "^4.11.1",
"@material-ui/icons": "^4.9.1",
"@testing-library/jest-dom": "^5.11.4", "@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0", "@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10", "@testing-library/user-event": "^12.1.10",
@ -15,6 +17,7 @@
"scripts": { "scripts": {
"start": "react-scripts start", "start": "react-scripts start",
"build": "react-scripts build", "build": "react-scripts build",
"deploy": "npm run build && scp -rp build/* nicholas@warzin.com:/var/www/random/yarn",
"test": "react-scripts test", "test": "react-scripts test",
"eject": "react-scripts eject" "eject": "react-scripts eject"
}, },

View File

@ -1,38 +1,14 @@
.App { .App {
text-align: center; text-align: center;
max-width: 400px;
margin: 12px auto;
padding: 0 20px;
} }
.App-logo { h1 {
height: 40vmin; font-size: 64px !important;
pointer-events: none;
} }
@media (prefers-reduced-motion: no-preference) { h6 {
.App-logo { margin-bottom: 20px !important;
animation: App-logo-spin infinite 20s linear;
}
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.App-link {
color: #61dafb;
}
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
} }

View File

@ -2,46 +2,64 @@ import { useState, useEffect } from "react";
import logo from './logo.svg'; import logo from './logo.svg';
import './App.css'; import './App.css';
import {Typography, TextField, InputAdornment, Grid} from "@material-ui/core"; import {Typography, TextField, InputAdornment, Grid, } from "@material-ui/core";
import FavoriteIcon from "@material-ui/icons/Favorite";
const App = (props) => { const App = (props) => {
const [values, setValues] = useState({ const [values, setValues] = useState({
total: 1914, total: "",
skeinLength: "", skeinLength: "",
skeinPrice: "", skeinPrice: "",
skeinCount: "",
}); });
// const [skeinCount, setSkeinCount] = useState("");
const [totalPrice, setTotalPrice] = useState(); const [totalPrice, setTotalPrice] = useState();
const [skeinsRequiredDisabled, setSkeinsRequiredDisabled] = useState(false);
const _handleChange = (event) => { const _handleChange = (event) => {
const { id, value } = event.target; const { id, value } = event.target;
console.log("changing", id, value); // console.log("changing", id, value);
setValues({ setValues({
...values, ...values,
[id]: Number(value), [id]: parseFloat(value || 0),
}); });
console.log(values);
}; };
useEffect(() => { useEffect(() => {
const newTotal = Math.ceil((Number(values.total) / Number(values.skeinLength || 0))) const newSkeinCount = Math.ceil((Number(values.total) / Number(values.skeinLength || 0)) || 0);
* Number(values.skeinPrice); const newTotal = Number(newSkeinCount * Number(values.skeinPrice) || 0).toFixed(2);
setTotalPrice(newTotal); // console.log(newSkeinCount, newTotal);
console.log("change"); if (!values.total && !values.skeinLength) {
// console.log("setting a basic total");
setSkeinsRequiredDisabled(false);
// setValues({ ...values, skeinCount: newSkeinCount });
setTotalPrice((Number(values.skeinCount) || 0) * (Number(values.skeinPrice) || 0));
} else {
// console.log("setting a complicated total");
if (newSkeinCount !== values.skeinCount) setValues({
...values,
skeinCount: newSkeinCount,
});
setSkeinsRequiredDisabled(true);
setTotalPrice(newTotal);
}
// console.log("change", values);
}, [values]); }, [values]);
return ( return (
<div className="App" style={{ width: "400px", margin: "0 auto", }}> <div className="App">
<Grid container direction="column" spacing={2}> <Grid container direction="column" spacing={2}>
<Grid item xs={12}> <Grid item xs={12}>
<Typography variant="h1" gutterBottom>hey, we love yarn!</Typography> <Typography variant="h1" gutterBottom>yarn calc <FavoriteIcon style={{ fontSize: "inherit", color: "#cc0000", position: "relative", top: "12px" }}/></Typography>
<Typography variant="h6">Project details</Typography> <Typography variant="h6">Project details</Typography>
<TextField <TextField
label="Total yardage" label="Total yardage"
@ -49,6 +67,10 @@ const App = (props) => {
value={values.total} value={values.total}
onChange={_handleChange} onChange={_handleChange}
type="number" type="number"
variant="outlined"
InputProps={{
endAdornment: <InputAdornment position="end">yards</InputAdornment>,
}}
fullWidth fullWidth
/> />
</Grid> </Grid>
@ -60,6 +82,10 @@ const App = (props) => {
value={values.skeinLength} value={values.skeinLength}
onChange={_handleChange} onChange={_handleChange}
type="number" type="number"
variant="outlined"
InputProps={{
endAdornment: <InputAdornment position="end">yards</InputAdornment>,
}}
fullWidth fullWidth
/> />
</Grid> </Grid>
@ -70,6 +96,7 @@ const App = (props) => {
value={values.skeinPrice} value={values.skeinPrice}
onChange={_handleChange} onChange={_handleChange}
type="number" type="number"
variant="outlined"
fullWidth fullWidth
InputProps={{ InputProps={{
startAdornment: <InputAdornment position="start">$</InputAdornment>, startAdornment: <InputAdornment position="start">$</InputAdornment>,
@ -77,15 +104,26 @@ const App = (props) => {
/> />
</Grid> </Grid>
<Grid item xs={12}> <Grid item xs={12}>
<TextField
label="Number of skeins required"
id="skeinCount"
type={skeinsRequiredDisabled ? null : "number"}
onChange={_handleChange}
value={values.skeinCount}
fullWidth
inputProps={{ readOnly: skeinsRequiredDisabled }}
/>
</Grid>
<Grid item xs={12}>
<Typography variant="h6">Total project cost</Typography> <Typography variant="h6">Total project cost</Typography>
<TextField <TextField
id="totalPrice" id="totalPrice"
value={totalPrice} value={totalPrice}
onChange={_handleChange}
type="number"
fullWidth fullWidth
InputProps={{ InputProps={{
readOnly: true, readOnly: true,
startAdornment: <InputAdornment position="start">$</InputAdornment>,
style: { fontSize: "36px" },
}} }}
/> />
</Grid> </Grid>