diff --git a/frontend/src/api/SubTaskApi.jsx b/frontend/src/api/SubTaskApi.jsx index 11a556f..1458153 100644 --- a/frontend/src/api/SubTaskApi.jsx +++ b/frontend/src/api/SubTaskApi.jsx @@ -1,6 +1,6 @@ import { axiosInstance } from "./AxiosConfig"; -export const getSubtasks = async (parentTaskId) => { +export const getSubtask = async (parentTaskId) => { try { const response = await axiosInstance.get(`subtasks?parent_task=${parentTaskId}`); return response.data; @@ -10,10 +10,11 @@ export const getSubtasks = async (parentTaskId) => { } }; -export const addSubtask = async (parentTaskId, text) => { +export const addSubtasks = async (parentTaskId, text) => { try { const response = await axiosInstance.post("subtasks/", { - text, + description: text, + completed: false, parent_task: parentTaskId, }); return response.data; @@ -23,7 +24,7 @@ export const addSubtask = async (parentTaskId, text) => { } }; -export const deleteSubtask = async (subtaskId) => { +export const deleteSubtasks = async (subtaskId) => { try { await axiosInstance.delete(`subtasks/${subtaskId}/`); } catch (error) { @@ -31,3 +32,13 @@ export const deleteSubtask = async (subtaskId) => { throw error; } }; + +export const updateSubtask = async (subtaskId, data) => { + try { + const response = await axiosInstance.patch(`subtasks/${subtaskId}/`, data); + return response.data; + } catch (error) { + console.error("Error updating subtask:", error); + throw error; + } +}; diff --git a/frontend/src/components/kanbanBoard/taskDetailModal.jsx b/frontend/src/components/kanbanBoard/taskDetailModal.jsx index 707572d..ddae1cf 100644 --- a/frontend/src/components/kanbanBoard/taskDetailModal.jsx +++ b/frontend/src/components/kanbanBoard/taskDetailModal.jsx @@ -1,23 +1,13 @@ -import { useState } from "react"; +import { useState, useEffect } from "react"; import { FaTasks, FaRegListAlt } from "react-icons/fa"; -import { FaPlus } from "react-icons/fa6"; +import { FaPlus, FaRegTrashCan } 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 { borderColor } from "@mui/system"; +import { addSubtasks, deleteSubtasks, getSubtask, updateSubtask } from "src/api/SubTaskApi"; -export function TaskDetailModal({ - title, - description, - tags, - difficulty, - challenge, - importance, - taskId, - updateTask, -}) { - let date = new Date(); +export function TaskDetailModal({ title, description, tags, difficulty, challenge, importance, taskId, updateTask }) { const [isChallengeChecked, setChallengeChecked] = useState(challenge); const [isImportantChecked, setImportantChecked] = useState(importance); const [currentDifficulty, setCurrentDifficulty] = useState(difficulty); @@ -27,7 +17,9 @@ export function TaskDetailModal({ const [startDateEnabled, setStartDateEnabled] = useState(false); const [endDateEnabled, setEndDateEnabled] = useState(false); const [isTaskComplete, setTaskComplete] = useState(false); - const [value, setValue] = useState('10:00'); + const [value, setValue] = useState("10:00"); + const [subtaskText, setSubtaskText] = useState(""); + const [subtasks, setSubtasks] = useState([]); const onChange = (timeValue) => { setValue(timeValue); @@ -46,11 +38,7 @@ export function TaskDetailModal({ const handleTagChange = (tag) => { const isSelected = selectedTags.includes(tag); - setSelectedTags( - isSelected - ? selectedTags.filter((selectedTag) => selectedTag !== tag) - : [...selectedTags, tag] - ); + setSelectedTags(isSelected ? selectedTags.filter((selectedTag) => selectedTag !== tag) : [...selectedTags, tag]); }; const handleStartDateChange = () => { @@ -75,12 +63,73 @@ export function TaskDetailModal({ } }; + const addSubtask = async () => { + try { + if (subtaskText.trim() !== "") { + const newSubtask = await addSubtasks(taskId, subtaskText.trim()); + setSubtasks([...subtasks, newSubtask]); + setSubtaskText(""); + } + } catch (error) { + console.error("Error adding subtask:", error); + } + }; + + const toggleSubtaskCompletion = async (index) => { + try { + const updatedSubtasks = [...subtasks]; + updatedSubtasks[index].completed = !updatedSubtasks[index].completed; + await updateSubtask(updatedSubtasks[index].id, { completed: updatedSubtasks[index].completed }); + setSubtasks(updatedSubtasks); + } catch (error) { + console.error("Error updating subtask:", error); + } + }; + + const deleteSubtask = async (index) => { + try { + await deleteSubtasks(subtasks[index].id); + const updatedSubtasks = [...subtasks]; + updatedSubtasks.splice(index, 1); + setSubtasks(updatedSubtasks); + } catch (error) { + console.error("Error deleting subtask:", error); + } + }; + + const subtaskElements = subtasks.map((subtask, index) => ( +
+ toggleSubtaskCompletion(index)} + /> +
+ {subtask.description} + deleteSubtask(index)} /> +
+
+ )); + + useEffect(() => { + const fetchSubtasks = async () => { + try { + const fetchedSubtasks = await getSubtask(taskId); + setSubtasks(fetchedSubtasks); + } catch (error) { + console.error("Error fetching subtasks:", error); + } + }; + + fetchSubtasks(); + }, [taskId]); + // Existing tags const existingTags = tags.map((tag, index) => (
+ className={`text-xs inline-flex items-center font-bold leading-sm uppercase px-2 py-1 bg-${tag.color}-200 text-${tag.color}-700 rounded-full`}> {tag.label}
)); @@ -89,8 +138,7 @@ export function TaskDetailModal({ const selectedTagElements = selectedTags.map((tag, index) => (
+ className={`text-xs inline-flex items-center font-bold leading-sm uppercase px-2 py-1 bg-${tag.color}-200 text-${tag.color}-700 rounded-full`}> {tag.label}
)); @@ -114,16 +162,10 @@ export function TaskDetailModal({
-
+
- -
@@ -202,19 +239,11 @@ export function TaskDetailModal({ -
- setDateEnd(date)} - disabled={!endDateEnabled} - /> +
+ setDateEnd(date)} disabled={!endDateEnabled} />
@@ -295,17 +324,19 @@ export function TaskDetailModal({ type="text" placeholder="subtask topic" className="input input-bordered flex-1 w-full" + value={subtaskText} + onChange={(e) => setSubtaskText(e.target.value)} /> - + {/* Display Subtasks */} +
{subtaskElements}
- +