"use client"; import { z } from "zod/v4"; import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, } from "~/components/custom_ui/form"; import { useZodForm } from "~/lib/zodForm"; import { api } from "~/utils/api"; import { Button } from "~/components/ui/button"; import { useTranslation } from "~/providers/I18nProvider"; import { cn } from "~/lib/utils"; import type { Users, UsersId } from "~/schemas/public/Users"; import { MultiSelect, RepackValues, UnpackOptions, } from "~/components/custom_ui/multiselect"; import { Switch } from "~/components/ui/switch"; import type { UsersAnagrafica } from "~/schemas/public/UsersAnagrafica"; import Input from "~/components/custom_ui/input"; import { checkFiscalCodeValidity, getComuneFieldValue } from "~/lib/form_utils"; import InputWIcon from "~/components/custom_ui/input-icon"; import { CalendarIcon, HelpCircleIcon, Mail } from "lucide-react"; import { Popover, PopoverContent, PopoverTrigger, } from "~/components/ui/popover"; import { format } from "date-fns"; import { Calendar } from "~/components/ui/calendar"; import { enUS, it } from "date-fns/locale"; import { GetNazioni } from "~/i18n/nazioni"; import { getComuniNames } from "~/i18n/comuni"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "~/components/ui/tooltip"; import { provincie } from "~/i18n/provincie"; import TipologiaPosizioneEnum from "~/schemas/public/TipologiaPosizioneEnum"; import type { Servizio } from "~/schemas/public/Servizio"; import toast from "react-hot-toast"; import { Counter } from "~/components/counter"; import { Slider } from "~/components/ui/slider"; import { Label } from "~/components/ui/label"; import { Badge } from "~/components/ui/badge"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "~/components/ui/card"; import { useRouter } from "next/router"; import { Separator } from "~/components/ui/separator"; import { PhoneInput } from "~/components/phone-input"; type InitialData = { servizio: Servizio; userData: Pick; anagrafica: UsersAnagrafica | undefined; }; export const FormNewServizioAcquisto = ({ initialData, userId, isAdmin = false, }: { initialData: InitialData; userId: UsersId; isAdmin?: boolean; }) => { const router = useRouter(); const Schema = z .object({ nome: z.string().nonempty("Inserisci un nome valido"), cognome: z.string().nonempty("Inserisci un cognome valido"), azienda: z.boolean(), fatturazione_aziendale: z.boolean(), codice_destinatario: z.string().nullable(), ragione_sociale: z.string().nullable(), sede_legale: z.string().nullable(), legale_rappresentante: z.string().nullable(), p_iva: z.string().nullable(), email: z.email(), telefono: z.string(), sesso: z.string(), data_nascita: z.date(), luogo_nascita: z.string(), nazione_nascita: z.string(), codice_fiscale: z.string(), indirizzo_recapiti: z.string().nonempty("Inserisci un indirizzo"), civico_recapiti: z.string().nonempty("Inserisci un civico"), cap_recapiti: z.string().length(5), citta_recapiti: z.string().nonempty("Inserisci una città"), provincia_recapiti: z .string() .refine((v) => v !== "", { params: { type: "provincia" } }), nazione_recapiti: z .string() .refine((v) => v !== "", { params: { type: "nazione" } }), tipologia: z.custom(), budget: z.number().positive(), entromese: z.number().nullable(), n_adulti: z.number().min(1), n_minori: z.number(), permanenza: z.number().nullable(), motivazione_transitorio: z.string().nullable(), reddito: z.string().nullable(), arredato: z.boolean(), animali: z.boolean(), fumatori: z.boolean(), giardino: z.boolean(), parcheggio: z.boolean(), terrazzo: z.boolean(), ascensore: z.boolean(), pianoterra: z.boolean(), skipOrdine: z.boolean(), }) .superRefine( ( { telefono, codice_fiscale, sesso, cognome, nome, data_nascita, luogo_nascita, nazione_nascita, n_adulti, permanenza, entromese, motivazione_transitorio, reddito, azienda, p_iva, sede_legale, legale_rappresentante, ragione_sociale, fatturazione_aziendale, codice_destinatario, }, refinementContext, ) => { if (entromese === null) { refinementContext.issues.push({ code: "custom", message: "Inserisci il mese di inizio", path: ["entromese"], input: "", }); } if (azienda) { if (!ragione_sociale || ragione_sociale.length < 1) { refinementContext.issues.push({ code: "custom", message: "Inserisci la ragione sociale", path: ["ragione_sociale"], input: "", }); } if (!sede_legale || sede_legale.length < 1) { refinementContext.issues.push({ code: "custom", message: "Inserisci la sede legale", path: ["sede_legale"], input: "", }); } if (!p_iva || p_iva.length < 1) { refinementContext.issues.push({ code: "custom", message: "Inserisci la partita iva", path: ["p_iva"], input: "", }); } if (!legale_rappresentante || legale_rappresentante.length < 1) { refinementContext.issues.push({ code: "custom", message: "Inserisci il legale rappresentante", path: ["legale_rappresentante"], input: "", }); } } if (fatturazione_aziendale) { if (!codice_destinatario || codice_destinatario.length != 7) { refinementContext.issues.push({ code: "custom", message: "Inserisci un codice destinatario valido", path: ["codice_destinatario"], input: "", }); } } if (!telefono || telefono.length < 10) { refinementContext.issues.push({ code: "custom", message: "Il numero di telefono deve essere lungo almeno 10 caratteri", input: "", }); } checkFiscalCodeValidity({ path: "codice_fiscale", codiceFiscale: codice_fiscale, cognome, nome, dataNascita: data_nascita, sesso, refinementContext, luogoNascita: luogo_nascita, nazioneNascita: nazione_nascita, }); if (n_adulti <= 0) { refinementContext.issues.push({ code: "custom", message: "Inserisci il numero di persone", path: ["n_adulti"], input: "", }); } if ( permanenza === null && tipologia === TipologiaPosizioneEnum.Transitorio ) { refinementContext.issues.push({ code: "custom", message: "Inserisci permanenza", path: ["permanenza"], input: "", }); } if (tipologia === TipologiaPosizioneEnum.Transitorio) { if ( motivazione_transitorio === "" || motivazione_transitorio === null ) { refinementContext.issues.push({ code: "custom", message: "Inserisci la motivazione", path: ["motivazione_transitorio"], input: "", }); } } else { if (reddito === "" || reddito === null) { refinementContext.issues.push({ code: "custom", message: "Inserisci il reddito", path: ["reddito"], input: "", }); } } }, ); type FormValues = z.infer; // This can come from your database or API. const defaultValues: FormValues = { ...initialData.userData, azienda: initialData.anagrafica?.azienda || false, ragione_sociale: initialData.anagrafica?.ragione_sociale || "", sede_legale: initialData.anagrafica?.sede_legale || "", legale_rappresentante: initialData.anagrafica?.legale_rappresentante || "", p_iva: initialData.anagrafica?.p_iva || "", luogo_nascita: initialData.anagrafica?.luogo_nascita || "", nazione_nascita: initialData.anagrafica?.nazione_nascita || "", codice_fiscale: initialData.anagrafica?.codice_fiscale || "", sesso: initialData.anagrafica?.sesso || "M", data_nascita: initialData.anagrafica?.data_nascita ? new Date(initialData.anagrafica.data_nascita) : new Date(), nazione_recapiti: initialData.anagrafica?.nazione_residenza || "", provincia_recapiti: initialData.anagrafica?.provincia_residenza || "", citta_recapiti: initialData.anagrafica?.comune_residenza || "", indirizzo_recapiti: initialData.anagrafica?.via_residenza || "", civico_recapiti: initialData.anagrafica?.civico_residenza || "", cap_recapiti: initialData.anagrafica?.cap_residenza || "", fatturazione_aziendale: initialData.anagrafica?.fatturazione_aziendale || false, codice_destinatario: initialData.anagrafica?.codice_destinatario || "", ...initialData.servizio, skipOrdine: false, }; const { locale, t } = useTranslation(); const nazioni_options = GetNazioni(); const comuni_options = getComuniNames(); z.config(z.locales[locale]()); const form = useZodForm(Schema, { defaultValues: defaultValues, }); const DatePickerLocale = locale === "it" ? it : enUS; const { mutate } = api.servizio.postAcquistoData.useMutation({ onMutate: () => { toast.loading("Invio dati in corso", { id: "salvataggio", }); }, onSuccess: async (data) => { toast.success("Servizio impostato con successo", { id: "salvataggio", }); if (isAdmin) { if (data) { await router.push(`/area-riservata/admin/user-view/ordini/${userId}`); } else { await router.push( `/area-riservata/admin/user-view/ricerca/${userId}`, ); } } else { await router.push(`/servizio/pagamento/${data}`); } }, onError: (error) => { toast.error("Errore invio dati: " + error.message, { id: "salvataggio", }); }, }); function onSubmit(fields: FormValues) { mutate({ servizioId: initialData.servizio.servizio_id, userId, user: { username: `${fields.nome.trim()} ${fields.cognome.trim()}`, nome: fields.nome, cognome: fields.cognome, email: fields.email, telefono: fields.telefono.replace(/\s/g, ""), }, anagrafica: { idanagrafica: initialData.anagrafica?.idanagrafica, azienda: fields.azienda, ragione_sociale: fields.ragione_sociale, sede_legale: fields.sede_legale, legale_rappresentante: fields.legale_rappresentante, p_iva: fields.p_iva, sesso: fields.sesso, data_nascita: fields.data_nascita, luogo_nascita: fields.luogo_nascita, nazione_nascita: fields.nazione_nascita, codice_fiscale: fields.codice_fiscale, nazione_residenza: fields.nazione_recapiti, provincia_residenza: fields.provincia_recapiti, comune_residenza: fields.citta_recapiti, via_residenza: fields.indirizzo_recapiti, civico_residenza: fields.civico_recapiti, cap_residenza: fields.cap_recapiti, userid: userId, fatturazione_aziendale: fields.fatturazione_aziendale, codice_destinatario: fields.codice_destinatario, }, servizio: { tipologia: fields.tipologia, budget: fields.budget, entromese: fields.entromese, n_adulti: fields.n_adulti, n_minori: fields.n_minori, permanenza: fields.permanenza, motivazione_transitorio: fields.motivazione_transitorio, arredato: fields.arredato, animali: fields.animali, fumatori: fields.fumatori, giardino: fields.giardino, parcheggio: fields.parcheggio, terrazzo: fields.terrazzo, ascensore: fields.ascensore, pianoterra: fields.pianoterra, reddito: fields.reddito, }, skipOrdine: isAdmin ? fields.skipOrdine : false, }); } type altrePrefMappingType = [ ["animali", string], ["fumatori", string], ["giardino", string], ["parcheggio", string], ["terrazzo", string], ["ascensore", string], ["pianoterra", string], ]; const altrePrefMapping = t.altrePrefMapping as altrePrefMappingType; const [ tipologia, azienda, fatturazione_aziendale, nazione_nascita, nazione_recapiti, budget, ] = form.watch([ "tipologia", "azienda", "fatturazione_aziendale", "nazione_nascita", "nazione_recapiti", "budget", ]); const texts = locale === "it" ? { dettagli: "Dettagli del servizio", dettagli_desc: "Questi dati rappresentano la tua ricerca", personali: "Dati personali", personali_desc: "Inserisci i tuoi dati personali", fattura: "Vuoi che la fatturazione sia intestata alla tua azienda?", sdi: "Codice destinatario SDI", salva: "Salva e procedi al pagamento", } : { dettagli: "Service Details", dettagli_desc: "These data represent your search", personali: "Personal Data", personali_desc: "Enter your personal data", fattura: "Do you want the invoice to be issued to your company?", sdi: "SDI Recipient Code", salva: "Save and proceed to payment", }; return (
{texts.dettagli} {texts.dettagli_desc} (
{t.preferenze.tipologia}
{ field.onChange(value.value); form.setValue("motivazione_transitorio", null); form.setValue("reddito", null); }} />
)} /> (
{`${t.preferenze.budget_label1} - ${field.value},00 ${ t.preferenze.budget_label2 }`}
{ field.onChange(Number(vals[0])); }} rangeClassName="bg-neutral-700" thumbClassName="border-neutral-700" value={[budget]} id="budgetslider" /> {t.preferenze.budget_desc}
)} />
(
{t.preferenze.dalmese_label}...
{ field.onChange( value.value !== "" ? parseInt(value.value) : null, ); }} placeholder="Seleziona..." isMulti={false} />
)} /> (
{t.preferenze.permanenza_label}
{ field.onChange( value.value !== "" ? parseInt(value.value) : null, ); }} placeholder="Seleziona..." isMulti={false} disabled={ tipologia !== TipologiaPosizioneEnum.Transitorio } /> {t.preferenze.permanenza_desc}
)} />
(
{t.preferenze.nadulti_label}
field.onChange(Number(v))} name="n_adulti" onlyPositive />
)} /> (
{t.preferenze.nminori_label}
field.onChange(Number(v))} name="n_minori" onlyPositive />
)} />
(
{t.preferenze.arredato_label}
{t.preferenze.arredato_desc}
)} />
{tipologia === TipologiaPosizioneEnum.Transitorio ? ( { const existingValue = t.preferenze.motivazioni_mappings.find( (m) => m.id == field.value, ); return (
{t.preferenze.motivazione_label}
({ value: option.id, label: option.title, }), )} onValueChange={(value) => { field.onChange(value.value); }} /> {t.preferenze.motivazione_desc}
); }} /> ) : ( (
{t.preferenze.reddito_label}
{ field.onChange(value.value); }} />
)} /> )}
{t.preferenze.altrepref_desc}
{altrePrefMapping.map((pair, index) => { if (pair) { return ( ( { field.onChange(!field.value); }} className={cn( "cursor-pointer text-sm", field.value ? "bg-neutral-800 hover:bg-neutral-800 sm:hover:bg-neutral-900/80" : "bg-neutral-200 text-neutral-700 hover:bg-neutral-200 sm:hover:bg-neutral-900/80 sm:hover:text-neutral-50", )} > {pair[1]} )} /> ); } })}
{texts.personali} {texts.personali_desc}
(
{t.account.nome}
)} /> (
{t.account.cognome}
)} /> (
{t.account.azienda_o_pf_disclamer} { field.onChange(v); if (!v) { form.setValue("ragione_sociale", null); form.setValue("sede_legale", null); form.setValue("p_iva", null); } }} id="azienda" className="data-[state=checked]:bg-neutral-700" />
)} />
{azienda && ( <>
(
{t.anagrafica.ragioneSociale}
)} /> (
{t.anagrafica.sedeLegale}
)} />
(
{t.anagrafica.p_iva}
)} /> (
{t.anagrafica.legale_rappresentante}
)} />
(
{texts.fattura} { field.onChange(v); if (!v) { form.setValue("codice_destinatario", null); } }} id="fatturazione_aziendale" className="data-[state=checked]:bg-neutral-700" />
)} /> {fatturazione_aziendale && ( (
{texts.sdi}
)} /> )} )}
(
{t.anagrafica.dataNascita}
date > new Date() || date < new Date("1900-01-01") } // eslint-disable-next-line jsx-a11y/no-autofocus autoFocus />
)} /> (
{t.anagrafica.nazioneNascita}
{ field.onChange(value.value); await form.trigger("luogo_nascita"); }} placeholder="Seleziona..." isMulti={false} />
)} /> { if (nazione_nascita === "0") { return (
{t.anagrafica.luogoNascita}
{ field.onChange(value.value); await form.trigger("luogo_nascita"); }} placeholder="Seleziona..." isMulti={false} />
); } return (
{t.anagrafica.luogoNascita}
{ field.onChange(v.target.value); await form.trigger("luogo_nascita"); }} />
); }} /> (
{t.anagrafica.sesso}{" "} {t.anagrafica.sesso_disclamer}
v.value == field.value, )} options={t.anagrafica.sesso_options} onValueChange={(value) => { field.onChange(value.value); }} />
)} />
(
{t.anagrafica.codiceFiscale}
{ field.onChange(v.target.value.toUpperCase()); await form.trigger("codice_fiscale"); }} type="text" className="uppercase" id="codice_fiscale" />
)} /> (
{t.account.email}
)} /> (
{t.account.telefono}
)} />
(
{t.recapiti.nazione}
{ field.onChange(value.value); form.setValue("provincia_recapiti", ""); await form.trigger("citta_recapiti"); }} placeholder="Seleziona..." isMulti={false} />
)} /> (
{t.recapiti.provincia}
{nazione_recapiti === "0" ? ( { field.onChange(value.value); }} defaultValue={RepackValues({ options: provincie, values: field.value, })} elementName="provincia" isMulti={false} placeholder="Seleziona" /> ) : ( )}
)} />
{ if (nazione_recapiti === "0") { return (
{t.recapiti.comune}
{ field.onChange(value.value); await form.trigger("citta_recapiti"); }} placeholder="Seleziona..." isMulti={false} />
); } return (
{t.recapiti.comune}
{ field.onChange(v.target.value); await form.trigger("citta_recapiti"); }} />
); }} /> (
{t.recapiti.cap}
)} />
(
{t.recapiti.indirizzo}
)} /> (
{t.recapiti.civico}
)} />
{isAdmin && ( (
Vuoi saltare la creazione dell'ordine e impostare il servizio come attivo? { field.onChange(v); }} id="skipOrdine" className="data-[state=checked]:bg-neutral-700" />
)} /> )}
); };