Refactor comuni and provincie data structures; add dynamic FormDebug component
- Updated `initializeComuniNames` to accept an optional `provincia` parameter for filtering comuni by province. - Renamed `getComuniNames` to `getComuni` and modified it to return an array of objects containing both comune names and their respective province siglas. - Introduced `provincieWithSigla` array to map province names to their siglas, along with a new function `getProvinciaFromSigla` for retrieving province names based on sigla. - Added a dynamic import for the `FormDebug` component to facilitate debugging in development mode while preventing it from rendering in production. - Commented out console logs in `checkFiscalCodeValidity` for cleaner production output.
This commit is contained in:
parent
da7683ba45
commit
967935f0a8
7 changed files with 1159 additions and 1012 deletions
|
|
@ -11,7 +11,6 @@ import {
|
|||
} from "react-hook-form";
|
||||
import { Label } from "src/components/ui/label";
|
||||
import { cn } from "src/lib/utils";
|
||||
import { env } from "~/env";
|
||||
|
||||
const Form = FormProvider;
|
||||
|
||||
|
|
@ -171,23 +170,6 @@ const FormMessage = React.forwardRef<
|
|||
});
|
||||
FormMessage.displayName = "FormMessage";
|
||||
|
||||
const FormDebug = React.forwardRef<
|
||||
React.ElementType,
|
||||
React.HTMLAttributes<HTMLDivElement>
|
||||
>(async () => {
|
||||
if (env.NODE_ENV !== "development") {
|
||||
return null;
|
||||
}
|
||||
const { control, formState } = useFormContext();
|
||||
const devtools = await import(/* webpackIgnore: true */ "@hookform/devtools");
|
||||
|
||||
if (Object.keys(formState.errors).length > 0) {
|
||||
console.error("errors", formState.errors);
|
||||
}
|
||||
return <devtools.DevTool control={control} />;
|
||||
});
|
||||
FormDebug.displayName = "FormDebug";
|
||||
|
||||
export {
|
||||
useFormField,
|
||||
Form,
|
||||
|
|
@ -197,5 +179,4 @@ export {
|
|||
FormDescription,
|
||||
FormMessage,
|
||||
FormField,
|
||||
FormDebug,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
import dynamic from "next/dynamic";
|
||||
import type React from "react";
|
||||
|
||||
export const DevT: React.ElementType = dynamic(
|
||||
() => import("@hookform/devtools").then((mod) => mod.DevTool),
|
||||
{ ssr: false },
|
||||
);
|
||||
|
|
@ -3,6 +3,7 @@ import { format } from "date-fns";
|
|||
import { enUS, it } from "date-fns/locale";
|
||||
import { CalendarIcon, HelpCircleIcon, Mail } from "lucide-react";
|
||||
import { useRouter } from "next/router";
|
||||
import { type Control, useWatch } from "react-hook-form";
|
||||
import toast from "react-hot-toast";
|
||||
import { z } from "zod/v4";
|
||||
import { Counter } from "~/components/counter";
|
||||
|
|
@ -48,9 +49,9 @@ import {
|
|||
TooltipProvider,
|
||||
TooltipTrigger,
|
||||
} from "~/components/ui/tooltip";
|
||||
import { getComuniNames } from "~/i18n/comuni";
|
||||
import { getComuni } from "~/i18n/comuni";
|
||||
import { GetNazioni } from "~/i18n/nazioni";
|
||||
import { provincie } from "~/i18n/provincie";
|
||||
import { getProvinciaFromSigla, provincieWithSigla } from "~/i18n/provincie";
|
||||
import { checkFiscalCodeValidity, getComuneFieldValue } from "~/lib/form_utils";
|
||||
import { cn } from "~/lib/utils";
|
||||
import { useZodForm } from "~/lib/zodForm";
|
||||
|
|
@ -67,18 +68,7 @@ type InitialData = {
|
|||
anagrafica: UsersAnagrafica | undefined;
|
||||
};
|
||||
|
||||
export const FormNewServizioAcquisto = ({
|
||||
initialData,
|
||||
userId,
|
||||
isAdmin = false,
|
||||
}: {
|
||||
initialData: InitialData;
|
||||
userId: UsersId;
|
||||
isAdmin?: boolean;
|
||||
}) => {
|
||||
const router = useRouter();
|
||||
const Schema = z
|
||||
.object({
|
||||
const FormNewServizioSchema = z.object({
|
||||
animali: z.boolean(),
|
||||
arredato: z.boolean(),
|
||||
ascensore: z.boolean(),
|
||||
|
|
@ -122,8 +112,20 @@ export const FormNewServizioAcquisto = ({
|
|||
telefono: z.string(),
|
||||
terrazzo: z.boolean(),
|
||||
tipologia: z.custom<TipologiaPosizioneEnum>(),
|
||||
})
|
||||
.superRefine(
|
||||
});
|
||||
type FormNewServizioValues = z.infer<typeof FormNewServizioSchema>;
|
||||
|
||||
export const FormNewServizioAcquisto = ({
|
||||
initialData,
|
||||
userId,
|
||||
isAdmin = false,
|
||||
}: {
|
||||
initialData: InitialData;
|
||||
userId: UsersId;
|
||||
isAdmin?: boolean;
|
||||
}) => {
|
||||
const router = useRouter();
|
||||
const schema = FormNewServizioSchema.superRefine(
|
||||
(
|
||||
{
|
||||
telefono,
|
||||
|
|
@ -265,10 +267,8 @@ export const FormNewServizioAcquisto = ({
|
|||
},
|
||||
);
|
||||
|
||||
type FormValues = z.infer<typeof Schema>;
|
||||
|
||||
// This can come from your database or API.
|
||||
const defaultValues: FormValues = {
|
||||
const defaultValues: FormNewServizioValues = {
|
||||
...initialData.userData,
|
||||
azienda: initialData.anagrafica?.azienda || false,
|
||||
cap_recapiti: initialData.anagrafica?.cap_residenza || "",
|
||||
|
|
@ -298,10 +298,10 @@ export const FormNewServizioAcquisto = ({
|
|||
|
||||
const { locale, t } = useTranslation();
|
||||
const nazioni_options = GetNazioni();
|
||||
const comuni_options = getComuniNames();
|
||||
const comuni_options = getComuni();
|
||||
z.config(z.locales[locale]());
|
||||
|
||||
const form = useZodForm(Schema, {
|
||||
const form = useZodForm(schema, {
|
||||
defaultValues: defaultValues,
|
||||
});
|
||||
const DatePickerLocale = locale === "it" ? it : enUS;
|
||||
|
|
@ -335,7 +335,7 @@ export const FormNewServizioAcquisto = ({
|
|||
},
|
||||
});
|
||||
|
||||
function onSubmit(fields: FormValues) {
|
||||
function onSubmit(fields: FormNewServizioValues) {
|
||||
mutate({
|
||||
anagrafica: {
|
||||
azienda: fields.azienda,
|
||||
|
|
@ -399,17 +399,8 @@ export const FormNewServizioAcquisto = ({
|
|||
["pianoterra", string],
|
||||
];
|
||||
const altrePrefMapping = t.altrePrefMapping as altrePrefMappingType;
|
||||
const [
|
||||
tipologia,
|
||||
azienda,
|
||||
fatturazione_aziendale,
|
||||
nazione_nascita,
|
||||
nazione_recapiti,
|
||||
budget,
|
||||
] = form.watch([
|
||||
const [tipologia, nazione_nascita, nazione_recapiti, budget] = form.watch([
|
||||
"tipologia",
|
||||
"azienda",
|
||||
"fatturazione_aziendale",
|
||||
"nazione_nascita",
|
||||
"nazione_recapiti",
|
||||
"budget",
|
||||
|
|
@ -438,7 +429,10 @@ export const FormNewServizioAcquisto = ({
|
|||
|
||||
return (
|
||||
<Form {...form}>
|
||||
<form className="space-y-8 px-0.5" onSubmit={form.handleSubmit(onSubmit)}>
|
||||
<form
|
||||
className="space-y-8 px-0.5 pb-5"
|
||||
onSubmit={form.handleSubmit(onSubmit)}
|
||||
>
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>{texts.dettagli}</CardTitle>
|
||||
|
|
@ -882,154 +876,9 @@ export const FormNewServizioAcquisto = ({
|
|||
/>
|
||||
</div>
|
||||
|
||||
{azienda && (
|
||||
<>
|
||||
<div className="flex w-full flex-col items-start justify-between gap-4 sm:flex-row">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="ragione_sociale"
|
||||
render={({ field }) => (
|
||||
<FormItem className="w-full">
|
||||
<div className="flex flex-wrap items-center gap-x-2">
|
||||
<FormLabel htmlFor="ragione_sociale">
|
||||
{t.anagrafica.ragioneSociale}
|
||||
</FormLabel>
|
||||
<FormMessage />
|
||||
</div>
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
id="ragione_sociale"
|
||||
type="text"
|
||||
value={field.value || undefined}
|
||||
/>
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="sede_legale"
|
||||
render={({ field }) => (
|
||||
<FormItem className="w-full">
|
||||
<div className="flex flex-wrap items-center gap-x-2">
|
||||
<FormLabel htmlFor="sede_legale">
|
||||
{t.anagrafica.sedeLegale}
|
||||
</FormLabel>
|
||||
<FormMessage />
|
||||
</div>
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
id="sede_legale"
|
||||
type="text"
|
||||
value={field.value || undefined}
|
||||
/>
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex w-full flex-col items-start justify-between gap-4 sm:flex-row">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="p_iva"
|
||||
render={({ field }) => (
|
||||
<FormItem className="w-full">
|
||||
<div className="flex flex-wrap items-center gap-x-2">
|
||||
<FormLabel htmlFor="p_iva">
|
||||
{t.anagrafica.p_iva}
|
||||
</FormLabel>
|
||||
<FormMessage />
|
||||
</div>
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
id="p_iva"
|
||||
type="text"
|
||||
value={field.value || undefined}
|
||||
/>
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="legale_rappresentante"
|
||||
render={({ field }) => (
|
||||
<FormItem className="w-full">
|
||||
<div className="flex flex-wrap items-center gap-x-2">
|
||||
<FormLabel htmlFor="legale_rappresentante">
|
||||
{t.anagrafica.legale_rappresentante}
|
||||
</FormLabel>
|
||||
<FormMessage />
|
||||
</div>
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
id="legale_rappresentante"
|
||||
type="text"
|
||||
value={field.value || undefined}
|
||||
/>
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="fatturazione_aziendale"
|
||||
render={({ field }) => (
|
||||
<FormItem className="py-2">
|
||||
<div className="flex items-center justify-start gap-x-4">
|
||||
<FormLabel htmlFor="fatturazione_aziendale">
|
||||
{texts.fattura}
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Switch
|
||||
checked={field.value}
|
||||
className="data-[state=checked]:bg-neutral-700"
|
||||
id="fatturazione_aziendale"
|
||||
onCheckedChange={(v) => {
|
||||
field.onChange(v);
|
||||
if (!v) {
|
||||
form.setValue("codice_destinatario", null);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</div>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
{fatturazione_aziendale && (
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="codice_destinatario"
|
||||
render={({ field }) => (
|
||||
<FormItem className="w-full">
|
||||
<div className="flex flex-wrap items-center gap-x-2">
|
||||
<FormLabel htmlFor="codice_destinatario">
|
||||
{texts.sdi}
|
||||
</FormLabel>
|
||||
<FormMessage />
|
||||
</div>
|
||||
<AziendaSection control={form.control} setValue={form.setValue} />
|
||||
<FatturazioneSection control={form.control} />
|
||||
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
id="codice_destinatario"
|
||||
type="text"
|
||||
value={field.value || undefined}
|
||||
/>
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
<Separator />
|
||||
<div className="flex w-full flex-col items-start justify-between gap-4 sm:flex-row">
|
||||
<FormField
|
||||
|
|
@ -1110,6 +959,9 @@ export const FormNewServizioAcquisto = ({
|
|||
onValueChange={async (value) => {
|
||||
field.onChange(value.value);
|
||||
await form.trigger("luogo_nascita");
|
||||
if (value.value !== "0") {
|
||||
form.setValue("luogo_nascita", "");
|
||||
}
|
||||
}}
|
||||
options={UnpackOptions({ options: nazioni_options })}
|
||||
placeholder="Seleziona..."
|
||||
|
|
@ -1124,6 +976,7 @@ export const FormNewServizioAcquisto = ({
|
|||
name="luogo_nascita"
|
||||
render={({ field }) => {
|
||||
if (nazione_nascita === "0") {
|
||||
const options = comuni_options.map((c) => c.nome);
|
||||
return (
|
||||
<FormItem className="w-full">
|
||||
<div className="flex flex-wrap items-center gap-x-2">
|
||||
|
|
@ -1137,7 +990,7 @@ export const FormNewServizioAcquisto = ({
|
|||
<MultiSelect
|
||||
defaultValue={getComuneFieldValue(
|
||||
field.value,
|
||||
comuni_options,
|
||||
options,
|
||||
)}
|
||||
elementId="select-comune-nascita"
|
||||
elementName="luogoNascita"
|
||||
|
|
@ -1146,7 +999,7 @@ export const FormNewServizioAcquisto = ({
|
|||
field.onChange(value.value);
|
||||
await form.trigger("luogo_nascita");
|
||||
}}
|
||||
options={UnpackOptions({ options: comuni_options })}
|
||||
options={UnpackOptions({ options })}
|
||||
placeholder="Seleziona..."
|
||||
/>
|
||||
</FormControl>
|
||||
|
|
@ -1310,7 +1163,9 @@ export const FormNewServizioAcquisto = ({
|
|||
onValueChange={async (value) => {
|
||||
field.onChange(value.value);
|
||||
form.setValue("provincia_recapiti", "");
|
||||
await form.trigger("citta_recapiti");
|
||||
if (value.value !== "0") {
|
||||
form.setValue("citta_recapiti", "");
|
||||
}
|
||||
}}
|
||||
options={UnpackOptions({ options: nazioni_options })}
|
||||
placeholder="Seleziona..."
|
||||
|
|
@ -1322,7 +1177,10 @@ export const FormNewServizioAcquisto = ({
|
|||
<FormField
|
||||
control={form.control}
|
||||
name="provincia_recapiti"
|
||||
render={({ field }) => (
|
||||
render={({ field }) => {
|
||||
const provinciaName =
|
||||
field.value && getProvinciaFromSigla(field.value);
|
||||
return (
|
||||
<FormItem className="w-full">
|
||||
<div className="flex flex-wrap items-center gap-x-2">
|
||||
<FormLabel htmlFor="provinciaRecapiti">
|
||||
|
|
@ -1333,26 +1191,38 @@ export const FormNewServizioAcquisto = ({
|
|||
|
||||
{nazione_recapiti === "0" ? (
|
||||
<MultiSelect
|
||||
defaultValue={RepackValues({
|
||||
options: provincie,
|
||||
values: field.value,
|
||||
})}
|
||||
defaultValue={
|
||||
field.value && provinciaName
|
||||
? {
|
||||
label: provinciaName,
|
||||
value: field.value,
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
elementId="provinciaRecapiti"
|
||||
elementName="provincia"
|
||||
isMulti={false}
|
||||
onValueChange={(value) => {
|
||||
field.onChange(value.value);
|
||||
}}
|
||||
options={UnpackOptions({ options: provincie })}
|
||||
options={provincieWithSigla.map((prov) => ({
|
||||
label: prov.nome,
|
||||
value: prov.sigla,
|
||||
}))}
|
||||
placeholder="Seleziona"
|
||||
/>
|
||||
) : (
|
||||
<FormControl>
|
||||
<Input {...field} id="provinciaRecapiti" type="text" />
|
||||
<Input
|
||||
{...field}
|
||||
id="provinciaRecapiti"
|
||||
type="text"
|
||||
/>
|
||||
</FormControl>
|
||||
)}
|
||||
</FormItem>
|
||||
)}
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex w-full flex-col items-start justify-between gap-4 sm:flex-row">
|
||||
|
|
@ -1361,6 +1231,12 @@ export const FormNewServizioAcquisto = ({
|
|||
name="citta_recapiti"
|
||||
render={({ field }) => {
|
||||
if (nazione_recapiti === "0") {
|
||||
const provincia = form.watch("provincia_recapiti");
|
||||
const options = comuni_options
|
||||
.filter((comune) =>
|
||||
provincia ? comune.provincia === provincia : true,
|
||||
)
|
||||
.map((comune) => comune.nome);
|
||||
return (
|
||||
<FormItem className="w-full">
|
||||
<div className="flex flex-wrap items-center gap-x-2">
|
||||
|
|
@ -1374,7 +1250,7 @@ export const FormNewServizioAcquisto = ({
|
|||
<MultiSelect
|
||||
defaultValue={getComuneFieldValue(
|
||||
field.value,
|
||||
comuni_options,
|
||||
options,
|
||||
)}
|
||||
elementId="select-comune"
|
||||
elementName="citta_recapiti"
|
||||
|
|
@ -1383,7 +1259,7 @@ export const FormNewServizioAcquisto = ({
|
|||
field.onChange(value.value);
|
||||
await form.trigger("citta_recapiti");
|
||||
}}
|
||||
options={UnpackOptions({ options: comuni_options })}
|
||||
options={UnpackOptions({ options })}
|
||||
placeholder="Seleziona..."
|
||||
/>
|
||||
</FormControl>
|
||||
|
|
@ -1484,7 +1360,7 @@ export const FormNewServizioAcquisto = ({
|
|||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<div className="flex w-full items-center justify-center gap-2 pb-8 sm:justify-end">
|
||||
<div className="flex w-full flex-wrap items-center justify-center gap-2 pb-8 sm:justify-end">
|
||||
{isAdmin && (
|
||||
<FormField
|
||||
control={form.control}
|
||||
|
|
@ -1520,3 +1396,194 @@ export const FormNewServizioAcquisto = ({
|
|||
</Form>
|
||||
);
|
||||
};
|
||||
|
||||
const AziendaSection = ({
|
||||
control,
|
||||
setValue,
|
||||
}: {
|
||||
control: Control<FormNewServizioValues>;
|
||||
setValue: (
|
||||
name: keyof FormNewServizioValues,
|
||||
// biome-ignore lint/suspicious/noExplicitAny: <fine here>
|
||||
value: any,
|
||||
) => void;
|
||||
}) => {
|
||||
const { t, locale } = useTranslation();
|
||||
const azienda = useWatch({
|
||||
control,
|
||||
name: "azienda",
|
||||
});
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className={cn(
|
||||
"flex w-full flex-col items-start justify-between gap-4 sm:flex-row",
|
||||
!azienda && "hidden",
|
||||
)}
|
||||
>
|
||||
<FormField
|
||||
control={control}
|
||||
name="ragione_sociale"
|
||||
render={({ field }) => (
|
||||
<FormItem className="w-full">
|
||||
<div className="flex flex-wrap items-center gap-x-2">
|
||||
<FormLabel htmlFor="ragione_sociale">
|
||||
{t.anagrafica.ragioneSociale}
|
||||
</FormLabel>
|
||||
<FormMessage />
|
||||
</div>
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
id="ragione_sociale"
|
||||
type="text"
|
||||
value={field.value || undefined}
|
||||
/>
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={control}
|
||||
name="sede_legale"
|
||||
render={({ field }) => (
|
||||
<FormItem className="w-full">
|
||||
<div className="flex flex-wrap items-center gap-x-2">
|
||||
<FormLabel htmlFor="sede_legale">
|
||||
{t.anagrafica.sedeLegale}
|
||||
</FormLabel>
|
||||
<FormMessage />
|
||||
</div>
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
id="sede_legale"
|
||||
type="text"
|
||||
value={field.value || undefined}
|
||||
/>
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={cn(
|
||||
"flex w-full flex-col items-start justify-between gap-4 sm:flex-row",
|
||||
!azienda && "hidden",
|
||||
)}
|
||||
>
|
||||
<FormField
|
||||
control={control}
|
||||
name="p_iva"
|
||||
render={({ field }) => (
|
||||
<FormItem className="w-full">
|
||||
<div className="flex flex-wrap items-center gap-x-2">
|
||||
<FormLabel htmlFor="p_iva">{t.anagrafica.p_iva}</FormLabel>
|
||||
<FormMessage />
|
||||
</div>
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
id="p_iva"
|
||||
type="text"
|
||||
value={field.value || undefined}
|
||||
/>
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={control}
|
||||
name="legale_rappresentante"
|
||||
render={({ field }) => (
|
||||
<FormItem className="w-full">
|
||||
<div className="flex flex-wrap items-center gap-x-2">
|
||||
<FormLabel htmlFor="legale_rappresentante">
|
||||
{t.anagrafica.legale_rappresentante}
|
||||
</FormLabel>
|
||||
<FormMessage />
|
||||
</div>
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
id="legale_rappresentante"
|
||||
type="text"
|
||||
value={field.value || undefined}
|
||||
/>
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<FormField
|
||||
control={control}
|
||||
name="fatturazione_aziendale"
|
||||
render={({ field }) => (
|
||||
<FormItem className={cn("py-2", !azienda && "hidden")}>
|
||||
<div className="flex items-center justify-start gap-x-4">
|
||||
<FormLabel htmlFor="fatturazione_aziendale">
|
||||
{locale === "it"
|
||||
? "Vuoi che la fatturazione sia intestata alla tua azienda?"
|
||||
: "Do you want the invoice to be issued to your company?"}
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Switch
|
||||
checked={field.value}
|
||||
className="data-[state=checked]:bg-neutral-700"
|
||||
id="fatturazione_aziendale"
|
||||
onCheckedChange={(v) => {
|
||||
field.onChange(v);
|
||||
if (!v) {
|
||||
setValue("codice_destinatario", null);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</div>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const FatturazioneSection = ({
|
||||
control,
|
||||
}: {
|
||||
control: Control<FormNewServizioValues>;
|
||||
}) => {
|
||||
const { locale } = useTranslation();
|
||||
const fatturazione_aziendale = useWatch({
|
||||
control,
|
||||
name: "fatturazione_aziendale",
|
||||
});
|
||||
return (
|
||||
<FormField
|
||||
control={control}
|
||||
name="codice_destinatario"
|
||||
render={({ field }) => (
|
||||
<FormItem className={cn("w-full", !fatturazione_aziendale && "hidden")}>
|
||||
<div className="flex flex-wrap items-center gap-x-2">
|
||||
<FormLabel htmlFor="codice_destinatario">
|
||||
{locale === "it"
|
||||
? "Codice destinatario SDI"
|
||||
: "SDI Recipient Code"}
|
||||
</FormLabel>
|
||||
<FormMessage />
|
||||
</div>
|
||||
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
id="codice_destinatario"
|
||||
type="text"
|
||||
value={field.value || undefined}
|
||||
/>
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
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 {
|
||||
|
|
@ -26,9 +27,9 @@ import {
|
|||
} from "~/components/ui/popover";
|
||||
import { Separator } from "~/components/ui/separator";
|
||||
import { Switch } from "~/components/ui/switch";
|
||||
import { getComuniNames } from "~/i18n/comuni";
|
||||
import { getComuni } from "~/i18n/comuni";
|
||||
import { GetNazioni } from "~/i18n/nazioni";
|
||||
import { provincie } from "~/i18n/provincie";
|
||||
import { getProvinciaFromSigla, provincieWithSigla } from "~/i18n/provincie";
|
||||
import { checkFiscalCodeValidity, getComuneFieldValue } from "~/lib/form_utils";
|
||||
import { cn } from "~/lib/utils";
|
||||
import { useZodForm } from "~/lib/zodForm";
|
||||
|
|
@ -36,13 +37,7 @@ import { useTranslation } from "~/providers/I18nProvider";
|
|||
import type { UserWithAnagrafica } from "~/server/services/user.service";
|
||||
import { api } from "~/utils/api";
|
||||
|
||||
export const ProfileFormAnagrafica = ({
|
||||
userData,
|
||||
}: {
|
||||
userData: UserWithAnagrafica;
|
||||
}) => {
|
||||
const profileFormSchema = z
|
||||
.object({
|
||||
const profileFormSchema = z.object({
|
||||
azienda: z.boolean(),
|
||||
cap_residenza: z.string().optional(),
|
||||
civico_residenza: z.string().optional(),
|
||||
|
|
@ -61,8 +56,15 @@ export const ProfileFormAnagrafica = ({
|
|||
sede_legale: z.string().nullable(),
|
||||
sesso: z.string().optional(),
|
||||
via_residenza: z.string().optional(),
|
||||
})
|
||||
.superRefine(
|
||||
});
|
||||
|
||||
type ProfileFormValues = z.infer<typeof profileFormSchema>;
|
||||
export const ProfileFormAnagrafica = ({
|
||||
userData,
|
||||
}: {
|
||||
userData: UserWithAnagrafica;
|
||||
}) => {
|
||||
const schema = profileFormSchema.superRefine(
|
||||
(
|
||||
{
|
||||
data_nascita,
|
||||
|
|
@ -149,6 +151,7 @@ export const ProfileFormAnagrafica = ({
|
|||
}
|
||||
if (
|
||||
codice_fiscale &&
|
||||
codice_fiscale.length > 0 &&
|
||||
data_nascita &&
|
||||
sesso &&
|
||||
luogo_nascita &&
|
||||
|
|
@ -169,8 +172,6 @@ export const ProfileFormAnagrafica = ({
|
|||
},
|
||||
);
|
||||
|
||||
type ProfileFormValues = z.infer<typeof profileFormSchema>;
|
||||
|
||||
const defaultValues: ProfileFormValues = {
|
||||
azienda: userData.azienda || false,
|
||||
cap_residenza: userData.cap_residenza || "",
|
||||
|
|
@ -192,9 +193,10 @@ export const ProfileFormAnagrafica = ({
|
|||
via_residenza: userData.via_residenza || "",
|
||||
};
|
||||
const { locale, t } = useTranslation();
|
||||
const DatePickerLocale = locale === "it" ? it : enUS;
|
||||
z.config(z.locales[locale]());
|
||||
|
||||
const form = useZodForm(profileFormSchema, {
|
||||
const form = useZodForm(schema, {
|
||||
defaultValues: defaultValues,
|
||||
});
|
||||
|
||||
|
|
@ -220,15 +222,12 @@ export const ProfileFormAnagrafica = ({
|
|||
});
|
||||
}
|
||||
const nazioni_options = GetNazioni();
|
||||
const comuni_options = getComuniNames();
|
||||
const azienda = form.watch("azienda");
|
||||
const nazione_nascita = form.watch("nazione_nascita");
|
||||
const nazione_residenza = form.watch("nazione_residenza");
|
||||
const fatturazione_aziendale = form.watch("fatturazione_aziendale");
|
||||
const DatePickerLocale = locale === "it" ? it : enUS;
|
||||
const comuni_options = getComuni();
|
||||
|
||||
return (
|
||||
<>
|
||||
<Form {...form}>
|
||||
{/* <FormDebug control={form.control} /> */}
|
||||
<form
|
||||
className="h-full space-y-8 px-0.5"
|
||||
onSubmit={form.handleSubmit(onSubmit)}
|
||||
|
|
@ -329,7 +328,8 @@ export const ProfileFormAnagrafica = ({
|
|||
control={form.control}
|
||||
name="luogo_nascita"
|
||||
render={({ field }) => {
|
||||
if (nazione_nascita === "0") {
|
||||
if (form.watch("nazione_nascita") === "0") {
|
||||
const options = comuni_options.map((c) => c.nome);
|
||||
return (
|
||||
<FormItem className="w-full">
|
||||
<div className="flex flex-wrap items-center gap-x-2">
|
||||
|
|
@ -343,7 +343,7 @@ export const ProfileFormAnagrafica = ({
|
|||
<MultiSelect
|
||||
defaultValue={
|
||||
field.value
|
||||
? getComuneFieldValue(field.value, comuni_options)
|
||||
? getComuneFieldValue(field.value, options)
|
||||
: undefined
|
||||
}
|
||||
elementId="select-comune"
|
||||
|
|
@ -354,7 +354,7 @@ export const ProfileFormAnagrafica = ({
|
|||
await form.trigger("luogo_nascita");
|
||||
await form.trigger("codice_fiscale");
|
||||
}}
|
||||
options={UnpackOptions({ options: comuni_options })}
|
||||
options={UnpackOptions({ options })}
|
||||
placeholder="Seleziona..."
|
||||
/>
|
||||
</FormControl>
|
||||
|
|
@ -405,8 +405,9 @@ export const ProfileFormAnagrafica = ({
|
|||
elementId="select-sesso"
|
||||
elementName="sesso"
|
||||
isMulti={false}
|
||||
onValueChange={(value) => {
|
||||
onValueChange={async (value) => {
|
||||
field.onChange(value.value);
|
||||
await form.trigger("codice_fiscale");
|
||||
}}
|
||||
options={t.anagrafica.sesso_options}
|
||||
placeholder=""
|
||||
|
|
@ -469,11 +470,45 @@ export const ProfileFormAnagrafica = ({
|
|||
)}
|
||||
/>
|
||||
</div>
|
||||
{azienda && (
|
||||
<>
|
||||
<div className="flex w-full flex-col items-start justify-between gap-4 sm:flex-row">
|
||||
<FormField
|
||||
|
||||
<AziendaSection control={form.control} setValue={form.setValue} />
|
||||
<FatturazioneSection control={form.control} />
|
||||
|
||||
<Separator />
|
||||
|
||||
<ResidenzaSection
|
||||
control={form.control}
|
||||
setValue={form.setValue}
|
||||
trigger={form.trigger}
|
||||
/>
|
||||
|
||||
<Button type="submit">{t.profile.aggiorna}</Button>
|
||||
</form>
|
||||
</Form>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const AziendaSection = ({
|
||||
control,
|
||||
setValue,
|
||||
}: {
|
||||
control: Control<ProfileFormValues>;
|
||||
// biome-ignore lint/suspicious/noExplicitAny: <fine here>
|
||||
setValue: (field: keyof ProfileFormValues, value: any) => void;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const azienda = useWatch({ control, name: "azienda" });
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className={cn(
|
||||
"flex w-full flex-col items-start justify-between gap-4 sm:flex-row",
|
||||
!azienda && "hidden",
|
||||
)}
|
||||
>
|
||||
<FormField
|
||||
control={control}
|
||||
name="ragione_sociale"
|
||||
render={({ field }) => (
|
||||
<FormItem className="w-full">
|
||||
|
|
@ -495,7 +530,7 @@ export const ProfileFormAnagrafica = ({
|
|||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
control={control}
|
||||
name="sede_legale"
|
||||
render={({ field }) => (
|
||||
<FormItem className="w-full">
|
||||
|
|
@ -517,16 +552,19 @@ export const ProfileFormAnagrafica = ({
|
|||
)}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex w-full flex-col items-start justify-between gap-4 sm:flex-row">
|
||||
<div
|
||||
className={cn(
|
||||
"flex w-full flex-col items-start justify-between gap-4 sm:flex-row",
|
||||
!azienda && "hidden",
|
||||
)}
|
||||
>
|
||||
<FormField
|
||||
control={form.control}
|
||||
control={control}
|
||||
name="p_iva"
|
||||
render={({ field }) => (
|
||||
<FormItem className="w-full">
|
||||
<div className="flex flex-wrap items-center gap-x-2">
|
||||
<FormLabel htmlFor="p_iva">
|
||||
{t.anagrafica.p_iva}
|
||||
</FormLabel>
|
||||
<FormLabel htmlFor="p_iva">{t.anagrafica.p_iva}</FormLabel>
|
||||
<FormMessage />
|
||||
</div>
|
||||
<FormControl>
|
||||
|
|
@ -541,7 +579,7 @@ export const ProfileFormAnagrafica = ({
|
|||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
control={control}
|
||||
name="legale_rappresentante"
|
||||
render={({ field }) => (
|
||||
<FormItem className="w-full">
|
||||
|
|
@ -564,10 +602,10 @@ export const ProfileFormAnagrafica = ({
|
|||
/>
|
||||
</div>
|
||||
<FormField
|
||||
control={form.control}
|
||||
control={control}
|
||||
name="fatturazione_aziendale"
|
||||
render={({ field }) => (
|
||||
<FormItem className="py-2">
|
||||
<FormItem className={cn("py-2", !azienda && "hidden")}>
|
||||
<div className="flex items-center justify-start gap-x-4">
|
||||
<FormLabel htmlFor="fatturazione_aziendale">
|
||||
Vuoi che la fatturazione sia intestata alla tua azienda?
|
||||
|
|
@ -580,7 +618,7 @@ export const ProfileFormAnagrafica = ({
|
|||
onCheckedChange={(v) => {
|
||||
field.onChange(v);
|
||||
if (!v) {
|
||||
form.setValue("codice_destinatario", null);
|
||||
setValue("codice_destinatario", null);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
|
@ -590,12 +628,28 @@ export const ProfileFormAnagrafica = ({
|
|||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
{fatturazione_aziendale && (
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const FatturazioneSection = ({
|
||||
control,
|
||||
}: {
|
||||
control: Control<ProfileFormValues>;
|
||||
}) => {
|
||||
const fatturazione_aziendale = useWatch({
|
||||
control,
|
||||
name: "fatturazione_aziendale",
|
||||
});
|
||||
return (
|
||||
<>
|
||||
<FormField
|
||||
control={form.control}
|
||||
control={control}
|
||||
name="codice_destinatario"
|
||||
render={({ field }) => (
|
||||
<FormItem className="w-full">
|
||||
<FormItem
|
||||
className={cn("w-full", !fatturazione_aziendale && "hidden")}
|
||||
>
|
||||
<div className="flex flex-wrap items-center gap-x-2">
|
||||
<FormLabel htmlFor="codice_destinatario">
|
||||
Codice destinatario (SDI)
|
||||
|
|
@ -614,13 +668,37 @@ export const ProfileFormAnagrafica = ({
|
|||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
<Separator />
|
||||
);
|
||||
};
|
||||
|
||||
const ResidenzaSection = ({
|
||||
control,
|
||||
setValue,
|
||||
trigger,
|
||||
}: {
|
||||
control: Control<ProfileFormValues>;
|
||||
// biome-ignore lint/suspicious/noExplicitAny: <fine here>
|
||||
setValue: (field: keyof ProfileFormValues, value: any) => void;
|
||||
trigger: (name?: keyof ProfileFormValues) => Promise<boolean>;
|
||||
}) => {
|
||||
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 (
|
||||
<>
|
||||
<div className="flex w-full flex-col items-start justify-between gap-4 sm:flex-row">
|
||||
<FormField
|
||||
control={form.control}
|
||||
control={control}
|
||||
name="nazione_residenza"
|
||||
render={({ field }) => (
|
||||
<FormItem className="w-full">
|
||||
|
|
@ -643,9 +721,9 @@ export const ProfileFormAnagrafica = ({
|
|||
elementName="nazione"
|
||||
isMulti={false}
|
||||
onValueChange={async (value) => {
|
||||
form.setValue("provincia_residenza", "");
|
||||
setValue("provincia_residenza", "");
|
||||
field.onChange(value.value);
|
||||
await form.trigger("comune_residenza");
|
||||
await trigger("comune_residenza");
|
||||
}}
|
||||
options={UnpackOptions({ options: nazioni_options })}
|
||||
placeholder="Seleziona"
|
||||
|
|
@ -655,9 +733,12 @@ export const ProfileFormAnagrafica = ({
|
|||
/>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
control={control}
|
||||
name="provincia_residenza"
|
||||
render={({ field }) => (
|
||||
render={({ field }) => {
|
||||
const provinciaName =
|
||||
field.value && getProvinciaFromSigla(field.value);
|
||||
return (
|
||||
<FormItem className="w-full">
|
||||
<div className="flex flex-wrap items-center gap-x-2">
|
||||
<FormLabel htmlFor="provincia_residenza">
|
||||
|
|
@ -669,11 +750,11 @@ export const ProfileFormAnagrafica = ({
|
|||
{nazione_residenza === "0" ? (
|
||||
<MultiSelect
|
||||
defaultValue={
|
||||
field.value
|
||||
? RepackValues({
|
||||
options: provincie,
|
||||
values: field.value,
|
||||
})
|
||||
field.value && provinciaName
|
||||
? {
|
||||
label: provinciaName,
|
||||
value: field.value,
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
elementId="provincia_residenza"
|
||||
|
|
@ -682,7 +763,10 @@ export const ProfileFormAnagrafica = ({
|
|||
onValueChange={(value) => {
|
||||
field.onChange(value.value);
|
||||
}}
|
||||
options={UnpackOptions({ options: provincie })}
|
||||
options={provincieWithSigla.map((prov) => ({
|
||||
label: prov.nome,
|
||||
value: prov.sigla,
|
||||
}))}
|
||||
placeholder="Seleziona"
|
||||
/>
|
||||
) : (
|
||||
|
|
@ -691,15 +775,24 @@ export const ProfileFormAnagrafica = ({
|
|||
</FormControl>
|
||||
)}
|
||||
</FormItem>
|
||||
)}
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex w-full flex-col items-start justify-between gap-4 sm:flex-row">
|
||||
<FormField
|
||||
control={form.control}
|
||||
control={control}
|
||||
name="comune_residenza"
|
||||
render={({ field }) => {
|
||||
if (nazione_residenza === "0") {
|
||||
const options = comuni_options
|
||||
.filter((comune) =>
|
||||
provincia_residenza
|
||||
? comune.provincia === provincia_residenza
|
||||
: true,
|
||||
)
|
||||
.map((comune) => comune.nome);
|
||||
|
||||
return (
|
||||
<FormItem className="w-full">
|
||||
<div className="flex flex-wrap items-center gap-x-2">
|
||||
|
|
@ -713,7 +806,7 @@ export const ProfileFormAnagrafica = ({
|
|||
<MultiSelect
|
||||
defaultValue={
|
||||
field.value
|
||||
? getComuneFieldValue(field.value, comuni_options)
|
||||
? getComuneFieldValue(field.value, options)
|
||||
: undefined
|
||||
}
|
||||
elementId="select-comune"
|
||||
|
|
@ -721,9 +814,11 @@ export const ProfileFormAnagrafica = ({
|
|||
isMulti={false}
|
||||
onValueChange={async (value) => {
|
||||
field.onChange(value.value);
|
||||
await form.trigger("comune_residenza");
|
||||
await trigger("comune_residenza");
|
||||
}}
|
||||
options={UnpackOptions({ options: comuni_options })}
|
||||
options={UnpackOptions({
|
||||
options: options,
|
||||
})}
|
||||
placeholder="Seleziona..."
|
||||
/>
|
||||
</FormControl>
|
||||
|
|
@ -745,7 +840,7 @@ export const ProfileFormAnagrafica = ({
|
|||
id="comune_residenza"
|
||||
onChange={async (v) => {
|
||||
field.onChange(v.target.value);
|
||||
await form.trigger("comune_residenza");
|
||||
await trigger("comune_residenza");
|
||||
}}
|
||||
type="text"
|
||||
/>
|
||||
|
|
@ -755,14 +850,12 @@ export const ProfileFormAnagrafica = ({
|
|||
}}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
control={control}
|
||||
name="cap_residenza"
|
||||
render={({ field }) => (
|
||||
<FormItem className="w-full">
|
||||
<div className="flex flex-wrap items-center gap-x-2">
|
||||
<FormLabel htmlFor="cap_residenza">
|
||||
{t.recapiti.cap}
|
||||
</FormLabel>
|
||||
<FormLabel htmlFor="cap_residenza">{t.recapiti.cap}</FormLabel>
|
||||
|
||||
<FormMessage />
|
||||
</div>
|
||||
|
|
@ -780,7 +873,7 @@ export const ProfileFormAnagrafica = ({
|
|||
</div>
|
||||
<div className="flex w-full flex-col items-start justify-between gap-4 sm:flex-row">
|
||||
<FormField
|
||||
control={form.control}
|
||||
control={control}
|
||||
name="via_residenza"
|
||||
render={({ field }) => (
|
||||
<FormItem className="w-full">
|
||||
|
|
@ -803,7 +896,7 @@ export const ProfileFormAnagrafica = ({
|
|||
/>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
control={control}
|
||||
name="civico_residenza"
|
||||
render={({ field }) => (
|
||||
<FormItem className="w-full">
|
||||
|
|
@ -826,10 +919,6 @@ export const ProfileFormAnagrafica = ({
|
|||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Button type="submit">{t.profile.aggiorna}</Button>
|
||||
</form>
|
||||
</Form>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -24,14 +24,14 @@ const searchComune = (comune: string): Comune | null => {
|
|||
return result;
|
||||
};
|
||||
let comuniNames: string[] | null = null;
|
||||
const initializeComuniNames = () => {
|
||||
const initializeComuniNames = (provincia?: string) => {
|
||||
if (!comuniNames) {
|
||||
comuniNames = comuniArray.map((comune) => comune.NOME);
|
||||
comuniNames = comuniArray.filter((c)=> provincia ? c.SIGLA==provincia:true).map((comune) => comune.NOME);
|
||||
}
|
||||
};
|
||||
export const getComuniNames = () => {
|
||||
initializeComuniNames();
|
||||
return comuniNames!;
|
||||
export const getComuni = () => {
|
||||
|
||||
return comuniArray.map((comune) => ({nome:comune.NOME, provincia:comune.SIGLA}));
|
||||
};
|
||||
export const getComuneFromIndex = (index: number): Comune | null => {
|
||||
initializeComuniNames();
|
||||
|
|
|
|||
|
|
@ -1,112 +1,120 @@
|
|||
export const provincie = [
|
||||
"AGRIGENTO",
|
||||
"ALESSANDRIA",
|
||||
"ANCONA",
|
||||
"AOSTA",
|
||||
"AREZZO",
|
||||
"ASCOLI PICENO",
|
||||
"ASTI",
|
||||
"AVELLINO",
|
||||
"BARI",
|
||||
"BARLETTA-ANDRIA-TRANI",
|
||||
"BELLUNO",
|
||||
"BENEVENTO",
|
||||
"BERGAMO",
|
||||
"BIELLA",
|
||||
"BOLOGNA",
|
||||
"BOLZANO",
|
||||
"BRESCIA",
|
||||
"BRINDISI",
|
||||
"CAGLIARI",
|
||||
"CALTANISSETTA",
|
||||
"CAMPOBASSO",
|
||||
"CARBONIA-IGLESIAS",
|
||||
"CASERTA",
|
||||
"CATANIA",
|
||||
"CATANZARO",
|
||||
"CHIETI",
|
||||
"COMO",
|
||||
"COSENZA",
|
||||
"CREMONA",
|
||||
"CROTONE",
|
||||
"CUNEO",
|
||||
"ENNA",
|
||||
"FERMO",
|
||||
"FERRARA",
|
||||
"FIRENZE",
|
||||
"FOGGIA",
|
||||
"FORLÌ-CESENA",
|
||||
"FROSINONE",
|
||||
"GENOVA",
|
||||
"GORIZIA",
|
||||
"GROSSETO",
|
||||
"IMPERIA",
|
||||
"ISERNIA",
|
||||
"LA SPEZIA",
|
||||
"L'AQUILA",
|
||||
"LATINA",
|
||||
"LECCE",
|
||||
"LECCO",
|
||||
"LIVORNO",
|
||||
"LODI",
|
||||
"LUCCA",
|
||||
"MACERATA",
|
||||
"MANTOVA",
|
||||
"MASSA-CARRARA",
|
||||
"MATERA",
|
||||
"MESSINA",
|
||||
"MILANO",
|
||||
"MODENA",
|
||||
"MONZA E DELLA BRIANZA",
|
||||
"NAPOLI",
|
||||
"NOVARA",
|
||||
"NUORO",
|
||||
"OLBIA-TEMPIO",
|
||||
"ORISTANO",
|
||||
"PADOVA",
|
||||
"PALERMO",
|
||||
"PARMA",
|
||||
"PAVIA",
|
||||
"PERUGIA",
|
||||
"PESARO E URBINO",
|
||||
"PESCARA",
|
||||
"PIACENZA",
|
||||
"PISA",
|
||||
"PISTOIA",
|
||||
"PORDENONE",
|
||||
"POTENZA",
|
||||
"PRATO",
|
||||
"RAGUSA",
|
||||
"RAVENNA",
|
||||
"REGGIO CALABRIA",
|
||||
"REGGIO EMILIA",
|
||||
"RIETI",
|
||||
"RIMINI",
|
||||
"ROMA",
|
||||
"ROVIGO",
|
||||
"SALERNO",
|
||||
"MEDIO CAMPIDANO",
|
||||
"SASSARI",
|
||||
"SAVONA",
|
||||
"SIENA",
|
||||
"SIRACUSA",
|
||||
"SONDRIO",
|
||||
"TARANTO",
|
||||
"TERAMO",
|
||||
"TERNI",
|
||||
"TORINO",
|
||||
"OGLIASTRA",
|
||||
"TRAPANI",
|
||||
"TRENTO",
|
||||
"TREVISO",
|
||||
"TRIESTE",
|
||||
"UDINE",
|
||||
"VARESE",
|
||||
"VENEZIA",
|
||||
"VERBANO-CUSIO-OSSOLA",
|
||||
"VERCELLI",
|
||||
"VERONA",
|
||||
"VIBO VALENTIA",
|
||||
"VICENZA",
|
||||
"VITERBO",
|
||||
|
||||
export const getProvinciaFromSigla = (sigla: string): string | undefined => {
|
||||
const provincia = provincieWithSigla.find((prov) => prov.sigla === sigla);
|
||||
return provincia ? provincia.nome : undefined;
|
||||
}
|
||||
export const provincieWithSigla: {
|
||||
nome: string;
|
||||
sigla: string;
|
||||
}[] = [
|
||||
{nome: "AGRIGENTO",sigla: "AG"},
|
||||
{nome: "ALESSANDRIA",sigla: "AL"},
|
||||
{nome: "ANCONA",sigla: "AN"},
|
||||
{nome: "AOSTA",sigla: "AO"},
|
||||
{nome: "AREZZO",sigla: "AR"},
|
||||
{nome: "ASCOLI PICENO",sigla: "AP"},
|
||||
{nome: "ASTI",sigla: "AT"},
|
||||
{nome: "AVELLINO",sigla: "AV"},
|
||||
{nome: "BARI",sigla: "BA"},
|
||||
{nome: "BARLETTA-ANDRIA-TRANI",sigla: "BT"},
|
||||
{nome: "BELLUNO",sigla: "BL"},
|
||||
{nome: "BENEVENTO",sigla: "BN"},
|
||||
{nome: "BERGAMO",sigla: "BG"},
|
||||
{nome: "BIELLA",sigla: "BI"},
|
||||
{nome: "BOLOGNA",sigla: "BO"},
|
||||
{nome: "BOLZANO",sigla: "BZ"},
|
||||
{nome: "BRESCIA",sigla: "BS"},
|
||||
{nome: "BRINDISI",sigla: "BR"},
|
||||
{nome: "CAGLIARI",sigla: "CA"},
|
||||
{nome: "CALTANISSETTA",sigla: "CL"},
|
||||
{nome: "CAMPOBASSO",sigla: "CB"},
|
||||
{nome: "CARBONIA-IGLESIAS",sigla: "CI"},
|
||||
{nome: "CASERTA",sigla: "CE"},
|
||||
{nome: "CATANIA",sigla: "CT"},
|
||||
{nome: "CATANZARO",sigla: "CZ"},
|
||||
{nome: "CHIETI",sigla: "CH"},
|
||||
{nome: "COMO",sigla: "CO"},
|
||||
{nome: "COSENZA",sigla: "CS"},
|
||||
{nome: "CREMONA",sigla: "CR"},
|
||||
{nome: "CROTONE",sigla: "KR"},
|
||||
{nome: "CUNEO",sigla: "CN"},
|
||||
{nome: "ENNA",sigla: "EN"},
|
||||
{nome: "FERMO",sigla: "FM"},
|
||||
{nome: "FERRARA",sigla: "FE"},
|
||||
{nome: "FIRENZE",sigla: "FI"},
|
||||
{nome: "FOGGIA",sigla: "FG"},
|
||||
{nome: "FORLÌ-CESENA",sigla: "FC"},
|
||||
{nome: "FROSINONE",sigla: "FR"},
|
||||
{nome: "GENOVA",sigla: "GE"},
|
||||
{nome: "GORIZIA",sigla: "GO"},
|
||||
{nome: "GROSSETO",sigla: "GR"},
|
||||
{nome: "IMPERIA",sigla: "IM"},
|
||||
{nome: "ISERNIA",sigla: "IS"},
|
||||
{nome: "LA SPEZIA",sigla: "SP"},
|
||||
{nome: "L'AQUILA",sigla: "AQ"},
|
||||
{nome: "LATINA",sigla: "LT"},
|
||||
{nome: "LECCE",sigla: "LE"},
|
||||
{nome: "LECCO",sigla: "LC"},
|
||||
{nome: "LIVORNO",sigla: "LI"},
|
||||
{nome: "LODI",sigla: "LO"},
|
||||
{nome: "LUCCA",sigla: "LU"},
|
||||
{nome: "MACERATA",sigla: "MC"},
|
||||
{nome: "MANTOVA",sigla: "MN"},
|
||||
{nome: "MASSA-CARRARA",sigla: "MS"},
|
||||
{nome: "MATERA",sigla: "MT"},
|
||||
{nome: "MESSINA",sigla: "ME"},
|
||||
{nome: "MILANO",sigla: "MI"},
|
||||
{nome: "MODENA",sigla: "MO"},
|
||||
{nome: "MONZA E DELLA BRIANZA",sigla: "MB"},
|
||||
{nome: "NAPOLI",sigla: "NA"},
|
||||
{nome: "NOVARA",sigla: "NO"},
|
||||
{nome: "NUORO",sigla: "NU"},
|
||||
{nome: "OLBIA-TEMPIO",sigla: "OT"},
|
||||
{nome: "ORISTANO",sigla: "OR"},
|
||||
{nome: "PADOVA",sigla: "PD"},
|
||||
{nome: "PALERMO",sigla: "PA"},
|
||||
{nome: "PARMA",sigla: "PR"},
|
||||
{nome: "PAVIA",sigla: "PV"},
|
||||
{nome: "PERUGIA",sigla: "PG"},
|
||||
{nome: "PESARO E URBINO",sigla: "PU"},
|
||||
{nome: "PESCARA",sigla: "PE"},
|
||||
{nome: "PIACENZA",sigla: "PC"},
|
||||
{nome: "PISA",sigla: "PI"},
|
||||
{nome: "PISTOIA",sigla: "PT"},
|
||||
{nome: "PORDENONE",sigla: "PN"},
|
||||
{nome: "POTENZA",sigla: "PZ"},
|
||||
{nome: "PRATO",sigla: "PO"},
|
||||
{nome: "RAGUSA",sigla: "RG"},
|
||||
{nome: "RAVENNA",sigla: "RA"},
|
||||
{nome: "REGGIO CALABRIA",sigla: "RC"},
|
||||
{nome: "REGGIO EMILIA",sigla: "RE"},
|
||||
{nome: "RIETI",sigla: "RI"},
|
||||
{nome: "RIMINI",sigla: "RN"},
|
||||
{nome: "ROMA",sigla: "RM"},
|
||||
{nome: "ROVIGO",sigla: "RO"},
|
||||
{nome: "SALERNO",sigla: "SA"},
|
||||
{nome: "MEDIO CAMPIDANO",sigla: "VS"},
|
||||
{nome: "SASSARI",sigla: "SS"},
|
||||
{nome: "SAVONA",sigla: "SV"},
|
||||
{nome: "SIENA",sigla: "SI"},
|
||||
{nome: "SIRACUSA",sigla: "SR"},
|
||||
{nome: "SONDRIO",sigla: "SO"},
|
||||
{nome: "TARANTO",sigla: "TA"},
|
||||
{nome: "TERAMO",sigla: "TE"},
|
||||
{nome: "TERNI",sigla: "TR"},
|
||||
{nome: "TORINO",sigla: "TO"},
|
||||
{nome: "OGLIASTRA",sigla: "OG"},
|
||||
{nome: "TRAPANI",sigla: "TP"},
|
||||
{nome: "TRENTO",sigla: "TN"},
|
||||
{nome: "TREVISO",sigla: "TV"},
|
||||
{nome: "TRIESTE",sigla: "TS"},
|
||||
{nome: "UDINE",sigla: "UD"},
|
||||
{nome: "VARESE",sigla: "VA"},
|
||||
{nome: "VENEZIA",sigla: "VE"},
|
||||
{nome: "VERBANO-CUSIO-OSSOLA",sigla: "VB"},
|
||||
{nome: "VERCELLI",sigla: "VC"},
|
||||
{nome: "VERONA",sigla: "VR"},
|
||||
{nome: "VIBO VALENTIA",sigla: "VV"},
|
||||
{nome: "VICENZA",sigla: "VI"},
|
||||
{nome: "VITERBO",sigla: "VT"}
|
||||
];
|
||||
|
|
@ -1,8 +1,17 @@
|
|||
import dynamic from "next/dynamic";
|
||||
import type { z } from "zod/v4";
|
||||
import type { ListOption } from "~/components/custom_ui/multiselect";
|
||||
import { getComuneFromIndex } from "~/i18n/comuni";
|
||||
import { searchNazioneByIndex } from "~/i18n/nazioni";
|
||||
|
||||
export const FormDebug: React.ElementType =
|
||||
process.env.NODE_ENV === "development"
|
||||
? dynamic(
|
||||
() => import("@hookform/devtools").then((module) => module.DevTool),
|
||||
{ ssr: false },
|
||||
)
|
||||
: () => null; // Return null component in production
|
||||
|
||||
export const getComuneFieldValue = (
|
||||
fieldValue: string,
|
||||
comuni_options: string[],
|
||||
|
|
@ -183,8 +192,8 @@ export const checkFiscalCodeValidity = ({
|
|||
gen !== codiceFiscale.slice(0, 15) &&
|
||||
!(codiceFiscale in getAlternativeCF(gen))
|
||||
) {
|
||||
console.log("gen", gen);
|
||||
console.log("codiceFiscale", codiceFiscale);
|
||||
//console.log("gen", gen);
|
||||
//console.log("codiceFiscale", codiceFiscale);
|
||||
console.log("alternative", getAlternativeCF(gen));
|
||||
refinementContext.issues.push({
|
||||
code: "custom",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue