Skip to content

Commit

Permalink
[PAGE] Add sub page layout
Browse files Browse the repository at this point in the history
[Description]
- Fixed sub page
- Add posts parser
- Apply function to view all posts
  • Loading branch information
goomba25 committed Aug 7, 2024
1 parent ae0eada commit 101b8e9
Show file tree
Hide file tree
Showing 17 changed files with 306 additions and 59 deletions.
9 changes: 9 additions & 0 deletions _posts/test.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
title: "Test post"
excerpt: "Test description"
date: "2024-07-28"
category: "Cpp"
categories: [Cpp]
---

Test
11 changes: 11 additions & 0 deletions src/_lib/_interface/post.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { MDXRemoteSerializeResult } from "next-mdx-remote";

export interface Post {
slug: string;
category: string;
title: string;
date: string;
excerpt: string;
content: string | MDXRemoteSerializeResult<Record<string, unknown>, Record<string, unknown>>;
categories: string[];
}
16 changes: 16 additions & 0 deletions src/_lib/categoryLists.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export const CategoryLists = [
{
title: 'C Family',
items: [
{ name: 'C 언어', slug: 'C'},
{ name: 'C++ 언어', slug: 'Cpp'},
]
},
{
title: 'Tools',
items: [
{ name: 'Docker', slug: 'Docker'},
{ name: 'Git', slug: 'Git'}
]
}
]
73 changes: 73 additions & 0 deletions src/_lib/postUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import fs from 'fs'
import path from 'path'
import matter from 'gray-matter'
import { serialize } from 'next-mdx-remote/serialize'
import { Post } from "@/_lib/_interface/post"

const postsDirectory = path.join(process.cwd(), '_posts')

export function getAllPosts() : Post[] {
const posts = getAllPostsRecursive(postsDirectory);
return posts.sort((a,b) => a.date < b.date ? 1 : -1);
}

function getAllPostsRecursive(dir: string) : Post[] {
const files = fs.readdirSync(dir);
let posts: Post[] = []

files.forEach(file => {
const filePath = path.join(dir, file);
const stat = fs.statSync(filePath);

if (stat.isDirectory()) {
posts = posts.concat(getAllPostsRecursive(filePath));
} else if (file.endsWith('.md') || file.endsWith('.mdx')) {
const fileContents = fs.readFileSync(filePath, 'utf-8');
const { data, content } = matter(fileContents);
const slug = file.replace(/\.mdx?$/, '');
const category = path.relative(postsDirectory, dir);

posts.push({
slug,
category,
title: data.title,
date: data.date,
excerpt: data.excerpt || '',
content,
categories: data.categories || [],
});
}
})

return posts;
}

export function getPostsByCategory(category: string) : Post[] {
return getAllPosts().filter(post => post.category === category);
}

export async function getPostBySlug(category: string, slug: string) : Promise<Post> {
const fullPath = path.join(postsDirectory, category, `${slug}.mdx`);
const fileContents = fs.readFileSync(fullPath, 'utf-8');
const { data, content } = matter(fileContents);
const mdxSource = await serialize(content);

return {
slug,
category,
title: data.title,
date: data.date,
excerpt: data.excerpt || '',
content: mdxSource,
categories: data.categories || [],
}
}

export function searchPosts(searchTerm: string): Post[] {
const allPosts = getAllPosts();
return allPosts.filter(post => {
const contentString = typeof post.content === 'string' ? post.content : JSON.stringify(post.content);
return post.title.toLowerCase().includes(searchTerm.toLowerCase())
|| contentString.toLowerCase().includes(searchTerm.toLowerCase());
});
}
7 changes: 0 additions & 7 deletions src/app/(route)/archive/categories/category_c/page.tsx

This file was deleted.

7 changes: 0 additions & 7 deletions src/app/(route)/archive/categories/category_cpp/page.tsx

This file was deleted.

10 changes: 5 additions & 5 deletions src/app/(route)/archive/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import styles from "@/styles/archive.module.css"
import Sidebar from "@/app/_components/sidebar"
import Sidebar from "@/app/_components/Sidebar"
import styles from "@/styles/_layouts/sublayout.module.css"

