refactor: clean up unused code and improve type definitions in various components

This commit is contained in:
Marco Pedone 2026-04-10 12:08:33 +02:00
parent d4c28117d7
commit 0e606aa60e
6 changed files with 206 additions and 190 deletions

View file

@ -51,7 +51,6 @@ import { useTranslation } from "~/providers/I18nProvider";
import { useServizio } from "~/providers/ServizioProvider"; import { useServizio } from "~/providers/ServizioProvider";
import type { AnnunciId } from "~/schemas/public/Annunci"; import type { AnnunciId } from "~/schemas/public/Annunci";
import type { Ordini } from "~/schemas/public/Ordini"; import type { Ordini } from "~/schemas/public/Ordini";
import type { Prezziario } from "~/schemas/public/Prezziario";
import type { ServizioServizioId } from "~/schemas/public/Servizio"; import type { ServizioServizioId } from "~/schemas/public/Servizio";
import TipologiaPosizioneEnum from "~/schemas/public/TipologiaPosizioneEnum"; import TipologiaPosizioneEnum from "~/schemas/public/TipologiaPosizioneEnum";
import type { UsersId } from "~/schemas/public/Users"; import type { UsersId } from "~/schemas/public/Users";
@ -246,7 +245,16 @@ export const OrdersModal = ({
}: { }: {
children: React.ReactNode; children: React.ReactNode;
isAdmin: boolean; isAdmin: boolean;
ordini: (Ordini & Pick<Prezziario, "testo_condizioni">)[]; ordini: Pick<
Ordini,
| "isActive"
| "ordine_id"
| "created_at"
| "packid"
| "amount_cent"
| "userid"
| "type"
>[];
}) => { }) => {
const [openOrders, setOpenOrders] = useState(false); const [openOrders, setOpenOrders] = useState(false);
const [openEdit, setOpenEdit] = useState(false); const [openEdit, setOpenEdit] = useState(false);

View file

@ -305,6 +305,7 @@ export const RichiesteTable = ({ data }: RichiesteTableProps) => {
const activeAcconto = acconti.find((a) => a.isActive); const activeAcconto = acconti.find((a) => a.isActive);
//hasActiveAcconto
if (activeAcconto) { if (activeAcconto) {
badgeClass = "border-yellow-500 bg-yellow-500/10 text-yellow-600"; badgeClass = "border-yellow-500 bg-yellow-500/10 text-yellow-600";
contents = ( contents = (
@ -359,6 +360,7 @@ export const RichiesteTable = ({ data }: RichiesteTableProps) => {
return; return;
} }
if ( if (
//hasConsulanzaDaPagare
row.original.ordini_servizio.some( row.original.ordini_servizio.some(
(o) => o.type === OrderTypeEnum.Consulenza && !o.isActive, (o) => o.type === OrderTypeEnum.Consulenza && !o.isActive,
) )
@ -557,9 +559,11 @@ export const RichiesteTable = ({ data }: RichiesteTableProps) => {
{ {
accessorKey: "ordini", accessorKey: "ordini",
cell: ({ row }) => { cell: ({ row }) => {
//paidOrdiniCount
const paidOrders = row.original.ordini_servizio.filter( const paidOrders = row.original.ordini_servizio.filter(
(o) => o.isActive, (o) => o.isActive,
).length; ).length;
//unpaidOrdiniCount
const unpaidOrders = row.original.ordini_servizio.length - paidOrders; const unpaidOrders = row.original.ordini_servizio.length - paidOrders;
return ( return (
<OrdersModal isAdmin={true} ordini={row.original.ordini_servizio}> <OrdersModal isAdmin={true} ordini={row.original.ordini_servizio}>

View file

@ -50,6 +50,24 @@ export type WithParsedDates<
? WithParsedDates<SetNestedPath<T, Head>, Tail> ? WithParsedDates<SetNestedPath<T, Head>, Tail>
: T; : T;
/** Extracts dot-separated paths leading to a `string` or `Date` leaf, auto-traversing arrays. */
type DateConvertiblePaths<
T,
Depth extends unknown[] = [],
> = Depth["length"] extends 5
? never
: T extends Record<string, unknown>
? {
[K in keyof T & string]:
| (NonNullable<T[K]> extends string | Date ? K : never)
| (NonNullable<T[K]> extends readonly (infer U)[]
? `${K}.${DateConvertiblePaths<U, [...Depth, unknown]>}`
: NonNullable<T[K]> extends Record<string, unknown>
? `${K}.${DateConvertiblePaths<NonNullable<T[K]>, [...Depth, unknown]>}`
: never);
}[keyof T & string]
: never;
// --- Runtime --- // --- Runtime ---
type ParsedPath = string[]; type ParsedPath = string[];
@ -144,7 +162,10 @@ type PluggedQuery<T> = {
* ).execute(); * ).execute();
* // rows: { items: { id: number; box_id: number; created_at: Date }[] }[] * // rows: { items: { id: number; box_id: number; created_at: Date }[] }[]
*/ */
export function withParsedDates<const Paths extends readonly string[], T>( export function withParsedDates<
T,
const Paths extends readonly DateConvertiblePaths<T>[],
>(
query: { query: {
withPlugin(plugin: KyselyPlugin): PluggedQuery<T>; withPlugin(plugin: KyselyPlugin): PluggedQuery<T>;
}, },

View file

@ -37,18 +37,6 @@ export const prezziarioRouter = createTRPCRouter({
.mutation(async ({ input }) => { .mutation(async ({ input }) => {
return await addPrezziario({ db, input: input.data }); return await addPrezziario({ db, input: input.data });
}), }),
// deletePrezziario: adminProcedure
// .input(
// z.object({
// idprezziario: zPrezziarioId,
// }),
// )
// .mutation(async ({ input }) => {
// return await deletePrezziario({
// db,
// prezziarioId: input.idprezziario,
// });
// }),
getPrezziario: publicProcedure.query(async () => { getPrezziario: publicProcedure.query(async () => {
return await getPrezziario(); return await getPrezziario();
}), }),

View file

@ -31,11 +31,7 @@ import {
import { db } from "~/server/db"; import { db } from "~/server/db";
import { NewMail, type NewMailProps } from "~/server/services/mailer"; import { NewMail, type NewMailProps } from "~/server/services/mailer";
import { getUser } from "~/server/services/user.service"; import { getUser } from "~/server/services/user.service";
import { import { withImages, withVideos } from "~/utils/kysely-helper";
parseNullableDateString,
withImages,
withVideos,
} from "~/utils/kysely-helper";
import { GetUserInterests } from "../services/interests.service"; import { GetUserInterests } from "../services/interests.service";
import { getServizioById } from "../services/servizio.service"; import { getServizioById } from "../services/servizio.service";
import type { AnnuncioRicerca } from "./annunci.controller"; import type { AnnuncioRicerca } from "./annunci.controller";
@ -487,8 +483,6 @@ export const getAllServizioAnnunci = async (
"annunci.modificato_il", "annunci.modificato_il",
"annunci.created_at", "annunci.created_at",
"annunci.open_contatti_at", "annunci.open_contatti_at",
"annunci.user_confirmed_at",
"annunci.accettato_conferma_at",
"annunci.contratto_decorrenza", "annunci.contratto_decorrenza",
"annunci.contratto_scadenza", "annunci.contratto_scadenza",
"annunci.disponibile_da", "annunci.disponibile_da",
@ -511,7 +505,8 @@ export const getServizioDataById = async (
servizioId: ServizioServizioId, servizioId: ServizioServizioId,
): Promise<ServizioData> => { ): Promise<ServizioData> => {
try { try {
const data = await db const data = await withParsedDates(
db
.selectFrom("servizio") .selectFrom("servizio")
.leftJoin( .leftJoin(
"users_anagrafica", "users_anagrafica",
@ -610,45 +605,38 @@ export const getServizioDataById = async (
eb eb
.selectFrom("ordini") .selectFrom("ordini")
.selectAll("ordini") .selectAll("ordini")
.innerJoin("prezziario", "prezziario.idprezziario", "ordini.packid") .innerJoin(
"prezziario",
"prezziario.idprezziario",
"ordini.packid",
)
.select("prezziario.testo_condizioni") .select("prezziario.testo_condizioni")
.whereRef("ordini.servizio_id", "=", "servizio.servizio_id") .whereRef("ordini.servizio_id", "=", "servizio.servizio_id")
.orderBy("ordini.created_at", "desc"), .orderBy("ordini.created_at", "desc"),
).as("ordini"), ).as("ordini"),
]) ])
.orderBy("servizio.created_at", "desc") .orderBy("servizio.created_at", "desc")
.where("servizio.servizio_id", "=", servizioId) .where("servizio.servizio_id", "=", servizioId),
.executeTakeFirst(); [
"annunci.created_at",
"annunci.open_contatti_at",
"annunci.contratto_decorrenza",
"annunci.contratto_scadenza",
"annunci.modificato_il",
"annunci.disponibile_da",
"annunci.media_updated_at",
"ordini.created_at",
"ordini.paid_at",
],
).executeTakeFirst();
if (!data) { if (!data) {
throw new TRPCError({ throw new TRPCError({
code: "NOT_FOUND", code: "NOT_FOUND",
message: "Servizio not found", message: "Servizio not found",
}); });
} }
const formattedData = {
...data,
annunci: data.annunci.map((annuncio) => ({
...annuncio,
created_at: new Date(annuncio.created_at),
open_contatti_at: parseNullableDateString(annuncio.open_contatti_at),
contratto_decorrenza: parseNullableDateString( return data;
annuncio.contratto_decorrenza,
),
contratto_scadenza: parseNullableDateString(
annuncio.contratto_scadenza,
),
modificato_il: parseNullableDateString(annuncio.modificato_il),
disponibile_da: parseNullableDateString(annuncio.disponibile_da),
media_updated_at: parseNullableDateString(annuncio.media_updated_at),
})),
ordini: data.ordini.map((ordine) => ({
...ordine,
created_at: new Date(ordine.created_at),
paid_at: ordine.paid_at ? new Date(ordine.paid_at) : null,
})),
};
return formattedData;
} catch (e) { } catch (e) {
throw new TRPCError({ throw new TRPCError({
code: "NOT_FOUND", code: "NOT_FOUND",
@ -1149,10 +1137,31 @@ export const getCompatibileAnnunci = async ({
} }
}; };
export type RichiesteData = Servizio & export type RichiesteData = Pick<
Servizio,
| "servizio_id"
| "user_id"
| "isInterrotto"
| "isOkAcconto"
| "isOkSaldo"
| "decorrenza"
| "tipologia"
| "onboardOk"
| "isOkConsulenza"
| "interruzioneDays"
> &
Pick<Users, "username" | "note" | "telefono"> & { Pick<Users, "username" | "note" | "telefono"> & {
annunci_servizio: ServizioAnnuncioData[]; annunci_servizio: ServizioAnnuncioData[];
ordini_servizio: (Ordini & Pick<Prezziario, "testo_condizioni">)[]; ordini_servizio: Pick<
Ordini,
| "isActive"
| "ordine_id"
| "created_at"
| "packid"
| "amount_cent"
| "userid"
| "type"
>[];
}; };
export const getRichieste = async (): Promise<RichiesteData[]> => { export const getRichieste = async (): Promise<RichiesteData[]> => {
@ -1161,7 +1170,18 @@ export const getRichieste = async (): Promise<RichiesteData[]> => {
db db
.selectFrom("servizio") .selectFrom("servizio")
.innerJoin("users", "users.id", "servizio.user_id") .innerJoin("users", "users.id", "servizio.user_id")
.selectAll("servizio") .select([
"servizio.servizio_id",
"servizio.user_id",
"servizio.isInterrotto",
"servizio.isOkAcconto",
"servizio.isOkSaldo",
"servizio.decorrenza",
"servizio.tipologia",
"servizio.onboardOk",
"servizio.isOkConsulenza",
"servizio.interruzioneDays",
])
.select(["users.username", "users.note", "users.telefono"]) .select(["users.username", "users.note", "users.telefono"])
.select((eb) => [ .select((eb) => [
jsonArrayFrom( jsonArrayFrom(
@ -1213,13 +1233,15 @@ export const getRichieste = async (): Promise<RichiesteData[]> => {
jsonArrayFrom( jsonArrayFrom(
eb eb
.selectFrom("ordini") .selectFrom("ordini")
.selectAll("ordini") .select([
.innerJoin( "ordini.isActive",
"prezziario", "ordini.ordine_id",
"prezziario.idprezziario", "ordini.created_at",
"ordini.packid", "ordini.packid",
) "ordini.amount_cent",
.select("prezziario.testo_condizioni") "ordini.userid",
"ordini.type",
])
.whereRef("ordini.servizio_id", "=", "servizio.servizio_id") .whereRef("ordini.servizio_id", "=", "servizio.servizio_id")
.orderBy("ordini.created_at", "desc"), .orderBy("ordini.created_at", "desc"),
).as("ordini_servizio"), ).as("ordini_servizio"),
@ -1229,16 +1251,14 @@ export const getRichieste = async (): Promise<RichiesteData[]> => {
"annunci_servizio.created_at", "annunci_servizio.created_at",
"annunci_servizio.open_contatti_at", "annunci_servizio.open_contatti_at",
"annunci_servizio.disponibile_da", "annunci_servizio.disponibile_da",
"annunci_servizio.user_confirmed_at",
"annunci_servizio.accettato_conferma_at",
"annunci_servizio.contratto_decorrenza", "annunci_servizio.contratto_decorrenza",
"annunci_servizio.contratto_scadenza", "annunci_servizio.contratto_scadenza",
"annunci_servizio.modificato_il", "annunci_servizio.modificato_il",
"annunci_servizio.media_updated_at", "annunci_servizio.media_updated_at",
"ordini_servizio.created_at", "ordini_servizio.created_at",
"ordini_servizio.paid_at",
], ],
).execute(); ).execute();
return data; return data;
} catch (e) { } catch (e) {
throw new TRPCError({ throw new TRPCError({

View file

@ -46,31 +46,6 @@ export const editAnagraficaHandler = async ({
}); });
} }
// if (anagraficaId) {
// return await db
// .updateTable("users_anagrafica")
// .set({
// ...rest,
// })
// .where("userid", "=", userId)
// .returningAll()
// .executeTakeFirst();
// }
// const searched = await db
// .selectFrom("users_anagrafica")
// .select("idanagrafica")
// .where("userid", "=", userId)
// .executeTakeFirst();
// if (searched) {
// return await db
// .updateTable("users_anagrafica")
// .set({
// ...rest,
// })
// .where("userid", "=", userId)
// .returningAll()
// .executeTakeFirst();
// }
return await db return await db
.insertInto("users_anagrafica") .insertInto("users_anagrafica")
.values({ .values({