feat: add admin override switch for ignoring service preferences in AnnunciCompatibili dialog

This commit is contained in:
Marco Pedone 2025-11-11 15:41:07 +01:00
parent db8d1da5ab
commit 4408295f56
3 changed files with 40 additions and 14 deletions

View file

@ -1,5 +1,6 @@
import { ExternalLink, UnfoldVertical } from "lucide-react"; import { ExternalLink, UnfoldVertical } from "lucide-react";
import Link from "next/link"; import Link from "next/link";
import { useState } from "react";
import { replaceWithBr } from "~/lib/newlineToBr"; import { replaceWithBr } from "~/lib/newlineToBr";
import { cn, formatCurrency } from "~/lib/utils"; import { cn, formatCurrency } from "~/lib/utils";
import { useTranslation } from "~/providers/I18nProvider"; import { useTranslation } from "~/providers/I18nProvider";
@ -22,11 +23,15 @@ import {
DialogTitle, DialogTitle,
DialogTrigger, DialogTrigger,
} from "../ui/dialog"; } from "../ui/dialog";
import { Label } from "../ui/label";
import { Switch } from "../ui/switch";
export const AnnunciCompatibili = () => { export const AnnunciCompatibili = () => {
const { servizioId } = useServizio(); const { servizioId, isAdmin } = useServizio();
const [adminOverride, setAdminOverride] = useState(false);
const { data, isLoading } = api.servizio.getCompatibileAnnunci.useQuery({ const { data, isLoading } = api.servizio.getCompatibileAnnunci.useQuery({
servizioId, servizioId,
adminOverride,
}); });
return ( return (
<Dialog> <Dialog>
@ -35,11 +40,25 @@ export const AnnunciCompatibili = () => {
Esplora Annunci Compatibili Esplora Annunci Compatibili
</Button> </Button>
</DialogTrigger> </DialogTrigger>
<DialogContent className="max-w-xl p-2 sm:max-w-5xl sm:p-6 md:max-w-7xl"> <DialogContent className="max-w-xl p-2 sm:max-w-5xl sm:p-6 md:max-w-7xl 2xl:max-w-[100rem]">
<DialogHeader> <DialogHeader className="flex-row flex-wrap items-center gap-5 pt-6">
<DialogTitle className="pt-6"> <DialogTitle>
Annunci compatibili con le preferenze del servizio Annunci compatibili con le preferenze del servizio
</DialogTitle> </DialogTitle>
{isAdmin && (
<div className="flex flex-wrap items-center gap-x-2">
<Label htmlFor="adminOverride">
Ignora limitazioni preferenze
</Label>
<Switch
checked={adminOverride}
className="data-[state=checked]:bg-neutral-700"
id="adminOverride"
onCheckedChange={setAdminOverride}
/>
</div>
)}
<DialogDescription className="sr-only"></DialogDescription> <DialogDescription className="sr-only"></DialogDescription>
</DialogHeader> </DialogHeader>
<div className="flex max-h-[80vh] flex-col gap-2 overflow-y-auto p-0.5 sm:p-2"> <div className="flex max-h-[80vh] flex-col gap-2 overflow-y-auto p-0.5 sm:p-2">
@ -55,7 +74,7 @@ export const AnnunciCompatibili = () => {
</span> </span>
</div> </div>
) : ( ) : (
<div className="relative z-0 mx-auto grid max-w-7xl grid-flow-row grid-cols-1 gap-4 sm:grid-cols-2 sm:gap-6 sm:gap-y-8 lg:grid-cols-3"> <div className="relative z-0 mx-auto grid max-w-full grid-flow-row grid-cols-1 gap-4 sm:grid-cols-2 sm:gap-6 sm:gap-y-10 lg:grid-cols-3 2xl:grid-cols-4">
{data.map((annuncio) => ( {data.map((annuncio) => (
<div <div
className="flex flex-col justify-center gap-1" className="flex flex-col justify-center gap-1"

View file

@ -142,10 +142,11 @@ export const servizioRouter = createTRPCRouter({
.input( .input(
z.object({ z.object({
servizioId: zServizioId, servizioId: zServizioId,
adminOverride: z.boolean().optional(),
}), }),
) )
.query(async ({ input }) => { .query(async ({ input }) => {
return await getCompatibileAnnunci(input.servizioId); return await getCompatibileAnnunci({ ...input });
}), }),
getOrdineById: protectedProcedure getOrdineById: protectedProcedure
.input( .input(

View file

@ -1577,9 +1577,13 @@ export const SendContactEmail = async ({
} }
}; };
export const getCompatibileAnnunci = async ( export const getCompatibileAnnunci = async ({
servizioId: ServizioServizioId, servizioId,
): Promise<AnnuncioRicerca[]> => { adminOverride = false,
}: {
servizioId: ServizioServizioId;
adminOverride?: boolean;
}): Promise<AnnuncioRicerca[]> => {
try { try {
const servizio = await getServizioById(servizioId); const servizio = await getServizioById(servizioId);
if (!servizio) { if (!servizio) {
@ -1628,8 +1632,12 @@ export const getCompatibileAnnunci = async (
.selectFrom("servizio_annunci") .selectFrom("servizio_annunci")
.select("annunci_id") .select("annunci_id")
.where("servizio_id", "=", servizioId), .where("servizio_id", "=", servizioId),
) );
.where("prezzo", "<=", servizio.budget * 1e2 * 1.2); // Allow 20% margin if (adminOverride) {
return await qry.execute();
}
qry = qry.where("prezzo", "<=", servizio.budget * 1e2 * 1.2); // Allow 20% margin
const month = new Date().getMonth() + 1; // Months are 0-indexed in JS const month = new Date().getMonth() + 1; // Months are 0-indexed in JS
if (servizio.entromese === month) { if (servizio.entromese === month) {
@ -1647,9 +1655,7 @@ export const getCompatibileAnnunci = async (
qry = qry.where("consegna", "=", servizio.entromese); qry = qry.where("consegna", "=", servizio.entromese);
} }
const annunci = await qry.execute(); return await qry.execute();
return annunci;
} catch (e) { } catch (e) {
throw new TRPCError({ throw new TRPCError({
code: "INTERNAL_SERVER_ERROR", code: "INTERNAL_SERVER_ERROR",