diff --git a/src/components/Common/Tag/Tag.tsx b/src/components/Common/Tag/Tag.tsx index f5e784b..b55671d 100644 --- a/src/components/Common/Tag/Tag.tsx +++ b/src/components/Common/Tag/Tag.tsx @@ -1,35 +1,33 @@ import { cn } from "@/utils"; -import TitleText from "../TitleText/TitleText"; -import { IoClose } from "react-icons/io5"; -import { useRouter, useSearchParams } from "next/navigation"; import { checkIsFoundTag } from "@/utils/profileHelper"; import { MouseEvent, useCallback } from "react"; +import { IoClose } from "react-icons/io5"; +import TitleText from "../TitleText/TitleText"; const Tag = ({ tag, searchTag, bgColor, isShowClose = false, + onClick, }: { tag: string; searchTag: string; bgColor: string; isShowClose?: boolean; + onClick?: (tag: string) => void; }) => { - const searchParams = useSearchParams(); - const router = useRouter(); const isTagActive = checkIsFoundTag(tag, searchTag); const onClickTag = useCallback( (e: MouseEvent) => { e.preventDefault(); - const tmpSearchParam = new URLSearchParams(searchParams.toString()); - - tmpSearchParam.set("tag", !isTagActive ? tag : ""); - - router.push(`/profile?${tmpSearchParam.toString()}`); + onClick?.(tag); + // const tmpSearchParam = new URLSearchParams(searchParams.toString()); + // tmpSearchParam.set("tag", !isTagActive ? tag : ""); + // router.push(`/profile?${tmpSearchParam.toString()}`); }, - [isTagActive, router, searchParams, tag] + [onClick, tag] ); return ( diff --git a/src/components/Profile/ProfileCardList/ProfileCardList.tsx b/src/components/Profile/ProfileCardList/ProfileCardList.tsx index 3c1fe46..82c20fb 100644 --- a/src/components/Profile/ProfileCardList/ProfileCardList.tsx +++ b/src/components/Profile/ProfileCardList/ProfileCardList.tsx @@ -4,15 +4,15 @@ import SpacingDivider from "@/components/Common/SpacingDivider/SpacingDivider"; import Tag from "@/components/Common/Tag/Tag"; import TitleText from "@/components/Common/TitleText/TitleText"; import ProfileCardItem from "@/components/Profile/ProfileCardItem/ProfileCardItem"; +import { opacityAnimation } from "@/data/animationVariants"; import { titleFont } from "@/fonts/fonts"; +import useProfileHook from "@/hooks/profile/useProfileHook"; import { cn, generateColorArray } from "@/utils/index"; -import { profileHelperService } from "@/utils/profileHelper"; import { Profile } from "contentlayer/generated"; +import { motion } from "framer-motion"; import { useSearchParams } from "next/navigation"; -import { useMemo, useState } from "react"; +import { useState } from "react"; import { IoPeople } from "react-icons/io5"; -import { motion } from "framer-motion"; -import { opacityAnimation } from "@/data/animationVariants"; type TPropsProfileCardList = { profiles: Profile[]; @@ -20,25 +20,17 @@ type TPropsProfileCardList = { const ProfileCardList = ({ profiles }: TPropsProfileCardList) => { const searchParams = useSearchParams(); - const searchTag = searchParams.get("tag") ?? ""; - const { uniqueTags, foundProfiles, searchedTags } = profileHelperService( - profiles, - searchTag - ); - - const [searchByName, setSearchByName] = useState(""); - const [uniqueTagColors] = useState(() => { - return generateColorArray(uniqueTags.length); - }); - - const filteredProfiles = useMemo(() => { - if (!!searchByName.trim().length) { - return foundProfiles.filter((profile) => - profile.name.toLowerCase().includes(searchByName.toLowerCase()) - ); - } - return foundProfiles; - }, [foundProfiles, searchByName]); + const initSearchTag = searchParams.get("tag") ?? ""; + const { + searchTag, + uniqueTagColors, + uniqueTags, + searchedTags, + filteredProfiles, + searchByName, + handleSearchByName, + handleSearchTag, + } = useProfileHook(profiles, initSearchTag); return ( <> @@ -48,15 +40,21 @@ const ProfileCardList = ({ profiles }: TPropsProfileCardList) => { transition={{ staggerChildren: 0.005 }} className="relative" > - {uniqueTags.map((tag, i) => ( - - - - ))} + {uniqueTagColors?.length && + uniqueTags.map((tag, i) => ( + + + + ))}
@@ -67,21 +65,23 @@ const ProfileCardList = ({ profiles }: TPropsProfileCardList) => { titleFont.className )} value={searchByName} - onChange={(e) => setSearchByName(e.target.value)} + onChange={handleSearchByName} /> Total Profiles :{filteredProfiles.length} - {searchedTags.map((tag, i) => ( - - ))} + {uniqueTagColors?.length && + searchedTags.map((tag, i) => ( + + ))}
diff --git a/src/fonts/fonts.ts b/src/fonts/fonts.ts index 9db2425..a677431 100644 --- a/src/fonts/fonts.ts +++ b/src/fonts/fonts.ts @@ -1,6 +1,5 @@ import { PT_Mono, Work_Sans } from "next/font/google"; import localFont from "next/font/local"; -// import {} from "next/font" export const titleFont = PT_Mono({ weight: "400", diff --git a/src/hooks/blog/useBlogHook.ts b/src/hooks/blog/useBlogHook.ts new file mode 100644 index 0000000..6ea972c --- /dev/null +++ b/src/hooks/blog/useBlogHook.ts @@ -0,0 +1,3 @@ +const useBlogHook = () => { + return {}; +}; diff --git a/src/hooks/profile/useProfileHook.ts b/src/hooks/profile/useProfileHook.ts new file mode 100644 index 0000000..7b835c6 --- /dev/null +++ b/src/hooks/profile/useProfileHook.ts @@ -0,0 +1,91 @@ +import { generateColorArray } from "@/utils"; +import { checkIsFoundTag, profileHelperService } from "@/utils/profileHelper"; +import { Profile } from "contentlayer/generated"; +import { ChangeEvent, useCallback, useMemo, useState } from "react"; + +const useProfileHook = (initProfiles: Profile[], initSearchTag: string) => { + const [uniqueTags, setUniqueTags] = useState([]); + const [foundProfiles, setFoundProfiles] = useState([]); + const [searchedTags, setSelectedTags] = useState([]); + const [uniqueTagColors, setUniqueTagColors] = useState(); + const [searchTag, setSearchTag] = useState(initSearchTag); + + const [profiles] = useState(() => { + const expensiveCalculation = profileHelperService( + initProfiles, + initSearchTag + ); + + setUniqueTags(expensiveCalculation.uniqueTags); + + setFoundProfiles(expensiveCalculation.foundProfiles); + + setSelectedTags(expensiveCalculation.searchedTags); + + setUniqueTagColors( + generateColorArray(expensiveCalculation.uniqueTags.length) + ); + + return initProfiles; + }); + + const [searchByName, setSearchByName] = useState(""); + + const handleSearchByName = useCallback((e: ChangeEvent) => { + setSearchByName(e.target.value); + }, []); + + const handleSearchTag = useCallback( + (tagName: string) => { + const isAlreadySearched = searchedTags.some((tag) => + checkIsFoundTag(tagName, tag) + ); + + console.log("isAlreadySearched", isAlreadySearched); + if (isAlreadySearched) { + setSearchTag(""); + setSelectedTags((prev) => []); + setFoundProfiles((profile) => profiles); + return; + } + + setFoundProfiles((prevFoundProfiles) => { + return profiles.filter((profile) => { + return profile.tags?.some((tag) => checkIsFoundTag(tag, tagName)); + }); + }); + + setSelectedTags( + uniqueTags.filter((tag) => checkIsFoundTag(tag, tagName)) + ); + + setSearchTag(tagName); + }, + [profiles, searchTag, uniqueTags] + ); + + const filteredProfiles = useMemo(() => { + const isSetSearchByName = !!searchByName.trim().length; + + if (isSetSearchByName) { + return foundProfiles.filter((profile) => + profile.name.toLowerCase().includes(searchByName.toLowerCase()) + ); + } + return foundProfiles; + }, [foundProfiles, searchByName]); + + return { + searchTag, + uniqueTagColors, + profiles, + searchByName, + foundProfiles, + uniqueTags, + searchedTags, + filteredProfiles, + handleSearchByName, + handleSearchTag, + }; +}; +export default useProfileHook;