From 650887153cc81cdc06002826cce3202b37be389f Mon Sep 17 00:00:00 2001 From: karan-sanskar Date: Sun, 20 Jul 2025 19:34:03 +0530 Subject: [PATCH 1/2] [Fix]: Updated filters for my day --- frontend/src/pages/quickdo/my-day-view.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/pages/quickdo/my-day-view.tsx b/frontend/src/pages/quickdo/my-day-view.tsx index 3f1f7cb..cb044f6 100644 --- a/frontend/src/pages/quickdo/my-day-view.tsx +++ b/frontend/src/pages/quickdo/my-day-view.tsx @@ -24,7 +24,7 @@ const MyDayView = (props: DashboardProps) => { const jsDate = new Date() // ? Use getFormattedDate for consistency with filter-utils const todayDate = getFormattedDate(jsDate) - const defaultFilter = [["date", "=", todayDate]] + const defaultFilter = [["date", "in", [todayDate,""]]] const [currentSort, setCurrentSort] = useState("creation") const [currentSortDirection, setCurrentSortDirection] = useState("desc") const [filters, setFilters] = useState(defaultFilter) From 63e3298794d7fd966c326ba61f40fd113625f9c1 Mon Sep 17 00:00:00 2001 From: karan-sanskar Date: Mon, 21 Jul 2025 01:38:13 +0530 Subject: [PATCH 2/2] [Feat]: New feature to auto close drawer on delete on all the view and fixed issue-34 Cannot able to close the drawer in the calendar view --- .../src/components/layout/quickdo-drawer.tsx | 431 ++++++++---------- .../src/components/layout/quickdo-item.tsx | 363 +++++++-------- frontend/src/pages/quickdo/calendar-view.tsx | 369 +++++++-------- frontend/src/types/Common.ts | 1 + 4 files changed, 519 insertions(+), 645 deletions(-) diff --git a/frontend/src/components/layout/quickdo-drawer.tsx b/frontend/src/components/layout/quickdo-drawer.tsx index 911108e..b8e716c 100644 --- a/frontend/src/components/layout/quickdo-drawer.tsx +++ b/frontend/src/components/layout/quickdo-drawer.tsx @@ -1,18 +1,20 @@ -import { FaAngleRight } from "react-icons/fa6"; -import { useEffect, useState } from "react"; +"use client" + +import { FaAngleRight } from "react-icons/fa6" +import { useEffect, useState } from "react" import { PiBellRingingLight, PiCalendarCheckFill, PiCalendarDotsLight, PiListBullets, PiListChecks, -} from "react-icons/pi"; -import { PiBellRingingFill } from "react-icons/pi"; -import { FaCheck } from "react-icons/fa6"; -import { HiOutlineStar } from "react-icons/hi2"; -import { BiSolidStar } from "react-icons/bi"; -import ConfirmBox from "@/components/ui/confirm"; -import { useAllCategories, DrawerProps, Status } from "../../types/Common"; +} from "react-icons/pi" +import { PiBellRingingFill } from "react-icons/pi" +import { FaCheck } from "react-icons/fa6" +import { HiOutlineStar } from "react-icons/hi2" +import { BiSolidStar } from "react-icons/bi" +import ConfirmBox from "@/components/ui/confirm" +import type { useAllCategories, DrawerProps, Status } from "../../types/Common" import { Drawer, DrawerClose, @@ -21,107 +23,127 @@ import { DrawerHeader, DrawerTitle, DrawerTrigger, -} from "@/components/ui/drawer"; -import { Button } from "@/components/ui/button"; -import { IoClose, IoInformationCircle } from "react-icons/io5"; -import { Calendar } from "@/components/ui/calendar"; -import { - Popover, - PopoverContent, - PopoverTrigger, -} from "@/components/ui/popover"; -import { Textarea } from "@/components/ui/textarea"; -import { RxCross1 } from "react-icons/rx"; +} from "@/components/ui/drawer" +import { Button } from "@/components/ui/button" +import { IoClose, IoInformationCircle } from "react-icons/io5" +import { Calendar } from "@/components/ui/calendar" +import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover" +import { Textarea } from "@/components/ui/textarea" +import { RxCross1 } from "react-icons/rx" const QuickDoDrawer = (props: DrawerProps) => { + // ? STATE HOOKS + const [status, setStatus] = useState(props.todoData.status) + const [isImportant, setIsImportant] = useState(props.todoData.is_important) + const [sendReminder, setSendReminder] = useState(props.todoData.send_reminder) + const [description, setDescription] = useState(props.todoData.description) + const [date, setdate] = useState(props.todoData.date) + const [showCategories, setShowCategories] = useState(false) + const [categories, setCategories] = useState(props.todoData.categories) + const [allCategories, setAllCategories] = useState(props.allCategories) + const [isDataChanged, setIsDataChanged] = useState(false) + + // ? RESPONSIVE: MOBILE SCREEN STATE + const [isMobileScreen, setIsMobileScreen] = useState( + typeof window !== "undefined" ? window.innerWidth < 640 : false + ) + + // ? HANDLE RESPONSIVE SCREEN SIZE + useEffect(() => { + const handler = () => setIsMobileScreen(window.innerWidth < 640) + handler() + window.addEventListener("resize", handler) + return () => window.removeEventListener("resize", handler) + }, []) - //? HOOKS - const [status, setStatus] = useState(props.todoData.status); - const [isImportant, setIsImportant] = useState(props.todoData.is_important); - const [sendReminder, setSendReminder] = useState(props.todoData.send_reminder); - const [description, setDescription] = useState(props.todoData.description); - const [date, setdate] = useState(props.todoData.date); - const [showCategories, setShowCategories] = useState(false); - const [categories, setCategories] = useState(props.todoData.categories); - const [allCategories, setAllCategories] = useState(props.allCategories); - const [autoOpenDrawer, setAutoOpenDrawer] = useState(props.autoOpenDrawer || false); - const [isDataChanged, setIsDataChanged] = useState(false); - - //? SET MOBILE SCREEN - const [isMobileScreen, setIsMobileScreen] = useState(window.innerWidth < 640 ? true : false); - - //? SET SCREEN WIDTH HANDLER + // ? RESET LOCAL STATE IF PROPS todoData CHANGE useEffect(() => { - const screenWidthHandler = () => { - if (window.innerWidth < 640) { - setIsMobileScreen(true); - } else { - setIsMobileScreen(false); - } - }; - screenWidthHandler(); - window.addEventListener("resize", screenWidthHandler); - }, [window.screen.width]); + setStatus(props.todoData.status) + setIsImportant(props.todoData.is_important) + setSendReminder(props.todoData.send_reminder) + setDescription(props.todoData.description) + setdate(props.todoData.date) + setCategories(props.todoData.categories) + setIsDataChanged(false) + }, [props.todoData]) + + // ? RESET ALL CATEGORIES STATE IF PROPS CHANGE + useEffect(() => { + setAllCategories(props.allCategories) + }, [props.allCategories]) - //? DELETE TODO HANDLER + // ? HANDLE DELETING THE TODO const handleDeleteTodo = () => { - props.handleDeleteTodo(props.todoData.name || ""); - }; - - //? STATUS HANDLER - const handleStatus = (status: Status) => { - if (status === "Open") { - setStatus("Completed"); - } else if (status === "Completed") { - setStatus("Cancelled"); - } else { - setStatus("Open"); - } - }; + props.handleDeleteTodo(props.todoData.name || "") + props.onCloseRequest?.() + } - // ? UPDATE DATA AS PROPS CHANGES - useEffect(() => { - setStatus(props.todoData.status); - setIsImportant(props.todoData.is_important); - setSendReminder(props.todoData.send_reminder); - setDescription(props.todoData.description); - setdate(props.todoData.date); - setCategories(props.todoData.categories); - }, [props.todoData]); + // ? HANDLE STATUS CYCLE CLICK + const handleStatus = () => { + setStatus((prevStatus) => { + let newStatus: Status + if (prevStatus === "Open") newStatus = "Completed" + else if (prevStatus === "Completed") newStatus = "Cancelled" + else newStatus = "Open" + setIsDataChanged(true) + return newStatus + }) + } - //? UPDATE CATEGORIES AS PROPS UPDATES - useEffect(() => { - setAllCategories(props.allCategories); - }, [props.allCategories]); + // ? HANDLE DESCRIPTION CHANGE + const handleDescriptionChange = (val: string) => { + setDescription(val) + setIsDataChanged(true) + } - //? UPDATE AUTO OPEN DRAWER AS PER THE PARENT - useEffect(() => { - setAutoOpenDrawer(props.autoOpenDrawer || false); - }, [props.autoOpenDrawer]); + // ? HANDLE DUE DATE CHANGE + const handleSetDate = (selectedDate: Date | undefined) => { + const year = selectedDate?.getFullYear() + const month = String((selectedDate?.getMonth() ?? 0) + 1).padStart(2, "0") + const day = String(selectedDate?.getDate()).padStart(2, "0") + const formattedDate = selectedDate ? `${year}-${month}-${day}` : "" + setdate(formattedDate) + setIsDataChanged(true) + } - //? HANDLE CLEAR CATEGORY - const handleClearCategory = () => { - setCategories([]); - setIsDataChanged(true); + // ? HANDLE IMPORTANCE + const handleImportance = () => { + setIsImportant((prev) => { + setIsDataChanged(true) + return !prev + }) } - //? HANDLE SET DATE - const handleSetDate = (e: any) => { - const year = e?.getFullYear(); - const month = String(e?.getMonth() + 1).padStart(2, "0"); - const day = String(e?.getDate()).padStart(2, "0"); + // ? HANDLE REMINDER + const handleReminder = () => { + setSendReminder((prev) => { + setIsDataChanged(true) + return !prev + }) + } - //? FORMAT DATE AS YYYY-MM-DD - const formattedDate = e ? `${year}-${month}-${day}` : ""; + // ? CLEAR ALL CATEGORIES + const handleClearCategory = () => { + setCategories([]) + setIsDataChanged(true) + } - setdate(formattedDate); - setIsDataChanged(true); - }; + // ? MULTISELECT CATEGORY HANDLER + const handleCategoryMultiSelect = (category: string) => { + setCategories((prevCategories) => { + let next: useAllCategories[] + if (prevCategories.some((item) => item.category === category)) { + next = prevCategories.filter((item) => item.category !== category) + } else { + next = [...prevCategories, { category }] + } + setIsDataChanged(true) + return next + }) + } - //? UPDATE TODO + // ? SAVE HANDLER (CALLED BY DRAWER ONCLOSE) const handleSaveToDo = () => { - - // ? UPDATE OLY OF THE DATA IS CHANGED if (isDataChanged) { props.handleSaveToDo({ name: props.todoData.name, @@ -135,64 +157,49 @@ const QuickDoDrawer = (props: DrawerProps) => { description: description, date: date, categories: categories, - }); - setIsDataChanged(false); + }) + setIsDataChanged(false) } - }; - - //? CATEGORIES MULTISELECT HANDLER - const handleCategoryMultiSelect = (category: string) => { - setCategories((prevCategories) => { - if (prevCategories.some((item) => item.category === category)) { - return prevCategories.filter((item) => item.category !== category); - } else { - return [...prevCategories, { category }]; - } - }); - setIsDataChanged(true); - }; + } + // ? RENDER return ( <> - - {/* DRAWER */} + {/* ? DRAWER COMPONENT (MOBILE=bottom, DESKTOP=right) */} { - handleSaveToDo(); + direction={isMobileScreen ? "bottom" : "right"} + onClose={handleSaveToDo} + open={props.autoOpenDrawer} + onOpenChange={(openState) => { + // ? REQUEST PARENT TO CLOSE IF DRAWER CLOSES (BACK OR DRAG CLOSE) + if (!openState) { + props.onCloseRequest?.() + } }} - open={autoOpenDrawer || undefined} > - - {/* DRAWER TRIGGER */} - + {/* ? DRAWER TRIGGER BUTTON */} + - {/* DRAWER CONTENT */} - - {/* DRAWER HEADER */} + {/* ? DRAWER CONTENT */} + + {/* ? DRAWER HEADER */} - - Drawer Description - - - - - {/* DELETE CONFIRM BOX */} + {/* ? DELETE CONFIRM BOX */} { - {/* MAIN CONTENT */} + {/* ? MAIN CONTENT */}
- - {/* TODO DESCRIPTION */} + {/* ? TODO DESCRIPTION FIELD */}
{ + onChange={(e) => handleDescriptionChange(e.target.value)} + />
- {/* FORM CONTAINER */} + {/* ? FORM CONTAINER */}
- {/* TODO DUE DATE */} + {/* ? TODO DUE DATE PICKER */} - +
- - + +
-
- {/* STATUS TODO */} + {/* ? TODO STATUS CYCLE */}
{ - handleStatus(status); - setIsDataChanged(true); - }} + onClick={handleStatus} title="Status" > - -
-

Status QuickDo

-
+

Status QuickDo

- {/* TODO IMPORTANCE */} + {/* ? TODO IMPORTANCE BUTTON */}
{ - setIsImportant(!isImportant); - setIsDataChanged(true); - }} + onClick={handleImportance} title="Importance" >

