From 36554cd66b3273efa8f25c1bfc35f3824a033fb1 Mon Sep 17 00:00:00 2001 From: Enzo Vieira Date: Thu, 30 Nov 2023 22:45:32 +0000 Subject: [PATCH] refactor: change schedule filter to query params --- components/Schedule/Day/Filters/index.jsx | 42 -------------- components/Schedule/Day/index.tsx | 23 +------- components/Schedule/Filters/index.tsx | 70 +++++++++++++++++++++++ components/Schedule/Table/index.jsx | 69 +++++++++++----------- components/Schedule/index.jsx | 8 +-- 5 files changed, 109 insertions(+), 103 deletions(-) delete mode 100644 components/Schedule/Day/Filters/index.jsx create mode 100644 components/Schedule/Filters/index.tsx diff --git a/components/Schedule/Day/Filters/index.jsx b/components/Schedule/Day/Filters/index.jsx deleted file mode 100644 index 619f0dfe..00000000 --- a/components/Schedule/Day/Filters/index.jsx +++ /dev/null @@ -1,42 +0,0 @@ -export function isSelected(filters, filter) { - return filters.includes(`/${filter}/`); -} - -//filters follows the format "/filter1//filter2/ ... /lastfilter/" - -export default function Filters(props) { - //must not contain slashes '/' - const filterList = ["Talks", "Pitch", "Workshops", "Breaks"]; - - function onClick(filter) { - return function () { - if (isSelected(props.filters, filter)) - props.updateFilters(props.filters.replace(`/${filter}/`, "")); - else props.updateFilters(`${props.filters}/${filter}/`); - }; - } - - return ( -
-
FILTER BY
-
- {filterList.map((f, i) => ( - - ))} -
-
- ); -} diff --git a/components/Schedule/Day/index.tsx b/components/Schedule/Day/index.tsx index 4ad16e08..453888d0 100644 --- a/components/Schedule/Day/index.tsx +++ b/components/Schedule/Day/index.tsx @@ -1,4 +1,3 @@ -import Filters from "./Filters"; import styles from "./style.module.css"; function getDayDescriptor(year, month, day) { @@ -16,7 +15,7 @@ function getDayDescriptor(year, month, day) { const today = new Date( _today.getFullYear(), _today.getMonth(), - _today.getDate() + _today.getDate(), ); const day_difference = @@ -48,10 +47,10 @@ export default function Day(props) { const date_descriptor = getDayDescriptor( parseInt(date[0]), parseInt(date[1]), - parseInt(date[2]) + parseInt(date[2]), ); - const Ans = () => ( + return (
@@ -83,20 +82,4 @@ export default function Day(props) {
); - - if (props.showFilters) { - return ( - <> - - - - - ); - } - - return ; } diff --git a/components/Schedule/Filters/index.tsx b/components/Schedule/Filters/index.tsx new file mode 100644 index 00000000..91b8a20a --- /dev/null +++ b/components/Schedule/Filters/index.tsx @@ -0,0 +1,70 @@ +import { usePathname, useRouter, useSearchParams } from "next/navigation"; +import { useCallback } from "react"; + +export default function Filters() { + const router = useRouter(); + const pathname = usePathname(); + const searchParams = useSearchParams(); + + const filterList = ["Talks", "Pitch", "Workshops", "Breaks"] as const; + + const handleClickFilter = useCallback( + (filter: (typeof filterList)[number]) => { + const params = new URLSearchParams(searchParams); + + const currentSelectedFilters = params.get("filter"); + + const currentSelectedFiltersArray = + currentSelectedFilters?.split(",") ?? []; + + const findFilterIndex = currentSelectedFiltersArray.indexOf(filter); + + if (findFilterIndex !== -1) { + currentSelectedFiltersArray.splice(findFilterIndex, 1); + } else { + currentSelectedFiltersArray.push(filter); + } + + params.set("filter", currentSelectedFiltersArray.join(",")); + + const queryString = params.toString(); + + router.push(pathname + "?" + queryString, { scroll: false }); + }, + [pathname, router, searchParams], + ); + + const isFilterSelected = useCallback( + (filter: (typeof filterList)[number]) => { + const currentSelectedFilters = + searchParams.get("filter")?.split(",") ?? []; + + return currentSelectedFilters.indexOf(filter) !== -1; + }, + [searchParams], + ); + + return ( +
+
FILTER BY
+
+ {filterList.map((filter, i) => ( + + ))} +
+
+ ); +} diff --git a/components/Schedule/Table/index.jsx b/components/Schedule/Table/index.jsx index d10b1824..a514aded 100644 --- a/components/Schedule/Table/index.jsx +++ b/components/Schedule/Table/index.jsx @@ -1,35 +1,9 @@ +import { useSearchParams } from "next/navigation"; + import Block from "./Block"; -import { isSelected } from "../Day/Filters"; import schedule from "/data/schedule.json"; -function filterElem(filters) { - return function (elem) { - if (filters == "") return true; - - let result = elem.activity.author == filters; - if (result) return true; - - switch (elem.activity.activityType) { - case "Coffee Break": - result = isSelected(filters, "Breaks"); - break; - case "Talk": - result = isSelected(filters, "Talks"); - break; - case "Pitch": - result = isSelected(filters, "Pitch"); - break; - case "Workshop": - result = isSelected(filters, "Workshops"); - break; - default: - break; - } - return result; - }; -} - /* * Groups the activities into arrays. Two elements will be in the same array if they happen at the same * time @@ -55,13 +29,9 @@ function group(list) { return result; } -export default function Table({ - date, - updateHasFocused, - hash, - filters, - detailed, -}) { +export default function Table({ date, updateHasFocused, hash, detailed }) { + const searchParams = useSearchParams(); + const obj = schedule.find((obj) => obj.date == date); if (obj === undefined || obj.activities === undefined) { @@ -75,7 +45,34 @@ export default function Table({ id: id, focused: hash == `${date}-${id}`, })) - .filter(filterElem(filters)); + .filter(({ activity }) => { + const currentSelectedFilters = + searchParams.get("filter")?.split(",") ?? []; + + // when query params are: filter = [] + if (currentSelectedFilters.length === 0) return true; + + // When query params are: filter = [""] + if ( + currentSelectedFilters.length === 1 && + currentSelectedFilters[0] === "" + ) + return true; + + // When query params are for example: filter = ["Pitch"]; or for example: filter = ["", "Pitch"] + switch (activity.activityType) { + case "Coffee Break": + return currentSelectedFilters.includes("Breaks"); + case "Talk": + return currentSelectedFilters.includes("Talks"); + case "Pitch": + return currentSelectedFilters.includes("Pitch"); + case "Workshop": + return currentSelectedFilters.includes("Workshops"); + default: + break; + } + }); updateHasFocused(filtered.filter((activity) => activity.focused).length != 0); diff --git a/components/Schedule/index.jsx b/components/Schedule/index.jsx index 448e6a2a..8befa40f 100644 --- a/components/Schedule/index.jsx +++ b/components/Schedule/index.jsx @@ -1,5 +1,6 @@ import Table from "./Table"; import Day from "./Day"; +import Filters from "./Filters"; import { useState, useEffect } from "react"; import { useRouter } from "next/router"; @@ -89,7 +90,6 @@ function addDate(date, days) { export default function Schedule(props) { const min_date = "2023/2/14"; const max_date = "2023/2/17"; - const defaultFilter = props.filters === undefined ? "" : props.filters; //calculate default date const _today = new Date(); @@ -104,7 +104,6 @@ export default function Schedule(props) { const [date, updateDate] = useState(default_date); const [hash, updateHash] = useState(""); - const [filters, updateFilters] = useState(defaultFilter); const [hasFocusedElem, updateHasFocused] = useState(false); if (props.updateHasFocused !== undefined) @@ -167,9 +166,9 @@ export default function Schedule(props) { nextDay={next_day} hasFocusedElem={hasFocusedElem} showFilters={props.detailed} - filters={filters} - updateFilters={props.detailed ? updateFilters : () => {}} /> + +
@@ -177,7 +176,6 @@ export default function Schedule(props) { detailed={props.detailed} date={date} hash={hash} - filters={filters} updateHasFocused={updateHasFocused} />