mirror of
https://github.com/TurTaskProject/TurTaskWeb.git
synced 2025-12-19 22:14:07 +01:00
Add placeholder for ui to provide more detail on task card
This commit is contained in:
parent
92731815da
commit
4a3f253e30
@ -42,6 +42,7 @@
|
|||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-beautiful-dnd": "^13.1.1",
|
"react-beautiful-dnd": "^13.1.1",
|
||||||
"react-bootstrap": "^2.9.1",
|
"react-bootstrap": "^2.9.1",
|
||||||
|
"react-datepicker": "^4.23.0",
|
||||||
"react-datetime-picker": "^5.5.3",
|
"react-datetime-picker": "^5.5.3",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-icons": "^4.11.0",
|
"react-icons": "^4.11.0",
|
||||||
|
|||||||
@ -101,6 +101,9 @@ dependencies:
|
|||||||
react-bootstrap:
|
react-bootstrap:
|
||||||
specifier: ^2.9.1
|
specifier: ^2.9.1
|
||||||
version: 2.9.1(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0)
|
version: 2.9.1(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
react-datepicker:
|
||||||
|
specifier: ^4.23.0
|
||||||
|
version: 4.23.0(react-dom@18.2.0)(react@18.2.0)
|
||||||
react-datetime-picker:
|
react-datetime-picker:
|
||||||
specifier: ^5.5.3
|
specifier: ^5.5.3
|
||||||
version: 5.5.3(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0)
|
version: 5.5.3(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0)
|
||||||
@ -3473,6 +3476,22 @@ packages:
|
|||||||
- '@types/react-dom'
|
- '@types/react-dom'
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/react-datepicker@4.23.0(react-dom@18.2.0)(react@18.2.0):
|
||||||
|
resolution: {integrity: sha512-w+msqlOZ14v6H1UknTKtZw/dw9naFMgAOspf59eY130gWpvy5dvKj/bgsFICDdvxB7PtKWxDcbGlAqCloY1d2A==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^16.9.0 || ^17 || ^18
|
||||||
|
react-dom: ^16.9.0 || ^17 || ^18
|
||||||
|
dependencies:
|
||||||
|
'@popperjs/core': 2.11.8
|
||||||
|
classnames: 2.3.2
|
||||||
|
date-fns: 2.30.0
|
||||||
|
prop-types: 15.8.1
|
||||||
|
react: 18.2.0
|
||||||
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
|
react-onclickoutside: 6.13.0(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
react-popper: 2.3.0(@popperjs/core@2.11.8)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
dev: false
|
||||||
|
|
||||||
/react-datetime-picker@5.5.3(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0):
|
/react-datetime-picker@5.5.3(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-bWGEPwGrZjaXTB8P4pbTSDygctLaqTWp0nNibaz8po+l4eTh9gv3yiJ+n4NIcpIJDqZaQJO57Bnij2rAFVQyLw==}
|
resolution: {integrity: sha512-bWGEPwGrZjaXTB8P4pbTSDygctLaqTWp0nNibaz8po+l4eTh9gv3yiJ+n4NIcpIJDqZaQJO57Bnij2rAFVQyLw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -3520,6 +3539,10 @@ packages:
|
|||||||
scheduler: 0.23.0
|
scheduler: 0.23.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/react-fast-compare@3.2.2:
|
||||||
|
resolution: {integrity: sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/react-fit@1.7.1(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0):
|
/react-fit@1.7.1(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-y/TYovCCBzfIwRJsbLj0rH4Es40wPQhU5GPPq9GlbdF09b0OdzTdMSkBza0QixSlgFzTm6dkM7oTFzaVvaBx+w==}
|
resolution: {integrity: sha512-y/TYovCCBzfIwRJsbLj0rH4Es40wPQhU5GPPq9GlbdF09b0OdzTdMSkBza0QixSlgFzTm6dkM7oTFzaVvaBx+w==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -3565,6 +3588,30 @@ packages:
|
|||||||
resolution: {integrity: sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==}
|
resolution: {integrity: sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/react-onclickoutside@6.13.0(react-dom@18.2.0)(react@18.2.0):
|
||||||
|
resolution: {integrity: sha512-ty8So6tcUpIb+ZE+1HAhbLROvAIJYyJe/1vRrrcmW+jLsaM+/powDRqxzo6hSh9CuRZGSL1Q8mvcF5WRD93a0A==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^15.5.x || ^16.x || ^17.x || ^18.x
|
||||||
|
react-dom: ^15.5.x || ^16.x || ^17.x || ^18.x
|
||||||
|
dependencies:
|
||||||
|
react: 18.2.0
|
||||||
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/react-popper@2.3.0(@popperjs/core@2.11.8)(react-dom@18.2.0)(react@18.2.0):
|
||||||
|
resolution: {integrity: sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q==}
|
||||||
|
peerDependencies:
|
||||||
|
'@popperjs/core': ^2.0.0
|
||||||
|
react: ^16.8.0 || ^17 || ^18
|
||||||
|
react-dom: ^16.8.0 || ^17 || ^18
|
||||||
|
dependencies:
|
||||||
|
'@popperjs/core': 2.11.8
|
||||||
|
react: 18.2.0
|
||||||
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
|
react-fast-compare: 3.2.2
|
||||||
|
warning: 4.0.3
|
||||||
|
dev: false
|
||||||
|
|
||||||
/react-redux@7.2.9(react-dom@18.2.0)(react@18.2.0):
|
/react-redux@7.2.9(react-dom@18.2.0)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ==}
|
resolution: {integrity: sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
|||||||
@ -1,16 +1,14 @@
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useEffect } from "react";
|
|
||||||
import { BsFillTrashFill } from "react-icons/bs";
|
|
||||||
import { useSortable } from "@dnd-kit/sortable";
|
import { useSortable } from "@dnd-kit/sortable";
|
||||||
import { CSS } from "@dnd-kit/utilities";
|
import { CSS } from "@dnd-kit/utilities";
|
||||||
import { TaskDetailModal } from "./taskDetailModal";
|
import { TaskDetailModal } from "./taskDetailModal";
|
||||||
|
import { GoChecklist, GoArchive } from "react-icons/go";
|
||||||
|
|
||||||
export function TaskCard({ task, deleteTask, updateTask }) {
|
export function TaskCard({ task, deleteTask, updateTask }) {
|
||||||
|
// State to track if the mouse is over the task card
|
||||||
const [mouseIsOver, setMouseIsOver] = useState(false);
|
const [mouseIsOver, setMouseIsOver] = useState(false);
|
||||||
// console.log(task.challenge);
|
|
||||||
// console.log(task.importance);
|
|
||||||
// console.log(task.difficulty);
|
|
||||||
|
|
||||||
|
// DnD Kit hook for sortable items
|
||||||
const { setNodeRef, attributes, listeners, transform, transition, isDragging } = useSortable({
|
const { setNodeRef, attributes, listeners, transform, transition, isDragging } = useSortable({
|
||||||
id: task.id,
|
id: task.id,
|
||||||
data: {
|
data: {
|
||||||
@ -18,67 +16,156 @@ export function TaskCard({ task, deleteTask, updateTask }) {
|
|||||||
task,
|
task,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Style for the task card, adjusting for dragging animation
|
||||||
const style = {
|
const style = {
|
||||||
transition,
|
transition,
|
||||||
transform: CSS.Transform.toString(transform),
|
transform: CSS.Transform.toString(transform),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ---- DESC AND TAG ---- */
|
||||||
|
|
||||||
|
// Tags
|
||||||
|
const tags =
|
||||||
|
task.tags.length > 0 ? (
|
||||||
|
<div className="flex flex-wrap mx-3 mt-4">
|
||||||
|
{task.tags.map((tag, index) => (
|
||||||
|
<div
|
||||||
|
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`}>
|
||||||
|
{tag.label}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
) : null;
|
||||||
|
|
||||||
{
|
// difficulty?
|
||||||
/* If card is dragged */
|
const difficultyTag = task.difficulty ? (
|
||||||
}
|
<span
|
||||||
|
className={`text-[10px] inline-flex items-center font-bold leading-sm uppercase px-2 py-1 rounded-full ${
|
||||||
|
task.difficulty === 1
|
||||||
|
? "bg-blue-200 text-blue-700"
|
||||||
|
: task.difficulty === 2
|
||||||
|
? "bg-green-200 text-green-700"
|
||||||
|
: task.difficulty === 3
|
||||||
|
? "bg-yellow-200 text-yellow-700"
|
||||||
|
: task.difficulty === 4
|
||||||
|
? "bg-purple-200 text-purple-700"
|
||||||
|
: "bg-red-200 text-red-700"
|
||||||
|
}`}>
|
||||||
|
difficulty
|
||||||
|
</span>
|
||||||
|
) : null;
|
||||||
|
|
||||||
|
// Due Date
|
||||||
|
const dueDateTag =
|
||||||
|
task.end_event && new Date(task.end_event) > new Date()
|
||||||
|
? (() => {
|
||||||
|
const daysUntilDue = Math.ceil((new Date(task.end_event) - new Date()) / (1000 * 60 * 60 * 24));
|
||||||
|
|
||||||
|
let colorClass =
|
||||||
|
daysUntilDue >= 365
|
||||||
|
? "gray-200"
|
||||||
|
: daysUntilDue >= 30
|
||||||
|
? "blue-200"
|
||||||
|
: daysUntilDue >= 7
|
||||||
|
? "green-200"
|
||||||
|
: daysUntilDue > 0
|
||||||
|
? "yellow-200"
|
||||||
|
: "red-200";
|
||||||
|
|
||||||
|
const formattedDueDate =
|
||||||
|
daysUntilDue >= 365
|
||||||
|
? new Date(task.end_event).toLocaleDateString("en-US", {
|
||||||
|
day: "numeric",
|
||||||
|
month: "short",
|
||||||
|
year: "numeric",
|
||||||
|
})
|
||||||
|
: new Date(task.end_event).toLocaleDateString("en-US", { day: "numeric", month: "short" });
|
||||||
|
|
||||||
|
return (
|
||||||
|
<span className={`bg-${colorClass} text-[10px] font-xl font-bold px-2 py-1 rounded-full`}>
|
||||||
|
Due: {formattedDueDate}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
})()
|
||||||
|
: null;
|
||||||
|
|
||||||
|
// Subtask count
|
||||||
|
const subtaskCountTag = task.subtaskCount ? (
|
||||||
|
<span className="bg-green-200 text-green-600 text-[10px] font-xl font-bold me-2 px-2.5 py-0.5 rounded">
|
||||||
|
<GoChecklist /> {task.subtaskCount}
|
||||||
|
</span>
|
||||||
|
) : null;
|
||||||
|
|
||||||
|
// ---- DRAG STATE ---- */
|
||||||
|
|
||||||
|
// If the card is being dragged
|
||||||
if (isDragging) {
|
if (isDragging) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
ref={setNodeRef}
|
ref={setNodeRef}
|
||||||
style={style}
|
style={style}
|
||||||
className="
|
className="opacity-30 bg-mainBackgroundColor p-2.5 items-center flex text-left rounded-xl border-2 border-gray-400 cursor-grab relative"
|
||||||
opacity-30
|
|
||||||
bg-mainBackgroundColor p-2.5 items-center flex text-left rounded-xl border-2 border-gray-400 cursor-grab relative
|
|
||||||
"
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the card is not being dragged
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
{/* Task Detail Modal */}
|
||||||
<TaskDetailModal
|
<TaskDetailModal
|
||||||
taskId={task.id}
|
taskId={task.id}
|
||||||
title={task.content}
|
title={task.content}
|
||||||
description={task.description}
|
description={task.description}
|
||||||
tags={task.tags}
|
tags={task.tags}
|
||||||
difficulty={task.difficulty}
|
difficulty={task.difficulty}
|
||||||
f challenge={task.challenge}
|
challenge={task.challenge}
|
||||||
importance={task.importance}
|
importance={task.importance}
|
||||||
|
updateTask={updateTask}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{/* -------- Task Card -------- */}
|
||||||
<div
|
<div
|
||||||
ref={setNodeRef}
|
ref={setNodeRef}
|
||||||
{...attributes}
|
{...attributes}
|
||||||
{...listeners}
|
{...listeners}
|
||||||
style={style}
|
style={style}
|
||||||
className="justify-center items-center flex text-left rounded-xl cursor-grab relative hover:border-2 hover:border-blue-400 shadow bg-white"
|
className="justify-center flex flex-col text-left rounded-xl cursor-grab relative hover:border-2 hover:border-blue-400 shadow bg-white"
|
||||||
onMouseEnter={() => {
|
onMouseEnter={() => {
|
||||||
setMouseIsOver(true);
|
setMouseIsOver(true);
|
||||||
}}
|
}}
|
||||||
onMouseLeave={() => {
|
onMouseLeave={() => {
|
||||||
setMouseIsOver(false);
|
setMouseIsOver(false);
|
||||||
}}>
|
}}>
|
||||||
<p
|
{/* -------- Task Content -------- */}
|
||||||
className={`p-2.5 my-auto w-full overflow-y-auto overflow-x-hidden whitespace-pre-wrap rounded-xl shadow bg-white`}
|
{/* Tags */}
|
||||||
onClick={() => document.getElementById(`task_detail_modal_${task.id}`).showModal()}>
|
{tags}
|
||||||
{task.content}
|
<div>
|
||||||
</p>
|
{/* Title */}
|
||||||
|
<p
|
||||||
{mouseIsOver && (
|
className={`p-2.5 my-auto w-full overflow-y-auto overflow-x-hidden whitespace-pre-wrap rounded-xl bg-white font-semibold`}
|
||||||
<button
|
onClick={() => document.getElementById(`task_detail_modal_${task.id}`).showModal()}>
|
||||||
onClick={() => {
|
{task.content}
|
||||||
deleteTask(task.id);
|
</p>
|
||||||
}}
|
{/* -------- Archive Task Button -------- */}
|
||||||
className="stroke-white absolute right-0 top-1/2 rounded-full bg-white -translate-y-1/2 bg-columnBackgroundColor p-2 hover:opacity-100 ">
|
{mouseIsOver && (
|
||||||
<BsFillTrashFill />
|
<button
|
||||||
</button>
|
onClick={() => {
|
||||||
)}
|
deleteTask(task.id);
|
||||||
|
}}
|
||||||
|
className="stroke-white absolute right-0 top-1/2 rounded-full bg-white -translate-y-1/2 bg-columnBackgroundColor p-2 hover:opacity-100 ">
|
||||||
|
<GoArchive />
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{/* Description */}
|
||||||
|
<div className="flex flex-wrap mb-4 mx-3 space-x-1">
|
||||||
|
{difficultyTag}
|
||||||
|
{dueDateTag}
|
||||||
|
{subtaskCountTag}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -2,14 +2,19 @@ import { useState } from "react";
|
|||||||
import { FaTasks, FaRegListAlt } from "react-icons/fa";
|
import { FaTasks, FaRegListAlt } from "react-icons/fa";
|
||||||
import { FaPlus } from "react-icons/fa6";
|
import { FaPlus } from "react-icons/fa6";
|
||||||
import { TbChecklist } from "react-icons/tb";
|
import { TbChecklist } from "react-icons/tb";
|
||||||
|
import DatePicker from "react-datepicker";
|
||||||
|
import "react-datepicker/dist/react-datepicker.css";
|
||||||
|
|
||||||
export function TaskDetailModal({ title, description, tags, difficulty, challenge, importance, taskId }) {
|
export function TaskDetailModal({ title, description, tags, difficulty, challenge, importance, taskId, updateTask }) {
|
||||||
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);
|
||||||
// console.log(currentDifficulty);
|
const [selectedTags, setSelectedTags] = useState([]);
|
||||||
// console.log(isChallengeChecked);
|
const [dateStart, setDateStart] = useState(new Date());
|
||||||
// console.log(isImportantChecked);
|
const [dateEnd, setDateEnd] = useState(new Date());
|
||||||
|
const [startDateEnabled, setStartDateEnabled] = useState(false);
|
||||||
|
const [endDateEnabled, setEndDateEnabled] = useState(false);
|
||||||
|
const [isTaskComplete, setTaskComplete] = useState(false);
|
||||||
|
|
||||||
const handleChallengeChange = () => {
|
const handleChallengeChange = () => {
|
||||||
setChallengeChecked(!isChallengeChecked);
|
setChallengeChecked(!isChallengeChecked);
|
||||||
@ -23,6 +28,51 @@ export function TaskDetailModal({ title, description, tags, difficulty, challeng
|
|||||||
setCurrentDifficulty(parseInt(event.target.value, 10));
|
setCurrentDifficulty(parseInt(event.target.value, 10));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleTagChange = (tag) => {
|
||||||
|
const isSelected = selectedTags.includes(tag);
|
||||||
|
setSelectedTags(isSelected ? selectedTags.filter((selectedTag) => selectedTag !== tag) : [...selectedTags, tag]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleStartDateChange = () => {
|
||||||
|
if (!isTaskComplete) {
|
||||||
|
setStartDateEnabled(!startDateEnabled);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleEndDateChange = () => {
|
||||||
|
if (!isTaskComplete) {
|
||||||
|
setEndDateEnabled(!endDateEnabled);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleTaskCompleteChange = () => {
|
||||||
|
if (isTaskComplete) {
|
||||||
|
setTaskComplete(false);
|
||||||
|
} else {
|
||||||
|
setTaskComplete(true);
|
||||||
|
setStartDateEnabled(false);
|
||||||
|
setEndDateEnabled(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Existing tags
|
||||||
|
const existingTags = tags.map((tag, index) => (
|
||||||
|
<div
|
||||||
|
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`}>
|
||||||
|
{tag.label}
|
||||||
|
</div>
|
||||||
|
));
|
||||||
|
|
||||||
|
// Selected tags
|
||||||
|
const selectedTagElements = selectedTags.map((tag, index) => (
|
||||||
|
<div
|
||||||
|
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`}>
|
||||||
|
{tag.label}
|
||||||
|
</div>
|
||||||
|
));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<dialog id={`task_detail_modal_${taskId}`} className="modal">
|
<dialog id={`task_detail_modal_${taskId}`} className="modal">
|
||||||
<div className="modal-box w-4/5 max-w-3xl">
|
<div className="modal-box w-4/5 max-w-3xl">
|
||||||
@ -38,7 +88,6 @@ export function TaskDetailModal({ title, description, tags, difficulty, challeng
|
|||||||
<p className="text-xs">{title}</p>
|
<p className="text-xs">{title}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Tags */}
|
{/* Tags */}
|
||||||
<div className="flex flex-col py-2 pb-4">
|
<div className="flex flex-col py-2 pb-4">
|
||||||
<div className="flex flex-row space-x-5">
|
<div className="flex flex-row space-x-5">
|
||||||
@ -46,19 +95,81 @@ export function TaskDetailModal({ title, description, tags, difficulty, challeng
|
|||||||
<label tabIndex={0} className="btn-md border-2 rounded-xl m-1 py-1">
|
<label tabIndex={0} className="btn-md border-2 rounded-xl m-1 py-1">
|
||||||
+ Add Tags
|
+ Add Tags
|
||||||
</label>
|
</label>
|
||||||
<ul tabIndex={0} className="dropdown-content z-[1] menu p-2 shadow bg-base-100 rounded-box w-52">
|
<ul tabIndex={0} className="dropdown-content z-[10] menu p-2 shadow bg-base-100 rounded-box w-52">
|
||||||
<li>
|
{tags.map((tag, index) => (
|
||||||
<a>
|
<li key={index}>
|
||||||
<input type="checkbox" checked="checked" className="checkbox checkbox-sm" />
|
<label className="cursor-pointer space-x-2">
|
||||||
Item 2
|
<input
|
||||||
</a>
|
type="checkbox"
|
||||||
</li>
|
checked={selectedTags.includes(tag)}
|
||||||
|
className="checkbox checkbox-sm"
|
||||||
|
onChange={() => handleTagChange(tag)}
|
||||||
|
/>
|
||||||
|
{tag.label}
|
||||||
|
</label>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-nowrap overflow-x-auto"></div>
|
<div className="flex flex-nowrap overflow-x-auto">
|
||||||
|
{existingTags}
|
||||||
|
{selectedTagElements}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* Date Picker */}
|
||||||
|
<div className="flex flex-col space-y-2 mb-2">
|
||||||
|
{/* Start */}
|
||||||
|
<div className="flex flex-row items-center">
|
||||||
|
<div>
|
||||||
|
<p className="text-xs font-bold">Start At</p>
|
||||||
|
<div className="flex items-center space-x-2">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
checked={startDateEnabled}
|
||||||
|
className="checkbox checkbox-xs"
|
||||||
|
onChange={handleStartDateChange}
|
||||||
|
/>
|
||||||
|
<div className={`rounded p-2 shadow border-2 ${!startDateEnabled && "opacity-50"}`}>
|
||||||
|
<DatePicker
|
||||||
|
selected={dateStart}
|
||||||
|
onChange={(date) => setDateStart(date)}
|
||||||
|
disabled={!startDateEnabled}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* Complete? */}
|
||||||
|
<div className="mx-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">
|
||||||
|
<p className="text-md mx-2">Complete</p>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
checked={isTaskComplete}
|
||||||
|
className="checkbox checkbox-xl"
|
||||||
|
onChange={handleTaskCompleteChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* End */}
|
||||||
|
<div>
|
||||||
|
<p className="text-xs font-bold">End At</p>
|
||||||
|
<div className="flex items-center space-x-2">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
checked={endDateEnabled}
|
||||||
|
className="checkbox checkbox-xs"
|
||||||
|
onChange={handleEndDateChange}
|
||||||
|
/>
|
||||||
|
<div className={`rounded p-2 shadow border-2 ${!endDateEnabled && "opacity-50"}`}>
|
||||||
|
<DatePicker selected={dateEnd} onChange={(date) => setDateEnd(date)} disabled={!endDateEnabled} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Description */}
|
{/* Description */}
|
||||||
<div className="flex flex-col gap-2">
|
<div className="flex flex-col gap-2">
|
||||||
<h2 className="font-bold">
|
<h2 className="font-bold">
|
||||||
@ -71,7 +182,6 @@ export function TaskDetailModal({ title, description, tags, difficulty, challeng
|
|||||||
{description}
|
{description}
|
||||||
</textarea>
|
</textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Difficulty, Challenge, and Importance */}
|
{/* Difficulty, Challenge, and Importance */}
|
||||||
<div className="flex flex-row space-x-3 my-4">
|
<div className="flex flex-row space-x-3 my-4">
|
||||||
<div className="flex-1 card shadow border-2 p-2">
|
<div className="flex-1 card shadow border-2 p-2">
|
||||||
@ -123,7 +233,6 @@ export function TaskDetailModal({ title, description, tags, difficulty, challeng
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Subtask */}
|
{/* Subtask */}
|
||||||
<div className="flex flex-col pt-2">
|
<div className="flex flex-col pt-2">
|
||||||
<h2 className="font-bold">
|
<h2 className="font-bold">
|
||||||
@ -140,7 +249,6 @@ export function TaskDetailModal({ title, description, tags, difficulty, challeng
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form method="dialog">
|
<form method="dialog">
|
||||||
<button className="btn btn-sm btn-circle btn-ghost absolute right-2 top-2">X</button>
|
<button className="btn btn-sm btn-circle btn-ghost absolute right-2 top-2">X</button>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user