انتقال تمام محتوای متنی سایت به دیتابیس — همه متنهای فرانتاند از GET /api/site خوانده میشوند
This commit is contained in:
@@ -6,25 +6,15 @@ import { Timeline } from '../components/home/Timeline'
|
||||
import { WhyUs } from '../components/home/WhyUs'
|
||||
import { Team } from '../components/home/Team'
|
||||
import { ContactSection } from '../components/ContactSection'
|
||||
import { IMAGES } from '../data/site'
|
||||
import { usePageHero } from '../api'
|
||||
|
||||
export function About() {
|
||||
const hero = usePageHero('about')
|
||||
return (
|
||||
<>
|
||||
<PageHero
|
||||
title="درباره ما"
|
||||
lead="گروه ساختمانی آرامش مجموعهای از معماران، مهندسان سازه و مدیران پروژه است که از سال ۱۳۸۳ در حوزه ساختوساز لوکس فعالیت میکند."
|
||||
image={IMAGES[3]}
|
||||
/>
|
||||
|
||||
<Story showLink={false} showLabel={false} alignTop={true}>
|
||||
<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">
|
||||
«ساختمان برای ما فقط آجر و بتن نیست؛ بلکه تعهدی است به کیفیت زندگی ساکنان. ما فضاهایی میسازیم که در گذر زمان ارزش و هویت خود را حفظ کنند.»
|
||||
</p>
|
||||
<p className="mt-5 text-sm font-bold text-copper">کامران آرامش — مدیرعامل شرکت ساختمانی آرامش</p>
|
||||
</div>
|
||||
</Story>
|
||||
<PageHero title={hero.title} lead={hero.lead} image={hero.image} />
|
||||
|
||||
<Story showLink={false} showLabel={false} showQuote={true} alignTop={true} />
|
||||
|
||||
<Stats />
|
||||
<Timeline />
|
||||
@@ -33,4 +23,4 @@ export function About() {
|
||||
<ContactSection />
|
||||
</>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,20 +5,16 @@ import { PageHero } from '../components/PageHero'
|
||||
import { Reveal } from '../components/Reveal'
|
||||
import { ArticleCard } from '../components/ArticleCard'
|
||||
import { Newsletter } from '../components/home/Newsletter'
|
||||
import { IMAGES } from '../data/site'
|
||||
import { useSite } from '../api'
|
||||
import { usePageHero, useSite } from '../api'
|
||||
|
||||
export function Blog() {
|
||||
const { articles } = useSite()
|
||||
const hero = usePageHero('blog')
|
||||
const [featured, ...rest] = articles
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageHero
|
||||
title="وبلاگ"
|
||||
lead="یادداشتهای تیم معماری، اجرا و سرمایهگذاری گروه ساختمانی آرامش درباره آنچه در کارگاه و بازار میگذرد."
|
||||
image={IMAGES[2]}
|
||||
/>
|
||||
<PageHero title={hero.title} lead={hero.lead} image={hero.image} />
|
||||
|
||||
<section className="bg-ink py-24 lg:py-32" aria-label="مقالات">
|
||||
<div className="mx-auto max-w-site px-6 lg:px-10">
|
||||
|
||||
@@ -2,28 +2,20 @@ import React from 'react'
|
||||
import { PageHero } from '../components/PageHero'
|
||||
import { ContactSection } from '../components/ContactSection'
|
||||
import { Reveal } from '../components/Reveal'
|
||||
import { IMAGES } from '../data/site'
|
||||
|
||||
const OFFICES = [
|
||||
{ city: 'تهران', address: 'خیابان ولیعصر، برج آرامش، طبقه هجدهم', hours: 'شنبه تا چهارشنبه، ۹ تا ۱۸' },
|
||||
{ city: 'اصفهان', address: 'خیابان چهارباغ بالا، مجتمع پارسه، طبقه ششم', hours: 'شنبه تا چهارشنبه، ۹ تا ۱۷' },
|
||||
{ city: 'نوشهر', address: 'بلوار دریا، دفتر پروژه دریاکنار', hours: 'شنبه تا پنجشنبه، ۱۰ تا ۱۶' },
|
||||
]
|
||||
import { usePageHero, useSite } from '../api'
|
||||
|
||||
export function ContactPage() {
|
||||
const { offices } = useSite()
|
||||
const hero = usePageHero('contact')
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageHero
|
||||
title="تماس با ما"
|
||||
lead="برای مشاوره ساخت، سرمایهگذاری یا بازدید از پروژهها، تیم ما در سه شهر آماده پاسخگویی است."
|
||||
image={IMAGES[1]}
|
||||
/>
|
||||
<PageHero title={hero.title} lead={hero.lead} image={hero.image} />
|
||||
|
||||
<section className="bg-ink py-24" aria-label="دفاتر ما">
|
||||
<div className="mx-auto grid max-w-site gap-6 px-6 md:grid-cols-3 lg:px-10">
|
||||
{OFFICES.map((office, i) => (
|
||||
<Reveal key={office.city} delay={0.06 * i} className="h-full">
|
||||
{/* اعمال فرمول برای نرم شدن بالا آمدن کارت، بدون هیچ تغییری روی متنها */}
|
||||
{offices.map((office, i) => (
|
||||
<Reveal key={office.id} delay={0.06 * i} className="h-full">
|
||||
<article className="flex h-full flex-col border border-ivory/10 bg-char px-8 py-12 text-center transition-all duration-300 ease-out hover:-translate-y-2 hover:border-copper/40 hover:shadow-lift transform-gpu will-change-transform">
|
||||
<h2 className="text-2xl font-bold text-copper">{office.city}</h2>
|
||||
<p className="mt-6 text-sm font-light leading-9 text-ivory/70">{office.address}</p>
|
||||
@@ -41,4 +33,4 @@ export function ContactPage() {
|
||||
<ContactSection />
|
||||
</>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,19 +2,16 @@ import React from 'react'
|
||||
import { PageHero } from '../components/PageHero'
|
||||
import { Faq } from '../components/home/Faq'
|
||||
import { ContactSection } from '../components/ContactSection'
|
||||
import { IMAGES } from '../data/site'
|
||||
import { usePageHero } from '../api'
|
||||
|
||||
export function FaqPage() {
|
||||
const hero = usePageHero('faq')
|
||||
return (
|
||||
<>
|
||||
<PageHero
|
||||
title="سوالات متداول"
|
||||
lead="پیش از تماس، شاید پاسخ پرسش شما همینجا باشد. اگر نبود، خوشحال میشویم مستقیم صحبت کنیم."
|
||||
image={IMAGES[1]}
|
||||
/>
|
||||
|
||||
<PageHero title={hero.title} lead={hero.lead} image={hero.image} />
|
||||
|
||||
<Faq hideHeading={true} />
|
||||
|
||||
|
||||
<ContactSection />
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -4,53 +4,32 @@ import { Reveal } from '../components/Reveal'
|
||||
import { SectionHeading } from '../components/SectionHeading'
|
||||
import { Stats } from '../components/home/Stats'
|
||||
import { ContactSection } from '../components/ContactSection'
|
||||
import { IMAGES } from '../data/site'
|
||||
|
||||
const MODELS = [
|
||||
{
|
||||
title: 'مشارکت در ساخت',
|
||||
desc: 'مالک زمین و گروه ساختمانی آرامش در سود پروژه شریک میشوند؛ اجرا، مجوزها و فروش بر عهده ماست.',
|
||||
points: ['ارزیابی رایگان زمین', 'قرارداد شفاف با ضمانت اجرا', 'گزارش ماهانه پیشرفت'],
|
||||
},
|
||||
{
|
||||
title: 'صندوق پروژهمحور',
|
||||
desc: 'سرمایهگذاری روی یک پروژه مشخص با واحدهای قابل خرید و بازدهی محاسبهشده در پایان دوره.',
|
||||
points: ['حداقل دوره ۲۴ ماه', 'گزارش ارزشگذاری فصلی', 'امکان انتقال واحد سرمایه'],
|
||||
},
|
||||
{
|
||||
title: 'پیشخرید واحد',
|
||||
desc: 'خرید واحد مسکونی یا تجاری در مراحل ابتدایی ساخت با قیمت پیش از تکمیل و پرداخت مرحلهای.',
|
||||
points: ['پرداخت مرحلهای متناسب با پیشرفت', 'امکان شخصیسازی پلان', 'تضمین زمان تحویل'],
|
||||
},
|
||||
]
|
||||
import { usePageHero, useSectionHeading, useSite } from '../api'
|
||||
|
||||
export function Investment() {
|
||||
const { investment_models } = useSite()
|
||||
const hero = usePageHero('investment')
|
||||
const heading = useSectionHeading('investment_models')
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageHero
|
||||
title="سرمایهگذاری"
|
||||
lead="سه مسیر روشن برای ورود به بازار ساختوساز لوکس، با ساختار مالی شفاف و گزارشدهی منظم."
|
||||
image={IMAGES[4]}
|
||||
/>
|
||||
<PageHero title={hero.title} lead={hero.lead} image={hero.image} />
|
||||
|
||||
<section className="bg-ink py-24 lg:py-32" aria-labelledby="models-title">
|
||||
<div className="mx-auto max-w-site px-6 lg:px-10">
|
||||
<SectionHeading
|
||||
title="مدلهای همکاری"
|
||||
lead="بسته به میزان سرمایه، افق زمانی و سطح ریسکی که میپذیرید، یکی از این سه مسیر مناسب شماست."
|
||||
/>
|
||||
<SectionHeading title={heading.title} lead={heading.lead} />
|
||||
<div className="mt-14 grid gap-6 lg:grid-cols-3">
|
||||
{MODELS.map((model, i) => (
|
||||
<Reveal key={model.title} delay={0.06 * i} className="h-full">
|
||||
{investment_models.map((model, i) => (
|
||||
<Reveal key={model.id} delay={0.06 * i} className="h-full">
|
||||
<article className="group flex h-full flex-col border border-ivory/10 bg-char p-10 transition-all duration-300 ease-out hover:-translate-y-2 hover:border-copper/40 hover:shadow-lift transform-gpu will-change-transform">
|
||||
<p className="text-sm font-bold text-copper/80">۰{(i + 1).toLocaleString('fa-IR')}</p>
|
||||
|
||||
|
||||
<h3 className="mt-6 text-2xl font-bold text-ivory transition-colors duration-300 ease-out group-hover:text-copper">
|
||||
{model.title}
|
||||
</h3>
|
||||
|
||||
|
||||
<p className="mt-5 text-sm font-light leading-9 text-ivory/65">{model.desc}</p>
|
||||
|
||||
|
||||
<div className="mt-auto pt-10">
|
||||
<ul className="space-y-4 border-t border-ivory/10 pt-8">
|
||||
{model.points.map((point) => (
|
||||
@@ -72,4 +51,4 @@ export function Investment() {
|
||||
<ContactSection />
|
||||
</>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,13 +6,13 @@ import { ButtonLink } from '../components/Button'
|
||||
import { ProjectCard } from '../components/ProjectCard'
|
||||
import { ContactSection } from '../components/ContactSection'
|
||||
import { Lightbox } from '../components/Lightbox'
|
||||
import { STATUS_LABEL } from '../data/site'
|
||||
import { useSite } from '../api'
|
||||
import { useSite, useStatusLabel } from '../api'
|
||||
|
||||
export function ProjectDetail() {
|
||||
const { slug } = useParams<{ slug: string }>()
|
||||
const { projects } = useSite()
|
||||
const project = projects.find((p) => p.slug === slug)
|
||||
const statusLabel = useStatusLabel(project?.status ?? '')
|
||||
const [lightbox, setLightbox] = useState<number | null>(null)
|
||||
|
||||
if (!project) {
|
||||
@@ -74,7 +74,7 @@ export function ProjectDetail() {
|
||||
<Reveal className="order-1">
|
||||
<span className="flex items-center gap-3 text-sm font-light text-copper">
|
||||
<span aria-hidden="true" className="h-px w-8 bg-copper" />
|
||||
{STATUS_LABEL[project.status]}
|
||||
{statusLabel}
|
||||
</span>
|
||||
<h2 className="mt-4 text-3xl font-bold text-ivory">درباره پروژه</h2>
|
||||
|
||||
|
||||
@@ -4,25 +4,23 @@ import { Reveal } from '../components/Reveal';
|
||||
import { ProjectCard } from '../components/ProjectCard';
|
||||
import { Gallery } from '../components/home/Gallery';
|
||||
import { ContactSection } from '../components/ContactSection';
|
||||
import { IMAGES, type ProjectStatus } from '../data/site';
|
||||
import { useSite } from '../api';
|
||||
|
||||
const FILTERS: {key: ProjectStatus;label: string;}[] = [
|
||||
{ key: 'done', label: 'انجام شده' },
|
||||
{ key: 'progress', label: 'در حال انجام' }];
|
||||
|
||||
import type { ProjectStatus } from '../data/site';
|
||||
import { usePageHero, useSite, useStatusLabel } from '../api';
|
||||
|
||||
export function Projects() {
|
||||
const { projects } = useSite();
|
||||
const hero = usePageHero('projects');
|
||||
const doneLabel = useStatusLabel('done');
|
||||
const progressLabel = useStatusLabel('progress');
|
||||
const FILTERS: {key: ProjectStatus;label: string;}[] = [
|
||||
{ key: 'done', label: doneLabel },
|
||||
{ key: 'progress', label: progressLabel }];
|
||||
const [status, setStatus] = useState<ProjectStatus>('done');
|
||||
const list = projects.filter((p) => p.status === status);
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageHero
|
||||
title="پروژهها"
|
||||
lead="مجموعهای از برجهای مسکونی، مراکز تجاری و ویلاهای اختصاصی؛ از پروژههای تحویلشده تا کارگاههای فعال امروز."
|
||||
image={IMAGES[0]} />
|
||||
<PageHero title={hero.title} lead={hero.lead} image={hero.image} />
|
||||
|
||||
|
||||
<section className="bg-ink py-24 lg:py-32" aria-label="فهرست پروژهها">
|
||||
|
||||
@@ -5,32 +5,25 @@ import { Faq } from '../components/home/Faq'
|
||||
import { ContactSection } from '../components/ContactSection'
|
||||
import { Reveal } from '../components/Reveal'
|
||||
import { SectionHeading } from '../components/SectionHeading'
|
||||
import { IMAGES } from '../data/site'
|
||||
|
||||
const PROCESS = [
|
||||
{ step: '۰۱', title: 'مطالعه و امکانسنجی', desc: 'بررسی زمین، ضوابط شهری و تحلیل بازدهی اقتصادی پروژه.' },
|
||||
{ step: '۰۲', title: 'طراحی و فاز اجرایی', desc: 'کانسپت معماری، طراحی سازه و تأسیسات و تهیه نقشههای اجرایی.' },
|
||||
{ step: '۰۳', title: 'اجرا و کنترل کیفیت', desc: 'ساخت با نظارت مستمر، گزارش ماهانه پیشرفت و کنترل هزینه.' },
|
||||
{ step: '۰۴', title: 'تحویل و پشتیبانی', desc: 'تحویل کلید، آموزش بهرهبرداری و پنج سال پشتیبانی فنی.' },
|
||||
]
|
||||
import { usePageHero, useSectionHeading, useSite } from '../api'
|
||||
|
||||
export function ServicesPage() {
|
||||
const { process_steps } = useSite()
|
||||
const hero = usePageHero('services')
|
||||
const heading = useSectionHeading('process')
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageHero
|
||||
title="خدمات"
|
||||
lead="هشت حوزه تخصصی که چرخه کامل یک پروژه ساختمانی را از ایده تا بهرهبرداری پوشش میدهند."
|
||||
image={IMAGES[1]}
|
||||
/>
|
||||
|
||||
<PageHero title={hero.title} lead={hero.lead} image={hero.image} />
|
||||
|
||||
<Services />
|
||||
|
||||
<section className="bg-char py-24 lg:py-32" aria-labelledby="process-title">
|
||||
<div className="mx-auto max-w-site px-6 lg:px-10">
|
||||
<SectionHeading title="فرآیند کار ما" lead="چهار مرحله شفاف، از نخستین جلسه تا تحویل کلید." align="center" />
|
||||
<SectionHeading title={heading.title} lead={heading.lead} align="center" />
|
||||
<div className="mt-14 grid gap-px bg-ivory/10 md:grid-cols-2 lg:grid-cols-4">
|
||||
{PROCESS.map((item, i) => (
|
||||
<Reveal key={item.step} delay={0.06 * i} className="h-full">
|
||||
{process_steps.map((item, i) => (
|
||||
<Reveal key={item.id} delay={0.06 * i} className="h-full">
|
||||
<div className="flex h-full flex-col justify-center bg-char px-6 py-14 text-center">
|
||||
<p className="text-4xl font-bold text-copper">{item.step}</p>
|
||||
<h3 className="mt-6 text-xl font-bold text-ivory">{item.title}</h3>
|
||||
@@ -46,4 +39,4 @@ export function ServicesPage() {
|
||||
<ContactSection />
|
||||
</>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user