import { Button } from "components/Inputs/Button"; import { useAppLayout } from "contexts/AppLayoutContext"; import { UploadImageFragment } from "graphql/generated"; import { AppStaticProps } from "graphql/getAppStaticProps"; import { prettyLanguage, prettySlug } from "helpers/formatters"; import { getOgImage, ImageQuality, OgImage } from "helpers/img"; import { Immutable } from "helpers/types"; import { useMediaMobile } from "hooks/useMediaQuery"; import { AnchorIds } from "hooks/useScrollTopOnChange"; import Head from "next/head"; import { useRouter } from "next/router"; import { useEffect, useMemo, useState } from "react"; import { useSwipeable } from "react-swipeable"; import { OrderableList } from "./Inputs/OrderableList"; import { Select } from "./Inputs/Select"; import { MainPanel } from "./Panels/MainPanel"; import { Popup } from "./Popup"; interface Props extends AppStaticProps { subPanel?: React.ReactNode; subPanelIcon?: string; contentPanel?: React.ReactNode; title?: string; navTitle: string | null | undefined; thumbnail?: UploadImageFragment; description?: string; } export function AppLayout(props: Immutable): JSX.Element { const { langui, currencies, languages, subPanel, contentPanel, thumbnail, title, navTitle, description, subPanelIcon, } = props; const router = useRouter(); const isMobile = useMediaMobile(); const appLayout = useAppLayout(); const sensibilitySwipe = 1.1; useMemo(() => { // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition router.events?.on("routeChangeStart", () => { appLayout.setConfigPanelOpen(false); appLayout.setMainPanelOpen(false); appLayout.setSubPanelOpen(false); }); // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition router.events?.on("hashChangeStart", () => { appLayout.setSubPanelOpen(false); }); }, [appLayout, router.events]); const handlers = useSwipeable({ onSwipedLeft: (SwipeEventData) => { if (appLayout.menuGestures) { if (SwipeEventData.velocity < sensibilitySwipe) return; if (appLayout.mainPanelOpen) { appLayout.setMainPanelOpen(false); } else if (subPanel && contentPanel) { appLayout.setSubPanelOpen(true); } } }, onSwipedRight: (SwipeEventData) => { if (appLayout.menuGestures) { if (SwipeEventData.velocity < sensibilitySwipe) return; if (appLayout.subPanelOpen) { appLayout.setSubPanelOpen(false); } else { appLayout.setMainPanelOpen(true); } } }, }); const turnSubIntoContent = subPanel && !contentPanel; const titlePrefix = "Accord’s Library"; const metaImage: OgImage = thumbnail ? getOgImage(ImageQuality.Og, thumbnail) : { image: "/default_og.jpg", width: 1200, height: 630, alt: "Accord's Library Logo", }; const ogTitle = title ?? navTitle ?? prettySlug(router.asPath.split("/").pop()); const metaDescription = description ?? langui.default_description ?? ""; useEffect(() => { document.getElementsByTagName("html")[0].style.fontSize = `${ (appLayout.fontSize ?? 1) * 100 }%`; }, [appLayout.fontSize]); const currencyOptions: string[] = []; currencies.map((currency) => { if (currency.attributes?.code) currencyOptions.push(currency.attributes.code); }); const [currencySelect, setCurrencySelect] = useState(-1); let defaultPreferredLanguages: string[] = []; if (router.locale && router.locales) { if (router.locale === "en") { defaultPreferredLanguages = [router.locale]; router.locales.map((locale) => { if (locale !== router.locale) defaultPreferredLanguages.push(locale); }); } else { defaultPreferredLanguages = [router.locale, "en"]; router.locales.map((locale) => { if (locale !== router.locale && locale !== "en") defaultPreferredLanguages.push(locale); }); } } useEffect(() => { if (appLayout.currency) setCurrencySelect(currencyOptions.indexOf(appLayout.currency)); // eslint-disable-next-line react-hooks/exhaustive-deps }, [appLayout.currency]); useEffect(() => { if (currencySelect >= 0) appLayout.setCurrency(currencyOptions[currencySelect]); // eslint-disable-next-line react-hooks/exhaustive-deps }, [currencySelect]); let gridCol = ""; if (subPanel) { if (appLayout.mainPanelReduced) { gridCol = "grid-cols-[6rem_20rem_1fr]"; } else { gridCol = "grid-cols-[20rem_20rem_1fr]"; } } else if (appLayout.mainPanelReduced) { gridCol = "grid-cols-[6rem_0px_1fr]"; } else { gridCol = "grid-cols-[20rem_0px_1fr]"; } return (
{`${titlePrefix} - ${ogTitle}`} {/* Background when navbar is opened */}
{ appLayout.setMainPanelOpen(false); appLayout.setSubPanelOpen(false); }} >
{/* Content panel */}
{contentPanel ? ( contentPanel ) : (

{langui.select_option_sidebar}

)}
{/* Sub panel */} {subPanel && (
{subPanel}
)} {/* Main panel */}
{/* Navbar */}
{ appLayout.setMainPanelOpen(!appLayout.mainPanelOpen); appLayout.setSubPanelOpen(false); }} > {appLayout.mainPanelOpen ? "close" : "menu"}

30 ? "text-xl max-h-14" : "text-2xl max-h-16" }`} > {ogTitle}

{ appLayout.setSubPanelOpen(!appLayout.subPanelOpen); appLayout.setMainPanelOpen(false); }} > {subPanel && !turnSubIntoContent ? appLayout.subPanelOpen ? "close" : subPanelIcon ? subPanelIcon : "tune" : ""}

{langui.settings}

{router.locales && (

{langui.languages}

{appLayout.preferredLanguages && ( 0 ? new Map( appLayout.preferredLanguages.map((locale) => [ locale, prettyLanguage(locale, languages), ]) ) : new Map( defaultPreferredLanguages.map((locale) => [ locale, prettyLanguage(locale, languages), ]) ) } insertLabels={ new Map([ [0, langui.primary_language], [1, langui.secondary_language], ]) } onChange={(items) => { const preferredLanguages = [...items].map( ([code]) => code ); appLayout.setPreferredLanguages(preferredLanguages); if (router.locale !== preferredLanguages[0]) { router.push(router.asPath, router.asPath, { locale: preferredLanguages[0], }); } }} /> )}
)}

{langui.theme}

{langui.currency}

appLayout.setPlayerName( (event.target as HTMLInputElement).value ) } value={appLayout.playerName} />
); }