diff --git a/frontend/src/components/charts/StatusDonutChart.tsx b/frontend/src/components/charts/StatusDonutChart.tsx index fe431de..b53c8dd 100644 --- a/frontend/src/components/charts/StatusDonutChart.tsx +++ b/frontend/src/components/charts/StatusDonutChart.tsx @@ -39,7 +39,6 @@ const chartConfig = { } satisfies ChartConfig export const StatusDonutChart = ({ data }: any) => { - console.log(data) const totalQuickdos = data.reduce((acc: any, curr: any) => acc + curr.quickdo, 0) return ( diff --git a/frontend/src/components/layout/filters.tsx b/frontend/src/components/layout/filters.tsx index 3a33755..fc7b136 100644 --- a/frontend/src/components/layout/filters.tsx +++ b/frontend/src/components/layout/filters.tsx @@ -1,9 +1,13 @@ -import React from "react"; +"use client" + +import type React from "react" +import { useState } from "react" import { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, + DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuSeparator, @@ -11,113 +15,237 @@ import { DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, - DropdownMenuItem } from "@/components/ui/dropdown-menu" -import { IoClose } from "react-icons/io5"; -import { Button } from "../ui/button"; +import { Calendar } from "@/components/ui/calendar" +import { X, Check } from "lucide-react" +import { Button } from "@/components/ui/button" + +// ? IMPORT ALL UTILITY FUNCTIONS FROM SINGLE FILE +import { + getSelectedDate, + getFormattedDate, + isSameDay, + isDateFilterActive, + isStatusFilterActive, + isCategoryFilterActive, + isImportanceFilterActive, + isReminderFilterActive, + type useStatusFiltersItems, +} from "@/utils/filter-utils" interface FiltersProps { - filters: any[]; - useStatusFilterData: any[]; - getAllCategories: any[]; - defaultFilter: any[]; - handleFilters: (type: string, value: string, label?: string) => void; - handleClearFilters: () => void; - setRefreshState: (state: boolean) => void; + filters: any[] + useStatusFilterData: useStatusFiltersItems[] + getAllCategories: any[] + defaultFilter?: any[] + handleFilters: (key: string, value: string, filter_type?: "single" | "multi", child_table?: string) => void + handleClearFilters: () => void + setRefreshState: (state: boolean) => void } -const Filters: React.FC = ({ filters, useStatusFilterData, getAllCategories, handleFilters, handleClearFilters, setRefreshState, defaultFilter = null }) => { +const Filters: React.FC = ({ + filters, + useStatusFilterData, + getAllCategories, + handleFilters, + handleClearFilters, + setRefreshState, + defaultFilter = [], +}) => { + const [dropdownOpen, setDropdownOpen] = useState(false) + + // ? HANDLE DATE SELECTION - SINGLE DATE ONLY WITH PROPER HIGHLIGHTING + const handleDateSelect = (selectedDate: Date | undefined) => { + const currentSelectedDate = getSelectedDate(filters) + + // ? If clicking on the same date that's already selected, remove the filter + if (selectedDate && currentSelectedDate && isSameDay(selectedDate, currentSelectedDate)) { + handleFilters("date", "", "single") + setDropdownOpen(false) + return + } + + // ? If no date selected, remove filter + if (!selectedDate) { + handleFilters("date", "", "single") + setDropdownOpen(false) + return + } + + // ? Apply filter for the selected date only + const formattedDate = getFormattedDate(selectedDate) + handleFilters("date", formattedDate, "single") + + // ? Close dropdown after selection + setTimeout(() => { + setDropdownOpen(false) + }, 150) + } + + // ? HANDLE IMPORTANCE FILTER WITH DROPDOWN CLOSE + const handleImportanceFilter = () => { + handleFilters("is_important", "1", "single") + setTimeout(() => { + setDropdownOpen(false) + }, 150) + } + + // ? HANDLE REMINDER FILTER WITH DROPDOWN CLOSE + const handleReminderFilter = () => { + handleFilters("send_reminder", "1", "single") + setTimeout(() => { + setDropdownOpen(false) + }, 150) + } return (
- + - + Filters - - {/* STATUS FILTERS */} + {/* // ? STATUS FILTERS - MULTI-VALUE WITH RIGHT-SIDE CHECKBOX */} - Status + +
+ Status +
+ {isStatusFilterActive(filters) && } +
+
+
- {useStatusFilterData.length > 0 && useStatusFilterData.map((data, index) => ( - filter[0] === "status" && filter[2]?.includes(data.name))} - onCheckedChange={() => handleFilters("status", data.name)} - > - {data.name} - - ))} + {useStatusFilterData.length > 0 && + useStatusFilterData.map((data, index) => ( + filter[0] === "status" && filter[2]?.includes(data.name))} + onCheckedChange={() => handleFilters("status", data.name, "multi")} + > + {data.name} + + ))}
- {/* CATEGORY FILTERS */} + {/* // ? CATEGORY FILTERS - MULTI-VALUE WITH RIGHT-SIDE CHECKBOX */} - - Category + +
+ Category +
+ {isCategoryFilterActive(filters) && } +
+
- {getAllCategories.length > 0 && getAllCategories.map((data, index) => ( - filter[0] === "QuickDo Categories" && filter[3]?.includes(data.category))} - onCheckedChange={() => handleFilters("category", data.category, "QuickDo Categories")} - > - {data.category} - - ))} + {getAllCategories.length > 0 && + getAllCategories.map((data, index) => ( + filter[0] === "QuickDo Categories" && filter[3]?.includes(data.category), + )} + onCheckedChange={() => handleFilters("category", data.category, "multi", "QuickDo Categories")} + > + {data.category} + + ))}
- {/* DUE DATE FILTER */} - - Due Date - + {/* // ? DUE DATE FILTER - SINGLE DATE SELECTION WITH RIGHT-SIDE CHECKBOX */} + + +
+ Due Date +
+ {isDateFilterActive(filters) && } +
+
+
+ + + + + +
- {/* IMPORTANCE FILTER */} - filter[0] === "is_important" && filter[2]?.includes("1"))} - onCheckedChange={() => handleFilters("is_important", "1")} + {/* // ? IMPORTANCE FILTER - SINGLE-VALUE WITH RIGHT-SIDE CHECKBOX AND DROPDOWN CLOSE */} + - Importance - + Importance +
+ {isImportanceFilterActive(filters) && } +
+ - {/* REMINDER FILTER */} - filter[0] === "send_reminder" && filter[2]?.includes("1"))} - onCheckedChange={() => handleFilters("send_reminder", "1")} + {/* // ? REMINDER FILTER - SINGLE-VALUE WITH RIGHT-SIDE CHECKBOX AND DROPDOWN CLOSE */} + - Reminder - + Reminder +
+ {isReminderFilterActive(filters) && } +
+
- {/* CLEAR FILTERS */} + {/* // ? CLEAR FILTERS */}
- ); -}; + ) +} -export default Filters; +export default Filters diff --git a/frontend/src/components/layout/quickdo-item.tsx b/frontend/src/components/layout/quickdo-item.tsx index cbff222..2323e9b 100644 --- a/frontend/src/components/layout/quickdo-item.tsx +++ b/frontend/src/components/layout/quickdo-item.tsx @@ -29,6 +29,7 @@ const QuickDoItem = (props: ListItemProps) => { const [categories, setCategories] = useState(props.todoData.categories); const [showCategories, setShowCategories] = useState(false); const [allCategories, setAllCategories] = useState(props.allCategories); + const [datePopupOpen, setDatePopupOpen] = useState(false); //? STATUS HANDLER @@ -170,7 +171,7 @@ const QuickDoItem = (props: ListItemProps) => { {/* DUE DATE */}
- +