Files
project-gifuu/frontend/source/components/main/PaneContent.tsx
T
2026-05-23 17:17:56 -07:00

59 lines
2.6 KiB
TypeScript

import { type ReactNode, useEffect, useState } from 'react'
import { ScrollContext } from '../../functions/Context'
import HeaderMessage from '../layout/HeaderMessage'
import HeaderError from '../layout/HeaderError'
import ViewAnimation from '../views/Animation'
import ViewHomepage from '../views/Homepage'
import ViewPersonal from '../views/Personal'
import ViewSearch from '../views/Search'
import ViewSettings from '../views/Settings'
import ViewText from '../views/Text'
import ViewUpload from '../views/Upload'
export default function PaneContent() {
const [mainElem, setMainElem] = useState<HTMLElement | null>(null)
const [path, setPath] = useState(window.location.pathname)
const [key, setKey] = useState(window.location.href)
// Track Path
useEffect(() => {
const onPop = () => {
setPath(window.location.pathname)
setKey(window.location.href)
}
window.addEventListener('popstate', onPop)
return () => window.removeEventListener('popstate', onPop)
}, [])
// Match Component
const views = new Array<{ route: RegExp; scroll: boolean; component: (m: RegExpMatchArray) => ReactNode }>(
{ route: /^\/art\/([0-9]+)$/, scroll: false, component: (m) => <ViewAnimation key={key} id={m[1]} /> },
{ route: /^\/text\/([a-z-]+)$/, scroll: true, component: (m) => <ViewText key={key} id={m[1]} /> },
{ route: /^\/personal$/, scroll: true, component: (_) => <ViewPersonal /> },
{ route: /^\/upload$/, scroll: false, component: (_) => <ViewUpload key={key} /> },
{ route: /^\/settings$/, scroll: true, component: (_) => <ViewSettings key={key} /> },
{ route: /^\/search$/, scroll: true, component: (_) => <ViewSearch key={key} /> },
{ route: /^\/$/, scroll: true, component: (_) => <ViewHomepage key={key} /> },
)
const match = views.map((v) => ({ v, m: path.match(v.route) })).find(({ m }) => m !== null)
const relevant = match ? { ...match.v, component: match.v.component(match.m!) } : null
// Render Content
return (
<ScrollContext.Provider value={mainElem}>
<main ref={setMainElem} className={`layout-content ${relevant?.scroll ? 'layout-scrolling' : ''}`}>
{relevant ? (
relevant.component
) : (
<>
<HeaderMessage label="System Message" />
<HeaderError reason="The page you requested was not found." />
</>
)}
</main>
</ScrollContext.Provider>
)
}