From c598803d43c855fcb51dcf5de67f0c561ff64854 Mon Sep 17 00:00:00 2001 From: James Milmine Date: Fri, 17 Mar 2023 12:11:02 +0000 Subject: [PATCH] update filters to use url parameters --- src/App.css | 2 +- src/App.js | 19 ++------------ src/ArticleItem.jsx | 48 +++++++++++++++------------------- src/ArticleList.jsx | 23 +++++----------- src/FilterBar.jsx | 64 ++++++++++++++++++++++++++++++--------------- src/Header.jsx | 18 ++----------- src/SortBar.jsx | 19 ++++++++++---- 7 files changed, 89 insertions(+), 104 deletions(-) diff --git a/src/App.css b/src/App.css index bb664b4..0e44301 100644 --- a/src/App.css +++ b/src/App.css @@ -211,7 +211,7 @@ select { height: 35px; background-color: #a2baab; display: grid; - grid-template-columns: 30px 90px 150px 30px auto; + grid-template-columns: auto 90px 150px 30px auto; text-align: left; } diff --git a/src/App.js b/src/App.js index 99537d0..81f2064 100644 --- a/src/App.js +++ b/src/App.js @@ -23,27 +23,12 @@ function App() { return (
-
+
+ } /> { +const ArticleItem = ({ article, className }) => { + const [searchParams, setSearchParams] = useSearchParams(); + const newParams = Object.fromEntries([...searchParams]); + + const filterTopic = (event) => { + event.preventDefault(); + newParams.topic = article.topic; + setSearchParams(newParams); + }; + + const filterAuthor = (event) => { + event.preventDefault(); + newParams.author = article.author; + setSearchParams(newParams); + }; + return ( {article.title}
- {topicFilter ? ( + {newParams.topic ? (

{capitaliseFirstLetter(article.topic)}

) : ( - )}
- {authorFilter ? ( + {newParams.author ? (

{article.author}

) : ( - )} diff --git a/src/ArticleList.jsx b/src/ArticleList.jsx index 442fbc7..ef037db 100644 --- a/src/ArticleList.jsx +++ b/src/ArticleList.jsx @@ -4,25 +4,19 @@ import ArticleItem from "./ArticleItem"; import LoadingSpinner from "./LoadingSpinner"; import { useSearchParams } from "react-router-dom"; -const ArticleList = ({ - setNumItems, - pageNumber, - topicFilter, - setTopicFilter, - authorFilter, - setAuthorFilter, - setAuthorValue, -}) => { +const ArticleList = ({ setNumItems, pageNumber }) => { const [isLoading, setIsLoading] = useState(true); const [articles, setArticles] = useState([]); const [noArticlesFound, setNoArticlesFound] = useState(false); const [searchParams, setSearchParams] = useSearchParams(); - const sortBy = searchParams.get("sort_by"); - const order = searchParams.get("order"); useEffect(() => { setIsLoading(true); setNumItems(null); + const sortBy = searchParams.get("sort_by"); + const order = searchParams.get("order"); + const authorFilter = searchParams.get("author"); + const topicFilter = searchParams.get("topic"); getArticles(pageNumber, topicFilter, authorFilter, sortBy, order) .then((articles) => { setNumItems(articles.total_count); @@ -38,7 +32,7 @@ const ArticleList = ({ setIsLoading(false); } }); - }, [pageNumber, topicFilter, authorFilter, sortBy, order]); + }, [pageNumber, searchParams]); return (
@@ -52,11 +46,6 @@ const ArticleList = ({ { +const FilterBar = () => { const { pathname: path } = useLocation(); const { user, setUser } = useContext(UserContext); - const navigate = useNavigate(); - const articleView = /\/articles\/[0-9]+/i.test(path); - const loginView = path === "/login"; + const [searchParams, setSearchParams] = useSearchParams(); const [isLoading, setIsLoading] = useState(true); const [topicList, setTopicList] = useState([]); const [buttonDisable, setButtonDisable] = useState(true); const [buttonClear, setButtonClear] = useState(false); + const [topicValue, setTopicValue] = useState(""); + const [authorValue, setAuthorValue] = useState(""); + + const navigate = useNavigate(); + const articleView = /\/articles\/[0-9]+/i.test(path); + const loginView = path === "/login"; + const newParams = Object.fromEntries([...searchParams]); useEffect(() => { setIsLoading(true); @@ -33,17 +36,22 @@ const FilterBar = ({ }, []); useEffect(() => { - if (authorFilter !== "") { + const newAuthorValue = searchParams.get("author") || ""; + setAuthorValue(newAuthorValue); + if (newAuthorValue) { setClearButton(); } - }, [authorFilter]); + setTopicValue(searchParams.get("topic") || ""); + }, [searchParams]); const authorChanged = (event) => { const currentValue = event.target.value; if (currentValue !== "") { - currentValue === authorFilter + currentValue === newParams.author ? setClearButton() : setSearchButton(false); + } else if (newParams.author) { + setClearButton(); } else { setButtonDisable(true); } @@ -52,16 +60,29 @@ const FilterBar = ({ const searchAuthor = (event) => { event.preventDefault(); - if (authorValue !== "") { - setAuthorFilter(authorValue); - setClearButton(); + if (authorValue) { + newParams.author = authorValue; + } else { + delete newParams.author; + } + setSearchParams(newParams); + }; + + const updateTopicFilter = (event) => { + const currentValue = event.target.value; + if (currentValue) { + newParams.topic = event.target.value; + } else { + delete newParams.topic; } + setSearchParams(newParams); }; const actionSearchClear = (event) => { if (buttonClear) { event.preventDefault(); - setAuthorFilter(""); + delete newParams.author; + setSearchParams(newParams); setAuthorValue(""); setSearchButton(); } @@ -94,8 +115,8 @@ const FilterBar = ({ id="topicSelector" name="topicFilter" disabled={isLoading} - value={topicFilter} - onChange={(event) => setTopicFilter(event.target.value)} + value={topicValue} + onChange={updateTopicFilter} > {topicList.map((topic) => { @@ -114,6 +135,7 @@ const FilterBar = ({ type="text" id="authorSearchField" placeholder="All authors" + autocomplete="off" value={authorValue} onChange={authorChanged} /> diff --git a/src/Header.jsx b/src/Header.jsx index eda567e..18a6e1d 100644 --- a/src/Header.jsx +++ b/src/Header.jsx @@ -3,14 +3,7 @@ import { useContext } from "react"; import { UserContext } from "./contexts/UserContext"; import FilterBar from "./FilterBar"; -const Header = ({ - topicFilter, - setTopicFilter, - setAuthorFilter, - authorValue, - setAuthorValue, - authorFilter, -}) => { +const Header = () => { const { user, setUser } = useContext(UserContext); const navigate = useNavigate(); @@ -40,14 +33,7 @@ const Header = ({ )}
- +
); diff --git a/src/SortBar.jsx b/src/SortBar.jsx index b1e8b36..956c675 100644 --- a/src/SortBar.jsx +++ b/src/SortBar.jsx @@ -1,20 +1,29 @@ import { useSearchParams } from "react-router-dom"; +import { useState, useEffect } from "react"; const SortBar = () => { const [searchParams, setSearchParams] = useSearchParams(); - const sortBy = searchParams.get("sort_by") || "created_at"; - const order = searchParams.get("order") || "desc"; + const [sortBy, setSortBy] = useState("created_at"); + const [order, setOrder] = useState("desc"); + const newParams = Object.fromEntries([...searchParams]); + + useEffect(() => { + setSortBy(searchParams.get("sort_by") || "created_at"); + setOrder(searchParams.get("order") || "desc"); + }, [searchParams]); const updateSortBy = (event) => { - setSearchParams({ sort_by: event.target.value, order }); + newParams.sort_by = event.target.value; + setSearchParams(newParams); }; const updateSortDirection = (event) => { if (order === "asc") { - setSearchParams({ sort_by: sortBy, order: "desc" }); + newParams.order = "desc"; } else { - setSearchParams({ sort_by: sortBy, order: "asc" }); + newParams.order = "asc"; } + setSearchParams(newParams); }; return (