From 50a3df40bc8d41271c4cd8d6873a6d4e1dd87b42 Mon Sep 17 00:00:00 2001 From: Armand Philippot Date: Thu, 20 Jan 2022 19:32:36 +0100 Subject: chore: add a project summary component --- .../ProjectSummary/ProjectSummary.module.scss | 73 ++++++++++++ src/components/ProjectSummary/ProjectSummary.tsx | 122 +++++++++++++++++++++ src/pages/projet/[slug].tsx | 2 + src/services/repos/github.ts | 15 +++ src/ts/types/github.ts | 5 + 5 files changed, 217 insertions(+) create mode 100644 src/components/ProjectSummary/ProjectSummary.module.scss create mode 100644 src/components/ProjectSummary/ProjectSummary.tsx create mode 100644 src/services/repos/github.ts create mode 100644 src/ts/types/github.ts (limited to 'src') diff --git a/src/components/ProjectSummary/ProjectSummary.module.scss b/src/components/ProjectSummary/ProjectSummary.module.scss new file mode 100644 index 0000000..cf1e77f --- /dev/null +++ b/src/components/ProjectSummary/ProjectSummary.module.scss @@ -0,0 +1,73 @@ +@use "@styles/abstracts/functions" as fun; + +.wrapper { + margin-bottom: var(--spacing-md); + padding: var(--spacing-sm) var(--spacing-md) var(--spacing-md); + border: fun.convert-px(1) solid var(--color-border); +} + +.cover { + height: fun.convert-px(150); + position: relative; +} + +.info { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(20ch, 1fr)); + align-items: start; + justify-content: left; + column-gap: var(--spacing-md); + margin: var(--spacing-md) 0 0; +} + +.inline-data { + display: inline-block; + margin-top: fun.convert-px(3); + + &:not(:last-of-type) { + margin-right: var(--spacing-xs); + } +} + +.techno { + padding: 0 var(--spacing-2xs); + border: fun.convert-px(1) solid var(--color-primary-darker); +} + +.repo { + display: block; + width: 3em; + height: 3em; + background: none; + box-shadow: fun.convert-px(1) fun.convert-px(1) fun.convert-px(1) + var(--color-shadow), + fun.convert-px(1) fun.convert-px(2) fun.convert-px(2) fun.convert-px(-1) + var(--color-shadow), + fun.convert-px(3) fun.convert-px(4) fun.convert-px(4) fun.convert-px(-3) + var(--color-shadow), + 0 0 0 0 var(--color-shadow); + transition: all 0.3s linear 0s; + + &:hover, + &:focus { + box-shadow: fun.convert-px(1) fun.convert-px(1) fun.convert-px(1) + var(--color-shadow), + fun.convert-px(1) fun.convert-px(1) fun.convert-px(2) fun.convert-px(-1) + var(--color-shadow-light), + fun.convert-px(3) fun.convert-px(3) fun.convert-px(4) fun.convert-px(-4) + var(--color-shadow-light), + fun.convert-px(6) fun.convert-px(6) fun.convert-px(10) fun.convert-px(-3) + var(--color-shadow); + transform: scale(1.15); + } + + &:focus { + outline: var(--color-primary) dashed fun.convert-px(2); + } + + &:active { + box-shadow: 0 0 0 0 var(--color-shadow); + outline: none; + transform: scale(0.9); + } +} diff --git a/src/components/ProjectSummary/ProjectSummary.tsx b/src/components/ProjectSummary/ProjectSummary.tsx new file mode 100644 index 0000000..0d00f06 --- /dev/null +++ b/src/components/ProjectSummary/ProjectSummary.tsx @@ -0,0 +1,122 @@ +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 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 getFormattedDate = (date: string) => { + const dateOptions: Intl.DateTimeFormatOptions = { + day: 'numeric', + month: 'long', + year: 'numeric', + }; + + return new Date(date).toLocaleDateString(locale, dateOptions); + }; + + return ( +
+
+ {t`${title} +
+
+ {data && ( +
+
{t`Created on`}
+
{t`${getFormattedDate(data.created_at)}`}
+
+ )} + {data && ( +
+
{t`Last updated on`}
+
{t`${getFormattedDate(data.updated_at)}`}
+
+ )} +
+
{t`License`}
+
{license}
+
+ {technologies && ( +
+
{t`Technologies`}
+ {technologies.map((techno) => ( +
+ {techno} +
+ ))} +
+ )} + {repos && ( +
+
{t`Repositories`}
+ {repos.github && ( +
+ + + Github + +
+ )} + {repos.gitlab && ( +
+ + + Gitlab + +
+ )} +
+ )} + {data && ( +
+
{t`Popularity`}
+
+ ⭐  + + {t`${data.stargazers_count} stars on Github`} + +
+
+ )} +
+
+ ); +}; + +export default ProjectSummary; diff --git a/src/pages/projet/[slug].tsx b/src/pages/projet/[slug].tsx index 03aa6ea..ce5dd66 100644 --- a/src/pages/projet/[slug].tsx +++ b/src/pages/projet/[slug].tsx @@ -1,5 +1,6 @@ import { getLayout } from '@components/Layouts/Layout'; import PostHeader from '@components/PostHeader/PostHeader'; +import ProjectSummary from '@components/ProjectSummary/ProjectSummary'; import Sidebar from '@components/Sidebar/Sidebar'; import { ToC } from '@components/Widgets'; import { config } from '@config/website'; @@ -102,6 +103,7 @@ const Project: NextPageWithLayout = ({
+
diff --git a/src/services/repos/github.ts b/src/services/repos/github.ts new file mode 100644 index 0000000..37400ad --- /dev/null +++ b/src/services/repos/github.ts @@ -0,0 +1,15 @@ +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 new file mode 100644 index 0000000..923fb08 --- /dev/null +++ b/src/ts/types/github.ts @@ -0,0 +1,5 @@ +export type RepoData = { + created_at: string; + updated_at: string; + stargazers_count: number; +}; -- cgit v1.2.3