Add CMS website and Qom landing pages with responsive layout fixes.

Ship blog/portfolio routes, shared content components, and mobile-safe typography so the marketing site can deploy cleanly.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Alireza Hassani
2026-07-29 21:57:44 +03:30
co-authored by Cursor
parent 47bee1ce66
commit 112e5eb46d
29 changed files with 1584 additions and 147 deletions
+59 -32
View File
@@ -1,50 +1,77 @@
import { posts } from "@/data/home";
import Link from "next/link";
import { getBlogCoverImage, getBlogs } from "@/lib/api";
export async function BlogSection() {
let posts: Awaited<ReturnType<typeof getBlogs>>["items"] = [];
try {
const data = await getBlogs({ page: 1, pageSize: 6 });
posts = data.items;
} catch {
posts = [];
}
if (posts.length === 0) return null;
export function BlogSection() {
return (
<section id="blog" className="border-t border-line/60 py-24 lg:py-32">
<div className="mx-auto max-w-7xl px-5 lg:px-8">
<div className="reveal mb-14 flex flex-col gap-4 md:flex-row md:items-end md:justify-between">
<div>
<h2 className="text-[clamp(1.15rem,3.2vw,2.5rem)] font-normal tracking-tight text-ink">
<h2 className="max-w-[16em] text-[clamp(1.15rem,3.2vw,2.5rem)] font-normal leading-snug tracking-tight text-ink">
رشدنامه، آموزشی و انگیزشی
</h2>
<p className="latin mt-3 text-xs uppercase tracking-[0.2em] text-muted">
Our Blog
</p>
</div>
<p className="max-w-sm text-sm text-muted">
با محتوای مشکی همیشه به‌روز باشید.
</p>
<div className="flex flex-col items-start gap-3 md:items-end">
<p className="max-w-sm text-sm text-muted">
با محتوای مشکی همیشه به‌روز باشید.
</p>
<Link href="/blog" className="link-hover text-sm text-ink-soft">
مشاهده همه مقالات
</Link>
</div>
</div>
<div className="grid gap-8 sm:grid-cols-2 lg:grid-cols-3">
{posts.map((post, index) => (
<article
key={post.title}
className={`reveal group ${
index % 3 === 1
? "reveal-delay-1"
: index % 3 === 2
? "reveal-delay-2"
: ""
}`}
>
<a href="#blog" className="block">
<div className="relative mb-4 aspect-[4/3] overflow-hidden rounded-2xl bg-paper-deep">
<img
src={post.image}
alt=""
className="h-full w-full object-cover transition duration-700 group-hover:scale-105"
/>
</div>
<h3 className="group-text-hover mb-2 text-lg font-normal leading-8 text-ink">
{post.title}
</h3>
<p className="text-sm leading-7 text-muted">{post.excerpt}</p>
</a>
</article>
))}
{posts.map((post, index) => {
const image = getBlogCoverImage(post);
return (
<article
key={post.id}
className={`reveal group ${
index % 3 === 1
? "reveal-delay-1"
: index % 3 === 2
? "reveal-delay-2"
: ""
}`}
>
<Link href={`/blog/${post.slug}`} className="block">
<div className="relative mb-4 overflow-hidden rounded-2xl bg-paper-deep">
{image ? (
<img
src={image}
alt=""
className="h-auto w-full transition duration-700 group-hover:scale-105"
/>
) : null}
</div>
<h3 className="group-text-hover mb-2 line-clamp-2 text-lg font-normal leading-8 text-ink">
{post.title}
</h3>
{post.abstract ? (
<p className="text-sm leading-7 text-muted">
{post.abstract}
</p>
) : null}
</Link>
</article>
);
})}
</div>
</div>
</section>