feat: enhance date formatting in changelog
Build & Push Docker Image / build (push) Has been cancelled
Build & Push Docker Image / build (push) Has been cancelled
- Added support for Latin digit formatting in release dates to improve readability. - Updated the ChangelogVersionCard component to ensure proper text direction for dates.
This commit is contained in:
@@ -31,7 +31,12 @@ export async function generateMetadata({
|
||||
params,
|
||||
}: BlogPostPageProps): Promise<Metadata> {
|
||||
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);
|
||||
|
||||
@@ -28,7 +28,7 @@ export function BlogPostCard({
|
||||
|
||||
if (variant === "related") {
|
||||
return (
|
||||
<Link href={`/blog/${encodeURIComponent(post.slug)}`} className="block h-full min-w-0">
|
||||
<Link href={`/blog/${post.slug}`} className="block h-full min-w-0">
|
||||
<Card className="h-full overflow-hidden transition-all rounded-md duration-300 hover:shadow-md flex flex-col p-0 gap-0">
|
||||
<CardContent className="p-3 sm:p-4 grid grid-cols-3 gap-3 sm:gap-4 min-w-0">
|
||||
{thumbnailUrl ? (
|
||||
@@ -76,7 +76,7 @@ export function BlogPostCard({
|
||||
|
||||
if (variant === "tiny") {
|
||||
return (
|
||||
<Link href={`/blog/${encodeURIComponent(post.slug)}`} className="block h-full">
|
||||
<Link href={`/blog/${post.slug}`} className="block h-full">
|
||||
<Card className="h-full overflow-hidden transition-all rounded-md duration-300 hover:shadow-md flex flex-col p-2">
|
||||
<CardContent className="p-2 grid grid-cols-3 gap-4">
|
||||
{thumbnailUrl ? (
|
||||
@@ -123,7 +123,7 @@ export function BlogPostCard({
|
||||
}
|
||||
|
||||
return (
|
||||
<Link href={`/blog/${encodeURIComponent(post.slug)}`} className="block h-full">
|
||||
<Link href={`/blog/${post.slug}`} className="block h-full">
|
||||
<Card className="h-full overflow-hidden transition-all duration-300 hover:-translate-y-1 hover:shadow-lg pt-0 gap-1">
|
||||
{thumbnailUrl ? (
|
||||
<div className="relative aspect-video w-full overflow-hidden bg-muted">
|
||||
|
||||
@@ -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 (
|
||||
<Link
|
||||
@@ -81,7 +81,7 @@ function PostCardRow({ post }: { post: WpPost }) {
|
||||
const date = post.date ? formatDateShamsi(post.date) : null;
|
||||
const authorName = post._embedded?.author?.[0]?.name ?? null;
|
||||
const thumbnailUrl = getFeaturedImageUrl(post, "medium");
|
||||
const href = `/blog/${encodeURIComponent(post.slug)}`;
|
||||
const href = `/blog/${post.slug}`;
|
||||
|
||||
return (
|
||||
<Link
|
||||
|
||||
Submodule
+1
Submodule lastest-project added at f7a163c4aa
+37
-9
@@ -136,18 +136,46 @@ export async function getPosts(
|
||||
return { posts, total, totalPages };
|
||||
}
|
||||
|
||||
export async function getPostBySlug(slug: string): Promise<WpPost | null> {
|
||||
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<string>();
|
||||
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<WpPost | null> {
|
||||
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(
|
||||
|
||||
Reference in New Issue
Block a user