mirror of
https://github.com/DefectingCat/DefectingCat.github.io
synced 2025-07-15 16:51:37 +00:00
Add post card in blog page
* add component and page tests
This commit is contained in:
@ -19,9 +19,7 @@ describe('NavBar', () => {
|
||||
expect(home).toBeInTheDocument();
|
||||
expect(blog).toBeInTheDocument();
|
||||
|
||||
expect(home.hasAttribute('href')).toBeTruthy();
|
||||
expect(home.getAttribute('href')).toEqual('/');
|
||||
expect(blog.hasAttribute('href')).toBeTruthy();
|
||||
expect(blog.getAttribute('href')).toEqual('/blog');
|
||||
expect(home).toHaveAttribute('href', '/');
|
||||
expect(blog).toHaveAttribute('href', '/blog');
|
||||
});
|
||||
});
|
||||
|
30
__tests__/components/PostCard.test.tsx
Normal file
30
__tests__/components/PostCard.test.tsx
Normal file
@ -0,0 +1,30 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import '@testing-library/jest-dom';
|
||||
import PostCard from 'components/PostCard';
|
||||
|
||||
const post = {
|
||||
slug: 'first-post',
|
||||
title: 'First post test',
|
||||
date: '2022-03-22',
|
||||
tags: ['functions', 'javascript'],
|
||||
};
|
||||
|
||||
describe('NavBar', () => {
|
||||
it('render posts', () => {
|
||||
render(<PostCard post={post} />);
|
||||
|
||||
expect(screen.getByText(/First post test/i)).toBeInTheDocument();
|
||||
});
|
||||
it('render tags', () => {
|
||||
render(<PostCard post={post} />);
|
||||
|
||||
expect(screen.getByText(/JavaScript/i)).toBeInTheDocument();
|
||||
});
|
||||
it('renders links', () => {
|
||||
render(<PostCard post={post} />);
|
||||
|
||||
const link = screen.getByRole('link', { name: /First post test/i });
|
||||
expect(link).toBeInTheDocument();
|
||||
expect(link).toHaveAttribute('href', '/p/first-post');
|
||||
});
|
||||
});
|
22
__tests__/pages/blog.test.tsx
Normal file
22
__tests__/pages/blog.test.tsx
Normal file
@ -0,0 +1,22 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import '@testing-library/jest-dom';
|
||||
import Blog from 'pages/blog';
|
||||
|
||||
const posts = [
|
||||
{
|
||||
slug: 'first-post',
|
||||
title: 'First post test',
|
||||
date: '2022-03-22',
|
||||
tags: ['functions', 'javascript'],
|
||||
},
|
||||
];
|
||||
|
||||
describe('NavBar', () => {
|
||||
it('renders blog title', async () => {
|
||||
render(<Blog posts={[]} />);
|
||||
|
||||
const heading = await screen.findByText(/Blog posts/i);
|
||||
|
||||
expect(heading).toBeInTheDocument();
|
||||
});
|
||||
});
|
@ -27,7 +27,7 @@ const HeadBar: FC = () => {
|
||||
<header
|
||||
className={cn(
|
||||
'flex justify-between mx-auto',
|
||||
'max-w-6xl p-6',
|
||||
'max-w-6xl p-6 h-[84px]',
|
||||
'items-center relative'
|
||||
)}
|
||||
>
|
||||
|
44
components/PostCard.tsx
Normal file
44
components/PostCard.tsx
Normal file
@ -0,0 +1,44 @@
|
||||
import Link from 'next/link';
|
||||
import { FC } from 'react';
|
||||
import { Post } from 'types';
|
||||
import cn from 'classnames';
|
||||
|
||||
interface Props {
|
||||
post: Post;
|
||||
}
|
||||
|
||||
const PostCard: FC<Props> = ({ post }) => {
|
||||
return (
|
||||
<>
|
||||
<Link href={`/p/${post.slug}`} passHref>
|
||||
<a>
|
||||
<article
|
||||
className={cn(
|
||||
'rounded-xl py-4 px-5 md:p-7',
|
||||
'hover:bg-sky-100 hover:bg-opacity-50',
|
||||
// 'hover:bg-rua-gray-100 hover:bg-opacity-10',
|
||||
'dark:hover:bg-rua-gray-800 dark:hover:bg-opacity-100',
|
||||
'flex items-center justify-between'
|
||||
)}
|
||||
>
|
||||
<div>
|
||||
<h2 className="mb-4 text-3xl font-Barlow">{post.title}</h2>
|
||||
|
||||
<div className="flex items-center text-sm">
|
||||
{post.tags.map((tag) => (
|
||||
<div key={tag} className="mr-4 last:mr-0">
|
||||
{tag}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>{post.date}</div>
|
||||
</article>
|
||||
</a>
|
||||
</Link>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default PostCard;
|
@ -25,5 +25,7 @@ export const postLists = async (): Promise<Post[]> => {
|
||||
})
|
||||
.sort(sortByDate);
|
||||
|
||||
console.log(posts);
|
||||
|
||||
return posts;
|
||||
};
|
||||
|
@ -2,18 +2,27 @@ import MainLayout from 'layouts/MainLayout';
|
||||
import { InferGetStaticPropsType } from 'next';
|
||||
import { ReactElement } from 'react';
|
||||
import { postLists } from 'lib/posts';
|
||||
import cn from 'classnames';
|
||||
import dynamic from 'next/dynamic';
|
||||
|
||||
const PostCard = dynamic(() => import('components/PostCard'));
|
||||
|
||||
const Blog = ({ posts }: InferGetStaticPropsType<typeof getStaticProps>) => {
|
||||
return (
|
||||
<>
|
||||
<main className="max-w-3xl mx-auto">
|
||||
<h1 className="text-5xl font-semibold text-center font-Barlow">
|
||||
<main className="max-w-4xl mx-auto">
|
||||
<h1
|
||||
className={cn(
|
||||
'text-5xl font-semibold text-center font-Barlow',
|
||||
'mt-8 mb-20'
|
||||
)}
|
||||
>
|
||||
Blog posts
|
||||
</h1>
|
||||
|
||||
<div>
|
||||
<div className="px-4 lg:px-0">
|
||||
{posts.map((post) => (
|
||||
<article key={post.slug}>{post.title}</article>
|
||||
<PostCard key={post.slug} post={post} />
|
||||
))}
|
||||
</div>
|
||||
</main>
|
||||
|
@ -1,7 +1,7 @@
|
||||
---
|
||||
title: First post test
|
||||
date: '2022-03-22'
|
||||
tags: ['functions', 'javascript']
|
||||
tags: ['functions', 'JavaScript']
|
||||
---
|
||||
|
||||
## Hello
|
||||
|
@ -13,7 +13,7 @@ export type AppPropsWithLayout = AppProps & {
|
||||
export interface MyMatters {
|
||||
title: string;
|
||||
date: string;
|
||||
tags: string;
|
||||
tags: string[];
|
||||
}
|
||||
|
||||
export interface Post extends MyMatters {
|
||||
|
Reference in New Issue
Block a user