Skip to content

Commit

Permalink
split admin
Browse files Browse the repository at this point in the history
  • Loading branch information
Hoishin committed Feb 10, 2024
1 parent afcac11 commit d860c1f
Show file tree
Hide file tree
Showing 31 changed files with 281 additions and 129 deletions.
8 changes: 3 additions & 5 deletions local-proxy/h2o.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ hosts:
paths:
/:
proxy.reverse.url: http://host.docker.internal:3000
/assets:
file.dir: /www/assets
expires: 1 year
header.set:
- "X-Content-Type-Options: nosniff"
/admin:
proxy.reverse.url: http://host.docker.internal:4000/admin
proxy.tunnel: ON
91 changes: 91 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@
"private": true,
"type": "module",
"scripts": {
"build": "panda codegen && cross-env NODE_ENV=production run-p build:*",
"build": "panda codegen && cross-env NODE_ENV=production run-s build:*",
"build:types": "tsc --noEmit",
"build:remix": "remix vite:build",
"build:server": "esbuild src/server/main.ts --bundle --format=esm --sourcemap --platform=node --target=node20 --outdir=out --packages=external --external:./build/server/index.js",
"build:admin": "cd src/admin && vite build",
"dev": "panda codegen && run-p dev:*",
"dev:remix": "onchange src/server src/shared -ik -- tsx --env-file=.env --env-file=.env.local src/server/main.ts",
"dev:db": "docker compose up",
"dev:types": "tsc --noEmit --watch --preserveWatchOutput",
"dev:prisma": "prisma generate --watch",
"dev:admin": "cd src/admin && npx vite",
"lint": "eslint --ext .ts,.tsx src"
},
"dependencies": {
Expand Down Expand Up @@ -54,6 +56,7 @@
"@types/react": "^18.2.55",
"@types/react-dom": "^18.2.19",
"@typescript-eslint/eslint-plugin": "^6.21.0",
"@vitejs/plugin-react": "^4.2.1",
"cross-env": "^7.0.3",
"esbuild": "0.20.0",
"eslint": "^8.56.0",
Expand Down
1 change: 1 addition & 0 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ model UserEmailChange {
}

enum Role {
SuperAdmin
Admin
}

Expand Down
17 changes: 12 additions & 5 deletions prisma/seed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@ import { PrismaClient, Role } from "@prisma/client";
const prisma = new PrismaClient();

const devSeed = async () => {
await prisma.user.create({
data: {
email: "superadmin@example.com",
UserRole: {
create: [{ role: Role.SuperAdmin }, { role: Role.Admin }],
},
},
});

await prisma.user.create({
data: {
email: "admin@example.com",
Expand Down Expand Up @@ -223,16 +232,14 @@ const prodSeed = async () => {
data: {
email: "hoishinxii@gmail.com",
UserRole: {
create: {
role: Role.Admin,
},
create: [{ role: Role.SuperAdmin }, { role: Role.Admin }],
},
},
});
};

if (process.env.NODE_ENV === "production") {
prodSeed();
await prodSeed();
} else {
devSeed();
await devSeed();
}
37 changes: 8 additions & 29 deletions src/app/routes/admin.$/route.tsx → src/admin/app.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import "./index.css";

import { Role } from "@prisma/client";
import type { LoaderFunctionArgs } from "@remix-run/node";
import { Admin, Resource } from "react-admin";

import { prisma } from "../../../shared/prisma.server";
import { assertSession } from "../../session.server";

import { authProvider } from "./auth-provider";
import { dataProvider } from "./data-provider";
import { EventCreate, EventEdit, EventList } from "./event";
import {
Expand All @@ -17,30 +13,13 @@ import {
import { RunEdit, RunList } from "./run";
import { UserList } from "./user";


export const loader = async ({ request }: LoaderFunctionArgs) => {
const session = await assertSession(request);

const adminRole = await prisma.userRole.findFirst({
where: {
userId: session.user.id,
role: Role.Admin,
},
select: {
role: true,
},
});

if (!adminRole) {
throw new Response(null, { status: 404 });
}

return null;
};

export default function AdminPage() {
export const App = () => {
return (
<Admin basename="/admin" dataProvider={dataProvider}>
<Admin
basename="/admin"
dataProvider={dataProvider}
authProvider={authProvider}
>
<Resource name="user" list={UserList} />
<Resource
name="eventGroup"
Expand All @@ -61,4 +40,4 @@ export default function AdminPage() {
<Resource name="run" list={RunList} edit={RunEdit} />
</Admin>
);
}
};
35 changes: 35 additions & 0 deletions src/admin/auth-provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { serialize } from "cookie";

import { SIGN_IN_REDIRECT_COOKIE_NAME } from "../shared/constants";

import { trpc } from "./trpc";

const noop = async () => {
// do nothing
};

export const authProvider = {
checkAuth: async () => {
const isSignedIn = await trpc.authentication.isSignedIn.query();
if (!isSignedIn) {
document.cookie = serialize(SIGN_IN_REDIRECT_COOKIE_NAME, "/admin");
location.href = "/sign-in";
return;
}

const roles = await trpc.authentication.roles.query();
if (roles.includes("SuperAdmin") || roles.includes("Admin")) {
return;
}
location.href = "/";
},

logout: async () => {
await trpc.authentication.signOut.mutate();
location.href = "/";
},

login: noop,
checkError: noop,
getPermissions: noop,
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import type {
CreateResult,
DataProvider,
DeleteManyParams,
DeleteManyResult,
DeleteParams,
Expand All @@ -18,7 +17,7 @@ import type {
UpdateResult,
} from "react-admin";

import { trpcClient } from "../../trpc";
import { trpc } from "./trpc";

const filterResource = (resource: string) => {
switch (resource) {
Expand All @@ -32,51 +31,49 @@ const filterResource = (resource: string) => {
}
};

export const dataProvider: DataProvider = {
export const dataProvider = {
getList: (
resource: string,
params: GetListParams,
): Promise<GetListResult> => {
return trpcClient.admin[filterResource(resource)].getList.query(params);
return trpc.admin[filterResource(resource)].getList.query(params);
},

getOne: (resource: string, params: GetOneParams): Promise<GetOneResult> => {
return trpcClient.admin[filterResource(resource)].getOne.query(params);
return trpc.admin[filterResource(resource)].getOne.query(params);
},

getMany: (resource: string, params: any): Promise<GetManyResult> => {
return trpcClient.admin[filterResource(resource)].getMany.query(params);
return trpc.admin[filterResource(resource)].getMany.query(params);
},

getManyReference: (
resource: string,
params: any,
): Promise<GetManyReferenceResult> => {
return trpcClient.admin[filterResource(resource)].getManyReference.query(
params,
);
return trpc.admin[filterResource(resource)].getManyReference.query(params);
},

create: (resource: string, params: any): Promise<CreateResult> => {
return trpcClient.admin[filterResource(resource)].create.mutate(params);
return trpc.admin[filterResource(resource)].create.mutate(params);
},

update: (resource: string, params: UpdateParams): Promise<UpdateResult> => {
return trpcClient.admin[filterResource(resource)].update.mutate(params);
return trpc.admin[filterResource(resource)].update.mutate(params);
},

updateMany: (resource: string, params: any): Promise<UpdateManyResult> => {
return trpcClient.admin[filterResource(resource)].updateMany.mutate(params);
return trpc.admin[filterResource(resource)].updateMany.mutate(params);
},

delete: (resource: string, params: DeleteParams): Promise<DeleteResult> => {
return trpcClient.admin[filterResource(resource)].delete.mutate(params);
return trpc.admin[filterResource(resource)].delete.mutate(params);
},

deleteMany: (
resource: string,
params: DeleteManyParams,
): Promise<DeleteManyResult> => {
return trpcClient.admin[filterResource(resource)].deleteMany.mutate(params);
return trpc.admin[filterResource(resource)].deleteMany.mutate(params);
},
};
8 changes: 8 additions & 0 deletions src/admin/entry.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { createRoot } from "react-dom/client";

import { App } from "./app";

const rootElement = document.getElementById("root");
if (rootElement) {
createRoot(rootElement).render(<App />);
}
File renamed without changes.
2 changes: 1 addition & 1 deletion src/app/routes/admin.$/event.tsx → src/admin/event.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
RadioButtonGroupInput,
} from "react-admin";

import { dataSourceType } from "../../../shared/constants";
import { dataSourceType } from "../shared/constants";

export const EventList = () => (
<List sort={{ field: "startDate", order: "ASC" }}>
Expand Down
File renamed without changes.

0 comments on commit d860c1f

Please sign in to comment.