Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: ✨ 一些优化 #9

Merged
merged 4 commits into from
Aug 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/app/about/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export default function About() {
theme === "dark" ? "text-indigo-300" : "text-indigo-700"
}`}
>
Zhuba-Ahhh
{process.env.NEXT_PUBLIC_AUTHOR_NAME}
</h2>
<p className={theme === "dark" ? "text-gray-400" : "text-gray-600"}>
前端开发者 / 技术博主
Expand Down
6 changes: 5 additions & 1 deletion src/app/blog/[id]/AnimatedBlogPost.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,14 @@ interface AnimatedBlogPostProps {
headings: Heading[];
readingTime: number;
relatedPosts: BlogPost[];
prevPost?: BlogPost;
nextPost?: BlogPost;
}

export default function AnimatedBlogPost({
post,
prevPost,
nextPost,
headings,
readingTime,
relatedPosts,
Expand Down Expand Up @@ -55,7 +59,7 @@ export default function AnimatedBlogPost({
contentFile={post?.contentFile}
components={mdxComponents}
/>
<BlogFooter post={post} />
<BlogFooter post={post} prevPost={prevPost} nextPost={nextPost} />
<RelatedPosts posts={relatedPosts} />
<ShareButtons
url={`https://yourblog.com/blog/${post.id}`}
Expand Down
38 changes: 34 additions & 4 deletions src/app/blog/[id]/BlogFooter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,15 @@ import { BlogPost } from "@/data/blogPosts";

interface BlogFooterProps {
post: BlogPost;
prevPost?: BlogPost;
nextPost?: BlogPost;
}

export default function BlogFooter({ post }: BlogFooterProps) {
export default function BlogFooter({
post,
prevPost,
nextPost,
}: BlogFooterProps) {
return (
<>
<div className="mb-6 flex flex-wrap gap-2">
Expand All @@ -21,9 +27,33 @@ export default function BlogFooter({ post }: BlogFooterProps) {
</Link>
))}
</div>
<Button asChild variant="outline">
<Link href="/blog">&larr; 返回博客列表</Link>
</Button>
<div className="flex justify-between items-center">
<div className="flex-1 flex justify-start">
{prevPost && (
<Button asChild variant="outline">
<Link href={`/blog/${prevPost.id}`}>
&larr; 上一篇: {prevPost.title}
</Link>
</Button>
)}
</div>
<div className="flex-shrink-0 mx-2">
<Button asChild variant="outline">
<Link href="/blog">返回博客列表</Link>
</Button>
</div>
<div className="flex-1 flex justify-end">
{nextPost ? (
<Button asChild variant="outline">
<Link href={`/blog/${nextPost.id}`}>
下一篇: {nextPost.title} &rarr;
</Link>
</Button>
) : (
<div></div>
)}
</div>
</div>
</>
);
}
69 changes: 62 additions & 7 deletions src/app/blog/[id]/BlogHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,27 @@ interface BlogHeaderProps {
}

