From 36958d5256053bc4c47a6e58960ffbbef1d4cf9c Mon Sep 17 00:00:00 2001 From: sosokker Date: Tue, 28 Nov 2023 11:57:53 +0700 Subject: [PATCH] taskmodal will now work with some apis (need to work with time and desc) - Editing Title - Editing complete, challenge, difficulty --- frontend/package.json | 1 + frontend/pnpm-lock.yaml | 11 +- .../kanbanBoard/taskDetailModal.jsx | 198 ++++++++++++++---- 3 files changed, 167 insertions(+), 43 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index b06025e..618e30c 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -34,6 +34,7 @@ "@wojtekmaj/react-daterange-picker": "^5.4.4", "axios": "^1.6.1", "bootstrap": "^5.3.2", + "date-fns": "^2.30.0", "dotenv": "^16.3.1", "framer-motion": "^10.16.4", "gapi-script": "^1.2.0", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index aca0306..b514b56 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -1,5 +1,9 @@ lockfileVersion: '6.0' +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + dependencies: '@dnd-kit/core': specifier: ^6.1.0 @@ -73,6 +77,9 @@ dependencies: bootstrap: specifier: ^5.3.2 version: 5.3.2(@popperjs/core@2.11.8) + date-fns: + specifier: ^2.30.0 + version: 2.30.0 dotenv: specifier: ^16.3.1 version: 16.3.1 @@ -4684,7 +4691,3 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} dev: true - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false diff --git a/frontend/src/components/kanbanBoard/taskDetailModal.jsx b/frontend/src/components/kanbanBoard/taskDetailModal.jsx index ddae1cf..3941ba1 100644 --- a/frontend/src/components/kanbanBoard/taskDetailModal.jsx +++ b/frontend/src/components/kanbanBoard/taskDetailModal.jsx @@ -1,44 +1,141 @@ import { useState, useEffect } from "react"; import { FaTasks, FaRegListAlt } from "react-icons/fa"; -import { FaPlus, FaRegTrashCan } from "react-icons/fa6"; +import { FaPlus, FaRegTrashCan, FaPencil } from "react-icons/fa6"; import { TbChecklist } from "react-icons/tb"; import DatePicker from "react-datepicker"; -import { TimePicker } from "react-ios-time-picker"; import "react-datepicker/dist/react-datepicker.css"; import { addSubtasks, deleteSubtasks, getSubtask, updateSubtask } from "src/api/SubTaskApi"; +import { updateTodoTaskPartial } from "src/api/TaskApi"; +import format from "date-fns/format"; -export function TaskDetailModal({ title, description, tags, difficulty, challenge, importance, taskId, updateTask }) { +export function TaskDetailModal({ + title, + description, + tags, + difficulty, + challenge, + importance, + taskId, + updateTask, + completed, +}) { const [isChallengeChecked, setChallengeChecked] = useState(challenge); const [isImportantChecked, setImportantChecked] = useState(importance); - const [currentDifficulty, setCurrentDifficulty] = useState(difficulty); + const [currentDifficulty, setCurrentDifficulty] = useState((difficulty - 1) * 25); const [selectedTags, setSelectedTags] = useState([]); const [dateStart, setDateStart] = useState(new Date()); const [dateEnd, setDateEnd] = useState(new Date()); const [startDateEnabled, setStartDateEnabled] = useState(false); const [endDateEnabled, setEndDateEnabled] = useState(false); - const [isTaskComplete, setTaskComplete] = useState(false); - const [value, setValue] = useState("10:00"); + const [isTaskComplete, setTaskComplete] = useState(completed); + const [starteventValue, setStartEventValue] = useState("10:00 PM"); + const [endeventValue, setEndEventValue] = useState("11:00 AM"); const [subtaskText, setSubtaskText] = useState(""); const [subtasks, setSubtasks] = useState([]); + const [currentTitle, setTitle] = useState(title); + const [isTitleEditing, setTitleEditing] = useState(false); - const onChange = (timeValue) => { - setValue(timeValue); + const handleTitleChange = async () => { + const data = { + title: currentTitle, + }; + await updateTodoTaskPartial(taskId, data); + setTitleEditing(false); }; - const handleChallengeChange = () => { + + const handleStartEventTimeChange = async (timeValue) => { + const formattedTime = convertToFormattedTime(timeValue); + setStartEventValue(formattedTime); + console.log(formattedTime); + const data = { + startTime: formattedTime, + }; + await updateTodoTaskPartial(taskId, data); + }; + + const handleEndEventTimeChange = async (timeValue) => { + const inputTime = event.target.value; + // Validate the input time format + if (!validateTimeFormat(inputTime)) { + // Display an error message or handle invalid format + console.error("Invalid time format. Please use HH:mm AM/PM"); + return; + } + + const formattedTime = convertToFormattedTime(timeValue); + setEndEventValue(formattedTime); + const data = { + endTime: formattedTime, + }; + await updateTodoTaskPartial(taskId, data); + }; + + const convertToFormattedTime = (timeValue) => { + const formattedTime = format(timeValue, "HH:mm:ss.SSSX", { timeZone: "UTC" }); + return formattedTime; + }; + + const validateTimeFormat = (time) => { + const timeFormatRegex = /^(0[1-9]|1[0-2]):[0-5][0-9] (AM|PM)$/i; + return timeFormatRegex.test(time); + }; + + const handleChallengeChange = async () => { setChallengeChecked(!isChallengeChecked); + const data = { + challenge: !isChallengeChecked, + }; + await updateTodoTaskPartial(taskId, data); }; - const handleImportantChange = () => { + const handleImportantChange = async () => { setImportantChecked(!isImportantChecked); + const data = { + important: !isImportantChecked, + }; + await updateTodoTaskPartial(taskId, data); }; - const handleDifficultyChange = (event) => { + const handleDifficultyChange = async (event) => { setCurrentDifficulty(parseInt(event.target.value, 10)); + let diff = event.target.value / 25 + 1; + const data = { + difficulty: diff, + }; + await updateTodoTaskPartial(taskId, data); }; const handleTagChange = (tag) => { const isSelected = selectedTags.includes(tag); setSelectedTags(isSelected ? selectedTags.filter((selectedTag) => selectedTag !== tag) : [...selectedTags, tag]); + ``; + }; + + const handleStartDateValueChange = (date) => { + if (!isTaskComplete) { + setDateStart(date); + const formattedStartDate = convertToFormattedDate(date); + const data = { + startTime: formattedStartDate, + }; + updateTodoTaskPartial(taskId, data); + } + }; + + const handleEndDateValueChange = (date) => { + if (!isTaskComplete) { + setDateEnd(date); + const formattedEndDate = convertToFormattedDate(date); + const data = { + endTime: formattedEndDate, + }; + updateTodoTaskPartial(taskId, data); + } + }; + + const convertToFormattedDate = (dateValue) => { + const formattedDate = format(dateValue, "yyyy-MM-dd'T'", { timeZone: "UTC" }); + return formattedDate; }; const handleStartDateChange = () => { @@ -53,14 +150,21 @@ export function TaskDetailModal({ title, description, tags, difficulty, challeng } }; - const handleTaskCompleteChange = () => { + const handleTaskCompleteChange = async () => { + let completed = false; if (isTaskComplete) { setTaskComplete(false); + completed = false; } else { setTaskComplete(true); + completed = true; setStartDateEnabled(false); setEndDateEnabled(false); } + const data = { + completed: completed, + }; + await updateTodoTaskPartial(taskId, data); }; const addSubtask = async () => { @@ -130,7 +234,7 @@ export function TaskDetailModal({ title, description, tags, difficulty, challeng
- {tag.label} + {tag.name}
)); @@ -139,7 +243,7 @@ export function TaskDetailModal({ title, description, tags, difficulty, challeng
- {tag.label} + {tag.name}
)); @@ -149,13 +253,29 @@ export function TaskDetailModal({ title, description, tags, difficulty, challeng {/* Title */}
-

- - {} - {title} - -

-

{title}

+ {isTitleEditing ? ( +
+ + setTitle(e.target.value)} + /> + +
+ ) : ( +

+ + {} + {currentTitle} + setTitleEditing(true)} /> + +

+ )} +

{currentTitle}

{/* Tags */} @@ -175,7 +295,7 @@ export function TaskDetailModal({ title, description, tags, difficulty, challeng className="checkbox checkbox-sm" onChange={() => handleTagChange(tag)} /> - {tag.label} + {tag} ))} @@ -201,33 +321,31 @@ export function TaskDetailModal({ title, description, tags, difficulty, challeng onChange={handleStartDateChange} />
- setDateStart(date)} - disabled={!startDateEnabled} - /> +
-
- + {/* handleStartEventTimeChange */} +
+ {/* Complete? */}

Complete

- + +
@@ -243,8 +361,10 @@ export function TaskDetailModal({ title, description, tags, difficulty, challeng onChange={handleEndDateChange} />
- setDateEnd(date)} disabled={!endDateEnabled} /> +
+ {/* End event time picker */} +
this is time picker