From 958569e09071e4bb290f0ec120b4309ae5983d2d Mon Sep 17 00:00:00 2001 From: Armand Philippot Date: Mon, 24 Jan 2022 14:52:04 +0100 Subject: refactor(project): replace repo api call method with hook and swr Instead of using post slug and an environment variable to fetch repo data, I use the given repo in each project MDX file. It allows me to fetch data from another user/organization if needed. To make it work, I no longer provide the full URL in MDX file. The new format is: "User/repo-slug". I also replaced the fetch method with SWR to improve caching and to avoid React complaining about cleanup useEffect. --- .env.example | 2 -- src/components/ProjectSummary/ProjectSummary.tsx | 41 +++++++++++------------- src/pages/projet/[slug].tsx | 2 +- src/services/repos/github.ts | 15 --------- src/ts/types/github.ts | 5 --- src/ts/types/repos.ts | 7 ++++ src/utils/hooks/useGithubApi.tsx | 23 +++++++++++++ 7 files changed, 50 insertions(+), 45 deletions(-) delete mode 100644 src/services/repos/github.ts delete mode 100644 src/ts/types/github.ts create mode 100644 src/ts/types/repos.ts create mode 100644 src/utils/hooks/useGithubApi.tsx diff --git a/.env.example b/.env.example index 88f4663..fddbd69 100644 --- a/.env.example +++ b/.env.example @@ -6,10 +6,8 @@ AUTHOR_NAME="Your Name" AUTHOR_EMAIL="your@email.com" AUTHOR_URL="https://www.yourWebsite.com/" FEED_DESCRIPTION="What you want..." -GITHUB_USER="YourName" NEXT_PUBLIC_FRONTEND_URL="$FRONTEND_URL" -NEXT_PUBLIC_GITHUB_USER="$GITHUB_USER" NEXT_PUBLIC_GRAPHQL_API="$BACKEND_URL$GRAPHQL_ENDPOINT" # Use this only in development mode. It prevents "unable to verify the first diff --git a/src/components/ProjectSummary/ProjectSummary.tsx b/src/components/ProjectSummary/ProjectSummary.tsx index 0d00f06..5a4f9c8 100644 --- a/src/components/ProjectSummary/ProjectSummary.tsx +++ b/src/components/ProjectSummary/ProjectSummary.tsx @@ -1,36 +1,25 @@ import GithubIcon from '@assets/images/social-media/github.svg'; import GitlabIcon from '@assets/images/social-media/gitlab.svg'; import { t } from '@lingui/macro'; -import { getRepoData } from '@services/repos/github'; import { ProjectMeta } from '@ts/types/app'; -import { RepoData } from '@ts/types/github'; import { slugify } from '@utils/helpers/slugify'; +import useGithubApi from '@utils/hooks/useGithubApi'; import Image from 'next/image'; import { useRouter } from 'next/router'; -import { useEffect, useState } from 'react'; import styles from './ProjectSummary.module.scss'; const ProjectSummary = ({ - slug, title, cover, meta, }: { - slug: string; title: string; cover: string; meta: ProjectMeta; }) => { const { license, repos, technologies } = meta; - const [data, setData] = useState(); const { locale } = useRouter(); - const githubUser = process.env.NEXT_PUBLIC_GITHUB_USER; - - useEffect(() => { - getRepoData(slug) - .then((repoData) => setData(repoData)) - .catch((e) => console.error(e)); - }, [slug]); + const { data } = useGithubApi(repos?.github ? repos.github : ''); const getFormattedDate = (date: string) => { const dateOptions: Intl.DateTimeFormatOptions = { @@ -87,7 +76,10 @@ const ProjectSummary = ({
{t`Repositories`}
{repos.github && (
- + Github @@ -95,7 +87,10 @@ const ProjectSummary = ({ )} {repos.gitlab && (
- + Gitlab @@ -103,15 +98,17 @@ const ProjectSummary = ({ )} )} - {data && ( + {data && repos && (
{t`Popularity`}
-
- ⭐  - - {t`${data.stargazers_count} stars on Github`} - -
+ {repos.github && ( +
+ ⭐  + + {t`${data.stargazers_count} stars on Github`} + +
+ )} )} diff --git a/src/pages/projet/[slug].tsx b/src/pages/projet/[slug].tsx index 82e2ea3..0f3aea9 100644 --- a/src/pages/projet/[slug].tsx +++ b/src/pages/projet/[slug].tsx @@ -103,7 +103,7 @@ const Project: NextPageWithLayout = ({
- +
diff --git a/src/services/repos/github.ts b/src/services/repos/github.ts deleted file mode 100644 index 37400ad..0000000 --- a/src/services/repos/github.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { RepoData } from '@ts/types/github'; - -/** - * Retrieve repository data from Github by slug. - * @param repo - The repository slug. - * @returns {Promise} - The repository data. - */ -export const getRepoData = async (repo: string): Promise => { - const user = process.env.NEXT_PUBLIC_GITHUB_USER; - const api = `https://api.github.com/repos/${user}/${repo}`; - - const response = await fetch(api); - - return response.json(); -}; diff --git a/src/ts/types/github.ts b/src/ts/types/github.ts deleted file mode 100644 index 923fb08..0000000 --- a/src/ts/types/github.ts +++ /dev/null @@ -1,5 +0,0 @@ -export type RepoData = { - created_at: string; - updated_at: string; - stargazers_count: number; -}; diff --git a/src/ts/types/repos.ts b/src/ts/types/repos.ts new file mode 100644 index 0000000..7dacacc --- /dev/null +++ b/src/ts/types/repos.ts @@ -0,0 +1,7 @@ +export type RepoData = { + created_at: string; + updated_at: string; + stargazers_count: number; +}; + +export type RepoAPI = 'github'; diff --git a/src/utils/hooks/useGithubApi.tsx b/src/utils/hooks/useGithubApi.tsx new file mode 100644 index 0000000..4b0b3b2 --- /dev/null +++ b/src/utils/hooks/useGithubApi.tsx @@ -0,0 +1,23 @@ +import { RepoData } from '@ts/types/repos'; +import useSWR, { Fetcher } from 'swr'; + +const fetcher: Fetcher = (...args) => + fetch(...args).then((res) => res.json()); + +/** + * Retrieve data from Github API. + * @param repo The repo name. Format: "User/project-slug". + * @returns {object} The data and two booleans to determine if is loading/error. + */ +const useGithubApi = (repo: string) => { + const apiUrl = repo ? `https://api.github.com/repos/${repo}` : null; + const { data, error } = useSWR(apiUrl, fetcher); + + return { + data, + isLoading: !error && !data, + isError: error, + }; +}; + +export default useGithubApi; -- cgit v1.2.3