From 4b2892b11e1f9c47878ccb181adb4e4e9e69eac9 Mon Sep 17 00:00:00 2001 From: Arif Rahman Hakim Date: Fri, 6 Sep 2024 09:28:52 +0800 Subject: [PATCH 1/3] style: sets the maximum avatars displayed --- src/components/team/TeamItem.tsx | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/components/team/TeamItem.tsx b/src/components/team/TeamItem.tsx index 0e806d8..2e67e4f 100644 --- a/src/components/team/TeamItem.tsx +++ b/src/components/team/TeamItem.tsx @@ -86,7 +86,9 @@ const TeamItem = ({ team, onItemUpdated, onItemDeleted }: TeamItemProps) => { maskClosable: true, closable: true, okCancel: true, - title: status ? `Hapus Admin: ${user.name}` : `Jadikan Admin: ${user.name}`, + title: status + ? `Hapus Admin: ${user.name}` + : `Jadikan Admin: ${user.name}`, content: status ? `Apakah Anda yakin ingin menghapus ${user.name} sebagai Admin?` : `Apakah Anda yakin ingin menjadikan ${user.name} sebagai Admin?`, @@ -150,7 +152,12 @@ const TeamItem = ({ team, onItemUpdated, onItemDeleted }: TeamItemProps) => {
{team.name}
- + {team.users.map((item, index) => { return ( From 16e3ac1efabbf01d060a397302e1ef5af0aa1684 Mon Sep 17 00:00:00 2001 From: Arif Rahman Hakim Date: Fri, 6 Sep 2024 09:33:23 +0800 Subject: [PATCH 2/3] chore: set maximum avatar display is 5 --- src/components/team/TeamItem.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/team/TeamItem.tsx b/src/components/team/TeamItem.tsx index 2e67e4f..7b6bdd2 100644 --- a/src/components/team/TeamItem.tsx +++ b/src/components/team/TeamItem.tsx @@ -154,7 +154,7 @@ const TeamItem = ({ team, onItemUpdated, onItemDeleted }: TeamItemProps) => {
{team.name}
From 989e513912cfd2fe12f77060f73cf0a222a76d38 Mon Sep 17 00:00:00 2001 From: Arif Rahman Hakim Date: Fri, 6 Sep 2024 11:46:09 +0800 Subject: [PATCH 3/3] perf: improve performence list services --- src/pages/ServicePage.tsx | 82 +++++++++++++++++---------------------- 1 file changed, 35 insertions(+), 47 deletions(-) diff --git a/src/pages/ServicePage.tsx b/src/pages/ServicePage.tsx index bb6b6c5..660b9a1 100644 --- a/src/pages/ServicePage.tsx +++ b/src/pages/ServicePage.tsx @@ -9,16 +9,25 @@ import { Suspense, useCallback, useEffect, useRef, useState } from "react"; import { useNavigate, useSearchParams } from "react-router-dom"; const ServicePage = () => { + const [searchParams] = useSearchParams(); + const initialKeyword = searchParams.get("keyword") || ""; + const initialLimit = parseInt(searchParams.get("limit") || "10") || 10; + const initialPage = parseInt(searchParams.get("page") || "1") || 1; + const initialTags = + searchParams.get("tags") == "" + ? [] + : searchParams.get("tags")?.split(",") || []; + const navigate = useNavigate(); const isMobile = useMediaQuery(); - const [keyword, setKeyword] = useState(""); + const [keyword, setKeyword] = useState(initialKeyword); + const [page, setPage] = useState(initialPage); + const [limit, setLimit] = useState(initialLimit); + const [tags, setTags] = useState(initialTags); + const [options, setOptions] = useState([]); const [debouncedKeyword, setDebouncedKeyword] = useState(keyword); const debounceTimeoutRef = useRef(null); - const [page, setPage] = useState(1); - const [limit, setLimit] = useState(10); - const [tags, setTags] = useState([]); - const [options, setOptions] = useState([]); - const [searchParams] = useSearchParams(); + const { services, total, fetchServices } = useServices( debouncedKeyword, tags, @@ -26,33 +35,33 @@ const ServicePage = () => { limit ); + const syncURLWithState = useCallback(() => { + const searchParams = new URLSearchParams(window.location.search); + + searchParams.set("page", page.toString()); + searchParams.set("limit", limit.toString()); + searchParams.set("keyword", keyword); + searchParams.set("tags", tags.join(",")); + + navigate({ + pathname: window.location.pathname, + search: searchParams.toString(), + }); + }, [page, limit, keyword, tags, navigate]); + const onPageChange = useCallback( (page: number, pageSize: number) => { setPage(page); setLimit(pageSize); - - const searchParams = new URLSearchParams(window.location.search); - searchParams.set("page", page.toString()); - searchParams.set("limit", pageSize.toString()); - - navigate({ - pathname: window.location.pathname, - search: searchParams.toString(), - }); + syncURLWithState(); }, - [navigate] + [syncURLWithState] ); const onKeywordChange = useCallback( (newKeyword: string) => { setKeyword(newKeyword); - const searchParams = new URLSearchParams(window.location.search); - searchParams.set("keyword", newKeyword); - - navigate({ - pathname: window.location.pathname, - search: searchParams.toString(), - }); + syncURLWithState(); if (debounceTimeoutRef.current) { clearTimeout(debounceTimeoutRef.current); @@ -62,38 +71,17 @@ const ServicePage = () => { setDebouncedKeyword(newKeyword); }, 300); }, - [navigate] + [syncURLWithState] ); const onTagsChange = useCallback( (value: string[]) => { setTags(value); - const searchParams = new URLSearchParams(window.location.search); - searchParams.set("tags", value.join(",")); - - navigate({ - pathname: window.location.pathname, - search: searchParams.toString(), - }); + syncURLWithState(); }, - [navigate] + [syncURLWithState] ); - useEffect(() => { - const initialKeyword = searchParams.get("keyword") || ""; - const initialLimit = parseInt(searchParams.get("limit") || "10") || 10; - const initialPage = parseInt(searchParams.get("page") || "1") || 1; - const initialTags = - searchParams.get("tags") == "" - ? [] - : searchParams.get("tags")?.split(",") || []; - - setKeyword(initialKeyword); - setLimit(initialLimit); - setPage(initialPage); - setTags(initialTags); - }, [searchParams]); - useEffect(() => { const fetchServiceTags = async () => { const data = await getServiceTags();