Skip to content

Commit

Permalink
feat: add blog detail page
Browse files Browse the repository at this point in the history
  • Loading branch information
nxhawk committed Jul 22, 2024
1 parent 05869c7 commit 334be62
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 0 deletions.
7 changes: 7 additions & 0 deletions app/blogs/[slug]/loading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import React from "react";

const Loading = () => {
return <div>Loading</div>;
};

export default Loading;
70 changes: 70 additions & 0 deletions app/blogs/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { getOneBlog } from "@/utils/fetch-blogs";
import React, { Suspense } from "react";
import Loading from "./loading";
import { formatDate } from "@/utils/helper";
import ImageFallback from "@/components/image-fallback";
import { Metadata } from "next";

interface BlogProps {
params: {
slug: string;
};
}

export async function generateMetadata({ params: { slug } }: BlogProps): Promise<Metadata> {
const blogData = await getOneBlog(slug);
if (!blogData) {
return {
title: "Bài viết không tồn tại",
description: "Bài viết không tồn tại",
};
}
return {
title: blogData.title,
description: blogData.description,
openGraph: {
title: blogData.title,
description: blogData.description,
images: [`/api/og?title=${blogData.title}&image=${blogData.imageUrl}`, blogData.imageUrl],
},
};
}

const BlogDetailPage = async ({ params: { slug } }: BlogProps) => {
const blogData = await getOneBlog(slug);
if (!blogData) {
return <div>Blog not found</div>;
}

const content = (
<span
className="mx-auto block max-w-7xl [&>*]:leading-7 [&>p>img]:mx-auto [&>p>img]:my-4 [&>p>img]:aspect-video [&>p>img]:max-w-4xl [&>p>img]:rounded-md [&>p>img]:border-2 [&>p>img]:border-gray-300 [&>p>img]:object-cover [&>p>img]:drop-shadow-lg [&>p]:text-lg [&>p]:font-normal dark:[&>p]:text-neutral-100"
dangerouslySetInnerHTML={{ __html: blogData?.content }}
/>
);

return (
<Suspense fallback={<Loading />}>
<div className="z-[5] h-full w-full">
<div className="space-y-2 p-4 md:p-8">
<p className="text-center">Ngày cập nhật: {formatDate(blogData.createdAt)}</p>
<div className="space-y-6 pt-6 max-w-screen-lg mx-auto">
<h1 className="text-center text-3xl font-black">{blogData.title}</h1>
<p className="text-center">Tác giả: {blogData.normalizedName || "Unknown"}</p>
<ImageFallback
fallbackSrc="/speaker-ui/og-image.jpg"
src={blogData.imageUrl}
alt={blogData.title}
width={1200}
height={600}
className="rounded-lg max-w-full aspect-video md:aspect-[5/2] object-cover shadow-lg border"
/>
{content}
</div>
</div>
</div>
</Suspense>
);
};

export default BlogDetailPage;
1 change: 1 addition & 0 deletions components/image-fallback.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"use client";
import Image from "next/image";
import { useEffect, useState } from "react";

Expand Down
10 changes: 10 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"clsx": "^2.1.1",
"lucide-react": "^0.411.0",
"mini-svg-data-uri": "^1.4.4",
"moment": "^2.30.1",
"next": "14.2.5",
"next-themes": "^0.3.0",
"react": "^18",
Expand Down
10 changes: 10 additions & 0 deletions utils/fetch-blogs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,13 @@ export async function getListBlog() {
const res = await fetch(`${baseUrl}/Blog/getList?type=${type}`);
return res.json() as Promise<Blog[]>;
}

export async function getOneBlog(slug: string) {
const res = await fetch(`${baseUrl}/Blog/getOneSlug/${slug}?type=${type}`);
return res.json() as Promise<Blog>;
}

export async function getImageBlog(slug: string) {
const data = await getOneBlog(slug);
return data.imageUrl || "";
}
6 changes: 6 additions & 0 deletions utils/helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import moment from "moment";

export function formatDate(date: string) {
const convertDate = new Date(date);
return moment(convertDate).format("DD-MM-YYYY");
}

0 comments on commit 334be62

Please sign in to comment.