2024-06-16 11:23:02 +02:00
|
|
|
import * as React from 'react'
|
2024-05-11 15:08:49 +02:00
|
|
|
import { useRouter } from '../hooks/useRouter'
|
|
|
|
|
import { useRouterStore } from '../hooks/useRouterStore'
|
2024-06-02 12:14:56 +02:00
|
|
|
import type { Route } from '../route'
|
2024-05-12 17:13:41 +02:00
|
|
|
import { RouteMatch } from './RouteMatch'
|
2024-05-11 16:08:51 +02:00
|
|
|
import NotFound from './NotFound'
|
2024-05-11 15:08:49 +02:00
|
|
|
|
2024-05-23 20:41:05 +02:00
|
|
|
interface MatchesProps {
|
|
|
|
|
// user defined props
|
|
|
|
|
serverSideProps: any
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-02 12:14:56 +02:00
|
|
|
const DYNAMIC_PATH_REGEX = /\[(.*?)\]/
|
|
|
|
|
|
|
|
|
|
export function getRouteByPathname(pathname: string): Route | undefined {
|
|
|
|
|
const { routesById } = useRouter()
|
|
|
|
|
|
|
|
|
|
if (routesById[pathname]) return routesById[pathname]
|
|
|
|
|
|
|
|
|
|
const dynamicRoutes = Object.keys(routesById).filter((route) =>
|
|
|
|
|
DYNAMIC_PATH_REGEX.test(route),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if (!dynamicRoutes.length) return
|
|
|
|
|
|
|
|
|
|
const pathSegments = pathname.split('/').filter(Boolean)
|
|
|
|
|
|
|
|
|
|
let match = undefined
|
|
|
|
|
|
|
|
|
|
// TODO: Check algo efficiency
|
|
|
|
|
for (const dynamicRoute of dynamicRoutes) {
|
|
|
|
|
const dynamicRouteSegments = dynamicRoute.split('/').filter(Boolean)
|
|
|
|
|
|
|
|
|
|
const routeSegmentsCollector: string[] = []
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < dynamicRouteSegments.length; i++) {
|
|
|
|
|
if (
|
|
|
|
|
dynamicRouteSegments[i] === pathSegments[i] ||
|
|
|
|
|
DYNAMIC_PATH_REGEX.test(dynamicRouteSegments[i] || '')
|
|
|
|
|
) {
|
|
|
|
|
routeSegmentsCollector.push(dynamicRouteSegments[i] ?? '')
|
|
|
|
|
} else {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (routeSegmentsCollector.length === pathSegments.length) {
|
|
|
|
|
match = `/${routeSegmentsCollector.join('/')}`
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!match) return
|
|
|
|
|
return routesById[match]
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-23 20:41:05 +02:00
|
|
|
export function Matches({ serverSideProps }: MatchesProps): JSX.Element {
|
2024-05-11 15:08:49 +02:00
|
|
|
const location = useRouterStore((st) => st.location)
|
|
|
|
|
|
2024-06-02 12:14:56 +02:00
|
|
|
const route = getRouteByPathname(location.pathname)
|
2024-05-11 15:08:49 +02:00
|
|
|
|
2024-05-11 16:08:51 +02:00
|
|
|
if (!route) {
|
|
|
|
|
return <NotFound />
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-23 20:41:05 +02:00
|
|
|
return <RouteMatch route={route} serverSideProps={serverSideProps} />
|
2024-05-14 21:23:32 +02:00
|
|
|
}
|