{"version":3,"file":"Footer-chunk-CBOxm0ng.js","sources":["../../theme/ts/services/footerService.ts","../../theme/ts/components/frontend-ui/SocialLinks/SocialLinks.tsx","../../theme/ts/components/frontend-ui/Footer/NavTopic.tsx","../../theme/ts/components/frontend-ui/Footer/Footer.tsx"],"sourcesContent":["import fetch from 'isomorphic-fetch';\nimport { url } from '@ts/utils/url';\n\nexport type FooterLinks = {\n icon: string;\n id: string;\n title: string;\n url: string;\n};\n\nexport type FooterResDto = {\n company: FooterLinks[];\n legal: FooterLinks[];\n services: FooterLinks[];\n};\n\nexport class FooterService {\n constructor(private readonly portalUrl: string = url.getPortalUrl()) {}\n\n getFooterLinks = async () => {\n const url = `${this.portalUrl}/@actions`;\n\n const settings: RequestInit = {\n method: 'GET',\n headers: {\n Accept: 'application/json',\n },\n };\n\n const response = await fetch(url, settings);\n\n if (!response.ok) {\n const msg = await response.text();\n throw new Error(`Status code:${response.status}\\nError:${msg}`);\n }\n\n const res = await response.json();\n\n const footerRes: FooterResDto = {\n legal: res.legal_actions,\n company: res.company_actions,\n services: res.services_actions,\n };\n\n return footerRes;\n };\n}\n","import { Icon } from '../Icon/Icon';\n\ntype SocialMedia = 'facebook' | 'twitter' | 'instagram' | 'youtube';\n\nconst mediaIcon: { [key in SocialMedia]: { width: number; height: number } } = {\n facebook: {\n width: 20,\n height: 20,\n },\n twitter: {\n width: 18,\n height: 18,\n },\n instagram: {\n width: 20,\n height: 20,\n },\n youtube: {\n width: 24,\n height: 17,\n },\n};\n\nconst urls: { [key in SocialMedia]: { url: string } } = {\n facebook: {\n url: 'https://www.facebook.com/derfreitag/',\n },\n twitter: {\n url: 'https://twitter.com/derfreitag/',\n },\n instagram: {\n url: 'https://www.instagram.com/freitag/',\n },\n youtube: {\n url: 'https://www.youtube.com/channel/UCqs44Wf09ppRItc5uqNBMxA',\n },\n};\n\ntype Props = {\n socialMedia?: SocialMedia[];\n};\n\nexport const SocialLinks = ({\n socialMedia = ['facebook', 'twitter', 'instagram'],\n}: Props) => {\n return (\n \n );\n};\n","import { useEffect, useRef } from 'preact/hooks';\nimport { FooterLinks } from '@ts/services/footerService';\nimport { useMediaQuery, useToggle } from 'usehooks-ts';\nimport { Icon } from '../Icon/Icon';\n\nexport const calculateDuration = (height: number) => {\n const baseSpeed = 2;\n const minHeight = 200; // Element's min height to apply `smooth speed`\n const speedAdjustmentFactor = 0.03; // Adjust `smooth speed` for shorter elements\n\n // Calculate adjusted speed based on height\n const adjustedSpeed =\n baseSpeed + (minHeight - height) * speedAdjustmentFactor;\n const duration = height * Math.max(adjustedSpeed, baseSpeed);\n\n return duration;\n};\n\nexport const applyStyles = (\n target: HTMLDivElement,\n { maxHeight = '0px', marginBottom = '0px', transition = '0ms' },\n) => {\n Object.assign(target.style, {\n transition,\n maxHeight,\n marginBottom,\n });\n};\n\ntype NavItemProps = {\n title: string;\n links: FooterLinks[] | undefined;\n};\n\nexport const NavTopic = ({ title, links }: NavItemProps) => {\n const navItemsRef = useRef(null);\n const [isOpen, toggleIsOpen, setIsOpen] = useToggle(false);\n const matchesLargeMedia = useMediaQuery('(min-width: 760px)', {\n initializeWithValue: true,\n }); // Mid-tablet media query\n\n const handleToggleNav = () => {\n if (matchesLargeMedia) return;\n\n const target = navItemsRef.current;\n if (!target) return;\n\n const height = `${target.scrollHeight}px`;\n const duration = calculateDuration(target.scrollHeight);\n\n const styles = isOpen\n ? {\n transition: `all ${duration}ms ease-in-out`,\n }\n : {\n maxHeight: height,\n marginBottom: '30px',\n transition: `all ${duration}ms ease-in-out`,\n };\n\n applyStyles(target, styles);\n\n toggleIsOpen();\n };\n\n const resetToggleNav = () => {\n const target = navItemsRef.current;\n if (!target) return;\n\n const styles = matchesLargeMedia\n ? { maxHeight: '100%', marginBottom: '30px' }\n : {};\n\n applyStyles(target, styles);\n\n setIsOpen(() => matchesLargeMedia);\n };\n\n useEffect(() => {\n resetToggleNav();\n }, [matchesLargeMedia]);\n\n return (\n \n
\n {title}\n\n \n
\n \n {links?.map((link, index) => (\n \n {link.title}\n \n ))}\n \n \n );\n};\n","import { useEffect, useState } from 'preact/hooks';\nimport {\n FooterResDto,\n FooterLinks,\n FooterService,\n} from '@ts/services/footerService';\nimport { SocialLinks } from '../SocialLinks/SocialLinks';\nimport { useComponent } from '../preact';\nimport { NavTopic } from './NavTopic';\nimport { Icon } from '../Icon/Icon';\n\ntype NavKey = 'legal' | 'company' | 'services';\n\ntype NavData = {\n key: NavKey;\n title: string;\n links: FooterLinks[] | undefined;\n};\n\nexport const Footer = ({ footerService = new FooterService() }) => {\n const [footerLinks, setFooterLinks] = useState();\n\n const navData: NavData[] = [\n {\n key: 'legal',\n title: 'Rechtliches',\n links: footerLinks?.legal,\n },\n {\n key: 'company',\n title: 'Unternehmen',\n links: footerLinks?.company,\n },\n {\n key: 'services',\n title: 'Kontakt & Service',\n links: footerLinks?.services,\n },\n ];\n\n const getLinks = async (service: FooterService): Promise => {\n try {\n const footerLinks = await service.getFooterLinks();\n\n setFooterLinks(() => footerLinks);\n } catch (error) {\n if (error instanceof Error)\n console.error(`Error getting footer links: ${error.message}`);\n }\n };\n\n useEffect(() => {\n getLinks(footerService);\n }, []);\n\n const dateObj = new Date();\n\n return (\n
\n
\n
\n \n
\n
\n Wir wollen bloß die Welt verändern.\n
\n
\n
\n {navData.map(({ key, title, links }) => (\n \n ))}\n
\n\n
\n © {dateObj.getFullYear()} der Freitag Mediengesellschaft mbH & Co. KG\n \n
\n
\n );\n};\n\nuseComponent('.pts-footer', () => {\n return