Skip to content

Commit 36958d5

Browse files
committed
taskmodal will now work with some apis (need to work with time and desc)
- Editing Title - Editing complete, challenge, difficulty
1 parent 9affc1e commit 36958d5

3 files changed

Lines changed: 167 additions & 43 deletions

File tree

frontend/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
"@wojtekmaj/react-daterange-picker": "^5.4.4",
3535
"axios": "^1.6.1",
3636
"bootstrap": "^5.3.2",
37+
"date-fns": "^2.30.0",
3738
"dotenv": "^16.3.1",
3839
"framer-motion": "^10.16.4",
3940
"gapi-script": "^1.2.0",

frontend/pnpm-lock.yaml

Lines changed: 7 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/src/components/kanbanBoard/taskDetailModal.jsx

Lines changed: 159 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,141 @@
11
import { useState, useEffect } from "react";
22
import { FaTasks, FaRegListAlt } from "react-icons/fa";
3-
import { FaPlus, FaRegTrashCan } from "react-icons/fa6";
3+
import { FaPlus, FaRegTrashCan, FaPencil } from "react-icons/fa6";
44
import { TbChecklist } from "react-icons/tb";
55
import DatePicker from "react-datepicker";
6-
import { TimePicker } from "react-ios-time-picker";
76
import "react-datepicker/dist/react-datepicker.css";
87
import { addSubtasks, deleteSubtasks, getSubtask, updateSubtask } from "src/api/SubTaskApi";
8+
import { updateTodoTaskPartial } from "src/api/TaskApi";
9+
import format from "date-fns/format";
910

