import { differenceInYears, format } from "date-fns"; import { enUS, it } from "date-fns/locale"; import { CalendarIcon } from "lucide-react"; import { type Control, useWatch } from "react-hook-form"; import toast from "react-hot-toast"; import { z } from "zod/v4"; import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage, } from "~/components/custom_ui/form"; import Input from "~/components/custom_ui/input"; import { MultiSelect, RepackValues, UnpackOptions, } from "~/components/custom_ui/multiselect"; import { Button } from "~/components/ui/button"; import { Calendar } from "~/components/ui/calendar"; import { Popover, PopoverContent, PopoverTrigger, } from "~/components/ui/popover"; import { Separator } from "~/components/ui/separator"; import { Switch } from "~/components/ui/switch"; import { getComuni } from "~/i18n/comuni"; import { GetNazioni } from "~/i18n/nazioni"; import { getProvinciaFromSigla, provincieWithSigla } from "~/i18n/provincie"; import { checkFiscalCodeValidity, getComuneFieldValue } from "~/lib/form_utils"; import { cn } from "~/lib/utils"; import { useZodForm } from "~/lib/zodForm"; import { useTranslation } from "~/providers/I18nProvider"; import type { UserWithAnagrafica } from "~/server/services/user.service"; import { api } from "~/utils/api"; const profileFormSchema = z.object({ azienda: z.boolean(), cap_residenza: z.string().optional(), civico_residenza: z.string().optional(), codice_destinatario: z.string().length(7).nullable(), codice_fiscale: z.string().optional(), comune_residenza: z.string().optional(), data_nascita: z.date().optional(), fatturazione_aziendale: z.boolean(), legale_rappresentante: z.string().nullable(), luogo_nascita: z.string().optional(), nazione_nascita: z.string().optional(), nazione_residenza: z.string().optional(), p_iva: z.string().nullable(), provincia_residenza: z.string().optional(), ragione_sociale: z.string().nullable(), sede_legale: z.string().nullable(), sesso: z.string().optional(), via_residenza: z.string().optional(), }); type ProfileFormValues = z.infer; export const ProfileFormAnagrafica = ({ userData, }: { userData: UserWithAnagrafica; }) => { const schema = profileFormSchema.superRefine( ( { data_nascita, codice_fiscale, sesso, luogo_nascita, nazione_nascita, cap_residenza, azienda, p_iva, ragione_sociale, sede_legale, legale_rappresentante, fatturazione_aziendale, codice_destinatario, }, refinementContext, ) => { if (azienda) { if (!ragione_sociale || ragione_sociale.length < 1) { refinementContext.issues.push({ code: "custom", input: "", message: "Inserisci la ragione sociale", path: ["ragione_sociale"], }); } if (!sede_legale || sede_legale.length < 1) { refinementContext.issues.push({ code: "custom", input: "", message: "Inserisci la sede legale", path: ["sede_legale"], }); } if (!p_iva || p_iva.length < 1) { refinementContext.issues.push({ code: "custom", input: "", message: "Inserisci la partita iva", path: ["p_iva"], }); } if (!legale_rappresentante || legale_rappresentante.length < 1) { refinementContext.issues.push({ code: "custom", input: "", message: "Inserisci il legale rappresentante", path: ["legale_rappresentante"], }); } } if (fatturazione_aziendale) { if (!codice_destinatario || codice_destinatario.length !== 7) { refinementContext.issues.push({ code: "custom", input: "", message: "Inserisci il codice destinatario", path: ["codice_destinatario"], }); } } if (cap_residenza) { if (cap_residenza.length !== 5) { refinementContext.issues.push({ code: "custom", input: "", message: "Inserisci un CAP valido", }); } } if (data_nascita) { const diff = differenceInYears(data_nascita, new Date()); if (diff === 0) { refinementContext.issues.push({ code: "custom", input: "", message: "Inserisci una data valida", path: ["data_nascita"], }); } } if ( codice_fiscale && codice_fiscale.length > 0 && data_nascita && sesso && luogo_nascita && nazione_nascita ) { checkFiscalCodeValidity({ codiceFiscale: codice_fiscale, cognome: userData.cognome?.toUpperCase() || "", dataNascita: data_nascita, luogoNascita: luogo_nascita, nazioneNascita: nazione_nascita, nome: userData.nome?.toUpperCase() || "", path: "codice_fiscale", refinementContext, sesso, }); } }, ); const defaultValues: ProfileFormValues = { azienda: userData.azienda || false, cap_residenza: userData.cap_residenza || "", civico_residenza: userData.civico_residenza || "", codice_destinatario: userData.codice_destinatario || null, codice_fiscale: userData.codice_fiscale || "", comune_residenza: userData.comune_residenza || "", data_nascita: userData.data_nascita || new Date(), fatturazione_aziendale: userData.fatturazione_aziendale || false, legale_rappresentante: userData.legale_rappresentante || null, luogo_nascita: userData.luogo_nascita || "", nazione_nascita: userData.nazione_nascita || "", nazione_residenza: userData.nazione_residenza || "", p_iva: userData.p_iva || null, provincia_residenza: userData.provincia_residenza || "", ragione_sociale: userData.ragione_sociale || null, sede_legale: userData.sede_legale || null, sesso: userData.sesso || "", via_residenza: userData.via_residenza || "", }; const { locale, t } = useTranslation(); const DatePickerLocale = locale === "it" ? it : enUS; z.config(z.locales[locale]()); const form = useZodForm(schema, { defaultValues: defaultValues, }); const utils = api.useUtils(); const { mutate } = api.users.editUserAnagrafica.useMutation({ onError: (error) => { toast.error(error.message); }, onSuccess: async () => { toast.success(t.profile.aggiornato); await utils.auth.getSession.invalidate(); await utils.users.getUser.invalidate(); await utils.users.getClientProfilo.invalidate({ userId: userData.id, }); }, }); function onSubmit(fields: ProfileFormValues) { mutate({ userId: userData.id, data: { ...fields }, }); } const nazioni_options = GetNazioni(); const comuni_options = getComuni(); return ( <>
{/* */}
(
{t.anagrafica.dataNascita}
)} /> (
{t.anagrafica.nazioneNascita}
{ field.onChange(value.value); await form.trigger("luogo_nascita"); }} options={UnpackOptions({ options: nazioni_options })} placeholder="Seleziona..." />
)} /> { if (form.watch("nazione_nascita") === "0") { const options = comuni_options.map((c) => c.nome); return (
{t.anagrafica.luogoNascita}
{ field.onChange(value.value); await form.trigger("luogo_nascita"); await form.trigger("codice_fiscale"); }} options={UnpackOptions({ options })} placeholder="Seleziona..." />
); } return (
{t.anagrafica.luogoNascita}
{ field.onChange(v.target.value); await form.trigger("luogo_nascita"); await form.trigger("codice_fiscale"); }} type="text" />
); }} />
(
{t.anagrafica.sesso}
v.value === field.value, )} elementId="select-sesso" elementName="sesso" isMulti={false} onValueChange={async (value) => { field.onChange(value.value); await form.trigger("codice_fiscale"); }} options={t.anagrafica.sesso_options} placeholder="" />
)} /> (
{t.anagrafica.codiceFiscale}
{ field.onChange(v.target.value.toUpperCase()); await form.trigger("codice_fiscale"); }} type="text" />
)} /> (
Azienda? { field.onChange(v); if (!v) { form.setValue("ragione_sociale", null); form.setValue("sede_legale", null); form.setValue("p_iva", null); } }} />
)} />
); }; const AziendaSection = ({ control, setValue, }: { control: Control; // biome-ignore lint/suspicious/noExplicitAny: setValue: (field: keyof ProfileFormValues, value: any) => void; }) => { const { t } = useTranslation(); const azienda = useWatch({ control, name: "azienda" }); return ( <>
(
{t.anagrafica.ragioneSociale}
)} /> (
{t.anagrafica.sedeLegale}
)} />
(
{t.anagrafica.p_iva}
)} /> (
{t.anagrafica.legale_rappresentante}
)} />
(
Vuoi che la fatturazione sia intestata alla tua azienda? { field.onChange(v); if (!v) { setValue("codice_destinatario", null); } }} />
)} /> ); }; const FatturazioneSection = ({ control, }: { control: Control; }) => { const fatturazione_aziendale = useWatch({ control, name: "fatturazione_aziendale", }); return ( <> (
Codice destinatario (SDI)
)} /> ); }; const ResidenzaSection = ({ control, setValue, trigger, }: { control: Control; // biome-ignore lint/suspicious/noExplicitAny: setValue: (field: keyof ProfileFormValues, value: any) => void; trigger: (name?: keyof ProfileFormValues) => Promise; }) => { const { t } = useTranslation(); const nazioni_options = GetNazioni(); const comuni_options = getComuni(); const nazione_residenza = useWatch({ control: control, name: "nazione_residenza", }); const provincia_residenza = useWatch({ control: control, name: "provincia_residenza", }); return ( <>
(
{t.recapiti.nazione}
{ setValue("provincia_residenza", ""); field.onChange(value.value); await trigger("comune_residenza"); }} options={UnpackOptions({ options: nazioni_options })} placeholder="Seleziona" />
)} /> { const provinciaName = field.value && getProvinciaFromSigla(field.value); return (
{t.recapiti.provincia}
{nazione_residenza === "0" ? ( { field.onChange(value.value); }} options={provincieWithSigla.map((prov) => ({ label: prov.nome, value: prov.sigla, }))} placeholder="Seleziona" /> ) : ( )}
); }} />
{ if (nazione_residenza === "0") { const options = comuni_options .filter((comune) => provincia_residenza ? comune.provincia === provincia_residenza : true, ) .map((comune) => comune.nome); return (
{t.recapiti.comune}
{ field.onChange(value.value); await trigger("comune_residenza"); }} options={UnpackOptions({ options: options, })} placeholder="Seleziona..." />
); } return (
{t.recapiti.comune}
{ field.onChange(v.target.value); await trigger("comune_residenza"); }} type="text" />
); }} /> (
{t.recapiti.cap}
)} />
(
{t.recapiti.indirizzo}
)} /> (
{t.recapiti.civico}
)} />
); };