export default function BlogHeader({ post, readingTime }: BlogHeaderProps) {
const { title, author, date, coverImage } = post;
return (
<>
<h1 className="text-4xl font-bold mb-4">{post.title}</h1>
<div className="mb-4 text-muted-foreground">
<span>{post.date}</span> | <span>{post.author}</span> |
<span>预计阅读时间: {readingTime} 分钟</span>
<h1 className="text-4xl font-bold mb-4">{title}</h1>
<div className="mb-4 text-muted-foreground flex items-center space-x-2">
<span className="flex items-center">
<CalendarIcon className="w-4 h-4 mr-1" />
{date}
</span>
<span>|</span>
<span>{author}</span>
<span>|</span>
<span className="flex items-center">
<ClockIcon className="w-4 h-4 mr-1" />
预计阅读时间: {readingTime} 分钟
</span>
</div>
{post.coverImage && (
{coverImage && (
<Image
src={post.coverImage}
alt={post.title}
src={coverImage}
alt={title}
width={800}
height={400}
layout="responsive"
Expand All @@ -27,3 +37,48 @@ export default function BlogHeader({ post, readingTime }: BlogHeaderProps) {
</>
);
}

const CalendarIcon = ({ className }: { className: string }) => {
return (
<svg
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="6372"
width="200"
height="200"
className={className}
>
<path
d="M819.057629 645.954349l-62.937128 0 0 62.999554 62.937128 0L819.057629 645.954349zM819.057629 771.829612l-62.937128 0 0 62.999554 62.937128 0L819.057629 771.829612zM630.244232 520.078079l-62.938135 0 0 63.00056 62.938135 0L630.244232 520.078079zM630.244232 79.389305 378.494713 79.389305l0 62.938135 251.749519 0L630.244232 79.389305zM284.333689 204.435918c17.270758 0 31.16147-18.747829 31.16147-41.857399L315.495159 58.24715c0-23.048151-13.890712-41.794973-31.16147-41.794973-17.146914 0-31.099044 18.746823-31.099044 41.794973l0 104.332376C253.234645 185.689095 267.186775 204.435918 284.333689 204.435918M724.90164 204.435918c17.576845 0 31.832042-18.747829 31.832042-41.857399L756.733682 58.24715c0-23.048151-14.255197-41.794973-31.832042-41.794973-17.58188 0-31.838083 18.746823-31.838083 41.794973l0 104.332376C693.063556 185.689095 707.31976 204.435918 724.90164 204.435918M630.244232 645.954349l-62.938135 0 0 62.999554 62.938135 0L630.244232 645.954349zM819.057629 520.078079l-62.937128 0 0 63.00056 62.937128 0L819.057629 520.078079zM252.618443 771.829612l-62.939142 0 0 63.058959 62.939142 0L252.618443 771.829612zM252.618443 645.954349l-62.939142 0 0 62.999554 62.939142 0L252.618443 645.954349zM944.932892 79.389305 819.057629 79.389305l0 62.938135 125.87627 0 0 188.815411L63.805046 331.142851 63.805046 142.32744l125.875263 0L189.680309 79.389305 63.805046 79.389305c-65.271041 0-62.938135 64.567243-62.938135 62.938135l0 818.192732c0 61.277814 60.604221 62.938135 62.938135 62.938135l881.128853 0c57.406418 0 62.937128-60.601201 62.937128-62.938135L1007.871027 142.32744C1007.87002 138.057324 1006.21272 79.389305 944.932892 79.389305M944.932892 960.520172 63.805046 960.520172 63.805046 394.080986l881.128853 0L944.933899 960.520172zM630.244232 771.829612l-62.938135 0 0 63.058959 62.938135 0L630.244232 771.829612zM441.433855 645.954349l-62.939142 0 0 62.999554 62.939142 0L441.433855 645.954349zM441.433855 520.078079l-62.939142 0 0 63.00056 62.939142 0L441.433855 520.078079zM441.433855 771.829612l-62.939142 0 0 63.058959 62.939142 0L441.433855 771.829612zM252.618443 520.078079l-62.939142 0 0 63.00056 62.939142 0L252.618443 520.078079z"
fill="currentColor"
p-id="6373"
></path>
</svg>
);
};

const ClockIcon = ({ className }: { className: string }) => {
return (
<svg
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="10998"
width="200"
height="200"
className={className}
>
<path
d="M512 64C256 64 51.2 272 51.2 524.8s208 460.8 460.8 460.8 460.8-208 460.8-460.8S768 64 512 64z m0 876.8C284.8 940.8 99.2 755.2 99.2 528S284.8 115.2 512 115.2 924.8 300.8 924.8 528 742.4 940.8 512 940.8z"
fill="currentColor"
p-id="10999"
></path>
<path
d="M809.6 544H531.2V262.4c0-12.8-9.6-22.4-22.4-22.4-12.8 0-22.4 9.6-22.4 22.4v307.2c0 12.8 9.6 22.4 22.4 22.4h300.8c12.8 0 22.4-9.6 22.4-22.4 0-16-9.6-25.6-22.4-25.6z"
fill="currentColor"
p-id="11000"
></path>
</svg>
);
};
12 changes: 6 additions & 6 deletions src/app/blog/[id]/TableOfContents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,26 +49,26 @@ const TableOfContents: React.FC<TableOfContentsProps> = ({ headings }) => {
return (
<div className="bg-white dark:bg-gray-800 p-4 rounded-lg shadow-md w-[240px] mr-2">
<h2
className="text-lg font-bold mb-3 text-gray-900 dark:text-gray-100 cursor-pointer"
className="text-lg font-bold mb-3 text-gray-900 dark:text-gray-100 cursor-pointer hover:text-blue-500 dark:hover:text-blue-300 transition-colors duration-200"
onClick={scrollToTopFn}
>
文章目录
</h2>
<nav>
<ul className="space-y-2">
<ul className="space-y-1">
{headings.map((heading) => (
<li
key={heading.slug}
className={`${heading.level === 3 ? "ml-4" : ""} rounded`}
className={`${heading.level === 3 ? "ml-3" : ""} rounded`}
>
<a
href={`#${heading.slug}`}
onClick={(e) => handleClick(e, heading.slug)}
className={`text-sm block py-1 px-2 transition-colors duration-200
className={`text-sm block py-1 px-2 transition-colors duration-200 rounded
${
activeId === heading.slug
? "bg-gray-100 dark:bg-gray-700 text-blue-500 dark:text-blue-300"
: "text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 hover:text-blue-500 dark:hover:text-blue-300"
? "bg-blue-100 dark:bg-blue-900 text-blue-700 dark:text-blue-200 font-medium"
: "text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 hover:text-blue-500 dark:hover:text-blue-300"
}`}
title={heading.text}
>
Expand Down
11 changes: 8 additions & 3 deletions src/app/blog/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,8 @@ export async function generateStaticParams() {
}

export default async function BlogPost({ params }: BlogPostParams) {
const post = blogPosts.find((p) => p.id.toString() === params.id) as
| BlogPost
| undefined;
const postIndex = blogPosts.findIndex((p) => p.id.toString() === params.id);
const post = blogPosts[postIndex];

if (!post) {
notFound();
Expand All @@ -38,6 +37,10 @@ export default async function BlogPost({ params }: BlogPostParams) {
)
.slice(0, 3);

const prevPost = postIndex > 0 ? blogPosts[postIndex - 1] : void 0;
const nextPost =
postIndex < blogPosts.length - 1 ? blogPosts[postIndex + 1] : void 0;

return (
<>
<ReadingProgress />
Expand All @@ -46,6 +49,8 @@ export default async function BlogPost({ params }: BlogPostParams) {
headings={headings}
readingTime={readingTime}
relatedPosts={relatedPosts}
prevPost={prevPost}
nextPost={nextPost}
/>
</>
);
Expand Down
16 changes: 14 additions & 2 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,20 @@ import { ThemeProvider } from "next-themes";
import AnimatedLayout from "@/components/app/AnimatedLayout";

export const metadata: Metadata = {
title: "我的博客",
description: "欢迎来到我的博客",
title: {
default: "我的博客",
template: "%s | 我的博客",
},
description: "欢迎来到我的博客,这里分享前端开发的最新趋势和技巧",
keywords: ["Next.js", "React", "JavaScript", "前端开发"],
authors: [{ name: process.env.NEXT_PUBLIC_AUTHOR_NAME }],
creator: process.env.NEXT_PUBLIC_AUTHOR_NAME,
openGraph: {
type: "website",
locale: "zh_CN",
url: "https://yourblog.com",
// site_name: "我的博客"
},
};

export default function RootLayout({
Expand Down
9 changes: 5 additions & 4 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ export default function Home() {
animate={{ opacity: 1 }}
transition={{ delay: 0.1, duration: 0.3 }}
>
你好,我是[Zhuba-Ahhh]。作为一名前端开发者,我热衷于探索和分享Web开发的最新趋势、技巧和最佳实践。
你好,我是[{process.env.NEXT_PUBLIC_AUTHOR_NAME}
]。作为一名前端开发者,我热衷于探索和分享Web开发的最新趋势、技巧和最佳实践。
</motion.p>

{/* 探索博客按钮 */}
Expand Down Expand Up @@ -66,12 +67,12 @@ export default function Home() {
transition={{ delay: 0.3, duration: 0.3 }}
>
<p>
联系我: [email protected] |{" "}
<a href="https://github.com/zhuba-Ahhh" className="underline">
联系我: {process.env.NEXT_PUBLIC_AUTHOR_EMAIL} |{" "}
<a href={process.env.NEXT_PUBLIC_GITHUB_URL} className="underline">
GitHub
</a>{" "}
|{" "}
<a href="https://twitter.com/yourusername" className="underline">
<a href={process.env.NEXT_PUBLIC_TWITTER_URL} className="underline">
Twitter
</a>
</p>
Expand Down
Loading