Add gist page

This commit is contained in:
Defectink
2022-04-25 10:45:53 +08:00
parent 5b175fa3c0
commit cedc921035
5 changed files with 122 additions and 84 deletions

View File

@ -10,7 +10,6 @@ import classNames from 'classnames';
import useInView from 'lib/hooks/useInView';
import loadingImage from 'public/images/img/mona-loading-default.gif';
import Image from 'next/image';
import Link from 'next/link';
interface Props {
gist: Gist;
@ -48,20 +47,13 @@ const GistsCode = ({ gist, f }: Props) => {
return (
<>
<div ref={ref} className={classNames('pb-4 text-sm')}>
<h1 className="md:text-lg">
{gist.owner.login} /
<Link href={`/g/${gist.id}`}>{file[f].filename}</Link>
</h1>
<p className="text-gray-400">Update at: {gist.updated_at}</p>
<p className="text-gray-500">{gist.description}</p>
<div ref={ref}>
{rawCode ? (
<div className={classNames(!rawCode && 'min-h-[300px]')}>{code}</div>
) : (
<div
className={classNames(
'h-[300px] flex',
'h-[300px] flex loading',
'flex-col items-center justify-center'
)}
>

View File

@ -1,13 +1,82 @@
import { GetStaticProps, InferGetStaticPropsType, GetStaticPaths } from 'next';
import dynamic from 'next/dynamic';
import { ReactElement } from 'react';
import { SignalGist } from 'types';
import avatar from 'public/images/img/avatar.svg';
import Image from 'next/image';
import styles from './styles.module.css';
import classNames from 'classnames';
const MainLayout = dynamic(() => import('layouts/MainLayout'));
const GistsCode = dynamic(() => import('components/gists/GistsCode'));
const Gist = ({ id }: InferGetStaticPropsType<typeof getStaticProps>) => {
const Gist = ({ gist }: InferGetStaticPropsType<typeof getStaticProps>) => {
return (
<>
<main className="max-w-5xl px-4 mx-auto lg:px-0">{id}</main>
<main className="max-w-5xl px-4 mx-auto lg:px-0">
<div className={'pb-4 text-sm'}>
<div className="flex items-center py-1 ">
<Image
src={avatar}
alt="Avatar"
priority
width={32}
height={32}
className="rounded-full "
/>
<h1 className="ml-2 text-xl">
{gist.owner.login} /{Object.keys(gist.files)[0]}
</h1>
</div>
<p className="pl-10 text-gray-400 ">Last active: {gist.updated_at}</p>
<div className="py-4">
<p className="pb-2 text-lg text-gray-500">{gist.description}</p>
{Object.keys(gist.files).map((f) => (
<div key={gist.files[f].raw_url} className={styles.wrapper}>
<div className="h-[30px] bg-[#f6f8fa] dark:bg-[hsl(220,13%,18%)] flex">
<div className="flex items-center h-full mx-3">
<div
className={classNames(
'box-border inline-block',
'w-[13px] h-[13px] mr-2',
'rounded-full bg-[#ce5347]'
)}
></div>
<div
className={classNames(
'box-border inline-block',
'w-[13px] h-[13px] mr-2',
'rounded-full bg-[#d6a243]'
)}
></div>
<div
className={classNames(
'box-border inline-block',
'w-[13px] h-[13px]',
'rounded-full bg-[#58a942]'
)}
></div>
</div>
<div
className={classNames(
'px-4 bg-white',
'leading-[30px]',
'dark:bg-[hsl(220,13%,18%)] dark:border-b dark:border-b-[rgb(128,203,196)]'
)}
>
{gist.files[f].filename}
</div>
</div>
<GistsCode gist={gist} f={f} />
</div>
))}
</div>
</div>
</main>
</>
);
};
@ -15,16 +84,22 @@ const Gist = ({ id }: InferGetStaticPropsType<typeof getStaticProps>) => {
export const getStaticPaths: GetStaticPaths = async () => {
return {
paths: [],
fallback: true,
fallback: 'blocking',
};
};
export const getStaticProps: GetStaticProps = async ({ params }) => {
export const getStaticProps: GetStaticProps<{
id: string | undefined;
gist: SignalGist;
}> = async ({ params }) => {
return {
props: {
id: params?.id,
id: params?.id?.toString(),
gist: await fetch(`https://api.github.com/gists/${params?.id}`).then(
(res) => res.json()
),
},
revalidate: 60,
revalidate: 3600,
};
};

13
pages/g/styles.module.css Normal file
View File

@ -0,0 +1,13 @@
.wrapper {
@apply overflow-hidden rounded-lg;
@apply mb-8 shadow-lg;
/* box-shadow: 0 13px 27px -5px rgb(50 50 93 / 25%),
0 8px 16px -8px rgb(0 0 0 / 30%), 0 -6px 16px -6px rgb(0 0 0 / 3%); */
}
.wrapper pre {
margin: unset;
border-radius: unset;
}
.wrapper .loading span {
margin: unset;
}

View File

@ -1,18 +1,21 @@
import { InferGetStaticPropsType } from 'next';
import { GetStaticProps, InferGetStaticPropsType } from 'next';
import { ReactElement } from 'react';
import { Gist, GithubUser } from 'types';
import Image from 'next/image';
import classNames from 'classnames';
import dynamic from 'next/dynamic';
import avatar from 'public/images/img/avatar.svg';
import Link from 'next/link';
const MainLayout = dynamic(() => import('layouts/MainLayout'));
const GistsCode = dynamic(() => import('components/gists/GistsCode'));
const Anchor = dynamic(() => import('components/mdx/Anchor'));
const Gists = ({
gists,
user,
}: InferGetStaticPropsType<typeof getStaticProps>) => {
console.log(gists);
return (
<>
<main className="max-w-5xl px-4 mx-auto lg:px-0">
@ -53,7 +56,18 @@ const Gists = ({
{gists.map((g) => (
<div key={g.id}>
{Object.keys(g.files).map((f) => (
<GistsCode key={g.files[f].raw_url} gist={g} f={f} />
<div key={g.files[f].raw_url} className="pb-4 ">
<h1 className="md:text-lg">
{g.owner.login} /
<Link href={`/g/${g.id}`} passHref>
<Anchor external={false}>{g.files[f].filename}</Anchor>
</Link>
</h1>
<p className="text-gray-400">Update at: {g.updated_at}</p>
<p className="text-gray-500">{g.description}</p>
<GistsCode gist={g} f={f} />
</div>
))}
</div>
))}
@ -64,17 +78,20 @@ const Gists = ({
);
};
export const getStaticProps = async () => {
export const getStaticProps: GetStaticProps<{
gists: Gist[];
user: GithubUser;
}> = async () => {
return {
props: {
gists: (await fetch(
gists: await fetch(
'https://api.github.com/users/DefectingCat/gists'
).then((res) => res.json())) as Gist[],
user: (await fetch('https://api.github.com/users/DefectingCat').then(
).then((res) => res.json()),
user: await fetch('https://api.github.com/users/DefectingCat').then(
(res) => res.json()
)) as GithubUser,
),
},
revalidate: 60,
revalidate: 600,
};
};

View File

@ -138,66 +138,7 @@ export interface GithubUser {
}
// Generated by https://quicktype.io
export interface SignalGist {
url: string;
forks_url: string;
commits_url: string;
id: string;
node_id: string;
git_pull_url: string;
git_push_url: string;
html_url: string;
files: { [key: string]: File };
public: boolean;
created_at: string;
updated_at: string;
description: string;
comments: number;
user: null;
comments_url: string;
owner: Owner;
export interface SignalGist extends Gist {
forks: any[];
history: History[];
truncated: boolean;
}
export interface File {
filename: string;
type: string;
language: string;
raw_url: string;
size: number;
truncated: boolean;
content: string;
}
export interface History {
user: Owner;
version: string;
committed_at: string;
change_status: ChangeStatus;
url: string;
}
export interface ChangeStatus {
total: number;
additions: number;
deletions: number;
}
export interface Owner {
login: string;
id: number;
node_id: string;
avatar_url: string;
gravatar_id: string;
url: string;
html_url: string;
followers_url: string;
following_url: string;
gists_url: string;
starred_url: string;
subscriptions_url: string;
organizations_url: string;
repos_url: string;
events_url: string;
received_events_url: string;
type: string;
site_admin: boolean;
}