feat(dashboard): setting up layout

This commit is contained in:
2025-11-12 16:51:59 +02:00
parent b8b2a15ee9
commit a3f46b6b38
61 changed files with 2957 additions and 123 deletions
+67
View File
@@ -0,0 +1,67 @@
import { Database, db } from "@basango/db/client";
import { initTRPC } from "@trpc/server";
import type { Context } from "hono";
import superjson from "superjson";
import { withAuthentication } from "@/trpc/middlewares/auth";
import { withDatabase } from "@/trpc/middlewares/db";
import { Session, verifyAccessToken } from "@/utils/auth";
import { getGeoContext } from "@/utils/geo";
type TRPCContext = {
session: Session | null;
db: Database;
geo: ReturnType<typeof getGeoContext>;
};
export const createTRPCContext = async (_: unknown, c: Context): Promise<TRPCContext> => {
const accessToken = c.req.header("Authorization")?.split(" ")[1];
const session = await verifyAccessToken(accessToken);
const geo = getGeoContext(c.req);
return {
db,
geo,
session,
};
};
const t = initTRPC.context<TRPCContext>().create({
transformer: superjson,
});
export const createTRPCRouter = t.router;
export const createCallerFactory = t.createCallerFactory;
const withDatabaseMiddleware = t.middleware(async (opts) => {
return withDatabase({
ctx: opts.ctx,
next: opts.next,
});
});
const withAutenticationMiddleware = t.middleware(async (opts) => {
return withAuthentication({
ctx: opts.ctx,
next: opts.next,
});
});
export const publicProcedure = t.procedure.use(withDatabaseMiddleware);
export const protectedProcedure = t.procedure
.use(withDatabaseMiddleware)
.use(withAutenticationMiddleware) // NOTE: This is needed to ensure that the teamId is set in the context
.use(async (opts) => {
const { session } = opts.ctx;
// if (!session) {
// throw new TRPCError({ code: "UNAUTHORIZED" });
// }
return opts.next({
ctx: {
session,
},
});
});
+36
View File
@@ -0,0 +1,36 @@
import type { Database } from "@basango/db/client";
// import { TRPCError } from "@trpc/server";
import type { Session } from "@/utils/auth";
export const withAuthentication = async <TReturn>(opts: {
ctx: {
session?: Session | null;
db: Database;
};
next: (opts: {
ctx: {
session?: Session | null;
db: Database;
};
}) => Promise<TReturn>;
}) => {
const { ctx, next } = opts;
// const userId = ctx.session?.user?.id;
// if (!userId) {
// throw new TRPCError({
// code: "UNAUTHORIZED",
// message: "No permission to access",
// });
// }
return next({
ctx: {
db: ctx.db,
session: ctx.session,
},
});
};
+23
View File
@@ -0,0 +1,23 @@
import { type Database, db } from "@basango/db/client";
import type { Session } from "@/utils/auth";
export const withDatabase = async <TReturn>(opts: {
ctx: {
session?: Session | null;
db: Database;
};
next: (opts: {
ctx: {
session?: Session | null;
db: Database;
};
}) => Promise<TReturn>;
}) => {
const { ctx, next } = opts;
ctx.db = db;
const result = await next({ ctx });
return result;
};
+13
View File
@@ -0,0 +1,13 @@
import type { inferRouterInputs, inferRouterOutputs } from "@trpc/server";
import { createTRPCRouter } from "@/trpc/init";
import { sourcesRouter } from "@/trpc/routers/sources";
export const appRouter = createTRPCRouter({
sources: sourcesRouter,
});
// export type definition of API
export type AppRouter = typeof appRouter;
export type RouterOutputs = inferRouterOutputs<AppRouter>;
export type RouterInputs = inferRouterInputs<AppRouter>;
+20
View File
@@ -0,0 +1,20 @@
import { createSource, getSourceById, getSources, updateSource } from "@basango/db/queries";
import { createSourceSchema, getSourceSchema, updateSourceSchema } from "@/schemas/sources";
import { createTRPCRouter, protectedProcedure } from "@/trpc/init";
export const sourcesRouter = createTRPCRouter({
create: protectedProcedure.input(createSourceSchema).mutation(async ({ ctx, input }) => {
return createSource(ctx.db, { ...input });
}),
get: protectedProcedure.query(async ({ ctx }) => getSources(ctx.db)),
getById: protectedProcedure.input(getSourceSchema).query(async ({ ctx, input }) => {
return getSourceById(ctx.db, { ...input });
}),
update: protectedProcedure.input(updateSourceSchema).mutation(async ({ ctx, input }) => {
return updateSource(ctx.db, { ...input });
}),
});