feat(frontend): add blog editor and interactions
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import type { Metadata } from "next";
|
||||
import { notFound } from "next/navigation";
|
||||
import Markdown from "@/components/Markdown";
|
||||
import BlogPostInteractions from "@/components/BlogPostInteractions";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Button } from "@/components/ui/button";
|
||||
@@ -35,18 +36,22 @@ export async function generateMetadata({
|
||||
const { slug } = await params;
|
||||
const post = await loadPost(slug);
|
||||
const description = cleanText(post.excerpt || post.content).slice(0, 160);
|
||||
const metaTitle = post.seo_title || post.og_title || post.title;
|
||||
const metaDescription = post.seo_description || post.og_description || description;
|
||||
const canonical = post.canonical_url || `/blog/${post.slug}`;
|
||||
const image = toAbsoluteUrl(
|
||||
post.absolute_featured_image_url || post.featured_image,
|
||||
post.og_image_url || post.absolute_featured_image_url || post.featured_image,
|
||||
apiBaseUrl,
|
||||
) ?? `${siteUrl}/favicon.ico`;
|
||||
|
||||
return {
|
||||
title: post.title,
|
||||
description,
|
||||
alternates: { canonical: `/blog/${post.slug}` },
|
||||
title: metaTitle,
|
||||
description: metaDescription,
|
||||
alternates: { canonical },
|
||||
robots: post.noindex ? { index: false, follow: true } : undefined,
|
||||
openGraph: {
|
||||
title: post.title,
|
||||
description,
|
||||
title: post.og_title || metaTitle,
|
||||
description: post.og_description || metaDescription,
|
||||
url: `${siteUrl}/blog/${post.slug}`,
|
||||
siteName: "انجمن علمی کامپیوتر شرق گیلان",
|
||||
type: "article",
|
||||
@@ -57,8 +62,8 @@ export async function generateMetadata({
|
||||
},
|
||||
twitter: {
|
||||
card: "summary_large_image",
|
||||
title: post.title,
|
||||
description,
|
||||
title: post.og_title || metaTitle,
|
||||
description: post.og_description || metaDescription,
|
||||
images: [image],
|
||||
},
|
||||
};
|
||||
@@ -72,8 +77,9 @@ export default async function BlogDetailPage({
|
||||
const { slug } = await params;
|
||||
const post = await loadPost(slug);
|
||||
const description = cleanText(post.excerpt || post.content).slice(0, 160);
|
||||
const metaDescription = post.seo_description || post.og_description || description;
|
||||
const image = toAbsoluteUrl(
|
||||
post.absolute_featured_image_url || post.featured_image,
|
||||
post.og_image_url || post.absolute_featured_image_url || post.featured_image,
|
||||
apiBaseUrl,
|
||||
) ?? `${siteUrl}/favicon.ico`;
|
||||
|
||||
@@ -81,7 +87,7 @@ export default async function BlogDetailPage({
|
||||
"@context": "https://schema.org",
|
||||
"@type": "BlogPosting",
|
||||
headline: post.title,
|
||||
description,
|
||||
description: metaDescription,
|
||||
image: [image],
|
||||
datePublished: post.published_at || post.created_at,
|
||||
dateModified: post.updated_at,
|
||||
@@ -150,6 +156,12 @@ export default async function BlogDetailPage({
|
||||
<Markdown content={post.content} justify size="base" />
|
||||
</CardContent>
|
||||
</Card>
|
||||
<BlogPostInteractions
|
||||
slug={post.slug}
|
||||
initialLikes={post.likes_count ?? 0}
|
||||
initialSaves={post.saves_count ?? 0}
|
||||
initialComments={post.comments_count ?? 0}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user