Repository: W-PTWD-April-2024-Liftoff/budget-breakers
Pull request #73: Chores creation form
Author: login: VolhaKarzhova
Created: 2025-03-16T20:03:34Z | Merged: 2025-03-18T23:51:30Z

created a basic page for chore creation and connected create button with POST API call from back-end, added validation on a client side, added notification model with success and failure messages.Status of the chore after creation is set to Open. User, group are not in use as of now as I need intiial functionality for them to be implemented first. Will return to this again alter. As well as no styling as of now.


Diff:
diff --git a/budget-planning-backend/src/main/java/org/launchcode/budget_planning_backend/controllers/ChoreController.java b/budget-planning-backend/src/main/java/org/launchcode/budget_planning_backend/controllers/ChoreController.java
new file mode 100644
index 0000000..8f93249
--- /dev/null
+++ b/budget-planning-backend/src/main/java/org/launchcode/budget_planning_backend/controllers/ChoreController.java
@@ -0,0 +1,27 @@
+package org.launchcode.budget_planning_backend.controllers;
+
+import jakarta.validation.Valid;
+import org.launchcode.budget_planning_backend.models.Chore;
+import org.launchcode.budget_planning_backend.models.ChoreDto;
+import org.launchcode.budget_planning_backend.models.Status;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.bind.annotation.*;
+
+import static org.launchcode.budget_planning_backend.models.Chore.createChore;
+
+@RestController
+@RequestMapping(value = "/chores")
+@CrossOrigin
+public class ChoreController {
+
+    private final Logger logger = LoggerFactory.getLogger(ChoreController.class);
+
+    @PostMapping(value="/create")
+    public Chore postChore(@Valid @RequestBody ChoreDto choreDto) {
+        Chore chore = createChore(choreDto.getName(), choreDto.getDescription(), choreDto.getAmountOfEarnings());
+        chore.setStatus(Status.OPEN);
+        logger.info("New Chore created: ".concat(chore.toString()));
+        return chore;
+    }
+}
diff --git a/budget-planning-backend/src/main/java/org/launchcode/budget_planning_backend/models/Chore.java b/budget-planning-backend/src/main/java/org/launchcode/budget_planning_backend/models/Chore.java
index be05813..32d45ea 100644
--- a/budget-planning-backend/src/main/java/org/launchcode/budget_planning_backend/models/Chore.java
+++ b/budget-planning-backend/src/main/java/org/launchcode/budget_planning_backend/models/Chore.java
@@ -1,9 +1,9 @@
 package org.launchcode.budget_planning_backend.models;
 
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
 
