Skip to content

Commit 74e63cf

Browse files
committed
Style: 디자인 개선 및 toc 추가
1 parent 7116a00 commit 74e63cf

30 files changed

+2206
-349
lines changed

app/(blog)/layout.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ export default function BlogLayout({
88
}) {
99
return (
1010
<>
11-
<LeftSidebar className="w-48 xl:w-52 2xl:w-56 lg:shrink-0 lg:sticky h-full lg:top-16 mb-4 lg:mb-0 mt-40" />
11+
<LeftSidebar className="w-48 xl:w-52 2xl:w-56 lg:shrink-0 lg:sticky h-full lg:top-16 mb-4 lg:mb-0 mt-52" />
1212
<div className="xl:max-w-5xl mx-auto rounded-lg w-full overflow-x-hidden p-3 2xl:p-6 h-full">
1313
{children}
1414
</div>
15-
<RightSidebar className="w-48 xl:w-52 2xl:w-56 shrink-0 hidden xl:block sticky top-16 h-full mt-40" />
15+
<RightSidebar className="w-48 xl:w-52 2xl:w-56 shrink-0 hidden xl:block sticky top-16 h-full mt-52" />
1616
</>
1717
);
1818
}

app/(blog)/page.tsx

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,24 @@
11
import PostCard from "@/components/post-card";
22
import { getPosts } from "@/lib/posts";
3+
import { HeaderSection, PostGrid, PostItem } from "@/components/home-animation";
4+
// Import global CSS classes for typography
35

46
export default async function Home() {
57
const posts = await getPosts();
68

79
return (
810
<div className="space-y-6 sm:space-y-8 2xl:space-y-10 h-full rounded-lg p-1 sm:p-7">
911
{/* 헤더 섹션 */}
10-
<section className="space-y-2 sm:space-y-3 md:space-y-4 ">
11-
<h1 className="text-lg sm:text-xl lg:text-2xl font-bold">
12-
{`Lazydino's DevLog`}
13-
</h1>
14-
<p className="text-sm sm:text-base text-muted-foreground">
15-
내가 한걸 티내기 위해 만든 블로그
16-
</p>
17-
</section>
12+
<HeaderSection
13+
title="Lazydino's DevLog"
14+
description="내가 한걸 티내기 위해 만든 블로그"
15+
/>
1816

1917
{/* 포스트 그리드 */}
20-
<section>
21-
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-5">
22-
{posts.map((post) => (
18+
<PostGrid>
19+
{posts.map((post, index) => (
20+
<PostItem key={post.urlPath} index={index}>
2321
<PostCard
24-
key={post.urlPath}
2522
urlPath={post.urlPath}
2623
title={post.title}
2724
summary={post.summary}
@@ -31,9 +28,9 @@ export default async function Home() {
3128
tags={post.tags}
3229
createdAt={post.createdAt}
3330
/>
34-
))}
35-
</div>
36-
</section>
31+
</PostItem>
32+
))}
33+
</PostGrid>
3734
</div>
3835
);
39-
}
36+
}

app/(blog)/posts/[...slug]/page.tsx

Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import MarkdownRenderer from "@/components/markdown-renderer";
21
import Link from "next/link";
3-
import { getPost, getPosts } from "@/lib/posts";
2+
import { getPost, getPosts, getAdjacentPosts } from "@/lib/posts";
43
import { ArrowLeft } from "lucide-react";
4+
import PostAnimation from "@/components/post-animation";
5+
import PostContent from "./post-content";
56

