mirror of
https://github.com/TurTaskProject/TurTaskWeb.git
synced 2025-12-18 21:44:07 +01:00
taskmodal will now work with some apis (need to work with time and desc)
- Editing Title - Editing complete, challenge, difficulty
This commit is contained in:
parent
9affc1ecba
commit
36958d5256
@ -34,6 +34,7 @@
|
|||||||
"@wojtekmaj/react-daterange-picker": "^5.4.4",
|
"@wojtekmaj/react-daterange-picker": "^5.4.4",
|
||||||
"axios": "^1.6.1",
|
"axios": "^1.6.1",
|
||||||
"bootstrap": "^5.3.2",
|
"bootstrap": "^5.3.2",
|
||||||
|
"date-fns": "^2.30.0",
|
||||||
"dotenv": "^16.3.1",
|
"dotenv": "^16.3.1",
|
||||||
"framer-motion": "^10.16.4",
|
"framer-motion": "^10.16.4",
|
||||||
"gapi-script": "^1.2.0",
|
"gapi-script": "^1.2.0",
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
lockfileVersion: '6.0'
|
lockfileVersion: '6.0'
|
||||||
|
|
||||||
|
settings:
|
||||||
|
autoInstallPeers: true
|
||||||
|
excludeLinksFromLockfile: false
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
'@dnd-kit/core':
|
'@dnd-kit/core':
|
||||||
specifier: ^6.1.0
|
specifier: ^6.1.0
|
||||||
@ -73,6 +77,9 @@ dependencies:
|
|||||||
bootstrap:
|
bootstrap:
|
||||||
specifier: ^5.3.2
|
specifier: ^5.3.2
|
||||||
version: 5.3.2(@popperjs/core@2.11.8)
|
version: 5.3.2(@popperjs/core@2.11.8)
|
||||||
|
date-fns:
|
||||||
|
specifier: ^2.30.0
|
||||||
|
version: 2.30.0
|
||||||
dotenv:
|
dotenv:
|
||||||
specifier: ^16.3.1
|
specifier: ^16.3.1
|
||||||
version: 16.3.1
|
version: 16.3.1
|
||||||
@ -4684,7 +4691,3 @@ packages:
|
|||||||
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
settings:
|
|
||||||
autoInstallPeers: true
|
|
||||||
excludeLinksFromLockfile: false
|
|
||||||
|
|||||||
@ -1,44 +1,141 @@
|
|||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import { FaTasks, FaRegListAlt } from "react-icons/fa";
|
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 { TbChecklist } from "react-icons/tb";
|
||||||
import DatePicker from "react-datepicker";
|
import DatePicker from "react-datepicker";
|
||||||
import { TimePicker } from "react-ios-time-picker";
|
|
||||||
import "react-datepicker/dist/react-datepicker.css";
|
import "react-datepicker/dist/react-datepicker.css";
|
||||||
import { addSubtasks, deleteSubtasks, getSubtask, updateSubtask } from "src/api/SubTaskApi";
|
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 [isChallengeChecked, setChallengeChecked] = useState(challenge);
|
||||||
const [isImportantChecked, setImportantChecked] = useState(importance);
|
const [isImportantChecked, setImportantChecked] = useState(importance);
|
||||||
const [currentDifficulty, setCurrentDifficulty] = useState(difficulty);
|
const [currentDifficulty, setCurrentDifficulty] = useState((difficulty - 1) * 25);
|
||||||
const [selectedTags, setSelectedTags] = useState([]);
|
const [selectedTags, setSelectedTags] = useState([]);
|
||||||
const [dateStart, setDateStart] = useState(new Date());
|
const [dateStart, setDateStart] = useState(new Date());
|
||||||
const [dateEnd, setDateEnd] = useState(new Date());
|
const [dateEnd, setDateEnd] = useState(new Date());
|
||||||
const [startDateEnabled, setStartDateEnabled] = useState(false);
|
const [startDateEnabled, setStartDateEnabled] = useState(false);
|
||||||
const [endDateEnabled, setEndDateEnabled] = useState(false);
|
const [endDateEnabled, setEndDateEnabled] = useState(false);
|
||||||
const [isTaskComplete, setTaskComplete] = useState(false);
|
const [isTaskComplete, setTaskComplete] = useState(completed);
|
||||||
const [value, setValue] = useState("10:00");
|
const [starteventValue, setStartEventValue] = useState("10:00 PM");
|
||||||
|
const [endeventValue, setEndEventValue] = useState("11:00 AM");
|
||||||
const [subtaskText, setSubtaskText] = useState("");
|
const [subtaskText, setSubtaskText] = useState("");
|
||||||
const [subtasks, setSubtasks] = useState([]);
|
const [subtasks, setSubtasks] = useState([]);
|
||||||
|
const [currentTitle, setTitle] = useState(title);
|
||||||
|
const [isTitleEditing, setTitleEditing] = useState(false);
|
||||||
|
|
||||||
const onChange = (timeValue) => {
|
const handleTitleChange = async () => {
|
||||||
setValue(timeValue);
|
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);
|
setChallengeChecked(!isChallengeChecked);
|
||||||
|
const data = {
|
||||||
|
challenge: !isChallengeChecked,
|
||||||
|
};
|
||||||
|
await updateTodoTaskPartial(taskId, data);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleImportantChange = () => {
|
const handleImportantChange = async () => {
|
||||||
setImportantChecked(!isImportantChecked);
|
setImportantChecked(!isImportantChecked);
|
||||||
|
const data = {
|
||||||
|
important: !isImportantChecked,
|
||||||
|
};
|
||||||
|
await updateTodoTaskPartial(taskId, data);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDifficultyChange = (event) => {
|
const handleDifficultyChange = async (event) => {
|
||||||
setCurrentDifficulty(parseInt(event.target.value, 10));
|
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 handleTagChange = (tag) => {
|
||||||
const isSelected = selectedTags.includes(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 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 = () => {
|
const handleStartDateChange = () => {
|
||||||
@ -53,14 +150,21 @@ export function TaskDetailModal({ title, description, tags, difficulty, challeng
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleTaskCompleteChange = () => {
|
const handleTaskCompleteChange = async () => {
|
||||||
|
let completed = false;
|
||||||
if (isTaskComplete) {
|
if (isTaskComplete) {
|
||||||
setTaskComplete(false);
|
setTaskComplete(false);
|
||||||
|
completed = false;
|
||||||
} else {
|
} else {
|
||||||
setTaskComplete(true);
|
setTaskComplete(true);
|
||||||
|
completed = true;
|
||||||
setStartDateEnabled(false);
|
setStartDateEnabled(false);
|
||||||
setEndDateEnabled(false);
|
setEndDateEnabled(false);
|
||||||
}
|
}
|
||||||
|
const data = {
|
||||||
|
completed: completed,
|
||||||
|
};
|
||||||
|
await updateTodoTaskPartial(taskId, data);
|
||||||
};
|
};
|
||||||
|
|
||||||
const addSubtask = async () => {
|
const addSubtask = async () => {
|
||||||
@ -130,7 +234,7 @@ export function TaskDetailModal({ title, description, tags, difficulty, challeng
|
|||||||
<div
|
<div
|
||||||
key={index}
|
key={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`}>
|
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}
|
{tag.name}
|
||||||
</div>
|
</div>
|
||||||
));
|
));
|
||||||
|
|
||||||
@ -139,7 +243,7 @@ export function TaskDetailModal({ title, description, tags, difficulty, challeng
|
|||||||
<div
|
<div
|
||||||
key={index}
|
key={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`}>
|
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}
|
{tag.name}
|
||||||
</div>
|
</div>
|
||||||
));
|
));
|
||||||
|
|
||||||
@ -149,13 +253,29 @@ export function TaskDetailModal({ title, description, tags, difficulty, challeng
|
|||||||
{/* Title */}
|
{/* Title */}
|
||||||
<div className="flex flex-col py-2">
|
<div className="flex flex-col py-2">
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<h3 className="font-bold text-lg">
|
{isTitleEditing ? (
|
||||||
<span className="flex gap-2">
|
<div className="flex gap-2 items-center">
|
||||||
{<FaTasks className="my-2" />}
|
<FaTasks className="my-2" />
|
||||||
{title}
|
<input
|
||||||
</span>
|
type="text"
|
||||||
</h3>
|
className="input-md input-bordered font-bold text-lg"
|
||||||
<p className="text-xs">{title}</p>
|
value={currentTitle}
|
||||||
|
onChange={(e) => setTitle(e.target.value)}
|
||||||
|
/>
|
||||||
|
<button className="btn btn-sm" onClick={handleTitleChange}>
|
||||||
|
Save
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<h3 className="font-bold text-lg">
|
||||||
|
<span className="flex gap-2">
|
||||||
|
{<FaTasks className="my-2" />}
|
||||||
|
{currentTitle}
|
||||||
|
<FaPencil className="my-2" onClick={() => setTitleEditing(true)} />
|
||||||
|
</span>
|
||||||
|
</h3>
|
||||||
|
)}
|
||||||
|
<p className="text-xs">{currentTitle}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/* Tags */}
|
{/* Tags */}
|
||||||
@ -175,7 +295,7 @@ export function TaskDetailModal({ title, description, tags, difficulty, challeng
|
|||||||
className="checkbox checkbox-sm"
|
className="checkbox checkbox-sm"
|
||||||
onChange={() => handleTagChange(tag)}
|
onChange={() => handleTagChange(tag)}
|
||||||
/>
|
/>
|
||||||
{tag.label}
|
{tag}
|
||||||
</label>
|
</label>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
@ -201,33 +321,31 @@ export function TaskDetailModal({ title, description, tags, difficulty, challeng
|
|||||||
onChange={handleStartDateChange}
|
onChange={handleStartDateChange}
|
||||||
/>
|
/>
|
||||||
<div className={`rounded p-2 shadow border-2 ${!startDateEnabled && "opacity-50"}`}>
|
<div className={`rounded p-2 shadow border-2 ${!startDateEnabled && "opacity-50"}`}>
|
||||||
<DatePicker
|
<DatePicker selected={dateStart} onChange={handleStartDateValueChange} disabled={!startDateEnabled} />
|
||||||
selected={dateStart}
|
|
||||||
onChange={(date) => setDateStart(date)}
|
|
||||||
disabled={!startDateEnabled}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="rounded p-2 shadow border-2">
|
{/* Start event time picker */}
|
||||||
<TimePicker
|
<div className="rounded p-2 shadow border-2 ml-2 mt-4">
|
||||||
value={value}
|
{/* handleStartEventTimeChange */}
|
||||||
onChange={onChange}
|
<input
|
||||||
className="rounded p-2 shadow border-2 z-[10000] relative"
|
type="text"
|
||||||
|
placeholder="10:00 AM"
|
||||||
|
className="input input-bordered w-full max-w-xs"
|
||||||
|
onClick={handleStartEventTimeChange}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Complete? */}
|
{/* Complete? */}
|
||||||
<div className="mx-4">
|
<div className="mx-4">
|
||||||
<div className="flex items-center space-x-2 mt-4">
|
<div className="flex items-center space-x-2 mt-4">
|
||||||
<div className="flex-1 flex-row card shadow border-2 p-2 pr-2">
|
<div className="flex-1 flex-row card shadow border-2 p-2 pr-2">
|
||||||
<p className="text-md mx-2">Complete</p>
|
<p className="text-md mx-2">Complete</p>
|
||||||
<input
|
<input type="checkbox" checked={isTaskComplete} className="checkbox checkbox-xl bg-gray-400" />
|
||||||
type="checkbox"
|
<button className="btn btn-sm mt-2" onClick={handleStartEventTimeChange}>
|
||||||
checked={isTaskComplete}
|
Update Start Time
|
||||||
className="checkbox checkbox-xl bg-gray-400"
|
</button>
|
||||||
onChange={handleTaskCompleteChange}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -243,8 +361,10 @@ export function TaskDetailModal({ title, description, tags, difficulty, challeng
|
|||||||
onChange={handleEndDateChange}
|
onChange={handleEndDateChange}
|
||||||
/>
|
/>
|
||||||
<div className={`rounded p-2 shadow border-2 ${!endDateEnabled && "opacity-50"}`}>
|
<div className={`rounded p-2 shadow border-2 ${!endDateEnabled && "opacity-50"}`}>
|
||||||
<DatePicker selected={dateEnd} onChange={(date) => setDateEnd(date)} disabled={!endDateEnabled} />
|
<DatePicker selected={dateEnd} onChange={handleEndDateValueChange} disabled={!endDateEnabled} />
|
||||||
</div>
|
</div>
|
||||||
|
{/* End event time picker */}
|
||||||
|
<div className="rounded p-2 shadow border-2">this is time picker</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user