From abc7e00bbe7a24d2dbd9a2e9ad99a89f66ec841b Mon Sep 17 00:00:00 2001 From: sianida26 Date: Tue, 7 May 2024 23:13:58 +0700 Subject: [PATCH] Added RPC wrapper function --- apps/backend/src/index.ts | 2 + apps/backend/src/routes/dev/route.ts | 16 +++++ .../modals/UserDeleteModal.tsx | 22 +++---- .../usersManagement/modals/UserFormModal.tsx | 1 + .../usersManagement/queries/userQueries.ts | 66 ++++++------------- apps/frontend/src/utils/fetchRPC.ts | 29 ++++++++ 6 files changed, 78 insertions(+), 58 deletions(-) create mode 100644 apps/backend/src/routes/dev/route.ts create mode 100644 apps/frontend/src/utils/fetchRPC.ts diff --git a/apps/backend/src/index.ts b/apps/backend/src/index.ts index 9ad18d7..bfc9bf2 100644 --- a/apps/backend/src/index.ts +++ b/apps/backend/src/index.ts @@ -13,6 +13,7 @@ import rolesRoute from "./routes/roles/route"; import { logger } from "hono/logger"; import DashboardError from "./errors/DashboardError"; import HonoEnv from "./types/HonoEnv"; +import devRoutes from "./routes/dev/route"; configDotenv(); @@ -75,6 +76,7 @@ const routes = app .route("/permissions", permissionRoutes) .route("/dashboard", dashboardRoutes) .route("/roles", rolesRoute) + .route("/dev", devRoutes) .onError((err, c) => { if (err instanceof DashboardError) { return c.json( diff --git a/apps/backend/src/routes/dev/route.ts b/apps/backend/src/routes/dev/route.ts new file mode 100644 index 0000000..6a9eb31 --- /dev/null +++ b/apps/backend/src/routes/dev/route.ts @@ -0,0 +1,16 @@ +import { Hono } from "hono"; +import DashboardError from "../../errors/DashboardError"; + +const devRoutes = new Hono().get("/error", async () => { + throw new DashboardError({ + errorCode: "TEST_ERROR", + message: "Test error", + severity: "LOW", + statusCode: 400, + formErrors: { + someField: "error", + }, + }); +}); + +export default devRoutes; diff --git a/apps/frontend/src/modules/usersManagement/modals/UserDeleteModal.tsx b/apps/frontend/src/modules/usersManagement/modals/UserDeleteModal.tsx index 3f791c4..ef4b57f 100644 --- a/apps/frontend/src/modules/usersManagement/modals/UserDeleteModal.tsx +++ b/apps/frontend/src/modules/usersManagement/modals/UserDeleteModal.tsx @@ -4,6 +4,7 @@ import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { getRouteApi, useSearch } from "@tanstack/react-router"; import { deleteUser } from "../queries/userQueries"; import { notifications } from "@mantine/notifications"; +import fetchRPC from "@/utils/fetchRPC"; const routeApi = getRouteApi("/_dashboardLayout/users/"); @@ -21,19 +22,14 @@ export default function UserDeleteModal() { queryKey: ["users", userId], queryFn: async () => { if (!userId) return null; - const res = await client.users[":id"].$get({ - param: { - id: userId, - }, - query: {}, - }); - - if (res.ok) { - console.log("ok"); - return await res.json(); - } - console.log("not ok"); - throw new Error(await res.text()); + return await fetchRPC( + client.users[":id"].$get({ + param: { + id: userId, + }, + query: {}, + }) + ); }, }); diff --git a/apps/frontend/src/modules/usersManagement/modals/UserFormModal.tsx b/apps/frontend/src/modules/usersManagement/modals/UserFormModal.tsx index 5c1998f..8cdb1e2 100644 --- a/apps/frontend/src/modules/usersManagement/modals/UserFormModal.tsx +++ b/apps/frontend/src/modules/usersManagement/modals/UserFormModal.tsx @@ -133,6 +133,7 @@ export default function UserFormModal() { }); form.setErrors({}); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [userQuery.data]); const handleSubmit = async (values: typeof form.values) => { diff --git a/apps/frontend/src/modules/usersManagement/queries/userQueries.ts b/apps/frontend/src/modules/usersManagement/queries/userQueries.ts index 549e282..3b0179a 100644 --- a/apps/frontend/src/modules/usersManagement/queries/userQueries.ts +++ b/apps/frontend/src/modules/usersManagement/queries/userQueries.ts @@ -1,4 +1,5 @@ import client from "@/honoClient"; +import fetchRPC from "@/utils/fetchRPC"; import { queryOptions } from "@tanstack/react-query"; import { InferRequestType } from "hono"; @@ -8,31 +9,21 @@ export const userQueryOptions = queryOptions({ }); export const fetchUsers = async () => { - const res = await client.users.$get({ - query: {}, - }); - - if (res.ok) { - return await res.json(); - } - - //TODO: Handle error - throw new Error(res.statusText); + return await fetchRPC( + client.users.$get({ + query: {}, + }) + ); }; export const createUser = async ( form: InferRequestType["form"] ) => { - const res = await client.users.$post({ - form, - }); - - if (res.ok) { - return await res.json(); - } - - //TODO: Handle error - throw Error(await res.text()); + return await fetchRPC( + client.users.$post({ + form, + }) + ); }; export const updateUser = async ( @@ -40,34 +31,19 @@ export const updateUser = async ( id: string; } ) => { - form; - const res = await client.users[":id"].$patch({ - param: { - id: form.id, - }, - form, - }); - - if (res.ok) { - return await res.json(); - } - - //TODO: Handle error - throw new Error(await res.text()); + return await fetchRPC( + client.users[":id"].$patch({ + param: { + id: form.id, + }, + form, + }) + ); }; export const deleteUser = async (id: string) => { - const res = await client.users[":id"].$delete({ - param: { - id, - }, + return await client.users[":id"].$delete({ + param: { id }, form: {}, }); - - if (res.ok) { - return await res.json(); - } - - //TODO: Handle error - throw new Error(await res.text()); }; diff --git a/apps/frontend/src/utils/fetchRPC.ts b/apps/frontend/src/utils/fetchRPC.ts new file mode 100644 index 0000000..56c0aff --- /dev/null +++ b/apps/frontend/src/utils/fetchRPC.ts @@ -0,0 +1,29 @@ +import { ClientResponse } from "hono/client"; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +type BlankRecordToNever = T extends any + ? T extends null + ? null + : keyof T extends never + ? never + : T + : never; + +async function fetchRPC( + endpoint: Promise> +): Promise> { + const res = await endpoint; + + if (res.ok) { + const data = await res.json(); + return data; + } + + //TODO: Add error reporting + + const data = (await res.json()) as unknown as { message?: string }; + + throw new Error(data.message ?? "Something is gone wrong"); +} + +export default fetchRPC;