mirror of
https://github.com/ragestudio/comty.git
synced 2025-06-11 03:24:16 +00:00
improve router handlers
This commit is contained in:
parent
a86e999e7d
commit
96396d9e4d
@ -1,13 +1,16 @@
|
|||||||
import React from "react"
|
import React from "react"
|
||||||
import { Route, Routes, useLocation, useNavigate, useParams } from "react-router-dom"
|
import { Route, Routes, useLocation, useNavigate, useParams } from "react-router-dom"
|
||||||
import { Skeleton } from "antd"
|
import { Skeleton, Button, Result } from "antd"
|
||||||
|
import config from "config"
|
||||||
import loadable from "@loadable/component"
|
import loadable from "@loadable/component"
|
||||||
|
|
||||||
const NotFoundRender = () => {
|
import routesDeclaration from "schemas/routes"
|
||||||
|
|
||||||
|
const DefaultNotFoundRender = () => {
|
||||||
return <div>Not found</div>
|
return <div>Not found</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
const LoadingRender = () => {
|
const DefaultLoadingRender = () => {
|
||||||
return <Skeleton active />
|
return <Skeleton active />
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -21,22 +24,6 @@ const pathsMobile = {
|
|||||||
...import.meta.glob("/src/pages/**/[a-z[]*.mobile.tsx"),
|
...import.meta.glob("/src/pages/**/[a-z[]*.mobile.tsx"),
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateElementWrapper(route, element, bindProps) {
|
|
||||||
return React.createElement((props) => {
|
|
||||||
const params = useParams()
|
|
||||||
|
|
||||||
return React.createElement(
|
|
||||||
loadable(element, {
|
|
||||||
fallback: React.createElement(LoadingRender),
|
|
||||||
}),
|
|
||||||
{
|
|
||||||
...props,
|
|
||||||
...bindProps,
|
|
||||||
params: params,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const routes = Object.keys(paths).map((route) => {
|
const routes = Object.keys(paths).map((route) => {
|
||||||
const path = route
|
const path = route
|
||||||
.replace(/\/src\/pages|index|\.jsx$/g, "")
|
.replace(/\/src\/pages|index|\.jsx$/g, "")
|
||||||
@ -63,6 +50,94 @@ const mobileRoutes = Object.keys(pathsMobile).map((route) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
function generatePageElementWrapper(route, element, bindProps) {
|
||||||
|
return React.createElement((props) => {
|
||||||
|
const params = useParams()
|
||||||
|
const url = new URL(window.location)
|
||||||
|
const query = new Proxy(url, {
|
||||||
|
get: (target, prop) => target.searchParams.get(prop),
|
||||||
|
})
|
||||||
|
|
||||||
|
const routeDeclaration = routesDeclaration.find((layout) => {
|
||||||
|
const routePath = layout.path.replace(/\*/g, ".*").replace(/!/g, "^")
|
||||||
|
|
||||||
|
return new RegExp(routePath).test(route)
|
||||||
|
}) ?? {
|
||||||
|
path: route,
|
||||||
|
useLayout: "default",
|
||||||
|
}
|
||||||
|
|
||||||
|
route = route.replace(/\?.+$/, "").replace(/\/{2,}/g, "/")
|
||||||
|
route = route.replace(/\/$/, "")
|
||||||
|
|
||||||
|
if (routeDeclaration) {
|
||||||
|
if (!bindProps.user && (window.location.pathname !== config.app?.authPath)) {
|
||||||
|
if (!routeDeclaration.public) {
|
||||||
|
if (typeof window.app.setLocation === "function") {
|
||||||
|
window.app.setLocation(config.app?.authPath ?? "/login")
|
||||||
|
return <div />
|
||||||
|
}
|
||||||
|
|
||||||
|
window.location.href = config.app?.authPath ?? "/login"
|
||||||
|
|
||||||
|
return <div />
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof routeDeclaration.requiredRoles !== "undefined") {
|
||||||
|
const isAdmin = bindProps.user?.roles?.includes("admin") ?? false
|
||||||
|
|
||||||
|
if (!isAdmin && !routeDeclaration.requiredRoles.some((role) => bindProps.user?.roles?.includes(role))) {
|
||||||
|
return <Result
|
||||||
|
status="403"
|
||||||
|
title="403"
|
||||||
|
subTitle="Sorry, you are not authorized to access this page."
|
||||||
|
extra={<Button type="primary" onClick={() => window.app.setLocation("/")}>Back Home</Button>}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (routeDeclaration.useLayout) {
|
||||||
|
app.layout.set(routeDeclaration.useLayout)
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (routeDeclaration.useHeader === true) {
|
||||||
|
// app.layout.header?.toggle(true)
|
||||||
|
// } else {
|
||||||
|
// app.layout.header?.toggle(false)
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (typeof routeDeclaration.useTitle !== "undefined") {
|
||||||
|
if (typeof routeDeclaration.useTitle === "function") {
|
||||||
|
routeDeclaration.useTitle = routeDeclaration.useTitle(route, params)
|
||||||
|
}
|
||||||
|
|
||||||
|
document.title = `${routeDeclaration.useTitle} - ${config.app.siteName}`
|
||||||
|
} else {
|
||||||
|
document.title = config.app.siteName
|
||||||
|
}
|
||||||
|
|
||||||
|
if (routeDeclaration.centeredContent) {
|
||||||
|
app.layout.toogleCenteredContent(true)
|
||||||
|
} else {
|
||||||
|
app.layout.toogleCenteredContent(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return React.createElement(
|
||||||
|
loadable(element, {
|
||||||
|
fallback: React.createElement(bindProps.staticRenders?.PageLoad || DefaultLoadingRender),
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
...props,
|
||||||
|
...bindProps,
|
||||||
|
url: url,
|
||||||
|
params: params,
|
||||||
|
query: query,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export const PageRender = React.memo((props) => {
|
export const PageRender = React.memo((props) => {
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
app.location = useLocation()
|
app.location = useLocation()
|
||||||
@ -77,7 +152,9 @@ export const PageRender = React.memo((props) => {
|
|||||||
state = {}
|
state = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
state.transitionDelay = Number((app.style.getValue("page-transition-duration") ?? "250ms").replace("ms", ""))
|
const transitionDuration = app.cores.style.getValue("page-transition-duration") ?? "250ms"
|
||||||
|
|
||||||
|
state.transitionDelay = Number(transitionDuration.replace("ms", ""))
|
||||||
|
|
||||||
app.eventBus.emit("router.navigate", to, {
|
app.eventBus.emit("router.navigate", to, {
|
||||||
state,
|
state,
|
||||||
@ -113,11 +190,14 @@ export const PageRender = React.memo((props) => {
|
|||||||
return <Route
|
return <Route
|
||||||
key={index}
|
key={index}
|
||||||
path={route.path}
|
path={route.path}
|
||||||
element={generateElementWrapper(route.path, route.element, props)}
|
element={generatePageElementWrapper(route.path, route.element, props)}
|
||||||
exact
|
exact
|
||||||
/>
|
/>
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
<Route path="*" element={React.createElement(props.staticRenders?.NotFound) ?? <NotFoundRender />} />
|
<Route
|
||||||
|
path="*"
|
||||||
|
element={React.createElement(props.staticRenders?.NotFound || DefaultNotFoundRender)}
|
||||||
|
/>
|
||||||
</Routes>
|
</Routes>
|
||||||
})
|
})
|
Loading…
x
Reference in New Issue
Block a user