Skip to content

Commit

Permalink
add popup form, code refacto-creating reusable component
Browse files Browse the repository at this point in the history
  • Loading branch information
ajeetchaulagain committed Jun 26, 2020
1 parent b042b92 commit 5b34891
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 69 deletions.
52 changes: 52 additions & 0 deletions src/components/common/PopupForm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React from "react";
import Button from "react-bootstrap/Button";
import Modal from "react-bootstrap/Modal";
import { PropTypes } from "prop-types";

const PopupModalForm = ({
showModal,
onHide,
onSubmit,
errors,
title,
buttonTitle,
children,
}) => {
return (
<Modal show={showModal} onHide={onHide} centered>
<Modal.Header
style={{ backgroundColor: "#000", color: "#fff", fontSize: "10px" }}
>
<Modal.Title>{title}</Modal.Title>
</Modal.Header>

<Modal.Body>
<form onSubmit={onSubmit}>{children}</form>
{errors && <div className="form-text text-danger">{errors}</div>}
</Modal.Body>

<Modal.Footer>
<Button variant="primary" size="sm" onClick={onSubmit}>
{buttonTitle}{" "}
<span
className="spinner-border spinner-border-sm"
role="status"
aria-hidden="true"
></span>
</Button>
</Modal.Footer>
</Modal>
);
};

PopupModalForm.propTypes = {
showModal: PropTypes.bool.isRequired,
onHide: PropTypes.func.isRequired,
onSubmit: PropTypes.func.isRequired,
errors: PropTypes.string,
title: PropTypes.string.isRequired,
buttonTitle: PropTypes.string.isRequired,
children: PropTypes.any,
};

export default PopupModalForm;
31 changes: 31 additions & 0 deletions src/components/common/TextInput.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from "react";
import { PropTypes } from "prop-types";

const TextInput = ({ name, value, onChange, type, placeholder }) => {
return (
<div className="field">
<input
className="form-control mb-4"
name={name}
type={type}
value={value}
onChange={onChange}
placeholder={placeholder}
/>
</div>
);
};

TextInput.propTypes = {
name: PropTypes.string.isRequired,
type: PropTypes.string,
value: PropTypes.string.isRequired,
onChange: PropTypes.func.isRequired,
placeholder: PropTypes.string,
};

TextInput.defaultProps = {
type: "text",
};

export default TextInput;
54 changes: 26 additions & 28 deletions src/components/dashboard/DashboardPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,33 +18,27 @@ class DashboardPage extends Component {
name: "",
},

activeProject: null,

apiErrorMessage: "",

projectInputErrors: "",
projectInputError: "",
showProjectModal: false,
};

