Replace the landing with the artifact design and rebuild the admin in Ant Design.
Adds consultation leads, section editors, and the one-time content reset for this release. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,38 +1,55 @@
|
||||
<template>
|
||||
<div class="min-h-screen px-6 pb-24 pt-28 md:px-10">
|
||||
<SiteNavbar
|
||||
:brand="chrome.brand"
|
||||
:logo-url="chrome.logoUrl"
|
||||
:timezone="chrome.timezone"
|
||||
/>
|
||||
<div class="mx-auto max-w-[1100px]">
|
||||
<h1 class="font-display text-4xl font-extrabold md:text-6xl">بلاگ</h1>
|
||||
<p class="mt-4 max-w-xl text-ash">یادداشتهایی درباره محصول، مهندسی و ساخت نرمافزار.</p>
|
||||
<ul class="mt-16 divide-y divide-white/[0.07] border-y border-white/[0.07]">
|
||||
<li v-for="post in posts" :key="post.id" class="py-8">
|
||||
<NuxtLink :to="`/blog/${post.slug}`" class="group block">
|
||||
<p class="text-sm text-ash">
|
||||
{{ post.publishedAt ? new Date(post.publishedAt).toLocaleDateString("fa-IR") : "" }}
|
||||
</p>
|
||||
<h2 class="mt-2 font-display text-2xl font-bold group-hover:text-volt md:text-3xl">
|
||||
{{ post.title }}
|
||||
</h2>
|
||||
<p class="mt-3 max-w-2xl text-sm text-ash">{{ post.excerpt }}</p>
|
||||
</NuxtLink>
|
||||
</li>
|
||||
</ul>
|
||||
<p v-if="!posts?.length" class="mt-10 text-ash">هنوز پستی منتشر نشده است.</p>
|
||||
<section class="py-24 relative overflow-hidden">
|
||||
<div class="absolute top-0 right-0 w-[500px] h-[500px] bg-brand-100/50 dark:bg-brand-600/15 rounded-full blur-[140px] pointer-events-none -z-10" />
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<PageHeading
|
||||
:title="page?.title || 'بلاگ'"
|
||||
:subtitle="page?.seo?.description || 'یادداشتهایی درباره محصول، مهندسی و ساخت نرمافزار.'"
|
||||
:crumbs="[{ label: 'خانه', to: '/' }, { label: page?.title || 'بلاگ', to: '/blog' }]"
|
||||
/>
|
||||
|
||||
<div v-if="posts?.length" class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
<NuxtLink
|
||||
v-for="post in posts"
|
||||
:key="post.id"
|
||||
:to="`/blog/${post.slug}`"
|
||||
class="fade-item group bg-white dark:bg-slate-900/90 rounded-3xl border border-slate-200/90 dark:border-slate-800 shadow-soft-card hover:shadow-hover-card hover:border-brand-300 dark:hover:border-brand-500/50 transition-all duration-300 overflow-hidden flex flex-col text-right"
|
||||
>
|
||||
<div class="aspect-[16/9] bg-gradient-to-br from-brand-50 via-sky-50 to-blue-100/70 dark:from-slate-900 dark:via-[#0c1e3f] dark:to-slate-900 overflow-hidden">
|
||||
<SafeImage
|
||||
v-if="post.coverUrl"
|
||||
:src="post.coverUrl"
|
||||
:alt="post.title"
|
||||
width="640"
|
||||
height="360"
|
||||
class="w-full h-full object-cover transition-transform duration-500 group-hover:scale-105"
|
||||
/>
|
||||
</div>
|
||||
<div class="p-6 space-y-2 flex-1 flex flex-col">
|
||||
<time v-if="post.publishedAt" :datetime="post.publishedAt" class="text-xs font-bold text-slate-400 dark:text-slate-500">{{ formatFaDate(post.publishedAt) }}</time>
|
||||
<h2 class="text-lg font-bold text-slate-900 dark:text-white group-hover:text-brand-600 dark:group-hover:text-brand-400 transition-colors">{{ post.title }}</h2>
|
||||
<p class="text-sm text-slate-500 dark:text-slate-400 leading-relaxed font-normal flex-1">{{ post.excerpt }}</p>
|
||||
<span class="pt-3 inline-flex items-center gap-2 text-sm font-bold text-brand-600 dark:text-brand-400">
|
||||
<svg class="w-4 h-4 transition-transform group-hover:-translate-x-1" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18" /></svg>
|
||||
ادامه مطلب
|
||||
</span>
|
||||
</div>
|
||||
</NuxtLink>
|
||||
</div>
|
||||
<p v-else class="text-center text-slate-500 dark:text-slate-400">هنوز پستی منتشر نشده است.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const chrome = await useSiteChrome();
|
||||
const { data: posts } = await useAsyncData("blog-list", () => fetchPublicBlog(), {
|
||||
getCachedData: () => undefined,
|
||||
});
|
||||
const { data: page } = await useAsyncData("page-blog", () => fetchPage("blog"), {
|
||||
getCachedData: () => undefined,
|
||||
});
|
||||
applyPageSeo(page.value?.seo);
|
||||
const [{ data: posts }, { data: page }] = await Promise.all([
|
||||
useAsyncData("blog-list", () => apiFetch<BlogPostSummary[]>("/api/public/blog").catch(() => [])),
|
||||
usePageMeta("blog"),
|
||||
]);
|
||||
|
||||
usePageSeo(() => page.value?.seo ?? { title: "بلاگ — منتک" });
|
||||
useBreadcrumbJsonLd([
|
||||
{ name: "خانه", path: "/" },
|
||||
{ name: page.value?.title || "بلاگ", path: "/blog" },
|
||||
]);
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user