diff --git a/src/app/(home)/tasks/page.js b/src/app/(home)/tasks/page.js index dbe7cd7..78b6d26 100755 --- a/src/app/(home)/tasks/page.js +++ b/src/app/(home)/tasks/page.js @@ -1,7 +1,7 @@ "use client"; // React imports -import React, { useState, useMemo, useEffect } from 'react'; +import React, { useState, useMemo, useEffect, useReducer } from 'react'; // Material UI imports import { useTheme } from '@mui/material/styles'; @@ -19,13 +19,15 @@ import { DragDropContext } from '@hello-pangea/dnd'; import TaskHeaderCard from "@/components/Cards/TaskHeaderCard"; import TaskCard from "@/components/Cards/TaskCard"; -import { Box } from "@mui/material"; +import { Box, Skeleton } from "@mui/material"; +import { Description } from '@mui/icons-material'; export default function Lists () { const client = generateClient({ authMode: 'userPool' }); // State management - const [tasks, setTasks] = useState([]); + const [tasks, setTasks] = useState(new Map()); + const [isLoading, setIsLoading] = useState(true); // Use theme from Material UI const theme = useTheme(); @@ -34,18 +36,32 @@ export default function Lists () { client.models.Tasks.list().then(({ data, errors }) => { - errors ? console.error(errors) : - setTasks(data); + let newMap = new Map(); + if(errors) { + console.error(errors); + } else { + for(const task of data) { + newMap.set(task.id, task); + } + + setIsLoading(false); + setTasks(newMap); + } }); } - useEffect(() => fetchTasks(), []); + useEffect(() => {fetchTasks()}, []); const handleTaskDelete = async (id) => { + let newMap = new Map(tasks); const { data, errors } = await client.models.Tasks.delete({ id: id }); - errors ? console.error(errors) : - fetchTasks(); + if (errors) { + console.log(errors); + } else { + newMap.delete(id); + setTasks(newMap); + } console.log('deleted'); } @@ -58,22 +74,87 @@ export default function Lists () important: false, done: false }) - errors ? console.error(errors) : - fetchTasks(); + + if (errors) { + console.log(errors); + } else { + let newMap = (new Map(tasks)).set(data.id, data); + setTasks(newMap); + } console.log('added a task'); } + const handleTitleChange = async (id, title) => { + const { errors, data } = await client.models.Tasks.update({ + "id": id, + "title": title, + }) + + if (errors) { + console.log(errors); + } else { + let newMap = (new Map(tasks)).set(data.id, data); + setTasks(newMap); + } + console.log(`updated task ${title}'s title`); + } + + const handleDescriptionChange = async (id, description) => { + const { errors, data } = await client.models.Tasks.update({ + "id": id, + "details": description, + }) + + if (errors) { + console.log(errors); + } else { + let newMap = (new Map(tasks)).set(data.id, data); + setTasks(newMap); + } + console.log(`updated task ${description}'s desc`); + } + + const handleImportantChange = async (id, important) => { + const { errors, data } = await client.models.Tasks.update({ + "id": id, + "important": important + }) + + if (errors) { + console.log(errors); + } else { + let newMap = (new Map(tasks)).set(data.id, data); + setTasks(newMap); + } + console.log(`updated task ${data.title}'s importance`); + } + + const handleDateChange = async (id, date) => { + const { errors, data } = await client.models.Tasks.update({ + "id": id, + "date": date + }) + + if (errors) { + console.log(errors); + } else { + let newMap = (new Map(tasks)).set(data.id, data); + setTasks(newMap); + } + console.log(`updated task ${data.title}'s date`); + } + return ( <> { - tasks.map((t, index) => + Array.from(tasks.values()).map((t, index) => { return ( (index === tasks.length - 1) ? - handleTaskDelete(t.id)} /> - : handleTaskDelete(t.id)} /> + handleTaskDelete(t.id)} onTitleChange={handleTitleChange} onDescriptionChange={handleDescriptionChange} onImportantChange={handleImportantChange} onDateChange={handleDateChange}/> + : handleTaskDelete(t.id)} onTitleChange={handleTitleChange} onDescriptionChange={handleDescriptionChange} onImportantChange={handleImportantChange} onDateChange={handleDateChange}/> ) }) } diff --git a/src/components/Cards/TaskCard.js b/src/components/Cards/TaskCard.js index c5a2ba7..278e30c 100644 --- a/src/components/Cards/TaskCard.js +++ b/src/components/Cards/TaskCard.js @@ -22,11 +22,14 @@ import React, { useState } from 'react'; import DatePickerDialog from "../Dialogs/DatePickerDialog"; -export default function TaskCard ({ task, borderBottomRadius, onDeleteClick }) +export default function TaskCard ({ task, borderBottomRadius, onDeleteClick, onTitleChange, onDescriptionChange, onImportantChange, onDateChange }) { const { title, details, date, important, done } = task; + const [titleValue, setTitleValue] = useState(""); + const [descrptionValue, setDescriptionValue] = useState(""); + const [enterPressed, setEnterPressed] = useState(false); const [isHovering, setIsHovering] = useState(false); const [anchorEl, setAnchorEl] = useState(null); const [isImportant, setIsImportant] = useState(important); @@ -38,12 +41,65 @@ export default function TaskCard ({ task, borderBottomRadius, onDeleteClick }) const handleMouseLeave = () => setIsHovering(false); const handleTaskOptionsClose = () => setAnchorEl(null); const handleTaskOptionsOpen = (event) => setAnchorEl(event.currentTarget); - const handleImportantIconClick = () => setIsImportant(!isImportant); + const handleImportantIconClick = () => toggleImportant(); const handleDateIconClick = () => setOpenCalendarDialog(true); - const handleCloseDialog = () => setOpenCalendarDialog(false); - - console.log(dateValue); - + const handleCloseDialog = () => handleDateChange(); + const handleTitleChange = (event) => setTitleValue(event.target.value); + const handleDescriptionChange = (event) => setDescriptionValue(event.target.value); + + const handleTitleKeyDown = (event) => { + if (event.key === 'Enter') { + setEnterPressed(true); + saveTitleValue(); + } + }; + + const handleDescriptionKeyDown = (event) => { + if (event.key === 'Enter') { + setEnterPressed(true); + saveDescriptionValue(); + } + }; + + const handleTitleBlur = () => { + if (!enterPressed) { + saveTitleValue(); + } + setEnterPressed(false); + }; + + const handleDescriptionBlur = () => { + if (!enterPressed) { + saveDescriptionValue(); + } + setEnterPressed(false); + }; + + const toggleImportant = () => { + saveImportantValue(); + setIsImportant(!isImportant); + } + + const handleDateChange = () => { + saveDateValue(); + setOpenCalendarDialog(false) + } + + const saveDescriptionValue = () => { + onDescriptionChange(task.id, descrptionValue); + }; + + const saveTitleValue = () => { + onTitleChange(task.id, titleValue); + }; + + const saveImportantValue = () => { + onImportantChange(task.id, !isImportant) + } + + const saveDateValue = () => { + onDateChange(task.id, dateValue) + } const TaskOptionsMenu = ( - + { (isHovering) ? <> @@ -99,7 +155,7 @@ export default function TaskCard ({ task, borderBottomRadius, onDeleteClick }) - + @@ -115,4 +171,4 @@ export default function TaskCard ({ task, borderBottomRadius, onDeleteClick }) ); -} \ No newline at end of file +}