انتقال تمام محتوای متنی سایت به دیتابیس — همه متنهای فرانتاند از GET /api/site خوانده میشوند
This commit is contained in:
+141
-1
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user