67
interface PostPageProps {
78
params: Promise<{ slug: string[] }>;
@@ -41,30 +42,21 @@ export default async function PostPage({ params }: PostPageProps) {
4142
}
4243

4344
const publishPath = post.urlPath.split("/").slice(0, -1).join("/");
45+
46+
// 이전/다음 게시물 가져오기
47+
const { prev, next } = await getAdjacentPosts(post);
4448

4549
return (
46-
<article className="rounded-lg p-2 sm:p-7 max-w-3xl mx-auto">
47-
{/* 마크다운 콘텐츠 */}
48-
<div className="min-h-[250px] sm:min-h-[300px]">
49-
<MarkdownRenderer
50-
content={post.content}
51-
publish={publishPath}
52-
published={post.createdAt}
53-
modified={post.modifiedAt}
54-
tags={post.tags}
55-
/>
56-
</div>
57-
58-
{/* 홈으로 돌아가기 */}
59-
<div className="mt-8 sm:mt-10 md:mt-12 pt-4 sm:pt-6 border-t">
60-
<Link
61-
href="/"
62-
className="text-primary hover:underline inline-flex items-center text-sm sm:text-base"
63-
>
64-
<ArrowLeft className="mr-1 sm:mr-2 h-3 w-3 sm:h-4 sm:w-4" />
65-
홈으로 돌아가기
66-
</Link>
67-
</div>
68-
</article>
50+
<PostAnimation>
51+
<PostContent
52+
content={post.content}
53+
publishPath={publishPath}
54+
published={post.createdAt}
55+
modified={post.modifiedAt}
56+
tags={post.tags}
57+
prevPost={prev}
58+
nextPost={next}
59+
/>
60+
</PostAnimation>
6961
);
7062
}
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
"use client";
2+
3+
import React from "react";
4+
import MarkdownRenderer from "@/components/markdown-renderer";
5+
import { BackToHomeButton } from "@/components/post-animation";
6+
import ScrollToTop from "@/components/scroll-to-top";
7+
import { Post } from "@/lib/posts";
8+
import Link from "next/link";
9+
import { motion } from "framer-motion";
10+
import { ArrowLeft, ArrowRight } from "lucide-react";
11+
12+
interface PostContentProps {
13+
content: string;
14+
publishPath: string;
15+
published: string;
16+
modified: string;
17+
tags: string[];
18+
prevPost: Post | null;
19+
nextPost: Post | null;
20+
}
21+
22+
export default function PostContent({
23+
content,
24+
publishPath,
25+
published,
26+
modified,
27+
tags,
28+
prevPost,
29+
nextPost,
30+
}: PostContentProps) {
31+
return (
32+
<>
33+
<div className="flex flex-col lg:flex-row gap-6">
34+
{/* 콘텐츠 부분 */}
35+
<div className="lg:w-[calc(100%)]">
36+
<div className="min-h-[250px] sm:min-h-[300px]">
37+
<MarkdownRenderer
38+
content={content}
39+
publish={publishPath}
40+
published={published}
41+
modified={modified}
42+
tags={tags}
43+
/>
44+
</div>
45+
46+
{/* 이전글/다음글 네비게이션 */}
47+
<nav className="mt-8 sm:mt-10 pt-4 sm:pt-6 border-t">
48+
<div className="flex flex-col sm:flex-row justify-between items-start sm:items-center gap-4">
49+
{prevPost ? (
50+
<motion.div
51+
className="w-full sm:w-auto"
52+
whileHover={{ x: -3 }}
53+
transition={{ type: "spring", stiffness: 400, damping: 15 }}
54+
>
55+
<Link
56+
href={`/posts/${prevPost.urlPath}`}
57+
className="flex items-center text-muted-foreground hover:text-primary transition-colors"
58+
>
59+
<ArrowLeft className="mr-2 h-4 w-4" />
60+
<div>
61+
<div className="text-xs mb-1">이전 글</div>
62+
<div className="text-sm font-medium truncate max-w-[250px]">{prevPost.title}</div>
63+
</div>
64+
</Link>
65+
</motion.div>
66+
) : (
67+
<div className="w-full sm:w-auto opacity-50">
68+
<div className="flex items-center text-muted-foreground">
69+
<ArrowLeft className="mr-2 h-4 w-4" />
70+
<div>
71+
<div className="text-xs mb-1">이전 글</div>
72+
<div className="text-sm font-medium">없음</div>
73+
</div>
74+
</div>
75+
</div>
76+
)}
77+
78+
{nextPost ? (
79+
<motion.div
80+
className="w-full sm:w-auto text-right"
81+
whileHover={{ x: 3 }}
82+
transition={{ type: "spring", stiffness: 400, damping: 15 }}
83+
>
84+
<Link
85+
href={`/posts/${nextPost.urlPath}`}
86+
className="flex items-center justify-end text-muted-foreground hover:text-primary transition-colors"
87+
>
88+
<div>
89+
<div className="text-xs mb-1">다음 글</div>
90+
<div className="text-sm font-medium truncate max-w-[250px]">{nextPost.title}</div>
91+
</div>
92+
<ArrowRight className="ml-2 h-4 w-4" />
93+
</Link>
94+
</motion.div>
95+
) : (
96+
<div className="w-full sm:w-auto text-right opacity-50">
97+
<div className="flex items-center justify-end text-muted-foreground">
98+
<div>
99+
<div className="text-xs mb-1">다음 글</div>
100+
<div className="text-sm font-medium">없음</div>
101+
</div>
102+
<ArrowRight className="ml-2 h-4 w-4" />
103+
</div>
104+
</div>
105+
)}
106+
</div>
107+
</nav>
108+
109+
<BackToHomeButton />
110+
</div>
111+
</div>
112+
<ScrollToTop />
113+
</>
114+
);
115+
}

0 commit comments

Comments
 (0)