-public class Chore extends AbstractEntity{
+public class Chore extends AbstractEntity {
+
+    private static int nextId = 0;
 
     private User user;
 
@@ -11,43 +11,49 @@ public class Chore extends AbstractEntity{
 
     private Contributions contribution;
 
-    @NotNull
-    @NotBlank(message = "A group selection is required.")
     private Group group;
 
-    private String status;
+    private Status status;
 
-    @NotNull
-    @NotBlank(message = "Amount of earnings for this chore is required.")
     private Double amountOfEarnings;
 
-    public Chore() {}
-
-    public User getUser() {return user;}
-
-    public void setUser(User user) {this.user = user;}
-
-    public Event getEvent() {return event;}
-
-    public void setEvent(Event event) {this.event = event;}
-
-    public Contributions getContribution() {return contribution;}
-
-    public void setContribution(Contributions contribution) {
-        this.contribution = contribution;
+    public Chore(String name, String description, Double amountOfEarnings){
+        setId(nextId++);
+        setName(name);
+        setDescription(description);
+        this.amountOfEarnings = amountOfEarnings;
     }
 
-    public Group getGroup() {return group;}
+    public static Chore createChore(String name, String description, Double amountOfEarnings) {
+        return new Chore(name, description, amountOfEarnings);
+    }
 
-    public void setGroup(Group group) {this.group = group;}
+    public Double getAmountOfEarnings() {
+        return amountOfEarnings;
+    }
 
-    public String getStatus() {return status;}
+    public void setAmountOfEarnings(Double amountOfEarnings) {
+        this.amountOfEarnings = amountOfEarnings;
+    }
 
-    public void setStatus(String status) {this.status = status;}
+    public Status getStatus() {
+        return status;
+    }
 
-    public Double getAmountOfEarnings() {return amountOfEarnings;}
+    public void setStatus(Status status) {
+        this.status = status;
+    }
 
-    public void setAmountOfEarnings(Double amountOfEarnings) {
-        this.amountOfEarnings = amountOfEarnings;
+    @Override
+    public String toString() {
+        return "Chore{" + "id=" + getId() + ", " +
+                "name=" + getName() +
+                ", description=" + getDescription() +
+                ", amountOfEarnings=" + getAmountOfEarnings() +
+                ", status=" + getStatus() +
+                ", user=" + user +
+                ", event=" + event +
+                ", contribution=" + contribution +
+                ", group=" + group + '}';
     }
 }
diff --git a/budget-planning-backend/src/main/java/org/launchcode/budget_planning_backend/models/ChoreDto.java b/budget-planning-backend/src/main/java/org/launchcode/budget_planning_backend/models/ChoreDto.java
new file mode 100644
index 0000000..4cbf09d
--- /dev/null
+++ b/budget-planning-backend/src/main/java/org/launchcode/budget_planning_backend/models/ChoreDto.java
@@ -0,0 +1,37 @@
+package org.launchcode.budget_planning_backend.models;
+
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Positive;
+
+public class ChoreDto extends AbstractEntity {
+
+    //private User user;
+
+    //private Event event;
+
+    //private Group group;
+
+    @Positive(message = "Amount must be a positive number.")
+    @NotNull(message = "Amount is required.")
+    private Double amountOfEarnings;
+
+    public ChoreDto() {}
+
+    //public User getUser() {return user;}
+
+    //public void setUser(User user) {this.user = user;}
+
+    //public Event getEvent() {return event;}
+
+    //public void setEvent(Event event) {this.event = event;}
+
+    //public Group getGroup() {return group;}
+
+    //public void setGroup(Group group) {this.group = group;}
+
+    public Double getAmountOfEarnings() {return amountOfEarnings;}
+
+    public void setAmountOfEarnings(Double amountOfEarnings) {
+        this.amountOfEarnings = amountOfEarnings;
+    }
+}
diff --git a/budget-planning-backend/src/main/java/org/launchcode/budget_planning_backend/models/Group.java b/budget-planning-backend/src/main/java/org/launchcode/budget_planning_backend/models/Group.java
index ba89a3c..215fa51 100644
--- a/budget-planning-backend/src/main/java/org/launchcode/budget_planning_backend/models/Group.java
+++ b/budget-planning-backend/src/main/java/org/launchcode/budget_planning_backend/models/Group.java
@@ -11,7 +11,7 @@ public class Group extends AbstractEntity{
 
     private final List<Event> events = new ArrayList<>();
 
-    private  final List<Chore> chores = new ArrayList<>();
+    private  final List<ChoreDto> choreDTOS = new ArrayList<>();
 
     public Group(List<User> users, List<Event> events){
         this.setId(nextId);
@@ -28,7 +28,7 @@ public List<Event> getEvents() {
         return events;
     }
 
-    public List<Chore> getChores() {
-        return chores;
+    public List<ChoreDto> getChores() {
+        return choreDTOS;
     }
 }
diff --git a/budget-planning-backend/src/main/java/org/launchcode/budget_planning_backend/models/Status.java b/budget-planning-backend/src/main/java/org/launchcode/budget_planning_backend/models/Status.java
index 4aaa414..a5a9542 100644
--- a/budget-planning-backend/src/main/java/org/launchcode/budget_planning_backend/models/Status.java
+++ b/budget-planning-backend/src/main/java/org/launchcode/budget_planning_backend/models/Status.java
@@ -1,9 +1,19 @@
 package org.launchcode.budget_planning_backend.models;
 
 public enum Status {
-    OPEN,
-    IN_PROGRESS,
-    COMPLETE,
-    PENDING,
-    CANCELLED
+    OPEN("open"),
+    IN_PROGRESS("inProgress"),
+    COMPLETE("complete"),
+    PENDING("pending"),
+    CANCELLED("cancelled");
+
+    private final String value;
+
+    Status(String value) {
+        this.value = value;
+    }
+
+    public String getValue() {
+        return value;
+    }
 }
diff --git a/budget-planning-frontend/.gitignore b/budget-planning-frontend/.gitignore
index a547bf3..4a008b8 100644
--- a/budget-planning-frontend/.gitignore
+++ b/budget-planning-frontend/.gitignore
@@ -15,7 +15,7 @@ dist-ssr
 # Editor directories and files
 .vscode/*
 !.vscode/extensions.json
-.idea
+.idea/*
 .DS_Store
 *.suo
 *.ntvs*
diff --git a/budget-planning-frontend/src/App.jsx b/budget-planning-frontend/src/App.jsx
index f67355a..d470b46 100644
--- a/budget-planning-frontend/src/App.jsx
+++ b/budget-planning-frontend/src/App.jsx
@@ -2,33 +2,17 @@ import { useState } from 'react'
 import reactLogo from './assets/react.svg'
 import viteLogo from '/vite.svg'
 import './App.css'
+import "bootstrap/dist/css/bootstrap.min.css";
 
 function App() {
   const [count, setCount] = useState(0)
 
   return (
     <>
-      <div>
-        <a href="https://vite.dev" target="_blank">
-          <img src={viteLogo} className="logo" alt="Vite logo" />
-        </a>
-        <a href="https://react.dev" target="_blank">
-          <img src={reactLogo} className="logo react" alt="React logo" />
-        </a>
-      </div>
-      <h1>Vite + React</h1>
-      <div className="card">
-        <button onClick={() => setCount((count) => count + 1)}>
-          count is {count}
-        </button>
-        <p>
-          Edit <code>src/App.jsx</code> and save to test HMR
-        </p>
-      </div>
-      <p className="read-the-docs">
-        Click on the Vite and React logos to learn more
-      </p>
+    <p>Placeholder for the main app page</p>
+
     </>
+
   )
 }
 
diff --git a/budget-planning-frontend/src/components/Button.jsx b/budget-planning-frontend/src/components/Button.jsx
new file mode 100644
index 0000000..ca44248
--- /dev/null
+++ b/budget-planning-frontend/src/components/Button.jsx
@@ -0,0 +1,11 @@
+
+const Button = ({ label, onClick }) => {
+    return (
+        <button
+            onClick={onClick}>
+            {label}
+        </button>
+    );
+};
+
+export default Button; 
\ No newline at end of file
diff --git a/budget-planning-frontend/src/components/ChoreCreationForm.jsx b/budget-planning-frontend/src/components/ChoreCreationForm.jsx
new file mode 100644
index 0000000..15f3cf7
--- /dev/null
+++ b/budget-planning-frontend/src/components/ChoreCreationForm.jsx
@@ -0,0 +1,76 @@
+import TextInputField from "./TextInputField";
+import { useState } from "react";
+import NumericInputField from "./NumericInputField";
+import Button from "./Button";
+import ModalWindow from "./ModalWindow";
+import TextAreaInputField from "./TextAreaInputField"
+
+
+const ChoreCreationForm = () => {
+    const [formData, setFormData] = useState({ name: "", description: "", amountOfEarnings: "" });
+    const [message, setMessage] = useState("");
+    const [errors, setErrors] = useState({});
+    const [modalType, setModalType] = useState("success");
+    const [showModal, setShowModal] = useState(false);
+
+    const failedMessage = "Oops! Something went wrong while creating the chore. Looks like the universe is not ready for this one. Give it another try!";
+    const successMessage = "Hooray! Your chore has been successfully created. Now get ready to watch the magic of hard work unfold!";
+
+    let validateUserInputs = () => {
+        let errors = {};
+        if (!formData.name.trim() ||formData.name.length < 3 || formData.name.length > 50 ) errors.name = "Name is required and must be between 3 and 50 characters.";
+        if (!formData.amountOfEarnings || isNaN(formData.amountOfEarnings) || formData.amountOfEarnings < 0) {
+            errors.amountOfEarnings = "Amount is required and must be a positive number";
+        }
+        setErrors(errors);
+        return Object.keys(errors).length === 0;
+    }
+
+    const handleSubmit = (e) => {
+        e.preventDefault();
+        if (!validateUserInputs()) return;
+        fetch("http://localhost:8080/chores/create", {
+            method: "POST",
+            headers: { "Content-Type": "application/json" },
+            body: JSON.stringify(formData),
+        })
+            .then((response) => {
+                if (response.ok) {
+                    setMessage(successMessage);
+                    setModalType("success");
+                    setErrors({});
+                } else {
+                    setMessage(failedMessage);
+                    setModalType("danger");
+                }
+                setShowModal(true);
+            })
+            .catch((error) => {
+                setMessage(failedMessage);
+                setModalType("danger");
+                setShowModal(true);
+            });
+    }
+
+    return (
+        <form>
+            <p>Create Chores, Fund the Fun!</p>
+            <div>Got a family event you're excited about? Time to get things done! Create chores now and let your kids
+                complete them. Watch them contributing towards the next big family adventure! The cleaner the room,
+                the closer the goal!
+            </div>
+            <div>
+                <TextInputField label="Chore Name" name="name" value={formData.name} setFormData={setFormData} />
+                {errors.name && <p className="error">{errors.name}</p>}
+                <TextAreaInputField label="Chore Description" name="description" value={formData.description} setFormData={setFormData} />
+                <NumericInputField label="Earning Amount, $" name="amountOfEarnings" value={formData.amountOfEarnings} setFormData={setFormData} />
+                {errors.amountOfEarnings && <p className="error">{errors.amountOfEarnings}</p>}
+                <Button label="Create Chore" onClick={handleSubmit} />
+            </div>
+            <ModalWindow showState={showModal} message={message} type={modalType} onClose={() => setShowModal(false)} />
+        </form>
+
+    );
+};
+
+export default ChoreCreationForm;
diff --git a/budget-planning-frontend/src/components/InputField.jsx b/budget-planning-frontend/src/components/InputField.jsx
new file mode 100644
index 0000000..b37d38e
--- /dev/null
+++ b/budget-planning-frontend/src/components/InputField.jsx
@@ -0,0 +1,23 @@
+const InputField = ({ label, name, value, setFormData, type }) => {
+
+    const handleChange = (e) => {
+        const { name, value } = e.target;
+        setFormData((prev) => ({ ...prev, [name]: value }));
+    };
+
+    return (
+        <div data-mdb-input-init className="form-outline mb-4">
+            <label >{label}:
+                <input
+                className="form-control"
+                    type={type}
+                    name={name}
+                    value={value}
+                    onChange={handleChange}
+                />
+            </label>
+        </div>
+    );
+};
+
+export default InputField;
diff --git a/budget-planning-frontend/src/components/ModalWindow.jsx b/budget-planning-frontend/src/components/ModalWindow.jsx
new file mode 100644
index 0000000..ea5b514
--- /dev/null
+++ b/budget-planning-frontend/src/components/ModalWindow.jsx
@@ -0,0 +1,30 @@
+import React from "react";
+import "bootstrap/dist/css/bootstrap.min.css";
+
+function ModalWindow({ showState, type, message, onClose }) {
+    if(!showState){return null;}
+
+    const headerClass = type === "success" ? "bg-success text-white" : "bg-danger text-white";
+    const buttonClass = type === "success" ? "btn-success" : "btn-danger";
+
+    return (
+        <div className="modal show d-block" tabIndex="-1" role="dialog">
+            <div className="modal-dialog" role="document">
+                <div className="modal-content">
+                    <div className={`modal-header ${headerClass}`}>
+                        <h5 className="modal-title">{type === "success" ? "Success" : "Error"}</h5>
+                        <button type="button" className="btn-close" onClick={onClose}></button>
+                    </div>
+                    <div className="modal-body">
+                        <p>{message}</p>
+                    </div>
+                    <div className="modal-footer">
+                        <button className={`btn ${buttonClass}`} onClick={onClose}>OK</button>
+                    </div>
+                </div>
+            </div>
+        </div>
+    );
+}
+
+export default ModalWindow;
diff --git a/budget-planning-frontend/src/components/NumericInputField.jsx b/budget-planning-frontend/src/components/NumericInputField.jsx
new file mode 100644
index 0000000..80ab290
--- /dev/null
+++ b/budget-planning-frontend/src/components/NumericInputField.jsx
@@ -0,0 +1,8 @@
+import InputField from "./InputField";
+
+const NumericInputField = ({ label, name, value, setFormData }) => {
+    return <InputField 
+    label={label} name={name} value={value} setFormData={setFormData} type="number" />;
+};
+
+export default NumericInputField;
\ No newline at end of file
diff --git a/budget-planning-frontend/src/components/TextAreaInputField.jsx b/budget-planning-frontend/src/components/TextAreaInputField.jsx
new file mode 100644
index 0000000..0115915
--- /dev/null
+++ b/budget-planning-frontend/src/components/TextAreaInputField.jsx
@@ -0,0 +1,27 @@
+const TextAreaInputField = ({ label, name, value, setFormData }) => {
+    const handleChange = (e) => {
+        const { name, value } = e.target;
+        setFormData((prev) => ({ ...prev, [name]: value }));
+    };
+
+    return (
+        <div data-mdb-input-init className="form-outline mb-4">
+            <label>{label}:
+                <textarea
+                    className="form-control"
+                    name={name}
+                    value={value}
+                    onChange={handleChange}
+                    maxLength={250}
+                    rows="5"
+                />
+            </label>
+            <div>
+                <small>{250 - value.length} characters remaining</small>
+            </div>
+
+        </div>
+    );
+};
+
+export default TextAreaInputField;
diff --git a/budget-planning-frontend/src/components/TextInputField.jsx b/budget-planning-frontend/src/components/TextInputField.jsx
new file mode 100644
index 0000000..b90533b
--- /dev/null
+++ b/budget-planning-frontend/src/components/TextInputField.jsx
@@ -0,0 +1,7 @@
+import InputField from "./InputField";
+
+const TextInputField = ({ label, name, value, setFormData }) => {
+    return <InputField label={label} name={name} value={value} setFormData={setFormData} type="text" />;
+};
+
+export default TextInputField;
\ No newline at end of file


Reviews:
user: login: catcadams
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-16T21:20:55Z
user: login: marionpoole
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-17T01:56:59Z
user: login: marionpoole
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-17T02:11:52Z
user: login: marionpoole
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-17T02:13:16Z
user: login: marionpoole
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-17T02:16:36Z
user: login: marionpoole
body: Nice job creating all these components and with your code. I left a few comments. I was having difficulty trying to run the front end branch when I tried earlier. I received an error related to Bootstrap.
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-17T02:16:51Z
user: login: VolhaKarzhova
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-17T14:26:58Z
user: login: VolhaKarzhova
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-17T14:31:24Z
user: login: VolhaKarzhova
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-17T14:35:26Z
user: login: VolhaKarzhova
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-17T14:36:33Z
user: login: VolhaKarzhova
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-17T14:41:24Z
user: login: VolhaKarzhova
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-17T14:43:02Z
user: login: marionpoole
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-17T21:36:26Z
user: login: marionpoole
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-17T21:52:03Z
user: login: marionpoole
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-17T21:53:01Z
user: login: marionpoole
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-17T21:54:32Z
user: login: catcadams
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-18T00:19:10Z
user: login: catcadams
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-18T00:20:11Z
user: login: VolhaKarzhova
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-18T01:18:43Z
user: login: VolhaKarzhova
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-18T01:22:02Z
user: login: KayalvizhiRajendran
body: @VolhaKarzhova 
 Pulled your branch and checked. The front end form works fine. We should plan and work on the styling. Thank you for the reusable text, textarea and button components. I will use it in my events too in next commit. Looks good for the initial chores creation page. Am good for it to be merged to main.
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-03-18T22:58:28Z

Review comments:
path: budget-planning-backend/src/main/java/org/launchcode/budget_planning_backend/models/Chore.java
user: login: catcadams
body: I think I messed this up when I first created the class, but I believe status, getStatus, and setStatus should all be of type Status rather than String so that it uses the enum class
created_at: 2025-03-16T20:57:26Z
author_association: COLLABORATOR
path: budget-planning-backend/src/main/java/org/launchcode/budget_planning_backend/controllers/ChoreController.java
user: login: catcadams
body: Is the logger that you added something that needs to be stored or is it something that only shows upon the creation of the chore and then goes away?
created_at: 2025-03-16T21:13:49Z
author_association: COLLABORATOR
path: budget-planning-backend/src/main/java/org/launchcode/budget_planning_backend/controllers/ChoreController.java
user: login: marionpoole
body: Is a logger a way of seeing a log of details in your terminal?
created_at: 2025-03-17T01:56:59Z
author_association: COLLABORATOR
path: budget-planning-frontend/src/App.jsx
user: login: marionpoole
body: I am receiving an error when I try to run the front end branch due to something related to Bootstrap. I'm not sure what is causing this or if you have received the same error.
created_at: 2025-03-17T02:11:51Z
author_association: COLLABORATOR
path: budget-planning-frontend/src/components/Button.jsx
user: login: marionpoole
body: This button component is a great idea! Should I also be utilizing this for the buttons on my UserForm and RegisterForm?
created_at: 2025-03-17T02:13:16Z
author_association: COLLABORATOR
path: budget-planning-backend/src/main/java/org/launchcode/budget_planning_backend/models/ChoreDto.java
user: login: marionpoole
body: Have you figured out how to get the default messages for the @NotNull and @Positive annotations to show when you run the front end in a user-friendly format?
created_at: 2025-03-17T02:16:36Z
author_association: COLLABORATOR
path: budget-planning-backend/src/main/java/org/launchcode/budget_planning_backend/controllers/ChoreController.java
user: login: VolhaKarzhova
body: Logger are used instead of printing in console. Logs works the same way, but it is preferable to use logger allowing to print on different levels than direct printing in console.They are not going away, these are logged and you can always go back and check what your app was dong by reading them. Moreover, logs are normally saved on server for some time for apps and are used for debugging purposes. 
created_at: 2025-03-17T14:26:58Z
author_association: COLLABORATOR
path: budget-planning-backend/src/main/java/org/launchcode/budget_planning_backend/models/ChoreDto.java
user: login: VolhaKarzhova
body: I added validation of the same things on front-end, I found it easier, to be honest. But for back-end validation that is something I do not know the answer either.To be honest, for MVP I believe having validation on client side (UI) is enough :) 
created_at: 2025-03-17T14:31:23Z
author_association: COLLABORATOR
path: budget-planning-frontend/src/App.jsx
user: login: VolhaKarzhova
body: you need to import bootstrap into your react project so it will update your package file with bootstrap dependencies. If I remember correctly I run: npm install boostrap  
created_at: 2025-03-17T14:35:26Z
author_association: COLLABORATOR
path: budget-planning-frontend/src/components/Button.jsx
user: login: VolhaKarzhova
body: I think we can reuse one component everywhere so when it comes to styling work, it will be easy to apply style in a single place, to look the same on all pages
created_at: 2025-03-17T14:36:33Z
author_association: COLLABORATOR
path: budget-planning-backend/src/main/java/org/launchcode/budget_planning_backend/models/Chore.java
user: login: VolhaKarzhova
body: You have very point! I like the suggestion, updated the code to use Status. Thank you!
created_at: 2025-03-17T14:41:24Z
author_association: COLLABORATOR
path: budget-planning-backend/src/main/java/org/launchcode/budget_planning_backend/controllers/ChoreController.java
user: login: VolhaKarzhova
body: Thank you everyone for the comments, questions, suggestion, I updated the code and , hope, answered allt he questions. Could you please review again and let me know! Thank you! :)
created_at: 2025-03-17T14:43:02Z
author_association: COLLABORATOR
path: budget-planning-backend/src/main/java/org/launchcode/budget_planning_backend/controllers/ChoreController.java
user: login: marionpoole
body: Thanks for the clarification!
created_at: 2025-03-17T21:36:26Z
author_association: COLLABORATOR
path: budget-planning-frontend/src/App.jsx
user: login: marionpoole
body: Thank you!! That worked! I was able to install this now I can view the page. When I run the React program in the front end and go to http://localhost:5183/chores/create to view the ChoresCreationForm, it is only showing the text "Placeholder for the main app page". I ran the back-end as well at the same time and tried the link you had in your fetch statement http://localhost:8080/chores/create and received an error page. I was only able to get my forms to show by using: import { BrowserRouter } from 'react-router-dom' in the App.jsx file, then adding route paths for each of the forms. This was the solution I found from an online search, so there may be a better way to do it.
created_at: 2025-03-17T21:52:03Z
author_association: COLLABORATOR
path: budget-planning-frontend/src/components/Button.jsx
user: login: marionpoole
body: Ok, I will look up how to utilize that Button. I appreciate it!
created_at: 2025-03-17T21:53:01Z
author_association: COLLABORATOR
path: budget-planning-backend/src/main/java/org/launchcode/budget_planning_backend/models/ChoreDto.java
user: login: marionpoole
body: Perfect! I will try that out on my forms to try to get the validation on my front-end instead of only the back-end.
created_at: 2025-03-17T21:54:32Z
author_association: COLLABORATOR
path: budget-planning-frontend/src/App.jsx
user: login: catcadams
body: I'm also getting an error page when I try to run both apps and go to http://localhost:8080/chores/create but I'm wondering if adding a GetMapping to display the ChoreCreationForm would help with that? 
created_at: 2025-03-18T00:19:10Z
author_association: COLLABORATOR
path: budget-planning-backend/src/main/java/org/launchcode/budget_planning_backend/controllers/ChoreController.java
user: login: catcadams
body: Yes, this was very helpful. I tried googling and got a very technical answer which was hard to understand; this makes a lot of sense when you explain it. Thank you!
created_at: 2025-03-18T00:20:11Z
author_association: COLLABORATOR
path: budget-planning-frontend/src/App.jsx
user: login: VolhaKarzhova
body: You cannot open the page like this because I didn't create GET call. Here we use react and I was working on react part to display the page for creation, and post call for create action, not for GET call. Get view will be implemented in the other story. I started with POST because if you start with GET, you will have no data to see as there is no data. The form looks good if you update App.jsx to render the page for testing purposes. I can show you tomorrow how to do that if needed.Here is the view from my screen:
<img width="1171" alt="Screen Shot 2025-03-17 at 8 15 57 PM" src="https://github.com/user-attachments/assets/40a8c686-fa6f-47ca-a98e-76c07d6a12eb" />

created_at: 2025-03-18T01:18:43Z
author_association: COLLABORATOR
path: budget-planning-frontend/src/App.jsx
user: login: VolhaKarzhova
body: @catcadams @marionpoole this is how you can update your App.jsx to see the page loaded:
<img width="597" alt="Screen Shot 2025-03-17 at 8 20 17 PM" src="https://github.com/user-attachments/assets/ef278f5f-279b-448a-a8be-53826e867d6a" />


created_at: 2025-03-18T01:22:02Z
author_association: COLLABORATOR

PR comments:
user: login: catcadams
created_at: 2025-03-16T21:15:08Z
body: I left a couple of comments but overall, I think this looks good for the chore creation forms and is something we can base the rest of the creation forms off of to have consistency. Thank you for adding reusable components in JS and for updating the Status class!
author_association: COLLABORATOR
user: login: VolhaKarzhova
created_at: 2025-03-16T21:19:36Z
body: @catcadams thank you! I do not see the comments, I assume you need to submit your review so I can see them :) Thank you!
author_association: COLLABORATOR
user: login: catcadams
created_at: 2025-03-16T21:21:22Z
body: > @catcadams thank you! I do not see the comments, I assume you need to submit your review so I can see them :) Thank you!

My apologies! Just submitted.
author_association: COLLABORATOR
user: login: catcadams
created_at: 2025-03-18T22:46:58Z
body: @VolhaKarzhova I think your code looks great and is ready to be merged into the main branch!
author_association: COLLABORATOR