diff --git a/src/components/Hero.tsx b/src/components/Hero.tsx index e6e6d845..e008fe23 100644 --- a/src/components/Hero.tsx +++ b/src/components/Hero.tsx @@ -1,14 +1,10 @@ import { MutableRefObject, useRef, useState } from "react"; import { useDebounce, useDidUpdate, useKeys } from "rooks"; -import { FaRegDotCircle } from "react-icons/fa"; -import { AiOutlineStar } from "react-icons/ai"; -// import StackedAvatar from "./StackedAvatar"; import { fetchRecommendations } from "../lib/supabase"; -import humanizeNumber from "../lib/humanizeNumber"; -import { getAvatarLink } from "../lib/github"; import searchNormal from "../assets/searchNormal.svg"; import cmdKIcon from "../assets/cmdK.svg"; +import SearchedRepoCard from "./SearchedRepoCard"; const Hero = () => { const containerRef = useRef(document); @@ -101,62 +97,11 @@ const Hero = () => {

Repository

- {fetchedData.map(({ full_name, name, description, issues, stars }) => ( - -
-
-
-
- {full_name} -
- -

- {full_name} -

-
- -

- {description} -

- -
- {/*
- -
*/} - -
-
-
- -
-
-
-
-
-
-
+ {fetchedData.map(data => ( + ))} )} diff --git a/src/components/HotRepoCard.tsx b/src/components/HotRepoCard.tsx index bb8fddc6..d34d7632 100644 --- a/src/components/HotRepoCard.tsx +++ b/src/components/HotRepoCard.tsx @@ -8,9 +8,10 @@ import Skeleton from "react-loading-skeleton"; import { getAvatarLink } from "../lib/github"; import humanizeNumber from "../lib/humanizeNumber"; -// import StackedAvatar from "./StackedAvatar"; +import StackedAvatar from "./StackedAvatar"; import useRepo from "../hooks/useRepo"; import useVotedRepos from "../hooks/useVotedRepos"; +import useContributions from "../hooks/useContributions"; export declare interface HotRepoCardProps { repoName: string; @@ -20,6 +21,7 @@ const HotRepoCard = ({ repoName }: HotRepoCardProps): JSX.Element => { const { votedReposIds, checkVoted, voteHandler } = useVotedRepos(); const { repo, isLoading, isError } = useRepo(repoName); const [isVoted, setIsVoted] = useState(false); + const { data: contributions } = useContributions(repoName); useEffect(() => { repo && setIsVoted(checkVoted(repo.id)); @@ -131,7 +133,7 @@ const HotRepoCard = ({ repoName }: HotRepoCardProps): JSX.Element => { - {/* */} + ); diff --git a/src/components/RepoList.tsx b/src/components/RepoList.tsx index ee462243..94397806 100644 --- a/src/components/RepoList.tsx +++ b/src/components/RepoList.tsx @@ -2,11 +2,11 @@ import { useEffect, useState } from "react"; import { FaArrowAltCircleUp, FaDotCircle, FaStar } from "react-icons/fa"; import humanizeNumber from "../lib/humanizeNumber"; import { getAvatarLink, getRepoLink } from "../lib/github"; - -// import StackedAvatar from "./StackedAvatar"; +import StackedAvatar from "./StackedAvatar"; import useVotedRepos from "../hooks/useVotedRepos"; import { RiCheckboxCircleFill } from "react-icons/ri"; import cx from "classnames"; +import useContributions from "../hooks/useContributions"; export declare interface RepoListProps { data: DbRepo; @@ -28,6 +28,9 @@ const RepoList = ({ data }: RepoListProps): JSX.Element => { // contributionsCount, } = data; + // {full_name} consists of `{owner}/{repo}`, so this link is actually `repos/{owner}/{repo}/contributions` + const { data: contributions } = useContributions(full_name); + useEffect(() => { setIsVoted(checkVoted(id)); }, [votedReposIds]); @@ -94,7 +97,7 @@ const RepoList = ({ data }: RepoListProps): JSX.Element => {

- {/* */} + diff --git a/src/components/SearchedRepoCard.tsx b/src/components/SearchedRepoCard.tsx new file mode 100644 index 00000000..c2af57d3 --- /dev/null +++ b/src/components/SearchedRepoCard.tsx @@ -0,0 +1,73 @@ +import { AiOutlineStar } from "react-icons/ai"; +import { FaRegDotCircle } from "react-icons/fa"; +import useContributions from "../hooks/useContributions"; +import { getAvatarLink } from "../lib/github"; +import humanizeNumber from "../lib/humanizeNumber"; +import StackedAvatar from "./StackedAvatar"; + +export declare interface SearchedRepoCardProps { + data: DbRepo; +} + +const SearchedRepoCard = ({ data: { full_name, name, description, issues, stars } }: SearchedRepoCardProps) => { + const { data: contributions } = useContributions(full_name); + + return ( + +
+
+
+
+ {full_name} +
+ +

+ {full_name} +

+
+ +

+ {description} +

+ +
+
+ +
+ +
+
+
+ +
+
+
+
+
+
+
+ ); +}; + +export default SearchedRepoCard; diff --git a/src/hooks/useContributions.ts b/src/hooks/useContributions.ts new file mode 100644 index 00000000..0cd7c257 --- /dev/null +++ b/src/hooks/useContributions.ts @@ -0,0 +1,25 @@ +import useSWR from "swr"; + +interface PaginatedContributorsResponse { + readonly data: DbContribution[]; + readonly meta: PageMetaDto; +} + +const useContributions = (repoName: string, limit = 10, orderBy = "recent") => { + const baseEndpoint = `repos/${repoName}/contributions`; + const limitQuery = `&limit=${limit}`; + const orderByQuery = orderBy ? `&updated_at=${orderBy}` : ""; + const endpointString = `${baseEndpoint}?${limitQuery}${orderByQuery}`; + + const { data, error, mutate } = useSWR(endpointString); + + return { + data: data?.data ?? [], + meta: data?.meta ?? { itemCount: 0 }, + isLoading: !error && !data, + isError: !!error, + mutate, + }; +}; + +export default useContributions;