refactor: streamline ServizioContent layout and enhance ServizioInfos with pack details retrieval
This commit is contained in:
parent
cd2c96ad58
commit
b376de48bb
7 changed files with 173 additions and 61 deletions
|
|
@ -203,16 +203,9 @@ export const ServizioContent = () => {
|
|||
);
|
||||
}
|
||||
|
||||
const annunciSelezionati = servizio.annunci.filter(
|
||||
(a) => a.user_confirmed_at === null,
|
||||
);
|
||||
|
||||
const annunciInConferma = servizio.annunci.filter(
|
||||
(a) => a.user_confirmed_at !== null,
|
||||
);
|
||||
|
||||
return (
|
||||
<ServizioCard
|
||||
cardClassName="gap-y-2"
|
||||
content={
|
||||
<>
|
||||
{annuncioConfermato.length > 0 && (
|
||||
|
|
@ -252,27 +245,8 @@ export const ServizioContent = () => {
|
|||
</div>
|
||||
)}
|
||||
<div className="flex flex-col gap-4">
|
||||
<div className="flex flex-col gap-2 overflow-y-auto">
|
||||
{annunciInConferma.map((data) => {
|
||||
return (
|
||||
<ServizioAnnuncioProvider
|
||||
data={data}
|
||||
key={data.id}
|
||||
servizioId={servizio.servizio_id}
|
||||
userId={userId}
|
||||
>
|
||||
<AnnuncioCard className="border-2 border-green-500" />
|
||||
</ServizioAnnuncioProvider>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
{annunciSelezionati.length > 0 && (
|
||||
<div className="flex flex-col gap-3">
|
||||
<h2 className="px-1 font-semibold text-xl">
|
||||
Annunci selezionati:
|
||||
</h2>
|
||||
<div className="grid grid-cols-1 gap-3 lg:grid-cols-2">
|
||||
{annunciSelezionati.map((data) => {
|
||||
{servizio.annunci.map((data) => {
|
||||
return (
|
||||
<ServizioAnnuncioProvider
|
||||
data={data}
|
||||
|
|
@ -285,11 +259,7 @@ export const ServizioContent = () => {
|
|||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{/* {annunciSelezionati.length > 0 && (
|
||||
<AnnunciSelezionatiAccordion annunci={annunciSelezionati} />
|
||||
)} */}
|
||||
|
||||
<div className="flex items-center justify-center">
|
||||
<AnnunciCompatibili />
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ import {
|
|||
FormEditServizio,
|
||||
} from "~/forms/FormEditServizioAdmin";
|
||||
import { FormNewServizio, type FormValues } from "~/forms/FormNewServizio";
|
||||
import { cn } from "~/lib/utils";
|
||||
import { cn, formatCurrency } from "~/lib/utils";
|
||||
import { useServizio } from "~/providers/ServizioProvider";
|
||||
import type { AnnunciId } from "~/schemas/public/Annunci";
|
||||
import type { ServizioServizioId } from "~/schemas/public/Servizio";
|
||||
|
|
@ -94,10 +94,13 @@ const ServizioInfos = () => {
|
|||
add(servizio.decorrenza, { days: 60 }),
|
||||
).toLocaleDateString("it-IT");
|
||||
return (
|
||||
<Collapsible className="space-y-3" onOpenChange={setOpen} open={open}>
|
||||
<Collapsible className="space-y-2" onOpenChange={setOpen} open={open}>
|
||||
<CollapsibleTrigger asChild>
|
||||
{open ? (
|
||||
<Button className="w-full justify-between" variant="outline">
|
||||
<Button
|
||||
className="w-full justify-between data-[state=open]:bg-accent dark:data-[state=open]:bg-input/50"
|
||||
variant="outline"
|
||||
>
|
||||
<span className="flex items-center gap-2">
|
||||
<Info />
|
||||
<span>Informazioni servizio</span>
|
||||
|
|
@ -126,7 +129,7 @@ const ServizioInfos = () => {
|
|||
</Button>
|
||||
)}
|
||||
</CollapsibleTrigger>
|
||||
<CollapsibleContent className="flex w-full flex-col gap-8 rounded-md border bg-card p-2 sm:items-start sm:gap-4">
|
||||
<CollapsibleContent className="mb-4 flex w-full flex-col gap-8 rounded-md border bg-card p-2 sm:items-start sm:gap-4">
|
||||
<ServizioBasicActions />
|
||||
<div className="flex w-full flex-col gap-8 sm:flex-row sm:items-start">
|
||||
<div className="flex flex-2 flex-col gap-2 sm:w-1/2">
|
||||
|
|
@ -149,6 +152,7 @@ const ServizioInfos = () => {
|
|||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<ServizioPacksInfos />
|
||||
</CollapsibleContent>
|
||||
</Collapsible>
|
||||
);
|
||||
|
|
@ -172,6 +176,49 @@ const ServizioBasicActions = ({ className }: { className?: string }) => {
|
|||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
const ServizioPacksInfos = () => {
|
||||
const { servizio } = useServizio();
|
||||
const { data: packs } = api.servizio.getPacksSolution.useQuery({
|
||||
servizioId: servizio.servizio_id,
|
||||
});
|
||||
if (!packs) return null;
|
||||
return (
|
||||
<div className="space-y-2">
|
||||
<h3 className="font-semibold text-lg">Prezzi:</h3>
|
||||
<div className="flex w-full flex-col gap-4 md:flex-row">
|
||||
{packs.acconto && (
|
||||
<div className="flex flex-1 flex-col gap-2 rounded-md bg-secondary/50 p-2">
|
||||
<span className="font-medium">{packs.acconto.nome_it}</span>
|
||||
<span className="text-muted-foreground text-sm">
|
||||
{packs.acconto.desc_it}
|
||||
</span>
|
||||
<span className="font-semibold text-lg">
|
||||
{formatCurrency(packs.acconto.prezzo_cent / 100)}
|
||||
</span>
|
||||
<span className="text-muted-foreground text-sm">
|
||||
COD: {packs.acconto.idprezziario}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
{packs.saldo && (
|
||||
<div className="flex flex-1 flex-col gap-2 rounded-md bg-secondary/50 p-2">
|
||||
<span className="font-medium">{packs.saldo.nome_it}</span>
|
||||
<span className="text-muted-foreground text-sm">
|
||||
{packs.saldo.desc_it}
|
||||
</span>
|
||||
<span className="font-semibold text-lg">
|
||||
{formatCurrency(packs.saldo.prezzo_cent / 100)}
|
||||
</span>
|
||||
<span className="text-muted-foreground text-sm">
|
||||
COD: {packs.saldo.idprezziario}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
export const AddAnnuncio = ({
|
||||
servizioId,
|
||||
userId,
|
||||
|
|
|
|||
|
|
@ -14,10 +14,6 @@ export const handleConsegna = ({
|
|||
aggiornamento: string;
|
||||
}) => {
|
||||
const currentMonth = new Date().getMonth() + 1;
|
||||
console.log("handleConsegna", {
|
||||
consegna: consegna,
|
||||
currentMonth: currentMonth,
|
||||
});
|
||||
if (consegna !== null) {
|
||||
if (consegna !== currentMonth) {
|
||||
return `${mesi[consegna]}`;
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ export const prezziarioRouter = createTRPCRouter({
|
|||
getPrezzoPerServizio: publicProcedure
|
||||
.input(z.object({ idprezziario: zPrezziarioId }))
|
||||
.query(async ({ input }) => {
|
||||
return await getPrezziarioByIdHandler({ db, input });
|
||||
return await getPrezziarioByIdHandler({ id: input.idprezziario });
|
||||
}),
|
||||
updatePrezziario: adminProcedure
|
||||
.input(
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import {
|
|||
getCompatibileAnnunci,
|
||||
getDataPerAcquisto,
|
||||
getOrdineRicevutaData,
|
||||
getPackPerServizio,
|
||||
getPreOnboardData,
|
||||
getServiziByUserId,
|
||||
getServizioAnnuncio,
|
||||
|
|
@ -50,6 +51,7 @@ import {
|
|||
userAccettaConferma,
|
||||
userSendConfermaIntent,
|
||||
} from "~/server/controllers/servizio.controller";
|
||||
import { getPrezziarioByIdHandler } from "~/server/services/prezziario.service";
|
||||
import {
|
||||
zAnnuncioId,
|
||||
zOrdineId,
|
||||
|
|
@ -340,7 +342,33 @@ export const servizioRouter = createTRPCRouter({
|
|||
servizioId: input.servizioId,
|
||||
});
|
||||
}),
|
||||
getPacksSolution: protectedProcedure
|
||||
.input(
|
||||
z.object({
|
||||
servizioId: zServizioId,
|
||||
}),
|
||||
)
|
||||
.query(async ({ input }) => {
|
||||
const accontoId = await getPackPerServizio({
|
||||
stage: "acconto",
|
||||
servizioId: input.servizioId,
|
||||
});
|
||||
const saldoId = await getPackPerServizio({
|
||||
stage: "saldo",
|
||||
servizioId: input.servizioId,
|
||||
});
|
||||
|
||||
const acconto = accontoId.success
|
||||
? await getPrezziarioByIdHandler({ id: accontoId.packId })
|
||||
: null;
|
||||
const saldo = saldoId.success
|
||||
? await getPrezziarioByIdHandler({ id: saldoId.packId })
|
||||
: null;
|
||||
return {
|
||||
acconto,
|
||||
saldo,
|
||||
};
|
||||
}),
|
||||
unlockServizioContatti: protectedProcedure
|
||||
.input(
|
||||
z.object({
|
||||
|
|
|
|||
|
|
@ -506,6 +506,74 @@ const ConsulenzaPriceMapping = {
|
|||
Transitorio: "CONS_TRAN" as PrezziarioIdprezziario,
|
||||
};
|
||||
|
||||
type GetPackError = { success: false; message: string };
|
||||
type GetPackResult = { success: true; packId: PrezziarioIdprezziario };
|
||||
|
||||
export const getPackPerServizio = async ({
|
||||
stage,
|
||||
servizioId,
|
||||
}: {
|
||||
stage: "acconto" | "saldo";
|
||||
servizioId: ServizioServizioId;
|
||||
}): Promise<GetPackResult | GetPackError> => {
|
||||
const servizio = await getServizioById(servizioId);
|
||||
if (!servizio) {
|
||||
return { success: false, message: "Servizio not found" };
|
||||
}
|
||||
switch (stage) {
|
||||
case "acconto": {
|
||||
switch (servizio.tipologia) {
|
||||
case TipologiaPosizioneEnum.Transitorio: {
|
||||
return {
|
||||
success: true,
|
||||
packId: "ACCONTO_BD" as PrezziarioIdprezziario,
|
||||
};
|
||||
}
|
||||
|
||||
case TipologiaPosizioneEnum.Stabile: {
|
||||
return {
|
||||
success: true,
|
||||
packId: "ACCONTO_CA" as PrezziarioIdprezziario,
|
||||
};
|
||||
}
|
||||
default:
|
||||
return { success: false, message: "Invalid tipologia" };
|
||||
}
|
||||
}
|
||||
case "saldo": {
|
||||
switch (servizio.tipologia) {
|
||||
case TipologiaPosizioneEnum.Transitorio: {
|
||||
const mpp =
|
||||
servizio.permanenza && SaldoTransitorioMapping[servizio.permanenza];
|
||||
if (!servizio.permanenza || !mpp) {
|
||||
return {
|
||||
success: false,
|
||||
message: "Permanenza not set for transitorio servizio",
|
||||
};
|
||||
}
|
||||
return { success: true, packId: mpp };
|
||||
}
|
||||
case TipologiaPosizioneEnum.Stabile: {
|
||||
if (servizio.budget >= 500) {
|
||||
return {
|
||||
success: true,
|
||||
packId: "SALDOCA500+" as PrezziarioIdprezziario,
|
||||
};
|
||||
}
|
||||
return {
|
||||
success: true,
|
||||
packId: "SALDOCA500" as PrezziarioIdprezziario,
|
||||
};
|
||||
}
|
||||
default:
|
||||
return { success: false, message: "Invalid tipologia" };
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
return { success: false, message: "Invalid stage" };
|
||||
}
|
||||
};
|
||||
type TipoEnum = keyof typeof ConsulenzaPriceMapping;
|
||||
export const setupSaldoConsulenzaServizio = async ({
|
||||
servizioId,
|
||||
|
|
@ -711,12 +779,12 @@ export const getAllServizioAnnunci = async (userId: UsersId) => {
|
|||
//ignora annunci che non sono disponibili
|
||||
.where("annunci.web", "=", true)
|
||||
.where("annunci.stato", "!=", "Sospeso")
|
||||
// .orderBy("servizio_annunci.user_confirmed_at", (ob) =>
|
||||
// ob.asc().nullsLast(),
|
||||
// )
|
||||
// .orderBy("servizio_annunci.open_contatti_at", (ob) =>
|
||||
// ob.asc().nullsFirst(),
|
||||
// )
|
||||
.orderBy("servizio_annunci.user_confirmed_at", (ob) =>
|
||||
ob.asc().nullsLast(),
|
||||
)
|
||||
.orderBy("servizio_annunci.open_contatti_at", (ob) =>
|
||||
ob.asc().nullsFirst(),
|
||||
)
|
||||
.orderBy("servizio_annunci.created_at", "asc")
|
||||
.whereRef(
|
||||
"servizio_annunci.servizio_id",
|
||||
|
|
|
|||
|
|
@ -26,19 +26,22 @@ export const getPrezziario = async () => {
|
|||
};
|
||||
|
||||
export const getPrezziarioByIdHandler = async ({
|
||||
db,
|
||||
input,
|
||||
id,
|
||||
}: {
|
||||
db: Querier;
|
||||
input: {
|
||||
idprezziario: PrezziarioIdprezziario;
|
||||
};
|
||||
id: PrezziarioIdprezziario;
|
||||
}) => {
|
||||
try {
|
||||
return await db
|
||||
.selectFrom("prezziario")
|
||||
.selectAll()
|
||||
.where("prezziario.idprezziario", "=", input.idprezziario)
|
||||
.where("prezziario.idprezziario", "=", id)
|
||||
.executeTakeFirst();
|
||||
} catch (error) {
|
||||
throw new TRPCError({
|
||||
code: "INTERNAL_SERVER_ERROR",
|
||||
message: `Error getting prezziario by id: ${(error as Error).message}`,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const addPrezziario = async ({
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue