feat(frontend): refine blog and profile experience
Some checks failed
Frontend CI/CD / build (push) Has been cancelled
Frontend CI/CD / deploy (push) Has been cancelled

This commit is contained in:
2026-06-09 08:53:31 +03:30
parent 8b1fc942cf
commit 8e5096d192
13 changed files with 962 additions and 898 deletions

View File

@@ -8,6 +8,7 @@ import { Button } from "@/components/ui/button";
import { Link } from "@/lib/router";
import { PublicApiError, getPublicPost } from "@/lib/public-api";
import { apiBaseUrl, siteUrl, toAbsoluteUrl } from "@/lib/site";
import { blogPostPath, blogPostUrl, normalizeBlogSlugParam } from "@/lib/blog-routes";
import { formatJalali } from "@/lib/utils";
type Params = Promise<{ slug: string }>;
@@ -36,11 +37,11 @@ export async function generateMetadata({
params: Params;
}): Promise<Metadata> {
const { slug } = await params;
const post = await loadPost(slug);
const post = await loadPost(normalizeBlogSlugParam(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 canonical = post.canonical_url || blogPostPath(post.slug);
const image = toAbsoluteUrl(
post.og_image_url || post.absolute_featured_image_url || post.featured_image,
apiBaseUrl,
@@ -54,7 +55,7 @@ export async function generateMetadata({
openGraph: {
title: post.og_title || metaTitle,
description: post.og_description || metaDescription,
url: `${siteUrl}/blog/${post.slug}`,
url: blogPostUrl(siteUrl, post.slug),
siteName: "انجمن علمی کامپیوتر شرق گیلان",
type: "article",
images: [image],
@@ -77,7 +78,7 @@ export default async function BlogDetailPage({
params: Params;
}) {
const { slug } = await params;
const post = await loadPost(slug);
const post = await loadPost(normalizeBlogSlugParam(slug));
const description = cleanText(post.excerpt || post.content).slice(0, 160);
const metaDescription = post.seo_description || post.og_description || description;
const image = toAbsoluteUrl(
@@ -93,7 +94,7 @@ export default async function BlogDetailPage({
image: [image],
datePublished: post.published_at || post.created_at,
dateModified: post.updated_at,
url: `${siteUrl}/blog/${post.slug}`,
url: blogPostUrl(siteUrl, post.slug),
author: {
"@type": "Person",
name: [post.author.first_name, post.author.last_name].filter(Boolean).join(" ") || post.author.username,