/
FactoryForm.js
114 lines (92 loc) · 3.43 KB
/
FactoryForm.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import React, { useEffect, useMemo, useState, useRef } from 'react';
import { css, StyleSheet } from 'aphrodite';
import PropTypes from 'prop-types';
import Button from "react-bootstrap/Button";
import Form from "react-bootstrap/Form";
import Attributes from "./partials/Attributes";
import FactorySelection from "./partials/FactorySelection";
import FormFieldsForOwner from "./partials/FormFieldsForOwner";
import Traits from "./partials/Traits";
import { factoryShape } from "lib/shapes";
import { indexBy, usePrevious } from "./framework";
function FactoryForm(props) {
const owner = props.owner;
const inquiry = props.inquiry || "What'll it be?";
const [factoryInput, setFactoryInput] = useState("");
function handleFactory(event) {
const value = event.target.value;
setFactoryInput(value);
}
const blueprints = useMemo(() => props.blueprints || [], [props.blueprints]);
const indexedBluePrints = useMemo(() => indexBy(blueprints, blueprint => blueprint.factory.name), [blueprints]);
const selectedBlueprint = useMemo(() => indexedBluePrints[factoryInput], [factoryInput, indexedBluePrints]);
const attributes = useMemo(() => (selectedBlueprint && selectedBlueprint.factory.attributes) || [], [selectedBlueprint]);
const traits = useMemo(() => (selectedBlueprint && selectedBlueprint.factory.traits) || [], [selectedBlueprint]);
const validSelection = !!selectedBlueprint;
const prevOwner = usePrevious(props.owner);
function sameOwner(owner, other) {
const ownerType = owner && owner.type;
const ownerId = owner && owner.id;
const otherOwnerType = other && other.type;
const otherOwnerId = other && other.id;
return ownerType === otherOwnerType && ownerId === otherOwnerId;
}
useEffect(() => {
if (!sameOwner(props.owner, prevOwner)) { setFactoryInput(""); }
}, [props.owner, prevOwner]);
const form = useRef(null);
function startOver() {
form.current && form.current.reset();
setFactoryInput("");
props.startOver();
}
return (
<Form ref={form} onSubmit={props.handleSubmit}>
<FactorySelection
options={blueprints}
label={inquiry}
value={factoryInput}
onChange={handleFactory}
owner={owner}
/>
<FormFieldsForOwner owner={owner} association={selectedBlueprint && selectedBlueprint.association} />
{traits.length > 0 && (
<Traits disabled={props.disabled} traits={traits} />
)}
{attributes.length > 0 && (
<Attributes disabled={props.disabled} attributes={attributes} />
)}
<div className={css(styles.buttons)}>
<Button variant="outline-dark" className="btn-primary" disabled={props.disabled || !validSelection} type="submit">
Gimme!
</Button>
<Button variant="outline-dark" className="btn-danger" disabled={props.disabled} onClick={startOver} type="button">
Start Over
</Button>{' '}
</div>
</Form>
);
}
FactoryForm.propTypes = {
blueprints: PropTypes.arrayOf(
PropTypes.shape({
factory: factoryShape.isRequired,
association: PropTypes.string,
})
).isRequired,
disabled: PropTypes.bool,
handleSubmit: PropTypes.func,
inquiry: PropTypes.string,
owner: PropTypes.shape({
type: PropTypes.string,
id: PropTypes.any,
}),
startOver: PropTypes.func,
};
const styles = StyleSheet.create({
buttons: {
display: "flex",
justifyContent: "space-between",
},
});
export default FactoryForm;