92 lines
3.1 KiB
TypeScript
92 lines
3.1 KiB
TypeScript
import { useEffect, useState } from 'react'
|
|
import type { HomePageQueryQuery } from '../graphql/graphql'
|
|
import { Hero } from '../sections/Hero'
|
|
import { Services } from '../sections/Services'
|
|
import { Solutions } from '../sections/Solutions'
|
|
import { Cases } from '../sections/Cases'
|
|
import { About } from '../sections/About'
|
|
import { Contact } from '../sections/Contact'
|
|
import { ContactModal } from '../components/ContactModal'
|
|
import { scrollToHashTarget } from '../lib/scrollToHash'
|
|
import type { Maybe } from '../lib/types'
|
|
|
|
const HEADER_OFFSET_PX = 85
|
|
|
|
type HomePageData = NonNullable<HomePageQueryQuery['homePage']>
|
|
type HomeSection = NonNullable<NonNullable<HomePageData['sections']>[number]>
|
|
|
|
type HeroSection = Extract<HomeSection, { __typename?: 'ComponentSectionsHomeHero' }>
|
|
type ServicesSection = Extract<HomeSection, { __typename?: 'ComponentSectionsServices' }>
|
|
type SolutionsSection = Extract<HomeSection, { __typename?: 'ComponentSectionsSolutions' }>
|
|
type CasesSection = Extract<HomeSection, { __typename?: 'ComponentSectionsCases' }>
|
|
type AboutSection = Extract<HomeSection, { __typename?: 'ComponentSectionsAbout' }>
|
|
|
|
function parseHomeSections(home: Maybe<HomePageData>) {
|
|
const sections = home?.sections ?? []
|
|
let hero: HeroSection | undefined
|
|
let services: ServicesSection | undefined
|
|
let solutions: SolutionsSection | undefined
|
|
let cases: CasesSection | undefined
|
|
let about: AboutSection | undefined
|
|
|
|
for (const s of sections) {
|
|
if (!s || s.__typename === 'Error') continue
|
|
switch (s.__typename) {
|
|
case 'ComponentSectionsHomeHero':
|
|
hero = s
|
|
break
|
|
case 'ComponentSectionsServices':
|
|
services = s
|
|
break
|
|
case 'ComponentSectionsSolutions':
|
|
solutions = s
|
|
break
|
|
case 'ComponentSectionsCases':
|
|
cases = s
|
|
break
|
|
case 'ComponentSectionsAbout':
|
|
about = s
|
|
break
|
|
default:
|
|
break
|
|
}
|
|
}
|
|
|
|
return { hero, services, solutions, cases, about }
|
|
}
|
|
|
|
export interface HomePageProps {
|
|
homePage?: Maybe<HomePageData>
|
|
}
|
|
|
|
export function HomePage({ homePage }: HomePageProps) {
|
|
const [contactOpen, setContactOpen] = useState(false)
|
|
const { hero, services, solutions, cases, about } = parseHomeSections(homePage ?? null)
|
|
|
|
useEffect(() => {
|
|
const onHashChange = () => scrollToHashTarget(window.location.hash.slice(1))
|
|
|
|
onHashChange()
|
|
window.addEventListener('hashchange', onHashChange)
|
|
return () => window.removeEventListener('hashchange', onHashChange)
|
|
}, [])
|
|
|
|
return (
|
|
<>
|
|
<Hero onOpenContactModal={() => setContactOpen(true)} data={hero} />
|
|
<Services data={services} />
|
|
<Solutions data={solutions} />
|
|
<div id="cases" style={{ scrollMarginTop: HEADER_OFFSET_PX }}>
|
|
<Cases data={cases} />
|
|
</div>
|
|
<div id="about" style={{ scrollMarginTop: HEADER_OFFSET_PX }}>
|
|
<About data={about} />
|
|
</div>
|
|
<div id="contact" style={{ scrollMarginTop: HEADER_OFFSET_PX }}>
|
|
<Contact />
|
|
</div>
|
|
<ContactModal isOpen={contactOpen} onClose={() => setContactOpen(false)} />
|
|
</>
|
|
)
|
|
}
|