-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Enhancement/update categories=page (#237)
* Delete unused components * 🚚 Move files to new directory * ✨Create new components for PhotoPage form * ♻️Refactor PhotoPage * Prepare for release * Add instruction line * ✨Use dropdown label on brand * 🐛Improve delete category handling * ✨Add click to enlarge photo * 🐛 Fix issues from rebasing * 🐛fix import path
- Loading branch information
Showing
35 changed files
with
1,008 additions
and
1,016 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
{ | ||
"compilerOptions": { "baseUrl": "src" } | ||
"compilerOptions": { | ||
"baseUrl": "src" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,212 @@ | ||
import React from "react"; | ||
import SelectControlSingleValue from "./SelectControlSingleValue"; | ||
import RemoveIcon from "@material-ui/icons/RemoveCircleOutline"; | ||
import Button from "@material-ui/core/Button"; | ||
import { withStyles } from "@material-ui/core/styles"; | ||
import { getValueAndAncestorsFromTree } from "../../../utils"; | ||
|
||
const styles = theme => ({}); | ||
|
||
class MultiFields extends React.Component { | ||
state = { | ||
fieldValues: [] | ||
}; | ||
|
||
textFieldValueError = this.props.field.subfields | ||
? Object.values(this.props.field.subfields).reduce((a, v) => { | ||
a[v.name] = { value: "", error: !"".match(v.regexValidation) }; | ||
return a; | ||
}, {}) | ||
: false; | ||
|
||
selectValue = { | ||
leafkey: { | ||
value: "" | ||
} | ||
}; | ||
|
||
handleClickAdd = e => { | ||
const fieldValues = [...this.state.fieldValues]; | ||
fieldValues.push({ | ||
...JSON.parse(JSON.stringify(this.textFieldValueError)), | ||
...JSON.parse(JSON.stringify(this.selectValue)) | ||
}); | ||
|
||
this.setState({ | ||
fieldValues | ||
}); | ||
}; | ||
|
||
handleClickRemove = index => e => { | ||
const length = this.state.fieldValues.length; | ||
if (index === 0 && length === 1) { | ||
this.setState({ | ||
fieldValues: [ | ||
{ | ||
...JSON.parse(JSON.stringify(this.textFieldValueError)), | ||
...JSON.parse(JSON.stringify(this.selectValue)) | ||
} | ||
] | ||
}); | ||
this.props.handleChange(null, false); | ||
} else { | ||
const fieldValues = this.state.fieldValues.filter( | ||
(fieldValue, loop_index) => loop_index !== index | ||
); | ||
this.setState({ | ||
fieldValues | ||
}); | ||
this.checkErrorAndPropagateResToParent(fieldValues); | ||
} | ||
}; | ||
|
||
checkErrorAndPropagateResToParent = values => { | ||
let res = []; | ||
let textFieldErrors = false; | ||
Object.values(values).forEach((obj, index) => { | ||
res.push({}); | ||
Object.entries(obj).forEach(([key, value]) => { | ||
res[index][key] = value.value; | ||
if (value.error && values[index].leafkey.value) { | ||
textFieldErrors = true; | ||
} | ||
}); | ||
}); | ||
this.props.handleChange(res, textFieldErrors); | ||
}; | ||
|
||
handleChangeSelect = index => (value, error) => { | ||
const fieldValues = [...this.state.fieldValues]; | ||
fieldValues[index].leafkey.value = value; | ||
|
||
this.setState({ | ||
fieldValues | ||
}); | ||
this.checkErrorAndPropagateResToParent(fieldValues); | ||
}; | ||
|
||
handleChangeTitleTextField = (index, field) => (value, error) => { | ||
const fieldValues = [...this.state.fieldValues]; | ||
fieldValues[index][field.name].error = error; | ||
fieldValues[index][field.name].value = value; | ||
|
||
this.setState({ | ||
fieldValues | ||
}); | ||
this.checkErrorAndPropagateResToParent(fieldValues); | ||
}; | ||
|
||
static toFormattedString = (s, data) => { | ||
const categories = typeof s === "string" ? JSON.parse(s) : s; | ||
let categoryId; | ||
return ( | ||
categories && | ||
categories.map((category, index) => ( | ||
<div key={index}> | ||
{index === 0 && <br />} | ||
<div>Category {index}</div> | ||
{Object.entries(category).map(([key, value]) => { | ||
let formattedValue = value; | ||
let formattedKey = key; | ||
if (key === "leafkey") { | ||
formattedValue = getValueAndAncestorsFromTree( | ||
data, | ||
value | ||
).toString(); | ||
categoryId = value; | ||
formattedKey = "category"; | ||
} | ||
return ( | ||
<div style={{ display: "flex" }} key={key}> | ||
<div style={{ fontWeight: 100 }}>{formattedKey}</div> :{" "} | ||
<div>{formattedValue}</div> | ||
</div> | ||
); | ||
})} | ||
<div style={{ display: "flex" }}> | ||
<div style={{ fontWeight: 100 }}>categoryId</div> :{" "} | ||
<div>{categoryId}</div> | ||
</div> | ||
<br /> | ||
</div> | ||
)) | ||
); | ||
}; | ||
|
||
componentDidMount() { | ||
this.handleClickAdd(); | ||
} | ||
|
||
render() { | ||
return ( | ||
<div> | ||
{this.state.fieldValues.map((fieldValue, index) => { | ||
return ( | ||
<div key={index}> | ||
<br /> | ||
<br /> | ||
<div style={{ display: "flex" }}> | ||
<SelectControlSingleValue | ||
single={fieldValue.leafkey.value} | ||
handleChangeSelect={this.handleChangeSelect(index)} | ||
{...this.props} | ||
/> | ||
<div | ||
style={{ | ||
marginBottom: this.props.theme.spacing(0.5), | ||
display: "flex", | ||
alignItems: "flex-end" | ||
}} | ||
> | ||
<RemoveIcon onClick={this.handleClickRemove(index)} /> | ||
</div> | ||
</div> | ||
{this.props.field.subfields && | ||
fieldValue && | ||
fieldValue.leafkey.value && ( | ||
<div> | ||
{Object.values(this.props.field.subfields).map( | ||
(subfield, index_subfield) => { | ||
return ( | ||
<div | ||
key={"subcomponent_" + index_subfield} | ||
style={{ marginTop: this.props.theme.spacing(1) }} | ||
> | ||
<subfield.component | ||
field={subfield} | ||
handleChange={this.handleChangeTitleTextField( | ||
index, | ||
subfield | ||
)} | ||
fieldValue={fieldValue[subfield.name]} | ||
/> | ||
</div> | ||
); | ||
} | ||
)} | ||
{index === this.state.fieldValues.length - 1 && ( | ||
<div style={{ marginTop: this.props.theme.spacing(1.5) }}> | ||
<Button | ||
disabled={this.props.error} | ||
fullWidth | ||
variant="outlined" | ||
onClick={this.handleClickAdd} | ||
> | ||
add another category | ||
</Button> | ||
</div> | ||
)} | ||
</div> | ||
)} | ||
</div> | ||
); | ||
})} | ||
</div> | ||
); | ||
} | ||
} | ||
|
||
export default { | ||
MultiFieldsWithStyles: withStyles(styles, { withTheme: true })(MultiFields), | ||
MultiFieldsOriginal: MultiFields | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
74 changes: 74 additions & 0 deletions
74
src/components/PhotoPage/CategoryField/components/Category.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import React, { useState, useEffect, useCallback } from "react"; | ||
|
||
import RemoveIcon from "@material-ui/icons/RemoveCircleOutline"; | ||
|
||
import { FieldLabelWithInput } from "./CategoryDropdown/FieldLabel"; | ||
|
||
import { validateString, validateIsPositiveNumber } from "./validation"; | ||
import CategoryDropdown from "./CategoryDropdown"; | ||
|
||
import "./Category.scss"; | ||
|
||
const CategoryField = ({ handleClickRemove, handleChange }) => { | ||
const [numberOfPieces, setNumberOfPieces] = useState(""); | ||
const [brand, setBrand] = useState(""); | ||
const [selectedOption, setSelectedOption] = useState(""); | ||
|
||
const handleChangeCallback = useCallback(value => handleChange(value), [ | ||
handleChange | ||
]); | ||
|
||
//TODO: come up with a nicer way of doing this with the whole tree | ||
useEffect(() => { | ||
const validBrand = validateString(brand); | ||
const validCategory = | ||
validBrand && | ||
validateIsPositiveNumber(numberOfPieces) && | ||
validateIsPositiveNumber(selectedOption && selectedOption.key); | ||
|
||
handleChangeCallback({ | ||
leafKey: selectedOption && selectedOption.key, | ||
number: numberOfPieces, | ||
brand: validBrand && brand.trim(), | ||
error: !validCategory | ||
}); | ||
}, [numberOfPieces, brand, selectedOption]); | ||
|
||
return ( | ||
<div className={"CategoryField__container"}> | ||
<div className="CategoryField__dropdownContainer"> | ||
<CategoryDropdown | ||
label="Type of rubbish" | ||
placeholder={"e.g. plastic bottle"} | ||
value={selectedOption} | ||
setValue={setSelectedOption} | ||
/> | ||
<RemoveIcon onClick={handleClickRemove} /> | ||
</div> | ||
|
||
{selectedOption && ( | ||
<> | ||
<FieldLabelWithInput | ||
label={`Brand of ${selectedOption.label}`} | ||
placeholder={'e.g. coca cola or "none"'} | ||
value={brand} | ||
setValue={setBrand} | ||
validationFn={validateString} | ||
required | ||
/> | ||
|
||
<FieldLabelWithInput | ||
label="Number of pieces" | ||
placeholder={"e.g. 1"} | ||
validationFn={validateIsPositiveNumber} | ||
value={numberOfPieces} | ||
setValue={setNumberOfPieces} | ||
required | ||
/> | ||
</> | ||
)} | ||
</div> | ||
); | ||
}; | ||
|
||
export default CategoryField; |
12 changes: 12 additions & 0 deletions
12
src/components/PhotoPage/CategoryField/components/Category.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
.CategoryField__container { | ||
margin-top: 10px; | ||
background: rgba(0, 0, 0, 0.09); | ||
border-radius: 8px; | ||
padding: 5px; | ||
} | ||
|
||
.CategoryField__dropdownContainer { | ||
display: flex; | ||
flex-direction: row; | ||
align-items: center; | ||
} |
17 changes: 17 additions & 0 deletions
17
...s/PhotoPage/CategoryField/components/CategoryDropdown/FieldLabel/components/FieldLabel.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import React from "react"; | ||
|
||
import "./FieldLabel.scss"; | ||
|
||
const FieldLabel = ({ label, required, children }) => { | ||
return ( | ||
<div className={"FieldLabel__container"}> | ||
<p className={"FieldLabel__label"}> | ||
{label} | ||
{required && <span className={"FieldLabel__required"}> *</span>} | ||
</p> | ||
{children} | ||
</div> | ||
); | ||
}; | ||
|
||
export default FieldLabel; |
16 changes: 16 additions & 0 deletions
16
...PhotoPage/CategoryField/components/CategoryDropdown/FieldLabel/components/FieldLabel.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
@import "custom/config.scss"; | ||
|
||
.FieldLabel__container { | ||
margin: 10px 0; | ||
width: 100%; | ||
} | ||
|
||
.FieldLabel__label { | ||
margin: 0; | ||
font-size: 13px; | ||
margin-bottom: 5px; | ||
} | ||
|
||
.FieldLabel__required { | ||
color: red; | ||
} |
Oops, something went wrong.