انتقال تمام محتوای متنی سایت به دیتابیس — همه متن‌های فرانت‌اند از GET /api/site خوانده می‌شوند

This commit is contained in:
MMD
2026-09-06 20:16:17 +03:30
parent 8bb303dda2
commit 1fde4e30fc
36 changed files with 1096 additions and 454 deletions
+27 -26
View File
@@ -2,23 +2,18 @@ import React from 'react'
import { ArrowLeftIcon } from 'lucide-react'
import { Reveal } from '../Reveal'
import { ButtonLink } from '../Button'
import { IMAGES } from '../../data/site'
const BENTO = [
{ src: IMAGES[0], alt: 'نمای برج مسکونی آرامش در تهران' },
{ src: IMAGES[1], alt: 'آتریوم مرکزی مجتمع تجاری پارسه' },
{ src: IMAGES[2], alt: 'ویلاهای ساخته‌شده در سواحل شمال' },
{ src: IMAGES[3], alt: 'نمای شبانه برج دوقلوی نیاوران' },
]
import { useSite } from '../../api'
type StoryProps = {
showLink?: boolean;
showLabel?: boolean;
showQuote?: boolean;
alignTop?: boolean;
children?: React.ReactNode;
}
export function Story({ showLink = true, showLabel = true, alignTop = false, children }: StoryProps) {
export function Story({ showLink = true, showLabel = true, showQuote = false, alignTop = false, children }: StoryProps) {
const { story } = useSite()
return (
<section id="story" className="bg-ink py-24 lg:py-32" aria-labelledby="story-title">
<div className={`mx-auto grid max-w-site gap-14 px-6 lg:grid-cols-2 lg:px-10 ${alignTop ? 'items-start' : 'items-center'}`}>
@@ -26,40 +21,46 @@ export function Story({ showLink = true, showLabel = true, alignTop = false, chi
{showLabel && (
<Reveal>
<h2 id="story-title" className="text-section font-bold text-ivory">
درباره ی ما
{story.title}
</h2>
<div className="mt-6 h-px w-24 bg-copper/70" />
</Reveal>
)}
<Reveal delay={0.08}>
<p className="mt-8 text-base font-light leading-9 text-ivory/65">
گروه ساختمانی آرامش با یک دفتر کوچک معماری آغاز شد و امروز یکی از مجموعه‌های شناخته‌شده ساخت‌وساز لوکس در ایران
است. در تمام این سال‌ها یک اصل تغییر نکرده است: ساختمان باید برای زندگی ساخته شود، نه برای فروش سریع.
</p>
<p className="mt-5 text-base font-light leading-9 text-ivory/65">
هر پروژه با مطالعه زمین، نور، اقلیم و الگوی زندگی ساکنان آغاز می‌شود؛ سپس تیم طراحی، سازه و اجرا در یک
فرآیند واحد آن را تا تحویل کلید پیش می‌برند.
</p>
{story.paragraphs.map((paragraph, i) => (
<p key={i} className={`text-base font-light leading-9 text-ivory/65 ${i === 0 ? 'mt-8' : 'mt-5'}`}>
{paragraph}
</p>
))}
</Reveal>
<Reveal delay={0.16}>
<div className="mt-10 grid grid-cols-2 gap-8 border-t border-ivory/10 pt-8">
<div>
<p className="text-2xl font-bold text-copper">۹۴٪</p>
<p className="mt-2 text-sm font-light text-ivory/55">تحویل به‌موقع پروژه‌ها</p>
<p className="text-2xl font-bold text-copper">{story.stat1_value}</p>
<p className="mt-2 text-sm font-light text-ivory/55">{story.stat1_label}</p>
</div>
<div>
<p className="text-2xl font-bold text-copper">۵ سال</p>
<p className="mt-2 text-sm font-light text-ivory/55">پشتیبانی پس از تحویل</p>
<p className="text-2xl font-bold text-copper">{story.stat2_value}</p>
<p className="mt-2 text-sm font-light text-ivory/55">{story.stat2_label}</p>
</div>
</div>
</Reveal>
{showQuote && story.quote && (
<Reveal delay={0.2}>
<div className="mt-12 border-r-2 border-copper bg-char/40 p-6">
<p className="text-sm font-light leading-8 text-ivory/80">{story.quote}</p>
<p className="mt-5 text-sm font-bold text-copper">{story.quote_author}</p>
</div>
</Reveal>
)}
{showLink && (
<Reveal delay={0.22}>
<ButtonLink to="/about" variant="outline" className="mt-10 font-light">
داستان کامل ما
<ButtonLink to={story.link_href} variant="outline" className="mt-10 font-light">
{story.link_label}
<ArrowLeftIcon className="h-4 w-4" />
</ButtonLink>
</Reveal>
@@ -73,7 +74,7 @@ export function Story({ showLink = true, showLabel = true, alignTop = false, chi
</div>
<div className="grid grid-cols-2 gap-4">
{BENTO.map((item, i) => (
{story.bento.map((item, i) => (
<Reveal key={item.src + i} delay={0.06 * i}>
<div className="overflow-hidden">
<img
@@ -88,4 +89,4 @@ export function Story({ showLink = true, showLabel = true, alignTop = false, chi
</div>
</section>
)
}
}