From cf2e2320972dfd89c6da797e49598458de23b230 Mon Sep 17 00:00:00 2001 From: nikotj1 <43423740+nikotj1@users.noreply.github.com> Date: Wed, 29 Apr 2020 14:16:12 +0700 Subject: [PATCH] Bug/294 can't edit task due to earliest date addition (#295) * Fixed bug: can't add task on a selected date #232 * Delete package-lock.json * Bug Issue 294 Fixed edit task * Fix Edit Bug * Added form validation and fixed earliestDate * fixed taskID problem due to async --- doto-backend/src/models/Task.js | 4 ++ doto-backend/src/routes/task-route.js | 1 + doto-backend/swagger.json | 4 ++ doto-backend/test/task.test.js | 5 ++ doto-frontend/src/components/ModalContent.js | 19 ++++++- .../src/components/pages/Calendar/Calendar.js | 2 +- .../updateModal/UpdateModalContent.js | 52 +++++++++++++++++-- doto-frontend/src/helpers/DotoService.js | 4 +- 8 files changed, 84 insertions(+), 7 deletions(-) diff --git a/doto-backend/src/models/Task.js b/doto-backend/src/models/Task.js index 1c95dd7c..d3809af4 100644 --- a/doto-backend/src/models/Task.js +++ b/doto-backend/src/models/Task.js @@ -58,6 +58,10 @@ const taskSchema = mongoose.Schema({ type: Number, required: false, }, + earliestDate: { + type: Date, + required: true, + }, category: { type: Number, }, diff --git a/doto-backend/src/routes/task-route.js b/doto-backend/src/routes/task-route.js index 53c52294..0b685945 100644 --- a/doto-backend/src/routes/task-route.js +++ b/doto-backend/src/routes/task-route.js @@ -27,6 +27,7 @@ router.post("/post", authenticateToken, function (req, res) { task.travelTime = req.body.travelTime; task.reminderType = req.body.reminderType; task.dueDate = req.body.dueDate; + task.earliestDate = req.body.earliestDate; task.category = req.body.category; task.save(function (err) { diff --git a/doto-backend/swagger.json b/doto-backend/swagger.json index ad0a2734..fc95b184 100644 --- a/doto-backend/swagger.json +++ b/doto-backend/swagger.json @@ -262,6 +262,10 @@ "reminderType": { "type": "integer", "uniqueItems": false + }, + "earliestDate": { + "type": "date", + "uniqueItems": false } } }, diff --git a/doto-backend/test/task.test.js b/doto-backend/test/task.test.js index 673eb20d..b2869478 100644 --- a/doto-backend/test/task.test.js +++ b/doto-backend/test/task.test.js @@ -26,6 +26,7 @@ const validTask = new TaskModel({ isComplete: false, travelTime: 10, dueDate: "2020-08-14T07:50:00+12:00", + earliestDate: "2020-08-14T07:50:00+12:00", }); process.env.TEST_SUITE = "task-test"; @@ -221,6 +222,7 @@ describe("Task Model Tests", function () { isComplete: false, travelTime: 20, dueDate: "2020-08-14T07:50:00+12:00", + earliestDate: "2020-08-14T07:50:00+12:00", }); await testTask.save(); const [retrievedTask] = await TaskModel.find({ @@ -247,6 +249,7 @@ describe("Task Model Tests", function () { isComplete: false, travelTime: 20, dueDate: "2020-08-14T07:50:00+12:00", + earliestDate: "2020-08-14T07:50:00+12:00", }); await testTask.save(); const retrievedTasks = await TaskModel.find({ @@ -274,6 +277,7 @@ describe("Task Model Tests", function () { isComplete: false, travelTime: 20, dueDate: "2020-08-14T07:50:00+12:00", + earliestDate: "2020-08-14T07:50:00+12:00", }); await testTask.save(); const retrievedTasks = await TaskModel.find({ @@ -301,6 +305,7 @@ describe("Task Model Tests", function () { isComplete: true, travelTime: 20, dueDate: "2020-08-14T07:50:00+12:00", + earliestDate: "2020-08-14T07:50:00+12:00", }); await testTask.save(); const retrievedTasks = await TaskModel.find({ diff --git a/doto-frontend/src/components/ModalContent.js b/doto-frontend/src/components/ModalContent.js index 4a69b893..a014101b 100644 --- a/doto-frontend/src/components/ModalContent.js +++ b/doto-frontend/src/components/ModalContent.js @@ -55,6 +55,8 @@ const ModalContent = props => { const [selectedLocation, setSelectedLocation] = useState(""); const [selectedPriority, setSelectedPriority] = useState(""); const [selectedReminder, setSelectedReminder] = useState(""); + const [dueDateValid, setDueDateValid] = useState(false); + const [earliestDateValid, setEarliestDateValid] = useState(true); const [selectedCategory, setSelectedCategory] = useState(""); // ----- HANDLERS FOR INPUT FIELDS ----- @@ -69,18 +71,23 @@ const ModalContent = props => { const handleDateChange = date => { if (date > new Date()) { setSelectedDueDate(date); + setDueDateValid(true); } else { setSelectedDueDate("invalid date"); + setDueDateValid(false); } }; const handleEarliestChange = date => { - if (date > new Date()) { + if (date >= new Date()) { setEarliestDate(date); + setEarliestDateValid(true); } else { setEarliestDate("invalid date"); + setEarliestDateValid(false); } }; + const handleLocationChange = event => { setSelectedLocation(event.target.value); }; @@ -168,6 +175,7 @@ const ModalContent = props => { KeyboardButtonProps={{ "aria-label": "Change date/time", }} + error={!dueDateValid} /> @@ -190,6 +198,7 @@ const ModalContent = props => { KeyboardButtonProps={{ "aria-label": "Change date/time", }} + error={!earliestDateValid} /> @@ -269,7 +278,13 @@ const ModalContent = props => { 5 Minutes Before - diff --git a/doto-frontend/src/components/pages/Calendar/Calendar.js b/doto-frontend/src/components/pages/Calendar/Calendar.js index a2e3e1fd..f19221cd 100644 --- a/doto-frontend/src/components/pages/Calendar/Calendar.js +++ b/doto-frontend/src/components/pages/Calendar/Calendar.js @@ -171,7 +171,7 @@ const Calendar = () => { const taskList = [...tasks]; const index = taskList.findIndex(currentTask => currentTask.taskId === task.taskId); taskList.splice(index, 1); - const { newTaskOrder, updatedTask } = addTaskToSchedule(task, taskList, new Date()); + const { newTaskOrder, updatedTask } = addTaskToSchedule(task, taskList); setTasks(newTaskOrder); await DotoService.deleteTask(task.taskId); await DotoService.setNewTask(updatedTask); diff --git a/doto-frontend/src/components/updateModal/UpdateModalContent.js b/doto-frontend/src/components/updateModal/UpdateModalContent.js index a5310bcf..fb2b92f7 100644 --- a/doto-frontend/src/components/updateModal/UpdateModalContent.js +++ b/doto-frontend/src/components/updateModal/UpdateModalContent.js @@ -37,7 +37,8 @@ const UpdateModalContent = props => { const [selectedName, setSelectedName] = useState(props.taskToUpdate.title); const [selectedDescription, setSelectedDescription] = useState(props.taskToUpdate.description); - const [selectedDueDate, setSelectedDueDate] = useState(new Date()); + const [selectedDueDate, setSelectedDueDate] = useState(props.taskToUpdate.dueDate); + const [selectedEarliestDate, setSelectedEarliestDate] = useState(props.taskToUpdate.earliestDate); // default duration is 1 hour var initialDuration = new Date(); @@ -54,6 +55,8 @@ const UpdateModalContent = props => { const [selectedLocation, setSelectedLocation] = useState(props.taskToUpdate.location); const [selectedPriority, setSelectedPriority] = useState(""); const [selectedReminder, setSelectedReminder] = useState(""); + const [dueDateValid, setDueDateValid] = useState(props.taskToUpdate.dueDate > new Date()); + const [earliestDateValid, setEarliestDateValid] = useState(props.taskToUpdate.earliestDate >= new Date()); const [selectedCategory, setSelectedCategory] = useState(""); useEffect(() => { @@ -66,6 +69,7 @@ const UpdateModalContent = props => { setSelectedCategory(props.taskToUpdate.category || ""); setSelectedPriority(props.taskToUpdate.priority || ""); setSelectedReminder(props.taskToUpdate.reminderType || ""); + setSelectedEarliestDate(props.taskToUpdate.earliestDate || ""); }, [props.taskToUpdate]); // ----- HANDLERS FOR INPUT FIELDS ----- @@ -80,8 +84,20 @@ const UpdateModalContent = props => { const handleDateChange = date => { if (date > new Date()) { setSelectedDueDate(date); + setDueDateValid(true); } else { - setSelectedDueDate("invalid beans"); + setSelectedDueDate("invalid date"); + setDueDateValid(false); + } + }; + + const handleEarliestChange = date => { + if (date >= new Date()) { + setSelectedEarliestDate(date); + setEarliestDateValid(true); + } else { + setSelectedEarliestDate("invalid date"); + setEarliestDateValid(false); } }; @@ -117,6 +133,7 @@ const UpdateModalContent = props => { title: selectedName, description: selectedDescription, dueDate: selectedDueDate, + earliestDate: selectedEarliestDate, duration: selectedDuration.getHours() * 60 + selectedDuration.getMinutes(), travelTime: selectedTravelTime.getHours() * 60 + selectedTravelTime.getMinutes(), location: selectedLocation, @@ -181,6 +198,30 @@ const UpdateModalContent = props => { KeyboardButtonProps={{ "aria-label": "Change date/time", }} + error={!dueDateValid} + /> + + +
+ +
@@ -265,7 +306,12 @@ const UpdateModalContent = props => {
-
diff --git a/doto-frontend/src/helpers/DotoService.js b/doto-frontend/src/helpers/DotoService.js index d82d03d3..2fdee927 100644 --- a/doto-frontend/src/helpers/DotoService.js +++ b/doto-frontend/src/helpers/DotoService.js @@ -22,6 +22,7 @@ const taskMapper = data => { ...(data.category && { category: data.category }), ...(data.location && { location: data.location }), isComplete: data.isComplete, + earliestDate: new Date(data.earliestDate), }; }; @@ -73,6 +74,7 @@ const DotoService = { ...(task.category && { category: task.category }), ...(task.location && { location: task.location }), isComplete: false, + earliestDate: task.earliestDate.toString(), }; axios({ @@ -85,7 +87,7 @@ const DotoService = { // TODO: catch for errors depending if it didn't post properly or maybe retry mechanism }, deleteTask: async taskId => { - axios({ + await axios({ method: "delete", url: baseUrl + `/task/${taskId}`, headers: { Authorization: "Bearer " + CookieManager.get("jwt") },