church-website/src/compositions/CollapsibleMapWithText/CollapsibleMapWithText.tsx
2026-04-29 14:21:44 +02:00

118 lines
3 KiB
TypeScript

'use client'
import { BackgroundColor, Section } from '@/components/Section/Section'
import { ChemnitzMap } from '@/components/ChemnitzMap/ChemnitzMap'
import { Title } from '@/components/Title/Title'
import styles from './styles.module.scss'
import { Container } from '@/components/Container/Container'
import { P } from '@/components/Text/Paragraph'
import { CollapsibleArrow } from '@/components/CollapsibleArrow/CollapsibleArrow'
import React, { useEffect, useRef, useState } from 'react'
import classNames from 'classnames'
type CollapsibleMapWithTextProps = {
backgroundColor?: BackgroundColor
title: string
text: string
content?: React.ReactNode
}
type MoreInformationProps = {
isCollapsed: boolean
onClick: () => void
}
const MoreInformation = ({ isCollapsed, onClick }: MoreInformationProps) => {
const [direction, setDirection] = useState<'UP' | 'DOWN'>(isCollapsed ? 'DOWN' : 'UP')
const toggleDirection = () => {
setDirection(direction == 'UP' ? 'DOWN' : 'UP')
}
const handleClick = () => {
toggleDirection()
onClick()
}
return (
<button
onClick={handleClick}
className={styles.more}
onMouseEnter={toggleDirection}
onMouseLeave={toggleDirection}
>
Mehr erfahren <CollapsibleArrow direction={direction} />
</button>
)
}
export function CollapsibleMapWithText({
title,
text,
content,
backgroundColor,
}: CollapsibleMapWithTextProps) {
const ref = useRef<HTMLDivElement>(null)
const ref2 = useRef<HTMLDivElement>(null)
const [contentHeight, setContentHeight] = useState(0)
const [isCollapsed, setIsCollapsed] = useState(true)
const collapse = () => {
setIsCollapsed(true)
ref.current?.scrollIntoView({ behavior: 'smooth' })
}
const toggle = () => {
if (isCollapsed) {
setIsCollapsed(false)
setTimeout(() => {
ref2.current?.scrollIntoView({ behavior: 'smooth'})
}, 500)
} else {
collapse()
}
}
useEffect(() => {
if (ref2.current) {
setContentHeight(ref2.current.scrollHeight)
}
}, [ref2])
return (
<div ref={ref}>
<Section backgroundColor={backgroundColor}>
<Container>
<Title title={title} size={'lg'} color={'base'} />
</Container>
<div className={styles.mapContainer}>
<ChemnitzMap/>
</div>
<Container>
<P width={'3/4'}>{text}</P>
{content && <MoreInformation isCollapsed={isCollapsed} onClick={toggle} />}
</Container>
</Section>
{content && (
<div
ref={ref2}
className={classNames({ [styles.content]: true })}
style={{ maxHeight: isCollapsed ? undefined : contentHeight }}
>
<Section backgroundColor={backgroundColor} padding={'small'} paddingBottom={'large'}>
<Container>{content}</Container>
<div className={styles.endButton}>
<CollapsibleArrow direction={'UP'} onClick={collapse} />
</div>
</Section>
</div>
)}
</div>
)
}