rxc-app/src/components/courses/ManageCoursePage.js

135 lines
3.3 KiB
JavaScript

import React, { useEffect, useState } from "react";
import { connect } from "react-redux";
import { loadCourses, saveCourse } from "../../redux/actions/courseActions";
import { loadAuthors } from "../../redux/actions/authorActions";
import PropTypes from "prop-types";
import { bindActionCreators } from "redux";
import CourseForm from "./CourseForm";
import { newCourse } from "../../../tools/mockData";
import Spinner from "../common/Spinner";
import { toast } from "react-toastify";
export function ManageCoursePage({
courses,
authors,
actions,
history,
...props
}) {
const [course, setCourse] = useState({ ...props.course });
const [errors, setErrors] = useState({});
const [saving, setSaving] = useState(false);
useEffect(() => {
if (courses.length === 0) {
actions.loadCourses().catch((error) => {
alert("Loading courses failed. " + error);
});
} else {
setCourse({ ...props.course });
}
if (authors.length === 0) {
actions.loadAuthors().catch((error) => {
alert("Loading authors failed. " + error);
});
}
}, [props.course]);
function handleChange(event) {
const { name, value } = event.target;
setCourse((prevCourse) => ({
...prevCourse,
[name]: name === "authorId" ? parseInt(value, 10) : value
}));
}
function formIsValid() {
const { title, authorId, category } = course;
const errors = {};
if (!title) errors.title = "Title is required.";
if (!authorId) errors.author = "Author is required";
if (!category) errors.category = "Category is required";
setErrors(errors);
// Form is valid if the errors object still has no properties
return Object.keys(errors).length === 0;
}
const checkSlug = () => {
if (course.slug) return;
course.slug = course.title.replace(/\s+/g, "-").toLowerCase();
};
function handleSave(event) {
event.preventDefault();
if (!formIsValid()) return;
checkSlug();
setSaving(true);
actions
.saveCourse(course)
.then(() => {
toast.success("Course saved.");
history.push("/courses");
})
.catch((error) => {
setSaving(false);
setErrors({ onSave: error.message });
});
}
return authors.length === 0 || course.length === 0 ? (
<Spinner />
) : (
<CourseForm
course={course}
errors={errors}
authors={authors}
onChange={handleChange}
onSave={handleSave}
saving={saving}
/>
);
}
ManageCoursePage.propTypes = {
course: PropTypes.object.isRequired,
courses: PropTypes.array.isRequired,
authors: PropTypes.array.isRequired,
actions: PropTypes.object.isRequired,
history: PropTypes.object.isRequired
};
function mapStateToProps(state, ownProps) {
const slug = ownProps.match.params.slug;
const course =
slug && state.courses.length > 0
? getCourseBySlug(state.courses, slug)
: newCourse;
return {
course,
courses: state.courses,
authors: state.authors
};
}
function getCourseBySlug(courses, slug) {
return courses.find((course) => course.slug === slug) || null;
}
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators(
{
loadCourses,
loadAuthors,
saveCourse
},
dispatch
)
};
}
export default connect(mapStateToProps, mapDispatchToProps)(ManageCoursePage);