انتقال تمام محتوای متنی سایت به دیتابیس — همه متن‌های فرانت‌اند از 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
+141 -1
View File
@@ -32,8 +32,109 @@ export type BeforeAfterInfo = {
after_label: string
}
export type NavItem = { id: number; label: string; href: string }
export type HeroContent = {
id: number
kicker: string
title: string
title_highlight: string
subtitle: string
badge_value: string
badge_label: string
cta_primary_label: string
cta_primary_href: string
cta_secondary_label: string
cta_secondary_href: string
scroll_label: string
}
export type StoryContent = {
id: number
title: string
paragraphs: string[]
quote: string
quote_author: string
stat1_value: string
stat1_label: string
stat2_value: string
stat2_label: string
link_label: string
link_href: string
bento: { src: string; alt: string }[]
}
export type SectionHeadingContent = {
id: number
key: string
label: string
title: string
lead: string
image: string
cta_label: string
cta_href: string
}
export type PageHeroContent = { id: number; key: string; title: string; lead: string; image: string }
export type InvestmentModelItem = { id: number; title: string; desc: string; points: string[] }
export type ProcessStepItem = { id: number; step: string; title: string; desc: string }
export type OfficeItem = { id: number; city: string; address: string; hours: string }
export type GalleryImageItem = { id: number; src: string; alt: string }
export type StatusLabelItem = { id: number; key: string; label: string }
export type ContactSectionContent = {
id: number
label: string
title: string
lead: string
address_label: string
phone_label: string
email_label: string
name_label: string
name_placeholder: string
phone_field_label: string
phone_placeholder: string
note_label: string
note_optional_label: string
note_placeholder: string
submit_label: string
sending_label: string
success_title: string
success_text: string
success_button_label: string
}
export type NewsletterContent = {
id: number
title: string
lead: string
placeholder: string
button_label: string
sending_label: string
success_text: string
}
export type SocialItem = { label: string; href: string; icon: string }
export type FooterContent = {
id: number
about_text: string
pages_heading: string
services_heading: string
contact_heading: string
copyright: string
tagline: string
socials: SocialItem[]
}
export interface SiteData {
brand: BrandInfo
nav: NavItem[]
hero: HeroContent
story: StoryContent
section_headings: SectionHeadingContent[]
page_heroes: PageHeroContent[]
services: Service[]
projects: Project[]
articles: Article[]
@@ -44,6 +145,14 @@ export interface SiteData {
stats: StatItem[]
why_us: WhyUsItem[]
before_after: BeforeAfterInfo
investment_models: InvestmentModelItem[]
process_steps: ProcessStepItem[]
offices: OfficeItem[]
gallery: GalleryImageItem[]
status_labels: StatusLabelItem[]
contact_section: ContactSectionContent
newsletter: NewsletterContent
footer: FooterContent
}
interface SiteContextValue {
@@ -68,7 +177,7 @@ export function SiteProvider({ children }: { children: ReactNode }) {
})
.then((json) => {
if (!cancelled) {
if (json.brand && json.before_after) setData(json)
if (json.brand && json.hero && json.footer && json.nav) setData(json)
else setError(true)
}
})
@@ -103,3 +212,34 @@ export function useSite(): SiteData {
}
return data
}
const EMPTY_HEADING: SectionHeadingContent = {
id: 0,
key: '',
label: '',
title: '',
lead: '',
image: '',
cta_label: '',
cta_href: '',
}
/** تیتر و توضیح یک بخش بر اساس key تعریف‌شده در پنل مدیریت */
export function useSectionHeading(key: string): SectionHeadingContent {
const { data } = useContext(SiteContext)
return data?.section_headings.find((s) => s.key === key) ?? { ...EMPTY_HEADING, key }
}
/** هیرو بالای صفحه بر اساس key تعریف‌شده در پنل مدیریت */
export function usePageHero(key: string): PageHeroContent {
const { data } = useContext(SiteContext)
return (
data?.page_heroes.find((p) => p.key === key) ?? { id: 0, key, title: '', lead: '', image: '' }
)
}
/** برچسب فارسی وضعیت پروژه (done | progress) از پنل مدیریت */
export function useStatusLabel(key: string): string {
const { data } = useContext(SiteContext)
return data?.status_labels.find((s) => s.key === key)?.label ?? key
}