feat: profile picture

This commit is contained in:
Henry
2025-01-21 22:41:04 +00:00
parent a162624eb8
commit ef8f42a460
16 changed files with 303 additions and 59 deletions

View File

@@ -5,6 +5,7 @@ import { importRouter } from "./routers/import";
import { labelRouter } from "./routers/label";
import { listRouter } from "./routers/list";
import { memberRouter } from "./routers/member";
import { userRouter } from "./routers/user";
import { workspaceRouter } from "./routers/workspace";
import { createTRPCRouter } from "./trpc";
@@ -16,6 +17,7 @@ export const appRouter = createTRPCRouter({
list: listRouter,
member: memberRouter,
import: importRouter,
user: userRouter,
workspace: workspaceRouter,
});

View File

@@ -1,52 +1,9 @@
import { TRPCError } from "@trpc/server";
import { z } from "zod";
import * as userRepo from "@kan/db/repository/user.repo";
import { createTRPCRouter, protectedProcedure, publicProcedure } from "../trpc";
import { createTRPCRouter, publicProcedure } from "../trpc";
export const authRouter = createTRPCRouter({
getUser: protectedProcedure
.meta({
openapi: {
method: "GET",
path: "/users/me",
summary: "Get user",
description:
"Retrieves the currently authenticated user's profile information",
tags: ["Users"],
protect: true,
},
})
.input(z.void())
.output(
z.object({
id: z.string(),
email: z.string(),
name: z.string().nullable(),
stripeCustomerId: z.string().nullable(),
}),
)
.query(async ({ ctx }) => {
const userId = ctx.user?.id;
if (!userId)
throw new TRPCError({
message: `User not authenticated`,
code: "UNAUTHORIZED",
});
const result = await userRepo.getById(ctx.db, userId);
if (!result?.name) {
throw new TRPCError({
message: `User not found`,
code: "NOT_FOUND",
});
}
return result;
}),
loginWithEmail: publicProcedure
.meta({
openapi: {

View File

@@ -0,0 +1,93 @@
import { TRPCError } from "@trpc/server";
import { z } from "zod";
import * as userRepo from "@kan/db/repository/user.repo";
import { createTRPCRouter, protectedProcedure } from "../trpc";
export const userRouter = createTRPCRouter({
getUser: protectedProcedure
.meta({
openapi: {
method: "GET",
path: "/users/me",
summary: "Get user",
description:
"Retrieves the currently authenticated user's profile information",
tags: ["Users"],
protect: true,
},
})
.input(z.void())
.output(
z.object({
id: z.string(),
email: z.string(),
name: z.string().nullable(),
image: z.string().nullable(),
stripeCustomerId: z.string().nullable(),
}),
)
.query(async ({ ctx }) => {
const userId = ctx.user?.id;
if (!userId)
throw new TRPCError({
message: `User not authenticated`,
code: "UNAUTHORIZED",
});
const result = await userRepo.getById(ctx.db, userId);
if (!result?.name) {
throw new TRPCError({
message: `User not found`,
code: "NOT_FOUND",
});
}
return result;
}),
update: protectedProcedure
.meta({
openapi: {
method: "PUT",
path: "/users",
summary: "Update user",
description:
"Updates the currently authenticated user's profile information",
tags: ["Users"],
protect: true,
},
})
.input(
z.object({
image: z.string(),
}),
)
.output(
z.object({
image: z.string().nullable(),
}),
)
.mutation(async ({ ctx, input }) => {
const userId = ctx.user?.id;
if (!userId)
throw new TRPCError({
message: `User not authenticated`,
code: "UNAUTHORIZED",
});
const result = await userRepo.update(ctx.adminDb, userId, input);
if (!result) {
throw new TRPCError({
message: `User not found`,
code: "NOT_FOUND",
});
}
return result;
}),
});