Importance

- {/* TODO REMINDER */} + {/* ? TODO REMINDER BUTTON */}
{ - setSendReminder(!sendReminder); - setIsDataChanged(true); - }} + onClick={handleReminder} title="Reminder" >

Reminder

- {/* TODO CATEGORIES */} + {/* ? TODO CATEGORIES SECTION */}
- - {/* CATEGORIES TOOLBAR */}
{ - setShowCategories(!showCategories); - }} + className="categories-toolbar pb-2 flex justify-between border-b border-gray-200 " + onClick={() => setShowCategories(!showCategories)} title="Categories" > - - {/* CATEGORIES ICON */}

Categories

- - {/* CLEAR CATEGORIES */} -
- - {/* CATEGORIES ITEMS DROPDOWN*/} -
+
{allCategories && allCategories.map((data, index) => (
{ id="ToDo" value={description} onChange={(e) => { - setDescription(e.target.value); + handleDescriptionChange(e.target.value) }} onKeyUp={(e) => { if (e.key === "Enter") { - e.currentTarget.blur(); + e.currentTarget.blur() } }} - onBlur={() => { - description.trim() !== props.todoData.description.trim() && handleSaveToDo(); - }} + onBlur={handleDescriptionBlur} />
- {/* EDIT AND CLOSE TASK */} + {/* ? END EDIT AND CLOSE TASK */} - {/* DUE DATE */} + {/* ? DUE DATE */}
- - { - handleSetDate(e); - setDatePopupOpen(false); + handleSetDate(e) + setDatePopupOpen(false) }} initialFocus />
- {/* END DUE DATE */} + {/* ? END DUE DATE */} - {/* IMPORTANCE */} + {/* ? IMPORTANCE */}
- {/* END IMPORTANCE */} + {/* ? END IMPORTANCE */} - {/* CATEGORIES */} + {/* ? CATEGORIES */}
- - {/* CATEGORIES MULTISELECT */} { categories={categories} handleCategories={handleCategories} /> - {/* END CATEGORIES MULTISELECT */} -
- {/* END CATEGORIES */} - - {/* MORE */} - - {/* END MORE */} - + {/* ? END CATEGORIES */} + + {/* ? MORE / DRAWER TRIGGER BUTTON */} + + + {/* ? QUICKDODRAWER - CONDITIONALLY RENDERED */} + {isDrawerOpen && ( + + )}
- {/* END LIST ITEMS */} + {/* ? END LIST ITEMS */} - ); -}; + ) +} -export default QuickDoItem; +export default QuickDoItem diff --git a/frontend/src/pages/quickdo/calendar-view.tsx b/frontend/src/pages/quickdo/calendar-view.tsx index 03a53f1..5b6c7bc 100644 --- a/frontend/src/pages/quickdo/calendar-view.tsx +++ b/frontend/src/pages/quickdo/calendar-view.tsx @@ -1,45 +1,43 @@ -import { CalendarEvents, DashboardProps, useAllQuickDoData, useAllCategories } from "@/types/Common"; -import { Calendar, dayjsLocalizer } from "react-big-calendar"; -import withDragAndDrop from "react-big-calendar/lib/addons/dragAndDrop"; -import dayjs from "dayjs"; -import "react-big-calendar/lib/addons/dragAndDrop/styles.css"; -import "react-big-calendar/lib/css/react-big-calendar.css"; -import { useEffect, useState } from "react"; -import axios from "axios"; -import { toast } from 'sonner' -import QuickDoDrawer from "@/components/layout/quickdo-drawer"; -import Navbar from "@/components/layout/navbar"; -import Sidebar from "@/components/layout/sidebar"; - -const localizer = dayjsLocalizer(dayjs); -const DnDCalendar = withDragAndDrop(Calendar); +"use client" + +import type { CalendarEvents, DashboardProps, useAllQuickDoData, useAllCategories } from "@/types/Common" +import { Calendar, dayjsLocalizer } from "react-big-calendar" +import withDragAndDrop from "react-big-calendar/lib/addons/dragAndDrop" +import dayjs from "dayjs" +import "react-big-calendar/lib/addons/dragAndDrop/styles.css" +import "react-big-calendar/lib/css/react-big-calendar.css" +import { useEffect, useState } from "react" +import axios from "axios" +import { toast } from "sonner" +import QuickDoDrawer from "@/components/layout/quickdo-drawer" +import Navbar from "@/components/layout/navbar" +import Sidebar from "@/components/layout/sidebar" + +const localizer = dayjsLocalizer(dayjs) +const DnDCalendar = withDragAndDrop(Calendar) const CalendarView = (props: DashboardProps) => { - - //? HOOKS - const [events, setEvents] = useState([]); - const BASE_URL = import.meta.env.VITE_BASE_URL || window.location.origin; - const AUTH_TOKEN = import.meta.env.VITE_AUTH_TOKEN || null; - - - // TODO WILL REPLACE WITH THE SOCKET - //? UPDATE STATE - const [refreshState, setRefreshState] = useState(true); + // ? HOOKS + const [events, setEvents] = useState([]) + const BASE_URL = import.meta.env.VITE_BASE_URL || window.location.origin + const AUTH_TOKEN = import.meta.env.VITE_AUTH_TOKEN || null + + // ? TODO WILL REPLACE WITH THE SOCKET + // ? UPDATE STATE + const [refreshState, setRefreshState] = useState(true) const handleRefreshState = (state: boolean) => { - setRefreshState(state); - }; - - //? CATEGORY API DATA - const [getAllCategories, setGetAllCategories] = useState([]); - + setRefreshState(state) + } - //? TODO DATA - const [todoData, setTodoData] = useState(); + // ? CATEGORY API DATA + const [getAllCategories, setGetAllCategories] = useState([]) + // ? TODO DATA + const [todoData, setTodoData] = useState() // ? EXPLICITLY SET TO UNDEFINED - //? CATEGORIES LIST API + // ? CATEGORIES LIST API useEffect(() => { - //? FETCH CATEGORY LIST API FUNCTION + // ? FETCH CATEGORY LIST API FUNCTION const fetchAPI = async () => { try { const response = await axios.get( @@ -48,33 +46,29 @@ const CalendarView = (props: DashboardProps) => { headers: { Authorization: AUTH_TOKEN, }, - } - ); - - //? IF THE API RETURNS DATA + }, + ) + // ? IF THE API RETURNS DATA if (response.data.message) { - //? SET ALL CATEGORIES STATE - setGetAllCategories(response.data.message); - - //? REFRESH STATE - handleRefreshState(false); + // ? SET ALL CATEGORIES STATE + setGetAllCategories(response.data.message) + // ? REFRESH STATE + handleRefreshState(false) } } catch (error) { - console.log(error); - toast.error("There was a problem while loading Categories!"); + console.log(error) + toast.error("There was a problem while loading Categories!") } - }; - - //? CALL THE FETCH API FUNCTION + } + // ? CALL THE FETCH API FUNCTION if (refreshState) { - fetchAPI(); + fetchAPI() } - }, [refreshState]); + }, [refreshState, BASE_URL, AUTH_TOKEN]) - //? SAVE TODO HANDLER + // ? SAVE TODO HANDLER const handleSaveToDo = (data: useAllQuickDoData) => { - - //? MAP THE OBJECT TO FRAPPE'S DATA + // ? MAP THE OBJECT TO FRAPPE'S DATA const finalData: useAllQuickDoData = { name: data?.name, owner: data?.owner, @@ -82,15 +76,14 @@ const CalendarView = (props: DashboardProps) => { modified: data?.modified, modified_by: data?.modified_by, doctype: "QuickDo", - status: data.status ? "Completed" : "Open", + status: data.status === "Completed" ? "Completed" : "Open", is_important: data.is_important, send_reminder: data.send_reminder, description: data.description, date: data.date, categories: data.categories, - }; - - //? FETCH SAVE TODO API FUNCTION + } + // ? FETCH SAVE TODO API FUNCTION const fetchAPI = async (finalData: useAllQuickDoData) => { try { const response = await axios.post( @@ -103,39 +96,34 @@ const CalendarView = (props: DashboardProps) => { headers: { Authorization: AUTH_TOKEN, }, - } - ); - - //? REFRESH THE STATE + }, + ) + // ? REFRESH THE STATE if (response.status === 200) { - handleRefreshState(true); - + handleRefreshState(true) // ? IF NEW CREATED if (!finalData.name) { - toast.success("The QuickDo has been created!"); + toast.success("The QuickDo has been created!") } - // ? IF UPDATED else { - toast.success("The QuickDo has been updated!"); + toast.success("The QuickDo has been updated!") } - - setTodoData(undefined); + setTodoData(undefined) // ? CLEAR TODODATA TO CLOSE THE DRAWER } } catch (error) { - console.log(error); - toast.error("There was a problem while saving QuickDo!"); - setTodoData(undefined); + console.log(error) + toast.error("There was a problem while saving QuickDo!") + setTodoData(undefined) // ? CLEAR TODODATA EVEN ON ERROR TO CLOSE THE DRAWER } - }; - - //? FETCH POST API CALL - fetchAPI(finalData); - }; + } + // ? FETCH POST API CALL + fetchAPI(finalData) + } - //? DELETE TODO HANDLER + // ? DELETE TODO HANDLER const handleDeleteTodo = (data: string) => { - //? FETCH DELETE TODO API FUNCTION + // ? FETCH DELETE TODO API FUNCTION const fetchAPI = async (data: string) => { try { const response = await axios.post( @@ -148,27 +136,26 @@ const CalendarView = (props: DashboardProps) => { headers: { Authorization: AUTH_TOKEN, }, - } - ); - - //? REFRESH THE STATE + }, + ) + // ? REFRESH THE STATE if (response.status === 200) { - handleRefreshState(true); - toast.success("The QuickDo has been deleted!"); + handleRefreshState(true) + toast.success("The QuickDo has been deleted!") + setTodoData(undefined) // ? CLEAR TODODATA TO CLOSE THE DRAWER } } catch (error) { - console.log(error); - toast.error("There was a problem while deleting QuickDo!"); + console.log(error) + toast.error("There was a problem while deleting QuickDo!") } - }; - - //? CALL FETCH API - fetchAPI(data); - }; + } + // ? CALL FETCH API + fetchAPI(data) + } - //? DELETE TODO HANDLER + // ? GET TODO HANDLER const handleGetTodo = (data: string) => { - //? FETCH DELETE TODO API FUNCTION + // ? FETCH GET TODO API FUNCTION const fetchAPI = async (data: string) => { try { const response = await axios.post( @@ -181,29 +168,19 @@ const CalendarView = (props: DashboardProps) => { headers: { Authorization: AUTH_TOKEN, }, - } - ); - - //? REFRESH THE STATE + }, + ) + // ? REFRESH THE STATE if (response.data.message) { - handleRefreshState(true); - - const todoDoc = response.data.message; - - //? PARSE THE TODO HTML - const parser = new DOMParser(); - const description_doc = parser.parseFromString( - todoDoc.description, - "text/html" - ); - const description: any = description_doc.querySelector( - ".ql-editor.read-mode p" - )?.textContent - ? description_doc.querySelector(".ql-editor.read-mode p") - ?.textContent - : todoDoc.description; - - //? UPDATE THE FINAL DATA + handleRefreshState(true) + const todoDoc = response.data.message + // ? PARSE THE TODO HTML + const parser = new DOMParser() + const description_doc = parser.parseFromString(todoDoc.description, "text/html") + const description: any = description_doc.querySelector(".ql-editor.read-mode p")?.textContent + ? description_doc.querySelector(".ql-editor.read-mode p")?.textContent + : todoDoc.description + // ? UPDATE THE FINAL DATA const finalData: useAllQuickDoData = { name: todoDoc.name, owner: todoDoc.owner, @@ -216,19 +193,17 @@ const CalendarView = (props: DashboardProps) => { description: description || "", date: todoDoc.date || "", categories: todoDoc.categories || [], - }; - - setTodoData(finalData); + } + setTodoData(finalData) } } catch (error) { - console.log(error); - toast.error("There was a problem while getting QuickDo!"); + console.log(error) + toast.error("There was a problem while getting QuickDo!") } - }; - - //? CALL FETCH API - fetchAPI(data); - }; + } + // ? CALL FETCH API + fetchAPI(data) + } // ? UPDATE QUICKDO FUNCTION const updateQuickDo = async (name: string, value: string) => { @@ -239,29 +214,25 @@ const CalendarView = (props: DashboardProps) => { doctype: "QuickDo", name: name, fieldname: "date", - value: value + value: value, }, { headers: { Authorization: AUTH_TOKEN, }, - } - ); - - //? IF QUICKDO UPDATED SUCCESSFULLY + }, + ) + // ? IF QUICKDO UPDATED SUCCESSFULLY if (response.status === 200) { - toast.success("The due date of the QuickDo has been updated!"); + toast.success("The due date of the QuickDo has been updated!") } } catch (error) { - console.log(error); - toast.error("There was a problem while updating QuickDo!"); + console.log(error) + toast.error("There was a problem while updating QuickDo!") } - }; - + } // ? LOAD QUICKDO DATA API FUNCTION - - useEffect(() => { const loadQuickDoDataAPI = async () => { try { @@ -269,119 +240,93 @@ const CalendarView = (props: DashboardProps) => { headers: { Authorization: AUTH_TOKEN, }, - }); - - //? IF NO ERROR + }) + // ? IF NO ERROR if (response.data.message) { - // ? DEFINE VARIABLES - const QuickDoData = response.data.message; - + const QuickDoData = response.data.message QuickDoData.map((item: any) => { - item.start = dateTimeConverter("start", item.start); - item.end = dateTimeConverter("end", item.end); - }); - + item.start = dateTimeConverter("start", item.start) + item.end = dateTimeConverter("end", item.end) + }) // ? SET EVENT DATA - setEvents(QuickDoData); + setEvents(QuickDoData) } - } - catch (error) { - console.log(error); - toast.error("There was a problem while loading QuickDos!"); + } catch (error) { + console.log(error) + toast.error("There was a problem while loading QuickDos!") } } - - loadQuickDoDataAPI(); - }, [refreshState]) - + loadQuickDoDataAPI() + }, [refreshState, BASE_URL, AUTH_TOKEN]) // ? DATE TIME CONVERTER - function dateTimeConverter(field: string = "start", date: string = "00-00-00") { + function dateTimeConverter(field = "start", date = "00-00-00") { if (field === "start") { return new Date(`${date} 00:00:00`) - } - else if (field === "end") { + } else if (field === "end") { return new Date(`${date} 23:59:59`) } } - //? SELECT EVENT HANDLER + // ? SELECT EVENT HANDLER const handleSelectEvent = (data: any) => { - handleGetTodo(data.name); + handleGetTodo(data.name) } - //? DROP EVENT HANDLER + // ? DROP EVENT HANDLER const handleDropEvent = (data: any) => { - - //? CHECK IF THE EVENT IS ONE DAY EVENT MAKE THE END DATE PRIMARY - const isSameDay = dayjs(data.start).isSame(dayjs(data.end), "day"); - - //? IF THE EVENT IS IN THE SAME DAY + // ? CHECK IF THE EVENT IS ONE DAY EVENT MAKE THE END DATE PRIMARY + const isSameDay = dayjs(data.start).isSame(dayjs(data.end), "day") + // ? IF THE EVENT IS IN THE SAME DAY if (isSameDay) { - // ? UPDATE THE EVENTS DATA setEvents((prevEvents) => - prevEvents.map((ev) => - ev.title === data.event.title ? { ...ev, start: data.start, end: data.end } : ev - ) - ); - + prevEvents.map((ev) => (ev.title === data.event.title ? { ...ev, start: data.start, end: data.end } : ev)), + ) // ? UPDATE THE DATA API - updateQuickDo(data.event.name, data.end.toISOString().split('T')[0]); + updateQuickDo(data.event.name, data.end.toISOString().split("T")[0]) } - // ? IF THE EVENT IS NOT IN SAME DAY MAKE IT AS START DATE ONE DAY EVENT else { - const startDate = dateTimeConverter("start", data.start.toISOString().split('T')[0]); - const endDate = dateTimeConverter("end", data.start.toISOString().split('T')[0]); - + const startDate = dateTimeConverter("start", data.start.toISOString().split("T")[0]) + const endDate = dateTimeConverter("end", data.start.toISOString().split("T")[0]) // ? UPDATE THE EVENTS DATA // @ts-ignore setEvents((prevEvents) => - prevEvents.map((ev) => - ev.title === data.event.title ? { ...ev, start: startDate, end: endDate } : ev - ) - ); - + prevEvents.map((ev) => (ev.title === data.event.title ? { ...ev, start: startDate, end: endDate } : ev)), + ) // ? UPDATE THE DATA API - updateQuickDo(data.event.name, data.start.toISOString().split('T')[0]); + updateQuickDo(data.event.name, data.start.toISOString().split("T")[0]) } - }; - - + } // ? EVENT COLOR STYLING USING THE EVENT PROP GETTER const eventPropGetter = (event: CalendarEvents) => { - // ? DEFINE VARIABLES - let backgroundColor = ""; - + let backgroundColor = "" // ? SET COLORS AS PER NEEDS if (event.color) { - backgroundColor = event.color; + backgroundColor = event.color } else if (event.is_important) { - backgroundColor = "#CB2929"; + backgroundColor = "#CB2929" } else if (event.sent_reminder) { - backgroundColor = "#EC864B"; + backgroundColor = "#EC864B" } else { - backgroundColor = "#3c50e0"; + backgroundColor = "#3c50e0" } - return { style: { backgroundColor }, - }; - }; + } + } + return ( <> - - {/* NAVBAR */} + {/* ? NAVBAR */} - - {/* SIDEBAR */} + {/* ? SIDEBAR */} - - {/* DASHBOARD CONTAINER */} + {/* ? DASHBOARD CONTAINER */}
{ onSelectEvent={handleSelectEvent} resizable={false} /> - {todoData && + {todoData && ( setTodoData(undefined)} // ? CALLBACK TO CLOSE THE DRAWER /> - } - + )}
- {/* END DASHBOARD CONTAINER */} + {/* ? END DASHBOARD CONTAINER */} - ); -}; + ) +} -export default CalendarView; +export default CalendarView diff --git a/frontend/src/types/Common.ts b/frontend/src/types/Common.ts index 0856bfc..b6064ae 100644 --- a/frontend/src/types/Common.ts +++ b/frontend/src/types/Common.ts @@ -158,6 +158,7 @@ export type DrawerProps = { handleSaveToDo: (data: useAllQuickDoData) => void; handleDeleteTodo: (data: string) => void; autoOpenDrawer?: boolean; + onCloseRequest?: () => void; }; //? CONFIRM BOX PROPS