componentDidMount() {
const { projects } = this.props;
console.log("componentDidMount() called");
if (this.props.projects.length === 0) {
if (projects.length === 0) {
this.props.loadProjects();
}
}

componentDidUpdate(prevProps) {
console.log("componentDidUpdate() called");

if (prevProps.apiError !== this.props.apiError) {
console.log("apiErrro", this.props.apiError);
if (this.props.apiError) toast.error(this.props.apiError);
const { apiError } = this.props;
if (prevProps.apiError !== apiError) {
console.log("apiErrro", apiError);
if (apiError) toast.error(apiError);
}

// if (prevProps.apiError !== this.props.apiError) {
// this.setState({ apiErrorMessage: this.props.apiError });
// console.log("serverError->", this.state.serverError);
// }
}

handleAddProject = () => {
Expand Down Expand Up @@ -82,17 +76,21 @@ class DashboardPage extends Component {

handleProjectFormSubmit = (event) => {
event.preventDefault();

const { error } = this.validateProjectInputFormData(this.state.project);
if (error) {
this.setState({ projectInputErrors: error.details[0].message });
this.setState({ projectInputError: error.details[0].message });
} else {
this.props.saveProject(this.state.project);
this.setState({ projectInputErrors: "" });
this.setState({ showProjectModal: false });
this.setState({});
// this.setState({ projectInputError: "" });
// this.setState({ showProjectModal: false });
// this.setState({});
const project = { ...this.state.project, name: "" };
this.setState({ project });

this.setState({
project,
projectInputError: "",
showProjectModal: false,
});
}
};

Expand All @@ -107,7 +105,8 @@ class DashboardPage extends Component {
};

render() {
console.log("render() called");
const { task, project, projectInputError, showProjectModal } = this.state;
const { tasks, projects } = this.props;
return (
<div className="container px-0 mt-1 ml-0 px-0 pb-5 h-100">
<br />
Expand All @@ -117,22 +116,21 @@ class DashboardPage extends Component {
) : (
<div className="row">
<ProjectSection
activeProject={this.props.projects.slice().reverse()[2]}
onSubmit={this.handleProjectFormSubmit}
projects={this.props.projects.slice().reverse()}
projects={projects.slice().reverse()}
onChange={this.handleProjectInputChange}
value={this.state.project.name}
errors={this.state.projectInputErrors}
showModal={this.state.showProjectModal}
value={project.name}
errors={projectInputError}
showModal={showProjectModal}
onAddButtonClick={this.handleAddProject}
onHide={this.handleHideModal}
onDelete={this.handleDeleteProject}
/>
<TaskSection
onSubmit={this.handleTaskFormSubmit}
tasks={this.props.tasks}
tasks={tasks}
onChange={this.handleTaskInputChange}
value={this.state.task.title}
value={task.title}
/>
</div>
)}
Expand All @@ -150,7 +148,7 @@ DashboardPage.propTypes = {
apiError: PropTypes.string,
isFetching: PropTypes.bool.isRequired,
saveProject: PropTypes.func.isRequired,
projectInputErrors: PropTypes.string,
projectInputError: PropTypes.string,
deleteProject: PropTypes.func.isRequired,
};

Expand Down
54 changes: 13 additions & 41 deletions src/components/dashboard/ProjectSection.js
Original file line number Diff line number Diff line change
@@ -1,43 +1,21 @@
import React from "react";

import { PropTypes } from "prop-types";
import { FaPlusCircle, FaTrashAlt, FaEdit } from "react-icons/fa";
import Button from "react-bootstrap/Button";
import Modal from "react-bootstrap/Modal";
import PopupModalForm from "../common/PopupForm";
import TextInput from "../common/TextInput";

const ProjectSection = (props) => {
const ProjectSection = ({ value, onChange, ...props }) => {
return (
<div className="col-3" style={{ textAlign: "left" }}>
<Modal show={props.showModal} onHide={props.onHide} centered>
<Modal.Header
style={{ backgroundColor: "#000", color: "#fff", fontSize: "10px" }}
>
<Modal.Title>Add a Project</Modal.Title>
</Modal.Header>
<Modal.Body>
<form onSubmit={props.onSubmit}>
<input
className="form-control mb-4"
id="projectInput"
type="text"
value={props.value}
onChange={props.onChange}
placeholder="Add a Project"
/>
</form>
{props.errors && <div className="text-danger">{props.errors}</div>}
</Modal.Body>
<Modal.Footer>
<Button variant="primary" size="sm" onClick={props.onSubmit}>
Add Project{" "}
<span
className="spinner-border spinner-border-sm"
role="status"
aria-hidden="true"
></span>
</Button>
</Modal.Footer>
</Modal>
<PopupModalForm {...props} title="Add New Project" buttonTitle="Save">
<TextInput
name="projectInput"
value={value}
onChange={onChange}
placeHolder="Add a Project"
/>
</PopupModalForm>

<div className="list-group">
<li
className="list-group-item
Expand All @@ -56,11 +34,7 @@ const ProjectSection = (props) => {
{props.projects &&
props.projects.map((project) => (
<a
className={
project === props.activeProject
? "list-group-item list-group-item-action d-flex justify-content-between shadow-none active bg-info"
: "list-group-item list-group-item-action d-flex justify-content-between shadow-none"
}
className="list-group-item list-group-item-action d-flex justify-content-between shadow-none"
style={{ fontSize: "15px" }}
key={project._id}
>
Expand Down Expand Up @@ -99,9 +73,7 @@ ProjectSection.propTypes = {
value: PropTypes.string.isRequired,
errors: PropTypes.string,
showModal: PropTypes.bool.isRequired,
onHide: PropTypes.func.isRequired,
onDelete: PropTypes.func.isRequired,
activeProject: PropTypes.obj,
};

export default ProjectSection;

0 comments on commit 5b34891

Please sign in to comment.