From f0c290786ead76199fe7f2b672c67d15d98cfbab Mon Sep 17 00:00:00 2001 From: "ar.badiei" Date: Sun, 12 Jul 2026 02:08:11 +0330 Subject: [PATCH] feat: enhance date formatting in changelog - Added support for Latin digit formatting in release dates to improve readability. - Updated the ChangelogVersionCard component to ensure proper text direction for dates. --- app/blog/[slug]/page.tsx | 7 ++++- components/blog-post-card.tsx | 6 ++-- components/featured-posts-grid.tsx | 4 +-- lastest-project | 1 + lib/wp-api.ts | 46 ++++++++++++++++++++++++------ 5 files changed, 49 insertions(+), 15 deletions(-) create mode 160000 lastest-project diff --git a/app/blog/[slug]/page.tsx b/app/blog/[slug]/page.tsx index 4a1972e..70131ce 100644 --- a/app/blog/[slug]/page.tsx +++ b/app/blog/[slug]/page.tsx @@ -31,7 +31,12 @@ export async function generateMetadata({ params, }: BlogPostPageProps): Promise { const { slug } = await params; - const post = await getPostBySlug(slug); + let post; + try { + post = await getPostBySlug(slug); + } catch { + return { title: "پست یافت نشد" }; + } if (!post) return { title: "پست یافت نشد" }; const titleRaw = post.title?.rendered ?? "پست"; const title = stripHtml(titleRaw); diff --git a/components/blog-post-card.tsx b/components/blog-post-card.tsx index e3131c3..fefee0d 100644 --- a/components/blog-post-card.tsx +++ b/components/blog-post-card.tsx @@ -28,7 +28,7 @@ export function BlogPostCard({ if (variant === "related") { return ( - + {thumbnailUrl ? ( @@ -76,7 +76,7 @@ export function BlogPostCard({ if (variant === "tiny") { return ( - + {thumbnailUrl ? ( @@ -123,7 +123,7 @@ export function BlogPostCard({ } return ( - + {thumbnailUrl ? (
diff --git a/components/featured-posts-grid.tsx b/components/featured-posts-grid.tsx index 472abc4..197e104 100644 --- a/components/featured-posts-grid.tsx +++ b/components/featured-posts-grid.tsx @@ -27,7 +27,7 @@ function PostCard({ const date = post.date ? formatDateShamsi(post.date) : null; const authorName = post._embedded?.author?.[0]?.name ?? null; const thumbnailUrl = getFeaturedImageUrl(post, size === "large" ? "medium_large" : "medium"); - const href = `/blog/${encodeURIComponent(post.slug)}`; + const href = `/blog/${post.slug}`; return ( { - const decodedSlug = decodeURIComponent(slug); - const params = new URLSearchParams({ slug: decodedSlug, _embed: "1" }); - const url = `${WP_API_BASE}/posts?${params.toString()}`; - const res = await fetchWithTimeout(url); +/** وردپرس گاهی slug را به‌صورت percent-encoded ذخیره می‌کند؛ مسیر ممکن است چندبار encode شده باشد. */ +export function normalizeBlogSlug(slug: string): string[] { + const variants: string[] = []; + const seen = new Set(); + let current = slug.trim(); - if (!res.ok) { - throw new Error(`WP API error: ${res.status} ${res.statusText}`); + for (let i = 0; i < 4 && current; i++) { + if (!seen.has(current)) { + seen.add(current); + variants.push(current); + } + try { + const decoded = decodeURIComponent(current); + if (decoded === current) break; + current = decoded; + } catch { + break; + } } - const posts: WpPost[] = await res.json(); - return posts.length > 0 ? posts[0] : null; + return variants; +} + +export async function getPostBySlug(slug: string): Promise { + const slugVariants = normalizeBlogSlug(slug); + + for (const slugVariant of slugVariants) { + const params = new URLSearchParams({ slug: slugVariant, _embed: "1" }); + const url = `${WP_API_BASE}/posts?${params.toString()}`; + const res = await fetchWithTimeout(url); + + if (!res.ok) { + throw new Error(`WP API error: ${res.status} ${res.statusText}`); + } + + const posts: WpPost[] = await res.json(); + if (posts.length > 0) return posts[0]; + } + + return null; } export async function getRelatedPosts(