feat: add ServizioPacksInfos component for displaying pricing information

This commit is contained in:
Marco Pedone 2026-01-07 16:18:21 +01:00
parent f9cacce912
commit 7763aac01c
2 changed files with 71 additions and 73 deletions

View file

@ -53,6 +53,7 @@ import { Label } from "../ui/label";
import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover"; import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover";
import { Switch } from "../ui/switch"; import { Switch } from "../ui/switch";
import { UploadModal } from "../upload_modal"; import { UploadModal } from "../upload_modal";
import { ServizioPacksInfos } from "./servizio_actions";
import { DocCombo, DocInfo } from "./shared"; import { DocCombo, DocInfo } from "./shared";
export const AdminLavoraConferma = () => { export const AdminLavoraConferma = () => {
@ -489,6 +490,7 @@ const MotivazioneSection = () => {
<span className="text-red-500 italic">Non inserita</span> <span className="text-red-500 italic">Non inserita</span>
)} )}
</p> </p>
{!servizio.skipDocMotivazione && (
<p> <p>
<span className="font-semibold">Documento caricato: </span> <span className="font-semibold">Documento caricato: </span>
{servizio.doc_motivazione_ref ? ( {servizio.doc_motivazione_ref ? (
@ -497,6 +499,7 @@ const MotivazioneSection = () => {
<span className="text-red-500 italic">Non caricato</span> <span className="text-red-500 italic">Non caricato</span>
)} )}
</p> </p>
)}
</div> </div>
</CardContent> </CardContent>
</Card> </Card>
@ -559,8 +562,8 @@ const TransitorioSection = () => {
"errore: testo non trovato in descrizione"); "errore: testo non trovato in descrizione");
return ( return (
<div className="flex flex-col gap-2"> <div className="flex flex-col items-start gap-4 rounded-md border border-border bg-muted p-2 sm:flex-row">
<div className="max-w-sm"> <div className="w-full">
<Label className="text-base" htmlFor="permanenza"> <Label className="text-base" htmlFor="permanenza">
Permanenza (da parametri servizio): Permanenza (da parametri servizio):
</Label> </Label>
@ -584,10 +587,10 @@ const TransitorioSection = () => {
placeholder="Seleziona..." placeholder="Seleziona..."
/> />
</div> </div>
<p> <div className="w-full space-y-2">
<span className="font-semibold">Permanenza in annuncio: </span> <p className="font-medium">Permanenza in annuncio:</p>
{permanenzaAnnuncio} <p>{permanenzaAnnuncio}</p>
</p> </div>
</div> </div>
); );
}; };
@ -624,8 +627,8 @@ const StabileSection = () => {
); );
return ( return (
<div className="flex flex-col gap-2"> <div className="flex flex-col gap-2 rounded-md border border-border bg-muted p-2 sm:flex-row">
<div className="flex max-w-sm flex-col gap-2"> <div className="flex w-full flex-col gap-2">
<span className="font-semibold">Budget (da preferenze servizio):</span> <span className="font-semibold">Budget (da preferenze servizio):</span>
<NumberInput <NumberInput
allowNegative={false} allowNegative={false}
@ -640,10 +643,10 @@ const StabileSection = () => {
suffix=" €" suffix=" €"
/> />
</div> </div>
<p> <div className="w-full space-y-2">
<span className="font-semibold">Prezzo in descrizione: </span> <p className="font-medium">Prezzo in descrizione:</p>
{formatCurrency(data.prezzo / 100)} <p>{formatCurrency(data.prezzo / 100)}</p>
</p> </div>
</div> </div>
); );
}; };
@ -711,7 +714,8 @@ const GeneralSection = () => {
return ( return (
<> <>
<div className="flex flex-col gap-2"> <div className="flex flex-col gap-x-4 gap-y-2 rounded-md border border-border bg-muted p-2 sm:flex-row">
<div className="w-full space-y-2">
<span className="font-semibold">Persone:</span> <span className="font-semibold">Persone:</span>
<div className="flex w-full gap-4"> <div className="flex w-full gap-4">
<div className="flex w-1/2 flex-col gap-2"> <div className="flex w-1/2 flex-col gap-2">
@ -734,15 +738,17 @@ const GeneralSection = () => {
/> />
</div> </div>
</div> </div>
<p>
<span className="font-semibold">Persone in annuncio: </span>
{personeAnnuncio}
</p>
</div> </div>
<div className="flex flex-col gap-2"> <div className="w-full space-y-2">
<span className="font-semibold">Entro mese:</span> <p className="font-medium">Persone in annuncio:</p>
<div className="max-w-sm"> <p>{personeAnnuncio}</p>
<Label htmlFor="select-mesi">{t.parametri.dalmese_label}</Label> </div>
</div>
<div className="flex flex-col gap-x-4 gap-y-2 rounded-md border border-border bg-muted p-2 sm:flex-row">
<div className="w-full">
<Label className="text-base" htmlFor="select-mesi">
Entro mese (da preferenze servizio):
</Label>
<MultiSelect <MultiSelect
defaultValue={ defaultValue={
servizio.entromese !== null servizio.entromese !== null
@ -763,11 +769,10 @@ const GeneralSection = () => {
placeholder="Seleziona..." placeholder="Seleziona..."
/> />
</div> </div>
<div className="w-full space-y-2">
<p> <p className="font-medium">Disponibilità in annuncio:</p>
<span className="font-semibold">Disponibilità in annuncio: </span> <p>{dispAnnuncio}</p>
{dispAnnuncio} </div>
</p>
</div> </div>
</> </>
); );
@ -776,7 +781,6 @@ const GeneralSection = () => {
const SendConferma = () => { const SendConferma = () => {
const { servizio } = useServizio(); const { servizio } = useServizio();
const { data } = useServizioAnnuncio(); const { data } = useServizioAnnuncio();
const [check, setCheck] = useState(data.hasConfermaAdmin);
const utils = api.useUtils(); const utils = api.useUtils();
const { mutate: handleUpdate } = const { mutate: handleUpdate } =
api.servizio.adminUpdateConfermaStatus.useMutation({ api.servizio.adminUpdateConfermaStatus.useMutation({
@ -812,14 +816,19 @@ const SendConferma = () => {
<StabileSection /> <StabileSection />
)} )}
<GeneralSection /> <GeneralSection />
<ServizioPacksInfos title="Prezzi in base a parametri:" />
</div> </div>
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<Switch <Switch
aria-label="Conferma Lavorata" aria-label="Conferma Lavorata"
checked={check} checked={data.hasConfermaAdmin}
id="conferma" id="conferma"
onCheckedChange={(c) => { onCheckedChange={(c) => {
setCheck(c); handleUpdate({
servizioId: servizio.servizio_id,
annuncioId: data.id,
status: c,
});
}} }}
/> />
<Label className="text-base" htmlFor="conferma"> <Label className="text-base" htmlFor="conferma">
@ -827,21 +836,6 @@ const SendConferma = () => {
</Label> </Label>
</div> </div>
</CardContent> </CardContent>
<CardFooter>
<Button
aria-label="Save Conferma Status"
onClick={() => {
handleUpdate({
servizioId: servizio.servizio_id,
annuncioId: data.id,
status: check,
});
}}
variant="success"
>
Salva
</Button>
</CardFooter>
</Card> </Card>
); );
}; };

View file

@ -182,7 +182,11 @@ const ServizioBasicActions = ({ className }: { className?: string }) => {
return null; return null;
}; };
const ServizioPacksInfos = () => { export const ServizioPacksInfos = ({
title = "Prezzi:",
}: {
title?: string;
}) => {
const { servizio } = useServizio(); const { servizio } = useServizio();
const { data: packs } = api.servizio.getPacksSolution.useQuery({ const { data: packs } = api.servizio.getPacksSolution.useQuery({
servizioId: servizio.servizio_id, servizioId: servizio.servizio_id,
@ -190,7 +194,7 @@ const ServizioPacksInfos = () => {
if (!packs) return null; if (!packs) return null;
return ( return (
<div className="w-full space-y-2"> <div className="w-full space-y-2">
<h3 className="font-semibold text-lg">Prezzi:</h3> <h3 className="font-semibold text-lg">{title}</h3>
<div className="flex w-full flex-col gap-4 md:flex-row"> <div className="flex w-full flex-col gap-4 md:flex-row">
<div className="flex flex-1 flex-col gap-2 rounded-md bg-secondary/50 p-2"> <div className="flex flex-1 flex-col gap-2 rounded-md bg-secondary/50 p-2">
{packs.acconto.success ? ( {packs.acconto.success ? (