export default function ArchiveLayout({
children,
Expand All @@ -8,10 +8,10 @@ export default function ArchiveLayout({
}) {
return (
<div className={styles.layout}>
<Sidebar/>
<div className={styles.content}>
{children}
<div className={styles.sidebar}>
<Sidebar />
</div>
<div className={styles.content}>{children}</div>
</div>
);
}
17 changes: 12 additions & 5 deletions src/app/(route)/archive/page.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
import React from "react"
import { getAllPosts } from "@/_lib/postUtils"
import PostList from "@/app/_components/PostList"
import Pagination from "@/app/_components/Pagination"
import styles from "@/styles/_pages/archive.module.css"

export default function Archive() {
const posts = getAllPosts();
const currentPage = 1;
const postsPerPage = 5;

return (
<div>
<h1>
Archive page
</h1>
<div className={styles.container}>
<h1 className={styles.title}>All Posts</h1>
<PostList posts={posts.slice((currentPage - 1) * postsPerPage, currentPage * postsPerPage)} />
<Pagination totalPosts={posts.length} postsPerPage={postsPerPage} currentPage={currentPage} />
</div>
)
}
39 changes: 39 additions & 0 deletions src/app/_components/Pagination.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import Link from "next/link";
import styles from "@/styles/_components/pagination.module.css"

interface PaginationProps {
totalPosts: number;
postsPerPage: number;
currentPage: number;
}

export default function Pagination({totalPosts, postsPerPage, currentPage}: PaginationProps) {
const totalPages = Math.ceil(totalPosts / postsPerPage);
const pageNumbers = [];

for (let i = 1; i <= Math.min(totalPages, 5); i++) {
pageNumbers.push(i);
}

return (
<nav className={styles.pagination}>
<ul className={styles.pagination_list}>
{currentPage > 1 && (
<li>
<Link href={`?page=${currentPage - 1}`} className={`${styles.pagination_link} ${styles.prev}`}></Link>
</li>
)}
{pageNumbers.map((number) => (
<li key={number}>
<Link href={`?page=${number}`} className={`${styles.pagination_link} ${currentPage === number ? styles.active : ''}`}>{number}</Link>
</li>
))}
{currentPage < totalPages && (
<li>
<Link href={`?page=${currentPage + 1}`} className={`${styles.pagination_link} ${styles.next}`}></Link>
</li>
)}
</ul>
</nav>
);
}
23 changes: 23 additions & 0 deletions src/app/_components/PostList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import Link from 'next/link'
import styles from "@/styles/_components/postList.module.css"
import { Post } from '@/_lib/_interface/post'

interface PostListProps {
posts: Post[]
}

export default function PostList({ posts } : PostListProps) {
return (
<ul className={styles.postList}>
{posts.map((post) => (
<li key={post.slug} className={styles.postItem}>
<Link href={`/posts/${post.category}/${post.slug}`} className={styles.postTitle}>
{post.title}
</Link>
<p className={styles.postDate}>{post.date}</p>
<p className={styles.postExcerpt}>{post.excerpt}</p>
</li>
))}
</ul>
)
}
32 changes: 19 additions & 13 deletions src/app/_components/sidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
import Link from "next/link";
import Link from 'next/link'
import { CategoryLists } from '@/_lib/categoryLists'
import styles from "@/styles/sidebar.module.css"

export default function Sidebar() {
return (
<div className={styles.sidebar}>
<h2>Categories</h2>
<ul className={styles.categories}>
<li>
<Link href="/archive/categories/category_c">C 언어</Link>
</li>
<li>
<Link href="/archive/categories/category_cpp">C++ 언어</Link>
</li>
</ul>
</div>
);
<aside className={styles.sidebar}>
{CategoryLists.map((section) => (
<div key={section.title} className={styles.sidebarSection}>
<h3 className={styles.sidebarTitle}>{section.title}</h3>
<ul className={styles.sidebarList}>
{section.items.map((item) => (
<li key={item.slug} className={styles.sidebarItem}>
<Link href={`/archive/${item.slug}`}>
{item.name}
</Link>
</li>
))}
</ul>
</div>
))}
</aside>
)
}
22 changes: 22 additions & 0 deletions src/styles/_components/pagination.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
.pagination {
margin-top: 2rem;
}

.pagination_list {
display: flex;
justify-content: center;
list-style-type: none;
padding: 0;
}

.pagination_link {
padding: 0.5rem 1rem;
margin: 0 0.25rem;
border: 1px solid #e2e8f0;
border-radius: 4px;
}

.pagination_link.active {
background-color: #0070f3;
color: white;
}
26 changes: 26 additions & 0 deletions src/styles/_components/postList.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
.postList {
list-style-type: none;
padding: 0;
}

.postItem {
border: 1px solid #e2e8f0;
padding: 1rem;
margin-bottom: 1rem;
border-radius: 4px;
}

.postTitle {
font-size: 1.25rem;
font-weight: bold;
color: #0070f3;
}

.postDate {
color: #718096;
margin-top: 0.25rem;
}

.postExcerpt {
margin-top: 0;
}
25 changes: 25 additions & 0 deletions src/styles/_layouts/sublayout.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
.layout {
display: flex;
flex-direction: column;
}

.sidebar {
width: 100%;
margin-bottom: 1rem;
}

.content {
flex-grow: 1;
}

@media (min-width: 768px) {
.layout {
flex-direction: row;
}

.sidebar {
width: 250px;
margin-bottom: 0;
margin-right: 2rem;
}
}
9 changes: 9 additions & 0 deletions src/styles/_pages/archive.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.container {
padding: 2rem 0;
}

.title {
font-size: 2rem;
font-weight: bold;
margin-bottom: 1rem;
}
8 changes: 0 additions & 8 deletions src/styles/archive.module.css

This file was deleted.

Loading

0 comments on commit 101b8e9

Please sign in to comment.