import { z } from "zod"; import { createTRPCRouter, protectedProcedure } from "@/server/api/trpc"; import { friendships, users } from "@/server/db/schema"; import { and, eq, ilike, inArray, not, or } from "drizzle-orm"; import { revalidatePath } from "next/cache"; export const friendRouter = createTRPCRouter({ // queries getAll: protectedProcedure.query(async ({ ctx }) => { const friends = await ctx.db.query.friendships.findMany({ where: or( eq(friendships.userOneId, ctx.session.user.id), eq(friendships.userTwoId, ctx.session.user.id) ), with: { userOne: true, userTwo: true, }, }); const returnOne = friends.map((f) => ({ id: f.id, status: f.status, requestedBy: ctx.session.user.id === f.userOneId ? "me" : "them", user: ctx.session.user.id === f.userOneId ? f.userTwo : f.userOne, })); console.log(returnOne[0]); return returnOne; }), getPendingFriendRequests: protectedProcedure.query( async ({ ctx }) => await ctx.db.query.friendships.findMany({ where: and( or( eq(friendships.userOneId, ctx.session.user.id), eq(friendships.userTwoId, ctx.session.user.id) ), eq(friendships.status, "pending") ), }) ), search: protectedProcedure .input(z.object({ search: z.string() })) .query(async ({ ctx, input }) => { const userId = ctx.session.user.id; const friendIds = await ctx.db.query.friendships.findMany({ where: and( or( eq(friendships.userOneId, userId), eq(friendships.userTwoId, userId) ) ), columns: { userOneId: true, userTwoId: true, status: true, }, }); const excludedIds = [ userId, ...friendIds .filter((f) => f.status !== "pending") .flatMap((f) => [f.userOneId === userId ? f.userTwoId : f.userOneId]), ]; const pendingIds = friendIds .filter((f) => f.status === "pending") .flatMap((f) => [f.userOneId === userId ? f.userTwoId : f.userOneId]); const searchResult = await ctx.db.query.users.findMany({ where: and( ilike(users.name, `%${input.search}%`), not(inArray(users.id, excludedIds)) ), columns: { image: true, name: true, id: true, }, }); return searchResult.map((user) => { const pending = pendingIds.includes(user.id); return { user, pending, }; }); }), // mutations add: protectedProcedure .input(z.object({ userId: z.string() })) .mutation(async ({ ctx, input }) => { await ctx.db.insert(friendships).values({ userOneId: ctx.session.user.id, userTwoId: input.userId, status: "pending", }); revalidatePath("/friend"); }), accept: protectedProcedure .input(z.object({ friendshipId: z.string() })) .mutation(async ({ ctx, input }) => { await ctx.db .update(friendships) .set({ status: "accepted", }) .where(eq(friendships.id, input.friendshipId)); revalidatePath("/friend"); }), cancel: protectedProcedure .input(z.object({ friendshipId: z.string() })) .mutation(async ({ ctx, input }) => { await ctx.db .delete(friendships) .where(eq(friendships.id, input.friendshipId)); }), });