122 lines
3.5 KiB
TypeScript
122 lines
3.5 KiB
TypeScript
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));
|
|
}),
|
|
});
|