reusable components SelectInput and TextInput + CourseForm

master
Tudor Stanciu 2020-04-11 23:43:14 +03:00
parent 2fe0b6c647
commit 528c5715f3
3 changed files with 153 additions and 0 deletions

View File

@ -0,0 +1,49 @@
import React from "react";
import PropTypes from "prop-types";
const SelectInput = ({
name,
label,
onChange,
defaultOption,
value,
error,
options
}) => {
return (
<div className="form-group">
<label htmlFor={name}>{label}</label>
<div className="field">
{/* Note, value is set here rather than on the option - docs: https://facebook.github.io/react/docs/forms.html */}
<select
name={name}
value={value}
onChange={onChange}
className="form-control"
>
<option value="">{defaultOption}</option>
{options.map((option) => {
return (
<option key={option.value} value={option.value}>
{option.text}
</option>
);
})}
</select>
{error && <div className="alert alert-danger">{error}</div>}
</div>
</div>
);
};
SelectInput.propTypes = {
name: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
onChange: PropTypes.func.isRequired,
defaultOption: PropTypes.string,
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
error: PropTypes.string,
options: PropTypes.arrayOf(PropTypes.object)
};
export default SelectInput;

View File

@ -0,0 +1,37 @@
import React from "react";
import PropTypes from "prop-types";
const TextInput = ({ name, label, onChange, placeholder, value, error }) => {
let wrapperClass = "form-group";
if (error && error.length > 0) {
wrapperClass += " " + "has-error";
}
return (
<div className={wrapperClass}>
<label htmlFor={name}>{label}</label>
<div className="field">
<input
type="text"
name={name}
className="form-control"
placeholder={placeholder}
value={value}
onChange={onChange}
/>
{error && <div className="alert alert-danger">{error}</div>}
</div>
</div>
);
};
TextInput.propTypes = {
name: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
onChange: PropTypes.func.isRequired,
placeholder: PropTypes.string,
value: PropTypes.string,
error: PropTypes.string
};
export default TextInput;

View File

@ -0,0 +1,67 @@
import React from "react";
import PropTypes from "prop-types";
import TextInput from "../common/TextInput";
import SelectInput from "../common/SelectInput";
const CourseForm = ({
course,
authors,
onSave,
onChange,
saving = false,
errors = {}
}) => {
return (
<form onSubmit={onSave}>
<h2>{course.id ? "Edit" : "Add"} Course</h2>
{errors.onSave && (
<div className="alert alert-danger" role="alert">
{errors.onSave}
</div>
)}
<TextInput
name="title"
label="Title"
value={course.title}
onChange={onChange}
error={errors.title}
/>
<SelectInput
name="authorId"
label="Author"
value={course.authorId || ""}
defaultOption="Select Author"
options={authors.map((author) => ({
value: author.id,
text: author.name
}))}
onChange={onChange}
error={errors.author}
/>
<TextInput
name="category"
label="Category"
value={course.category}
onChange={onChange}
error={errors.category}
/>
<button type="submit" disabled={saving} className="btn btn-primary">
{saving ? "Saving..." : "Save"}
</button>
</form>
);
};
CourseForm.propTypes = {
authors: PropTypes.array.isRequired,
course: PropTypes.object.isRequired,
errors: PropTypes.object,
onSave: PropTypes.func.isRequired,
onChange: PropTypes.func.isRequired,
saving: PropTypes.bool
};
export default CourseForm;