10-
export function TaskDetailModal({ title, description, tags, difficulty, challenge, importance, taskId, updateTask }) {
11+
export function TaskDetailModal({
12+
title,
13+
description,
14+
tags,
15+
difficulty,
16+
challenge,
17+
importance,
18+
taskId,
19+
updateTask,
20+
completed,
21+
}) {
1122
const [isChallengeChecked, setChallengeChecked] = useState(challenge);
1223
const [isImportantChecked, setImportantChecked] = useState(importance);
13-
const [currentDifficulty, setCurrentDifficulty] = useState(difficulty);
24+
const [currentDifficulty, setCurrentDifficulty] = useState((difficulty - 1) * 25);
1425
const [selectedTags, setSelectedTags] = useState([]);
1526
const [dateStart, setDateStart] = useState(new Date());
1627
const [dateEnd, setDateEnd] = useState(new Date());
1728
const [startDateEnabled, setStartDateEnabled] = useState(false);
1829
const [endDateEnabled, setEndDateEnabled] = useState(false);
19-
const [isTaskComplete, setTaskComplete] = useState(false);
20-
const [value, setValue] = useState("10:00");
30+
const [isTaskComplete, setTaskComplete] = useState(completed);
31+
const [starteventValue, setStartEventValue] = useState("10:00 PM");
32+
const [endeventValue, setEndEventValue] = useState("11:00 AM");
2133
const [subtaskText, setSubtaskText] = useState("");
2234
const [subtasks, setSubtasks] = useState([]);
35+
const [currentTitle, setTitle] = useState(title);
36+
const [isTitleEditing, setTitleEditing] = useState(false);
2337

24-
const onChange = (timeValue) => {
25-
setValue(timeValue);
38+
const handleTitleChange = async () => {
39+
const data = {
40+
title: currentTitle,
41+
};
42+
await updateTodoTaskPartial(taskId, data);
43+
setTitleEditing(false);
44+
};
45+
46+
const handleStartEventTimeChange = async (timeValue) => {
47+
const formattedTime = convertToFormattedTime(timeValue);
48+
setStartEventValue(formattedTime);
49+
console.log(formattedTime);
50+
const data = {
51+
startTime: formattedTime,
52+
};
53+
await updateTodoTaskPartial(taskId, data);
54+
};
55+
56+
const handleEndEventTimeChange = async (timeValue) => {
57+
const inputTime = event.target.value;
58+
// Validate the input time format
59+
if (!validateTimeFormat(inputTime)) {
60+
// Display an error message or handle invalid format
61+
console.error("Invalid time format. Please use HH:mm AM/PM");
62+
return;
63+
}
64+
65+
const formattedTime = convertToFormattedTime(timeValue);
66+
setEndEventValue(formattedTime);
67+
const data = {
68+
endTime: formattedTime,
69+
};
70+
await updateTodoTaskPartial(taskId, data);
2671
};
27-
const handleChallengeChange = () => {
72+
73+
const convertToFormattedTime = (timeValue) => {
74+
const formattedTime = format(timeValue, "HH:mm:ss.SSSX", { timeZone: "UTC" });
75+
return formattedTime;
76+
};
77+
78+
const validateTimeFormat = (time) => {
79+
const timeFormatRegex = /^(0[1-9]|1[0-2]):[0-5][0-9] (AM|PM)$/i;
80+
return timeFormatRegex.test(time);
81+
};
82+
83+
const handleChallengeChange = async () => {
2884
setChallengeChecked(!isChallengeChecked);
85+
const data = {
86+
challenge: !isChallengeChecked,
87+
};
88+
await updateTodoTaskPartial(taskId, data);
2989
};
3090

31-
const handleImportantChange = () => {
91+
const handleImportantChange = async () => {
3292
setImportantChecked(!isImportantChecked);
93+
const data = {
94+
important: !isImportantChecked,
95+
};
96+
await updateTodoTaskPartial(taskId, data);
3397
};
3498

35-
const handleDifficultyChange = (event) => {
99+
const handleDifficultyChange = async (event) => {
36100
setCurrentDifficulty(parseInt(event.target.value, 10));
101+
let diff = event.target.value / 25 + 1;
102+
const data = {
103+
difficulty: diff,
104+
};
105+
await updateTodoTaskPartial(taskId, data);
37106
};
38107

39108
const handleTagChange = (tag) => {
40109
const isSelected = selectedTags.includes(tag);
41110
setSelectedTags(isSelected ? selectedTags.filter((selectedTag) => selectedTag !== tag) : [...selectedTags, tag]);
111+
``;
112+
};
113+
114+
const handleStartDateValueChange = (date) => {
115+
if (!isTaskComplete) {
116+
setDateStart(date);
117+
const formattedStartDate = convertToFormattedDate(date);
118+
const data = {
119+
startTime: formattedStartDate,
120+
};
121+
updateTodoTaskPartial(taskId, data);
122+
}
123+
};
124+
125+
const handleEndDateValueChange = (date) => {
126+
if (!isTaskComplete) {
127+
setDateEnd(date);
128+
const formattedEndDate = convertToFormattedDate(date);
129+
const data = {
130+
endTime: formattedEndDate,
131+
};
132+
updateTodoTaskPartial(taskId, data);
133+
}
134+
};
135+
136+
const convertToFormattedDate = (dateValue) => {
137+
const formattedDate = format(dateValue, "yyyy-MM-dd'T'", { timeZone: "UTC" });
138+
return formattedDate;
42139
};
43140

44141
const handleStartDateChange = () => {
@@ -53,14 +150,21 @@ export function TaskDetailModal({ title, description, tags, difficulty, challeng
53150
}
54151
};
55152

56-
const handleTaskCompleteChange = () => {
153+
const handleTaskCompleteChange = async () => {
154+
let completed = false;
57155
if (isTaskComplete) {
58156
setTaskComplete(false);
157+
completed = false;
59158
} else {
60159
setTaskComplete(true);
160+
completed = true;
61161
setStartDateEnabled(false);
62162
setEndDateEnabled(false);
63163
}
164+
const data = {
165+
completed: completed,
166+
};
167+
await updateTodoTaskPartial(taskId, data);
64168
};
65169

66170
const addSubtask = async () => {
@@ -130,7 +234,7 @@ export function TaskDetailModal({ title, description, tags, difficulty, challeng
130234
<div
131235
key={index}
132236
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`}>
133-
{tag.label}
237+
{tag.name}
134238
</div>
135239
));
136240

@@ -139,7 +243,7 @@ export function TaskDetailModal({ title, description, tags, difficulty, challeng
139243
<div
140244
key={index}
141245
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`}>
142-
{tag.label}
246+
{tag.name}
143247
</div>
144248
));
145249

@@ -149,13 +253,29 @@ export function TaskDetailModal({ title, description, tags, difficulty, challeng
149253
{/* Title */}
150254
<div className="flex flex-col py-2">
151255
<div className="flex flex-col">
152-
<h3 className="font-bold text-lg">
153-
<span className="flex gap-2">
154-
{<FaTasks className="my-2" />}
155-
{title}
156-
</span>
157-
</h3>
158-
<p className="text-xs">{title}</p>
256+
{isTitleEditing ? (
257+
<div className="flex gap-2 items-center">
258+
<FaTasks className="my-2" />
259+
<input
260+
type="text"
261+
className="input-md input-bordered font-bold text-lg"
262+
value={currentTitle}
263+
onChange={(e) => setTitle(e.target.value)}
264+
/>
265+
<button className="btn btn-sm" onClick={handleTitleChange}>
266+
Save
267+
</button>
268+
</div>
269+
) : (
270+
<h3 className="font-bold text-lg">
271+
<span className="flex gap-2">
272+
{<FaTasks className="my-2" />}
273+
{currentTitle}
274+
<FaPencil className="my-2" onClick={() => setTitleEditing(true)} />
275+
</span>
276+
</h3>
277+
)}
278+
<p className="text-xs">{currentTitle}</p>
159279
</div>
160280
</div>
161281
{/* Tags */}
@@ -175,7 +295,7 @@ export function TaskDetailModal({ title, description, tags, difficulty, challeng
175295
className="checkbox checkbox-sm"
176296
onChange={() => handleTagChange(tag)}
177297
/>
178-
{tag.label}
298+
{tag}
179299
</label>
180300
</li>
181301
))}
@@ -201,33 +321,31 @@ export function TaskDetailModal({ title, description, tags, difficulty, challeng
201321
onChange={handleStartDateChange}
202322
/>
203323
<div className={`rounded p-2 shadow border-2 ${!startDateEnabled && "opacity-50"}`}>
204-
<DatePicker
205-
selected={dateStart}
206-
onChange={(date) => setDateStart(date)}
207-
disabled={!startDateEnabled}
208-
/>
324+
<DatePicker selected={dateStart} onChange={handleStartDateValueChange} disabled={!startDateEnabled} />
209325
</div>
210326
</div>
211327
</div>
212328

213-
<div className="rounded p-2 shadow border-2">
214-
<TimePicker
215-
value={value}
216-
onChange={onChange}
217-
className="rounded p-2 shadow border-2 z-[10000] relative"
329+
{/* Start event time picker */}
330+
<div className="rounded p-2 shadow border-2 ml-2 mt-4">
331+
{/* handleStartEventTimeChange */}
332+
<input
333+
type="text"
334+
placeholder="10:00 AM"
335+
className="input input-bordered w-full max-w-xs"
336+
onClick={handleStartEventTimeChange}
218337
/>
219338
</div>
339+
220340
{/* Complete? */}
221341
<div className="mx-4">
222342
<div className="flex items-center space-x-2 mt-4">
223343
<div className="flex-1 flex-row card shadow border-2 p-2 pr-2">
224344
<p className="text-md mx-2">Complete</p>
225-
<input
226-
type="checkbox"
227-
checked={isTaskComplete}
228-
className="checkbox checkbox-xl bg-gray-400"
229-
onChange={handleTaskCompleteChange}
230-
/>
345+
<input type="checkbox" checked={isTaskComplete} className="checkbox checkbox-xl bg-gray-400" />
346+
<button className="btn btn-sm mt-2" onClick={handleStartEventTimeChange}>
347+
Update Start Time
348+
</button>
231349
</div>
232350
</div>
233351
</div>
@@ -243,8 +361,10 @@ export function TaskDetailModal({ title, description, tags, difficulty, challeng
243361
onChange={handleEndDateChange}
244362
/>
245363
<div className={`rounded p-2 shadow border-2 ${!endDateEnabled && "opacity-50"}`}>
246-
<DatePicker selected={dateEnd} onChange={(date) => setDateEnd(date)} disabled={!endDateEnabled} />
364+
<DatePicker selected={dateEnd} onChange={handleEndDateValueChange} disabled={!endDateEnabled} />
247365
</div>
366+
{/* End event time picker */}
367+
<div className="rounded p-2 shadow border-2">this is time picker</div>
248368
</div>
249369
</div>
250370
</div>

0 commit comments

Comments
 (0)