refactor: enhance AdminLavoraConferma component with GeneralSection and improve form handling in AnnuncioEditForm
This commit is contained in:
parent
4ce60fd827
commit
c783dfed03
4 changed files with 194 additions and 35 deletions
|
|
@ -12,6 +12,8 @@ import { useState } from "react";
|
|||
import toast from "react-hot-toast";
|
||||
import { useDebounce } from "react-use";
|
||||
import z from "zod";
|
||||
import { it } from "~/i18n/it";
|
||||
import { handleConsegna } from "~/lib/annuncio_details";
|
||||
import { formatCurrency } from "~/lib/utils";
|
||||
import { useTranslation } from "~/providers/I18nProvider";
|
||||
import { useServizio, useServizioAnnuncio } from "~/providers/ServizioProvider";
|
||||
|
|
@ -19,6 +21,7 @@ import TipologiaPosizioneEnum from "~/schemas/public/TipologiaPosizioneEnum";
|
|||
import type { UsersStorageUserStorageId } from "~/schemas/public/UsersStorage";
|
||||
import { api } from "~/utils/api";
|
||||
import { Confirm } from "../confirm";
|
||||
import { Counter } from "../counter";
|
||||
import {
|
||||
Credenza,
|
||||
CredenzaBody,
|
||||
|
|
@ -548,6 +551,12 @@ const TransitorioSection = () => {
|
|||
});
|
||||
};
|
||||
const preferenzeDescrizione = data.desc_it?.match(/Permanenza:.*$/m);
|
||||
|
||||
const permanenzaAnnuncio = data.permanenza
|
||||
? `${data.permanenza.join(" - ")} mesi`
|
||||
: (preferenzeDescrizione?.[0] ??
|
||||
"errore: testo non trovato in descrizione");
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-2">
|
||||
<div className="max-w-sm">
|
||||
|
|
@ -575,10 +584,8 @@ const TransitorioSection = () => {
|
|||
/>
|
||||
</div>
|
||||
<p>
|
||||
<span className="font-semibold">Permanenza in descrizione: </span>
|
||||
{preferenzeDescrizione
|
||||
? preferenzeDescrizione[0]
|
||||
: "errore: testo non trovato in descrizione"}
|
||||
<span className="font-semibold">Permanenza in annuncio: </span>
|
||||
{permanenzaAnnuncio}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
|
|
@ -639,6 +646,131 @@ const StabileSection = () => {
|
|||
);
|
||||
};
|
||||
|
||||
const GeneralSection = () => {
|
||||
const { servizio } = useServizio();
|
||||
const { data } = useServizioAnnuncio();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { servizioId, userId } = useServizio();
|
||||
const utils = api.useUtils();
|
||||
const { mutate: update } = api.servizio.updateServizio.useMutation({
|
||||
onError: (error) => {
|
||||
toast.error(error.message);
|
||||
},
|
||||
onSuccess: async () => {
|
||||
toast.success("Servizio modificato con successo");
|
||||
await utils.servizio.getUserServizi.invalidate();
|
||||
await utils.servizio.getAllServizioAnnunci.invalidate({ userId });
|
||||
},
|
||||
});
|
||||
|
||||
const handleDisponibilitàChange = (value: ListOption) => {
|
||||
update({
|
||||
servizioId,
|
||||
data: {
|
||||
entromese: value.value !== "" ? parseInt(value.value) : null,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const handleAdultiChange = (value: number) => {
|
||||
update({
|
||||
servizioId,
|
||||
data: {
|
||||
n_adulti: value,
|
||||
},
|
||||
});
|
||||
};
|
||||
const handleMinoriChange = (value: number) => {
|
||||
update({
|
||||
servizioId,
|
||||
data: {
|
||||
n_minori: value,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const personeDescrizione = data.desc_it?.match(/Preferenza:.*$/m);
|
||||
|
||||
const personeAnnuncio = data.persone
|
||||
? data.persone.join(", ").toUpperCase()
|
||||
: (personeDescrizione?.[0] ?? "errore: testo non trovato in descrizione");
|
||||
|
||||
const dispAnnuncio = data.disponibile_da
|
||||
? format(new Date(data.disponibile_da), "dd/MM/yyyy")
|
||||
: handleConsegna({
|
||||
consegna: data.consegna,
|
||||
aggiornamento: it.card.in_aggiornamento,
|
||||
|
||||
consegna_da: it.card.consegna_da,
|
||||
mesi: it.preferenze.mesi,
|
||||
subito: it.card.consegna_subito,
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="flex flex-col gap-2">
|
||||
<span className="font-semibold">Persone:</span>
|
||||
<div className="flex w-full gap-4">
|
||||
<div className="flex w-1/2 flex-col gap-2">
|
||||
<Label htmlFor="n_adulti">{t.preferenze.nadulti_label}</Label>
|
||||
<Counter
|
||||
name="n_adulti"
|
||||
onlyPositive
|
||||
setValue={(v) => handleAdultiChange(Number(v))}
|
||||
value={servizio.n_adulti || 0}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex w-1/2 flex-col gap-2">
|
||||
<Label htmlFor="n_minori">{t.preferenze.nminori_label}</Label>
|
||||
<Counter
|
||||
name="n_minori"
|
||||
onlyPositive
|
||||
setValue={(v) => handleMinoriChange(Number(v))}
|
||||
value={servizio.n_minori || 0}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<p>
|
||||
<span className="font-semibold">Persone in annuncio: </span>
|
||||
{personeAnnuncio}
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex flex-col gap-2">
|
||||
<span className="font-semibold">Entro mese:</span>
|
||||
<div className="max-w-sm">
|
||||
<Label htmlFor="select-mesi">{t.preferenze.dalmese_label}</Label>
|
||||
<MultiSelect
|
||||
defaultValue={
|
||||
servizio.entromese !== null
|
||||
? {
|
||||
// biome-ignore lint/style/noNonNullAssertion: <known size>
|
||||
label: t.preferenze.mesi[servizio.entromese]!,
|
||||
value: String(servizio.entromese),
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
elementId="select-mesi"
|
||||
elementName="entro_mese"
|
||||
isMulti={false}
|
||||
onValueChange={handleDisponibilitàChange}
|
||||
options={UnpackOptions({
|
||||
options: t.preferenze.mesi,
|
||||
})}
|
||||
placeholder="Seleziona..."
|
||||
/>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
<span className="font-semibold">Disponibilità in annuncio: </span>
|
||||
{dispAnnuncio}
|
||||
</p>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const SendConferma = () => {
|
||||
const { servizio } = useServizio();
|
||||
const { data } = useServizioAnnuncio();
|
||||
|
|
@ -667,7 +799,7 @@ const SendConferma = () => {
|
|||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-10">
|
||||
<div className="flex flex-col gap-2">
|
||||
<div className="flex flex-col gap-4">
|
||||
<p>
|
||||
<span className="font-semibold">Tipologia servizio: </span>
|
||||
{servizio.tipologia}
|
||||
|
|
@ -677,6 +809,7 @@ const SendConferma = () => {
|
|||
) : (
|
||||
<StabileSection />
|
||||
)}
|
||||
<GeneralSection />
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<Switch
|
||||
|
|
|
|||
|
|
@ -1041,11 +1041,25 @@ export const AnnuncioEditForm = ({ data }: { data: AnnunciWithMedia }) => {
|
|||
name="disponibile_da"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<div className="flex flex-wrap items-center gap-x-2">
|
||||
<div className="relative flex flex-wrap items-center gap-x-2">
|
||||
<FormLabel htmlFor="disponibile_da">
|
||||
Disponibile Da
|
||||
</FormLabel>
|
||||
<FormMessage />
|
||||
{field.value !== null && (
|
||||
<Button
|
||||
className="-top-2 absolute right-0 flex items-center gap-1"
|
||||
onClick={() => {
|
||||
form.setValue("disponibile_da", null);
|
||||
}}
|
||||
size="sm"
|
||||
type="button"
|
||||
variant="link"
|
||||
>
|
||||
<RotateCw className="size-4" />
|
||||
Reset
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
|
|
@ -1096,36 +1110,38 @@ export const AnnuncioEditForm = ({ data }: { data: AnnunciWithMedia }) => {
|
|||
<FormField
|
||||
control={form.control}
|
||||
name="consegna"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<div className="flex flex-wrap items-center gap-x-2">
|
||||
<FormLabel htmlFor="select-consegna">
|
||||
Consegna
|
||||
</FormLabel>
|
||||
<FormMessage />
|
||||
</div>
|
||||
render={({ field: { value, onChange } }) => {
|
||||
const currVal =
|
||||
value !== null
|
||||
? consegnaOptions.filter(
|
||||
(o) => value.toString() === o.value,
|
||||
)[0]
|
||||
: undefined;
|
||||
return (
|
||||
<FormItem>
|
||||
<div className="flex flex-wrap items-center gap-x-2">
|
||||
<FormLabel htmlFor="select-consegna">
|
||||
Consegna
|
||||
</FormLabel>
|
||||
<FormMessage />
|
||||
</div>
|
||||
|
||||
<FormControl>
|
||||
<MultiSelect
|
||||
defaultValue={
|
||||
field.value
|
||||
? consegnaOptions.filter((o) =>
|
||||
field.value?.toString().includes(o.value),
|
||||
)
|
||||
: undefined
|
||||
}
|
||||
elementId="select-consegna"
|
||||
elementName="consegna"
|
||||
isMulti={false}
|
||||
onValueChange={async (value) => {
|
||||
field.onChange(parseInt(value.value));
|
||||
}}
|
||||
options={consegnaOptions}
|
||||
placeholder="Seleziona..."
|
||||
/>
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
)}
|
||||
<FormControl>
|
||||
<MultiSelect
|
||||
defaultValue={currVal}
|
||||
elementId="select-consegna"
|
||||
elementName="consegna"
|
||||
isMulti={false}
|
||||
onValueChange={async (value) => {
|
||||
onChange(parseInt(value.value));
|
||||
}}
|
||||
options={consegnaOptions}
|
||||
placeholder="Seleziona..."
|
||||
/>
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
}
|
||||
children2={
|
||||
|
|
|
|||
|
|
@ -14,6 +14,10 @@ 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]}`;
|
||||
|
|
|
|||
|
|
@ -635,6 +635,9 @@ export const getAllServizioAnnunci = async (userId: UsersId) => {
|
|||
"servizio.skipPayment",
|
||||
"servizio.skipControlloDoc",
|
||||
"servizio.skipDocMotivazione",
|
||||
"servizio.n_adulti",
|
||||
"servizio.n_minori",
|
||||
"servizio.entromese",
|
||||
jsonObjectFrom(
|
||||
eb
|
||||
.selectFrom("users_storage")
|
||||
|
|
@ -699,6 +702,9 @@ export const getAllServizioAnnunci = async (userId: UsersId) => {
|
|||
"annunci.media_updated_at",
|
||||
"annunci.homepage",
|
||||
"annunci.web",
|
||||
"annunci.disponibile_da",
|
||||
"annunci.persone",
|
||||
"annunci.permanenza",
|
||||
withImages(),
|
||||
withVideos(),
|
||||
])
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue