system-praktyk-front/src/routing.tsx
2020-09-27 22:06:53 +02:00

70 lines
2.9 KiB
TypeScript

import React, { ReactComponentElement } from "react";
import { MainPage } from "@/pages/main";
import { RouteProps } from "react-router-dom";
import { InternshipProposalFormPage, InternshipProposalPreviewPage } from "@/pages/internship/proposal";
import { FallbackPage } from "@/pages/fallback";
import SubmitPlanPage from "@/pages/internship/plan";
import { UserLoginPage } from "@/pages/user/login";
import { RegisterEditionPage } from "@/pages/edition/register";
import PickEditionPage from "@/pages/edition/pick";
import { isReadyMiddleware } from "@/middleware";
type Route = {
name?: string;
content: () => ReactComponentElement<any>,
condition?: () => boolean,
middlewares?: Middleware<any, any>[],
} & RouteProps;
export type Middleware<TReturn, TArgs extends any[]> = (next: () => any, ...args: TArgs) => TReturn;
export function processMiddlewares<TArgs extends any[]>(middleware: Middleware<any, TArgs>[], ...args: TArgs): any {
if (middleware.length == 0) {
return null;
}
const current = middleware.slice(0, 1)[0];
const left = middleware.slice(1);
return current(() => processMiddlewares(left, ...args), ...args);
}
export const routes: Route[] = [
{ name: "home", path: "/", exact: true, content: () => <MainPage/>, middlewares: [ isReadyMiddleware ] },
// edition
{ name: "edition_register", path: "/edition/register", exact: true, content: () => <RegisterEditionPage/> },
{ name: "edition_pick", path: "/edition/pick", exact: true, content: () => <PickEditionPage/> },
// internship
{ name: "internship_proposal", path: "/internship/proposal", exact: true, content: () => <InternshipProposalFormPage/>, middlewares: [ isReadyMiddleware ] },
{ name: "internship_proposal_preview", path: "/internship/preview/proposal", exact: true, content: () => <InternshipProposalPreviewPage/>, middlewares: [ isReadyMiddleware ] },
{ name: "internship_plan", path: "/internship/plan", exact: true, content: () => <SubmitPlanPage/> },
// user
{ name: "user_login", path: "/user/login", content: () => <UserLoginPage/> },
// fallback route for 404 pages
{ name: "fallback", path: "*", content: () => <FallbackPage/> }
]
const routeNameMap = new Map(routes.filter(({ name }) => !!name).map(({ name, path }) => [name, path instanceof Array ? path[0] : path])) as Map<string, string>
export type URLParams = { [param: string]: string };
export const prepare = (url: string, params: URLParams) => Object
.entries(params)
.reduce((url, [name, value]) => url.replace(`:${ name }`, value), url)
export function route(name: string, params: URLParams = {}) {
const url = routeNameMap.get(name) || "";
return prepare(url, params)
}
export const query = (url: string, params: URLParams) => {
const query = Object.entries(params).map(([name, value]) => `${ name }=${ encodeURIComponent(value) }`).join("&");
return url + (query.length > 0 ? `?${ query }` : '');
}