2025-08-28 18:27:07 +02:00
|
|
|
import { TRPCError } from "@trpc/server";
|
|
|
|
|
import z from "zod/v4";
|
2025-10-20 16:22:20 +02:00
|
|
|
import { env } from "~/env";
|
2025-08-28 18:27:07 +02:00
|
|
|
import { createTRPCRouter, protectedProcedure } from "~/server/api/trpc";
|
|
|
|
|
import { db } from "~/server/db";
|
2025-08-04 17:45:44 +02:00
|
|
|
import {
|
2025-08-28 18:27:07 +02:00
|
|
|
AddIntrest,
|
|
|
|
|
GetUserInterests,
|
|
|
|
|
HasUserInterest,
|
|
|
|
|
RemoveInterest,
|
2025-08-04 17:45:44 +02:00
|
|
|
} from "~/server/services/interests.service";
|
|
|
|
|
import { NewMail } from "~/server/services/mailer";
|
|
|
|
|
import { findUser_byId_MINI } from "~/server/services/user.service";
|
2025-08-28 18:27:07 +02:00
|
|
|
import { zAnnuncioId, zUserId } from "~/server/utils/zod_types";
|
2025-08-04 17:45:44 +02:00
|
|
|
|
|
|
|
|
export const intrestsRouter = createTRPCRouter({
|
2025-08-28 18:27:07 +02:00
|
|
|
addIntrest: protectedProcedure
|
|
|
|
|
.input(
|
|
|
|
|
z.object({
|
|
|
|
|
annuncioId: zAnnuncioId,
|
|
|
|
|
/**Optional */
|
|
|
|
|
userId: zUserId.optional(),
|
|
|
|
|
}),
|
|
|
|
|
)
|
|
|
|
|
.mutation(async ({ ctx, input }) => {
|
|
|
|
|
const userId = input.userId || ctx.session.id;
|
|
|
|
|
await AddIntrest({
|
|
|
|
|
annuncioId: input.annuncioId,
|
|
|
|
|
userId,
|
|
|
|
|
});
|
|
|
|
|
const annuncio = await db
|
|
|
|
|
.selectFrom("annunci")
|
|
|
|
|
.select(["id", "codice", "titolo_it"])
|
|
|
|
|
.where("id", "=", input.annuncioId)
|
|
|
|
|
.executeTakeFirst();
|
|
|
|
|
if (!annuncio) {
|
|
|
|
|
throw new TRPCError({
|
|
|
|
|
code: "NOT_FOUND",
|
|
|
|
|
message: "Annuncio not found",
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
const user = await findUser_byId_MINI({
|
|
|
|
|
userId,
|
|
|
|
|
});
|
|
|
|
|
if (!user) {
|
|
|
|
|
throw new TRPCError({
|
|
|
|
|
code: "NOT_FOUND",
|
|
|
|
|
message: "User not found",
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
await NewMail({
|
|
|
|
|
mailType: "generic",
|
|
|
|
|
props: {
|
|
|
|
|
link: {
|
|
|
|
|
href: `${env.NEXT_PUBLIC_BASE_URL}/area-riservata/admin/user-view/ricerca/${userId}`,
|
|
|
|
|
label: "Visualizza utente",
|
|
|
|
|
},
|
2025-08-29 16:18:32 +02:00
|
|
|
testo: `L'utente ${user.username} (${user.email}) ha mostrato interesse per l'annuncio "${annuncio.titolo_it}" (Codice: ${annuncio.codice}).`,
|
|
|
|
|
title: "Nuovo interesse per un annuncio",
|
2025-08-28 18:27:07 +02:00
|
|
|
},
|
2025-08-29 16:18:32 +02:00
|
|
|
subject: "Utente interessato ad un annuncio",
|
|
|
|
|
to: "web@infoalloggi.it",
|
|
|
|
|
userId,
|
2025-08-28 18:27:07 +02:00
|
|
|
});
|
|
|
|
|
return { success: true };
|
|
|
|
|
}),
|
|
|
|
|
getUserInterests: protectedProcedure
|
|
|
|
|
.input(
|
|
|
|
|
z.object({
|
|
|
|
|
userId: zUserId.optional(),
|
|
|
|
|
}),
|
|
|
|
|
)
|
|
|
|
|
.query(async ({ input, ctx }) => {
|
|
|
|
|
return await GetUserInterests(input.userId || ctx.session.id);
|
|
|
|
|
}),
|
|
|
|
|
getUserInterestsAnnunci: protectedProcedure
|
|
|
|
|
.input(
|
|
|
|
|
z.object({
|
|
|
|
|
userId: zUserId.optional(),
|
|
|
|
|
}),
|
|
|
|
|
)
|
|
|
|
|
.query(async ({ input, ctx }) => {
|
|
|
|
|
try {
|
|
|
|
|
const interests = await GetUserInterests(
|
|
|
|
|
input.userId || ctx.session.id,
|
|
|
|
|
);
|
|
|
|
|
if (!interests || interests.length === 0) {
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
const annunci = await db
|
|
|
|
|
.selectFrom("annunci")
|
|
|
|
|
.select([
|
|
|
|
|
"annunci.id",
|
|
|
|
|
"annunci.codice",
|
|
|
|
|
"annunci.prezzo",
|
|
|
|
|
"annunci.desc_en",
|
|
|
|
|
"annunci.desc_it",
|
|
|
|
|
"annunci.url_immagini",
|
|
|
|
|
"annunci.titolo_en",
|
|
|
|
|
"annunci.titolo_it",
|
|
|
|
|
"annunci.tipo",
|
|
|
|
|
"annunci.consegna",
|
|
|
|
|
"annunci.stato",
|
|
|
|
|
"annunci.web",
|
|
|
|
|
])
|
|
|
|
|
.where("web", "=", true)
|
|
|
|
|
.where("stato", "!=", "Sospeso")
|
|
|
|
|
.where("annunci.id", "in", interests)
|
|
|
|
|
.execute();
|
|
|
|
|
return annunci;
|
|
|
|
|
} catch (e) {
|
|
|
|
|
throw new TRPCError({
|
|
|
|
|
code: "INTERNAL_SERVER_ERROR",
|
|
|
|
|
message: `Errore durante il recupero degli annunci: ${(e as Error).message}`,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}),
|
2025-08-29 16:18:32 +02:00
|
|
|
hasUserInterest: protectedProcedure
|
|
|
|
|
.input(
|
|
|
|
|
z.object({
|
|
|
|
|
annuncioId: zAnnuncioId,
|
|
|
|
|
userId: zUserId.optional(),
|
|
|
|
|
}),
|
|
|
|
|
)
|
|
|
|
|
.query(async ({ ctx, input }) => {
|
|
|
|
|
return await HasUserInterest({
|
|
|
|
|
annuncioId: input.annuncioId,
|
|
|
|
|
userId: input.userId || ctx.session.id,
|
|
|
|
|
});
|
|
|
|
|
}),
|
|
|
|
|
removeIntrest: protectedProcedure
|
|
|
|
|
.input(
|
|
|
|
|
z.object({
|
|
|
|
|
annuncioId: zAnnuncioId,
|
|
|
|
|
userId: zUserId.optional(),
|
|
|
|
|
}),
|
|
|
|
|
)
|
|
|
|
|
.mutation(async ({ ctx, input }) => {
|
|
|
|
|
return await RemoveInterest({
|
|
|
|
|
annuncioId: input.annuncioId,
|
|
|
|
|
userId: input.userId || ctx.session.id,
|
|
|
|
|
});
|
|
|
|
|
}),
|
2025-08-04 17:45:44 +02:00
|
|
|
});
|