import type { IRouteParams } from "@ethicdevs/react-monolith";
import { AppRouter, AppRouterGroup, Router } from "@ethicdevs/react-monolith";
import { FastifySchema } from "fastify";
import React from "react";
import { authenticatedOrLogin, guestOrRedirect } from "./utils/server";
import { AuthController } from "./controllers/auth";
import { RepositoryController } from "./controllers/repository";
import * as HomeController from "./controllers/HomeController";
import * as ThemeController from "./controllers/ThemeController";
export enum AppRoute {
HOME = "home",
SET_THEME = "set_theme.action",
AUTH_REGISTER = "auth.register",
AUTH_REGISTER_ACTION = "auth.register.action",
AUTH_LOGIN = "auth.login",
AUTH_LOGIN_ACTION = "auth.login.action",
AUTH_LOGOUT_ACTION = "auth.logout.action",
USER_DASHBOARD = "user.dashboard",
REPOSITORY_EXPLORE = "repository.explore",
}
export interface AppRoutesParams extends IRouteParams {
[AppRoute.HOME]: undefined;
[AppRoute.SET_THEME]: {
themeScheme: string;
};
[AppRoute.AUTH_REGISTER]: undefined;
[AppRoute.AUTH_REGISTER_ACTION]: {
body: {
email_address: string;
username: string;
password: string;
};
};
[AppRoute.AUTH_LOGIN]: undefined;
[AppRoute.AUTH_LOGIN_ACTION]: {
body: {
email_address: string;
password: string;
};
};
[AppRoute.AUTH_LOGOUT_ACTION]: undefined;
[AppRoute.USER_DASHBOARD]: undefined;
[AppRoute.REPOSITORY_EXPLORE]: undefined;
}
export const AppRoutesSchemas: Record<AppRoute, undefined | FastifySchema> = {
[AppRoute.HOME]: undefined,
[AppRoute.SET_THEME]: {
params: {
type: "object",
required: ["themeScheme"],
additionalProperties: false,
properties: {
themeScheme: {
type: "string",
enum: ["light", "dark"],
},
},
},
},
[AppRoute.AUTH_REGISTER]: undefined,
[AppRoute.AUTH_REGISTER_ACTION]: {
body: {
type: "object",
required: ["email_address", "username", "password"],
additionalProperties: false,
properties: {
email_address: { type: "string" },
username: { type: "string" },
password: { type: "string" },
},
},
},
[AppRoute.AUTH_LOGIN]: undefined,
[AppRoute.AUTH_LOGIN_ACTION]: {
body: {
type: "object",
required: ["email_address", "password"],
additionalProperties: false,
properties: {
email_address: { type: "string" },
password: { type: "string" },
},
},
},
[AppRoute.AUTH_LOGOUT_ACTION]: undefined,
[AppRoute.USER_DASHBOARD]: undefined,
[AppRoute.REPOSITORY_EXPLORE]: undefined,
};
const RootAppRouter: AppRouter = () => {
const guestOrDashboardRedirect = guestOrRedirect("/dashboard");
const loggedOrLoginRedirect = authenticatedOrLogin();
return (
<Router.Root>
<></>
<Router.Group type={AppRouterGroup.API}>
<Router.Route
name={AppRoute.SET_THEME}
method={"GET"}
path={"/theme/:themeScheme"}
schema={AppRoutesSchemas[AppRoute.SET_THEME]}
handler={ThemeController.getTheme}
/>
{}
<Router.Route
name={AppRoute.HOME}
method={"GET"}
path={"/"}
preHandler={guestOrDashboardRedirect}
handler={HomeController.getHomeView}
/>
{}
<Router.Route
name={AppRoute.AUTH_REGISTER}
method={"GET"}
path={"/auth/register"}
preHandler={guestOrDashboardRedirect}
handler={AuthController.getRegisterView}
/>
<Router.Route
name={AppRoute.AUTH_REGISTER_ACTION}
method={"POST"}
path={"/auth/register"}
schema={AppRoutesSchemas[AppRoute.AUTH_REGISTER_ACTION]}
preHandler={guestOrDashboardRedirect}
handler={AuthController.postRegisterAction}
/>
{}
<Router.Route
name={AppRoute.AUTH_LOGIN}
method={"GET"}
path={"/auth/login"}
preHandler={guestOrDashboardRedirect}
handler={AuthController.getLoginView}
/>
<Router.Route
name={AppRoute.AUTH_LOGIN_ACTION}
method={"POST"}
path={"/auth/login"}
schema={AppRoutesSchemas[AppRoute.AUTH_LOGIN_ACTION]}
preHandler={guestOrDashboardRedirect}
handler={AuthController.postLoginAction}
/>
<Router.Route
name={AppRoute.AUTH_LOGOUT_ACTION}
method={"GET"}
path={"/auth/logout"}
schema={AppRoutesSchemas[AppRoute.AUTH_LOGOUT_ACTION]}
preHandler={loggedOrLoginRedirect}
handler={AuthController.getLogoutAction}
/>
{}
<Router.Route
name={AppRoute.USER_DASHBOARD}
method={"GET"}
path={"/dashboard"}
preHandler={loggedOrLoginRedirect}
handler={AuthController.getDashboardView}
/>
{}
<Router.Route
name={AppRoute.REPOSITORY_EXPLORE}
method={"GET"}
path={"/repo/explore"}
handler={RepositoryController.getRepositoryExploreView}
/>
<Router.Route
name={AppRoute.REPOSITORY_EXPLORE}
method={"GET"}
path={"/repo/new"}
preHandler={loggedOrLoginRedirect}
handler={RepositoryController.getRepositoryCreateView}
/>
</Router.Group>
</Router.Root>
);
};
export default RootAppRouter;