2025-08-28 18:27:07 +02:00
import { format } from "date-fns" ;
import { it } from "date-fns/locale" ;
2025-10-15 15:45:24 +02:00
import {
CalendarIcon ,
2025-10-17 19:14:27 +02:00
CodeSquare ,
2025-10-15 15:45:24 +02:00
Eye ,
Printer ,
2025-10-17 19:14:27 +02:00
RefreshCcw ,
2025-10-15 15:45:24 +02:00
RotateCw ,
TriangleAlert ,
} from "lucide-react" ;
2025-08-28 18:27:07 +02:00
import Link from "next/link" ;
import toast from "react-hot-toast" ;
2025-08-28 13:19:43 +02:00
import z from "zod" ;
2025-08-28 18:27:07 +02:00
import { CarouselAnnuncio } from "~/components/annuncio_card" ;
2025-10-15 15:45:24 +02:00
import { Confirm } from "~/components/confirm" ;
2025-08-28 13:19:43 +02:00
import {
2025-08-28 18:27:07 +02:00
Form ,
FormControl ,
FormField ,
FormItem ,
FormLabel ,
FormMessage ,
2025-08-28 13:19:43 +02:00
} from "~/components/custom_ui/form" ;
2025-11-14 17:21:21 +01:00
import { NumberInput } from "~/components/custom_ui/InputNumber" ;
2025-08-28 18:27:07 +02:00
import Input from "~/components/custom_ui/input" ;
2025-08-28 13:19:43 +02:00
import { DualInputLayout } from "~/components/custom_ui/inputLayouts" ;
import {
2025-08-28 18:27:07 +02:00
type ListOption ,
MultiSelect ,
2025-08-28 13:19:43 +02:00
} from "~/components/custom_ui/multiselect" ;
2025-08-28 18:27:07 +02:00
import { Textarea } from "~/components/custom_ui/textarea" ;
import { PhoneInput } from "~/components/phone-input" ;
2025-08-28 13:19:43 +02:00
import { Button } from "~/components/ui/button" ;
2025-08-28 18:27:07 +02:00
import { Calendar } from "~/components/ui/calendar" ;
2025-08-28 13:19:43 +02:00
import { Card , CardContent , CardHeader , CardTitle } from "~/components/ui/card" ;
2025-08-28 18:27:07 +02:00
import {
Popover ,
PopoverContent ,
PopoverTrigger ,
} from "~/components/ui/popover" ;
import { Switch } from "~/components/ui/switch" ;
2025-08-28 13:19:43 +02:00
import { Tabs , TabsContent , TabsList , TabsTrigger } from "~/components/ui/tabs" ;
2025-08-28 18:27:07 +02:00
import { filteredCaratteristiche } from "~/hooks/schedaAnnuncioUtils" ;
2025-08-28 13:19:43 +02:00
import { cn } from "~/lib/utils" ;
2025-08-28 18:27:07 +02:00
import { useZodForm } from "~/lib/zodForm" ;
import { StatusBadge } from "~/pages/area-riservata/admin/edit-annuncio/[id]" ;
import { useTranslation } from "~/providers/I18nProvider" ;
2025-11-18 15:20:14 +01:00
import type { AnnunciWithMedia } from "~/server/controllers/annunci.controller" ;
2025-08-28 18:27:07 +02:00
import { zAnnuncioId } from "~/server/utils/zod_types" ;
import { api } from "~/utils/api" ;
import type { Caratteristiche } from "~/utils/kanel-types" ;
2025-08-28 13:19:43 +02:00
2025-11-18 15:20:14 +01:00
export const AnnuncioEditForm = ( { data } : { data : AnnunciWithMedia } ) = > {
2025-08-28 18:27:07 +02:00
const schema = z . object ( {
2025-08-29 16:18:32 +02:00
accessori : z.string ( ) . array ( ) . nullable ( ) ,
2025-08-28 18:27:07 +02:00
2025-08-29 16:18:32 +02:00
// ALTRI DATI IMMOBILE
anno : z.string ( ) . nullable ( ) ,
cap : z.string ( ) . nullable ( ) ,
caratteristiche : z.custom < Caratteristiche > ( ) . nullable ( ) ,
categorie : z.string ( ) . array ( ) . nullable ( ) ,
civico : z.string ( ) . nullable ( ) ,
civico_secondario : z.string ( ) . nullable ( ) ,
classe : z.string ( ) . nullable ( ) ,
codice : z.string ( ) ,
comune : z.string ( ) . nullable ( ) ,
consegna : z.number ( ) . nullable ( ) ,
desc_en : z.string ( ) . nullable ( ) ,
desc_it : z.string ( ) . nullable ( ) ,
disponibile_da : z.date ( ) . nullable ( ) ,
2025-08-28 18:27:07 +02:00
email : z.email ( ) . optional ( ) ,
2025-08-29 16:18:32 +02:00
homepage : z.boolean ( ) . nullable ( ) ,
//BASE
id : zAnnuncioId ,
2025-08-28 18:27:07 +02:00
// DATI IMMOBILE
indirizzo : z.string ( ) . nullable ( ) ,
indirizzo_secondario : z.string ( ) . nullable ( ) ,
2025-08-29 16:18:32 +02:00
lat : z.string ( ) . nullable ( ) ,
2025-08-28 18:27:07 +02:00
lat_secondario : z.string ( ) . nullable ( ) ,
2025-08-29 16:18:32 +02:00
// DATI LOCATORE
locatore : z.string ( ) . nullable ( ) ,
lon : z.string ( ) . nullable ( ) ,
lon_secondario : z.string ( ) . nullable ( ) ,
2025-11-25 12:05:14 +01:00
mq : z.number ( ) . nullable ( ) ,
2025-08-29 16:18:32 +02:00
numero : z.string ( ) . nullable ( ) ,
2025-08-28 18:27:07 +02:00
numero_bagni : z.number ( ) . nullable ( ) ,
numero_balconi : z.number ( ) . nullable ( ) ,
numero_box : z.number ( ) . nullable ( ) ,
2025-08-29 16:18:32 +02:00
numero_camere : z.number ( ) . nullable ( ) ,
2025-08-28 18:27:07 +02:00
numero_postiauto : z.number ( ) . nullable ( ) ,
2025-08-29 16:18:32 +02:00
numero_terrazzi : z.number ( ) . nullable ( ) ,
numero_vani : z.number ( ) . nullable ( ) ,
permanenza : z.number ( ) . array ( ) . nullable ( ) ,
persone : z.string ( ) . array ( ) . nullable ( ) ,
piano : z.string ( ) . nullable ( ) ,
piano_palazzo : z.number ( ) . nullable ( ) ,
prezzo : z.number ( ) ,
provincia : z.string ( ) . nullable ( ) ,
regione : z.string ( ) . nullable ( ) ,
stato : z.string ( ) . nullable ( ) ,
// DATI CONTRATTO
tipo : z.string ( ) . nullable ( ) ,
titolo_en : z.string ( ) . nullable ( ) ,
titolo_it : z.string ( ) . nullable ( ) ,
unita_condominio : z.number ( ) . nullable ( ) ,
web : z.boolean ( ) . nullable ( ) ,
2025-08-28 18:27:07 +02:00
// MEDIA
//url_immagini: z.string().array().nullable(),
//url_video: z.string().array().nullable(),
//og_url: z.string().nullable(),
//creato_il: z.date().nullable(),
//modificato_il: z.date().nullable(),
} ) ;
type FormValues = z . infer < typeof schema > ;
const { locale } = useTranslation ( ) ;
const utils = api . useUtils ( ) ;
const { mutate : edit } = api . annunci . editAnnuncio . useMutation ( {
onSettled : async ( ) = > {
await utils . annunci . getAnnuncio . invalidate ( { cod : data.codice } ) ;
2025-08-29 18:18:37 +02:00
await utils . annunci . getAnnuncioById_rawImgUrls . invalidate ( {
id : data.id ,
} ) ;
2025-08-28 18:27:07 +02:00
await utils . annunci . getAnnunciList . invalidate ( ) ;
toast . success ( "Annuncio modificato con successo" ) ;
} ,
} ) ;
2025-10-15 15:45:24 +02:00
const { mutateAsync : revalidate } =
2025-11-20 12:38:42 +01:00
api . revalidation . revalidateAnnuncio . useMutation ( {
2025-10-15 15:45:24 +02:00
onSettled : async ( ) = > {
2025-10-17 19:48:28 +02:00
await utils . annunci . getAnnuncio . invalidate ( { cod : data.codice } ) ;
await utils . annunci . getAnnuncioById_rawImgUrls . invalidate ( {
id : data.id ,
} ) ;
2025-10-17 19:14:27 +02:00
toast . success ( "Revalidazione completata" ) ;
2025-10-15 15:45:24 +02:00
} ,
} ) ;
2025-11-20 12:38:42 +01:00
const { mutateAsync : update } = api . revalidation . updateAnnuncio . useMutation ( {
2025-10-17 19:14:27 +02:00
onSettled : async ( ) = > {
2025-10-17 19:48:28 +02:00
await utils . annunci . getAnnuncio . invalidate ( { cod : data.codice } ) ;
await utils . annunci . getAnnuncioById_rawImgUrls . invalidate ( {
id : data.id ,
} ) ;
2025-10-17 19:14:27 +02:00
toast . success (
"L'aggiornamento dell'annuncio è stata richiesta con successo,\n potrebbero volerci alcuni minuti prima che le modifiche siano visibili." ,
{
duration : 5000 ,
} ,
) ;
} ,
} ) ;
2025-08-28 18:27:07 +02:00
const defaultValues : FormValues = {
. . . data ,
2025-12-03 14:51:39 +01:00
mq : Number ( data . mq ) || null ,
2025-08-28 18:27:07 +02:00
email : data.email || undefined ,
} ;
z . config ( z . locales [ locale ] ( ) ) ;
const form = useZodForm ( schema , {
defaultValues : defaultValues ,
} ) ;
function onSubmit ( fields : FormValues ) {
edit ( {
annuncioId : data.id ,
data : { . . . fields , email : fields.email || null } ,
} ) ;
}
const personeOptions : ListOption [ ] = [
"single" ,
"coppia" ,
"colleghi" ,
"famiglia" ,
] . map ( ( p ) = > ( {
label : p ,
2025-08-29 16:18:32 +02:00
value : p ,
2025-08-28 18:27:07 +02:00
} ) ) ;
const permanenzaOptions : ListOption [ ] = [
2025-08-29 16:18:32 +02:00
{ label : "1 mese" , value : "1" } ,
{ label : "3 mesi" , value : "3" } ,
{ label : "6 mesi" , value : "6" } ,
{ label : "9 mesi" , value : "9" } ,
{ label : "12 mesi" , value : "12" } ,
{ label : "18 mesi" , value : "18" } ,
{ label : "24 mesi" , value : "24" } ,
2025-08-28 18:27:07 +02:00
] ;
const tipoOptions : ListOption [ ] = [
"Transitorio" ,
"Stabile" ,
"Vendita" ,
"Cessione" ,
"Errore" ,
2025-08-29 16:18:32 +02:00
] . map ( ( o ) = > ( { label : o , value : o } ) ) ;
2025-08-28 18:27:07 +02:00
const statoOptions = [ "Attivo" , "Sospeso" , "Trattativa" ] . map ( ( o ) = > ( {
label : o ,
2025-08-29 16:18:32 +02:00
value : o ,
2025-08-28 18:27:07 +02:00
} ) ) ;
const consegnaOptions : ListOption [ ] = [
2025-08-29 16:18:32 +02:00
{ label : "Gennaio" , value : "1" } ,
{ label : "Febbraio" , value : "2" } ,
{ label : "Marzo" , value : "3" } ,
{ label : "Aprile" , value : "4" } ,
{ label : "Maggio" , value : "5" } ,
{ label : "Giugno" , value : "6" } ,
{ label : "Luglio" , value : "7" } ,
{ label : "Agosto" , value : "8" } ,
{ label : "Settembre" , value : "9" } ,
{ label : "Ottobre" , value : "10" } ,
{ label : "Novembre" , value : "11" } ,
{ label : "Dicembre" , value : "12" } ,
2025-08-28 18:27:07 +02:00
] ;
return (
< >
< Form { ...form } >
< form
className = "mt-3 grid flex-1 items-start gap-4 p-2 sm:px-4 sm:py-0 md:gap-8"
2025-08-29 16:18:32 +02:00
onSubmit = { form . handleSubmit ( onSubmit ) }
2025-08-28 18:27:07 +02:00
>
2025-11-12 15:52:04 +01:00
< div className = "mx-auto grid w-full flex-1 auto-rows-max gap-4" >
2025-10-17 19:14:27 +02:00
< div className = "flex flex-col gap-2" >
< div className = "flex flex-wrap items-center gap-2" >
< h1 className = "whitespace-nowrap font-semibold text-2xl tracking-tight" >
Annuncio { data . codice }
< / h1 >
< StatusBadge status = { data . stato } / >
2025-11-06 13:17:20 +01:00
< span > { data . media_updated_at ? . toLocaleString ( "it-IT" ) } < / span >
2025-10-17 19:14:27 +02:00
< div className = "ml-auto flex items-center gap-2" >
< Button className = "bg-green-500" size = "sm" type = "submit" >
Salva
< / Button >
< / div >
< / div >
< div className = "flex flex-wrap items-center gap-2" >
< Link href = { ` /annuncio/ ${ data . codice } ` } target = "_blank" >
2025-11-03 10:59:45 +01:00
< Button size = "sm" type = "button" variant = "outline" >
2025-10-17 19:14:27 +02:00
< Eye / > pubblica
< / Button >
< / Link >
< Link
href = { ` /area-riservata/admin/scheda-annuncio-stampa/ ${ data . id } ` }
target = "_blank"
2025-10-15 15:45:24 +02:00
>
2025-11-03 10:59:45 +01:00
< Button size = "sm" type = "button" variant = "outline" >
2025-10-17 19:14:27 +02:00
< Printer / > Scheda
< / Button >
< / Link >
< Popover >
< PopoverTrigger asChild >
2025-11-03 10:59:45 +01:00
< Button size = "sm" type = "button" >
2025-10-17 19:14:27 +02:00
< CodeSquare / > Strumenti
< / Button >
< / PopoverTrigger >
< PopoverContent className = "flex w-fit items-center gap-2" >
< Button
2025-11-03 10:59:45 +01:00
className = "bg-purple-500"
2025-10-17 19:14:27 +02:00
onClick = { async ( ) = > {
await revalidate ( {
cod : data.codice ,
} ) ;
} }
size = "sm"
type = "button"
>
< RefreshCcw / > Rigenera pagina
< / Button >
< Confirm
description = "Sei sicuro di voler richiedere l'aggiornamento dell'annuncio? Questa operazione potrebbe richiedere alcuni minuti prima che le modifiche siano visibili e resetterà eventuali modifiche effettuate dopo la sincronizzazione giornaliera."
onConfirm = { async ( ) = > {
await update ( { cod : data.codice } ) ;
} }
title = "Aggiornamento Annuncio"
>
2025-11-03 10:59:45 +01:00
< Button size = "sm" type = "button" variant = "warning" >
2025-10-17 19:14:27 +02:00
< TriangleAlert / > Aggiorna
< / Button >
< / Confirm >
< / PopoverContent >
< / Popover >
2025-08-28 18:27:07 +02:00
< / div >
< / div >
< div className = "grid h-max gap-3 md:grid-cols-[1fr_250px] lg:grid-cols-3" >
< div className = "h-full items-start gap-3 lg:col-span-2" >
< Card className = "h-full py-4" >
< CardContent className = "h-full w-full grow px-4" >
< Tabs defaultValue = "ita" >
< TabsList className = "grid h-full w-full grid-cols-2" >
< TabsTrigger value = "ita" > Italiano < / TabsTrigger >
< TabsTrigger value = "eng" > Inglese < / TabsTrigger >
< / TabsList >
< TabsContent value = "ita" >
< Card >
< CardHeader >
< CardTitle > Descrizione ITA < / CardTitle >
< / CardHeader >
< CardContent >
< div className = "grid gap-6" >
< div className = "grid gap-3" >
< FormField
control = { form . control }
name = "titolo_it"
render = { ( { field } ) = > (
< FormItem >
< div className = "flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "titolo_it" >
Titolo ITA
< / FormLabel >
< FormMessage / >
< / div >
< FormControl >
< Input
placeholder = ""
{ . . . field }
id = "titolo_it"
value = { field . value || undefined }
/ >
< / FormControl >
< / FormItem >
) }
/ >
< / div >
< div className = "grid gap-3" >
< FormField
control = { form . control }
name = "desc_it"
render = { ( { field } ) = > (
< FormItem >
< div className = "flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "desc_it" >
Descrizione ITA
< / FormLabel >
< FormMessage / >
< / div >
< FormControl >
< Textarea
className = "min-h-64"
2025-08-29 16:18:32 +02:00
placeholder = ""
2025-08-28 18:27:07 +02:00
{ . . . field }
id = "desc_it"
value = { field . value || undefined }
/ >
< / FormControl >
< / FormItem >
) }
/ >
< / div >
< / div >
< / CardContent >
< / Card >
< / TabsContent >
< TabsContent value = "eng" >
< Card >
< CardHeader >
< CardTitle > Descrizione ENG < / CardTitle >
< / CardHeader >
< CardContent >
< div className = "grid gap-6" >
< div className = "grid gap-3" >
< FormField
control = { form . control }
name = "titolo_en"
render = { ( { field } ) = > (
< FormItem >
< div className = "flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "titolo_en" >
Titolo ENG
< / FormLabel >
< FormMessage / >
< / div >
< FormControl >
< Input
placeholder = ""
{ . . . field }
id = "titolo_en"
value = { field . value || undefined }
/ >
< / FormControl >
< / FormItem >
) }
/ >
< / div >
< div className = "grid gap-3" >
< FormField
control = { form . control }
name = "desc_en"
render = { ( { field } ) = > (
< FormItem >
< div className = "flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "desc_en" >
Descrizione ENG
< / FormLabel >
< FormMessage / >
< / div >
< FormControl >
< Textarea
className = "min-h-64"
2025-08-29 16:18:32 +02:00
placeholder = ""
2025-08-28 18:27:07 +02:00
{ . . . field }
id = "desc_en"
value = { field . value || undefined }
/ >
< / FormControl >
< / FormItem >
) }
/ >
< / div >
< / div >
< / CardContent >
< / Card >
< / TabsContent >
< / Tabs >
< / CardContent >
< / Card >
< / div >
< div className = "grid auto-rows-max items-start gap-3 lg:gap-8" >
< Card >
< CardHeader >
< CardTitle > Status Annuncio < / CardTitle >
< / CardHeader >
< CardContent className = "space-y-2" >
< FormField
control = { form . control }
name = "stato"
render = { ( { field } ) = > (
< FormItem >
< div className = "flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "select-stato" > Stato < / FormLabel > { " " }
< FormMessage / >
< / div >
< FormControl >
< MultiSelect
defaultValue = {
field . value
? statoOptions . filter ( ( o ) = >
field . value ? . includes ( o . value ) ,
)
: undefined
}
2025-08-29 16:18:32 +02:00
elementId = "select-stato"
elementName = "stato"
isMulti = { false }
2025-08-28 18:27:07 +02:00
onValueChange = { async ( value ) = > {
field . onChange ( value . value ) ;
} }
2025-08-29 16:18:32 +02:00
options = { statoOptions }
2025-08-28 18:27:07 +02:00
placeholder = "Seleziona..."
/ >
< / FormControl >
< / FormItem >
) }
/ >
< FormField
control = { form . control }
name = "web"
render = { ( { field } ) = > (
< FormItem className = "mt-6 w-full px-4" >
< div className = "flex w-full items-center justify-between gap-x-4" >
< FormLabel htmlFor = "web" > Web < / FormLabel >
< FormControl >
< Switch
checked = { field . value || false }
className = "data-[state=checked]:bg-neutral-700"
2025-08-29 16:18:32 +02:00
id = "web"
onCheckedChange = { field . onChange }
2025-08-28 18:27:07 +02:00
/ >
< / FormControl >
< FormMessage / >
< / div >
< / FormItem >
) }
/ >
< FormField
control = { form . control }
name = "homepage"
render = { ( { field } ) = > (
< FormItem className = "mt-6 w-full px-4" >
< div className = "flex items-center justify-between gap-x-4" >
< FormLabel htmlFor = "homepage" > Homepage < / FormLabel >
< FormControl >
< Switch
checked = { field . value || false }
className = "data-[state=checked]:bg-neutral-700"
2025-08-29 16:18:32 +02:00
id = "homepage"
onCheckedChange = { field . onChange }
2025-08-28 18:27:07 +02:00
/ >
< / FormControl >
< FormMessage / >
< / div >
< / FormItem >
) }
/ >
< / CardContent >
< / Card >
< Card className = "overflow-hidden" >
< CardHeader >
< CardTitle > Imagini Annuncio < / CardTitle >
< / CardHeader >
< CardContent >
2025-09-01 15:59:08 +02:00
< CarouselAnnuncio
2025-11-18 15:20:14 +01:00
immagini = { data . images }
2025-09-01 15:59:08 +02:00
single
2025-11-06 13:17:20 +01:00
updated_at = { data . media_updated_at }
2025-11-18 15:20:14 +01:00
videos = { data . videos }
2025-09-01 15:59:08 +02:00
/ >
2025-08-28 18:27:07 +02:00
< / CardContent >
< / Card >
< / div >
< / div >
< Card >
< CardHeader >
< CardTitle > Dati di contatto < / CardTitle >
< / CardHeader >
< CardContent className = "space-y-4" >
< FormField
control = { form . control }
name = "locatore"
render = { ( { field } ) = > (
< FormItem >
< div className = "flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "locatore" >
Locatore o incaricato
< / FormLabel >
< FormMessage / >
< / div >
< FormControl >
< Input
placeholder = ""
{ . . . field }
id = "locatore"
onChange = { ( e ) = >
field . onChange ( e . target . value || null )
}
2025-08-29 16:18:32 +02:00
value = { field . value || undefined }
2025-08-28 18:27:07 +02:00
/ >
< / FormControl >
< / FormItem >
) }
/ >
< DualInputLayout
children1 = {
< FormField
control = { form . control }
name = "email"
render = { ( { field } ) = > (
< FormItem >
< div className = "flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "email" > Email < / FormLabel > { " " }
< FormMessage / >
< / div >
< FormControl >
< Input
placeholder = "esempio@email.com"
{ . . . field }
id = "email"
onChange = { ( e ) = >
field . onChange (
e . target . value && e . target . value !== ""
? e . target . value
: null ,
)
}
2025-08-29 16:18:32 +02:00
value = { field . value || undefined }
2025-08-28 18:27:07 +02:00
/ >
< / FormControl >
< / FormItem >
) }
/ >
}
children2 = {
< FormField
control = { form . control }
name = "numero"
render = { ( { field } ) = > (
< FormItem >
< div className = "flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "numero" > Telefono < / FormLabel >
< FormMessage / >
< / div >
< FormControl >
< PhoneInput
{ . . . field }
id = "numero"
onChange = { ( n ) = > field . onChange ( n || null ) }
2025-08-29 16:18:32 +02:00
value = { field . value || undefined }
2025-08-28 18:27:07 +02:00
/ >
< / FormControl >
< / FormItem >
) }
/ >
}
/ >
< p >
Indirizo : { data . indirizzo } , { data . civico } { data . comune } (
{ data . provincia } )
< / p >
< / CardContent >
< / Card >
< Card >
< CardHeader >
< CardTitle > Dati Immobile < / CardTitle >
< / CardHeader >
< CardContent className = "space-y-4" >
< DualInputLayout
children1 = {
< FormField
control = { form . control }
name = "indirizzo"
render = { ( { field } ) = > (
< FormItem >
< div className = "flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "indirizzo" > Indirizzo < / FormLabel > { " " }
< FormMessage / >
< / div >
< FormControl >
< Input
placeholder = ""
{ . . . field }
id = "indirizzo"
value = { field . value || undefined }
/ >
< / FormControl >
< / FormItem >
) }
/ >
}
children2 = {
< FormField
control = { form . control }
name = "civico"
render = { ( { field } ) = > (
< FormItem >
< div className = "flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "civico" > Civico < / FormLabel >
< FormMessage / >
< / div >
< FormControl >
< Input
placeholder = ""
{ . . . field }
id = "civico"
value = { field . value || undefined }
/ >
< / FormControl >
< / FormItem >
) }
/ >
}
/ >
< DualInputLayout
children1 = {
< FormField
control = { form . control }
name = "comune"
render = { ( { field } ) = > (
< FormItem >
< div className = "flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "comune" > Comune < / FormLabel > { " " }
< FormMessage / >
< / div >
< FormControl >
< Input
placeholder = ""
{ . . . field }
id = "comune"
value = { field . value || undefined }
/ >
< / FormControl >
< / FormItem >
) }
/ >
}
children2 = {
< FormField
control = { form . control }
name = "cap"
render = { ( { field } ) = > (
< FormItem >
< div className = "flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "cap" > Cap < / FormLabel >
< FormMessage / >
< / div >
< FormControl >
< Input
placeholder = ""
{ . . . field }
id = "cap"
value = { field . value || undefined }
/ >
< / FormControl >
< / FormItem >
) }
/ >
}
/ >
< DualInputLayout
children1 = {
< FormField
control = { form . control }
name = "provincia"
render = { ( { field } ) = > (
< FormItem >
< div className = "flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "provincia" > Provincia < / FormLabel > { " " }
< FormMessage / >
< / div >
< FormControl >
< Input
placeholder = ""
{ . . . field }
id = "provincia"
value = { field . value || undefined }
/ >
< / FormControl >
< / FormItem >
) }
/ >
}
children2 = {
< FormField
control = { form . control }
name = "regione"
render = { ( { field } ) = > (
< FormItem >
< div className = "flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "regione" > Regione < / FormLabel >
< FormMessage / >
< / div >
< FormControl >
< Input
placeholder = ""
{ . . . field }
id = "regione"
value = { field . value || undefined }
/ >
< / FormControl >
< / FormItem >
) }
/ >
}
/ >
< DualInputLayout
children1 = {
< FormField
control = { form . control }
name = "lat"
render = { ( { field } ) = > (
< FormItem >
< div className = "flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "lat" > Lat < / FormLabel > { " " }
< FormMessage / >
< / div >
< FormControl >
< Input
placeholder = ""
{ . . . field }
id = "lat"
value = { field . value || undefined }
/ >
< / FormControl >
< / FormItem >
) }
/ >
}
children2 = {
< FormField
control = { form . control }
name = "lon"
render = { ( { field } ) = > (
< FormItem >
< div className = "flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "lon" > Lon < / FormLabel >
< FormMessage / >
< / div >
< FormControl >
< Input
placeholder = ""
{ . . . field }
id = "lon"
value = { field . value || undefined }
/ >
< / FormControl >
< / FormItem >
) }
/ >
}
/ >
< p >
< Link
href = { ` https://www.google.com/maps/place/ ${ form . getValues ( "lat" ) } , ${ form . getValues ( "lon" ) } ` }
target = "_blank"
>
🗺 ️ < span className = "underline" > Vedi su maps < / span >
< / Link >
< / p >
< DualInputLayout
children1 = {
< FormField
control = { form . control }
name = "indirizzo_secondario"
render = { ( { field } ) = > (
< FormItem >
< div className = "flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "indirizzo_secondario" >
Indirizzo Secondario
< / FormLabel > { " " }
< FormMessage / >
< / div >
< FormControl >
< Input
placeholder = ""
{ . . . field }
id = "indirizzo_secondario"
value = { field . value || undefined }
/ >
< / FormControl >
< / FormItem >
) }
/ >
}
children2 = {
< FormField
control = { form . control }
name = "civico_secondario"
render = { ( { field } ) = > (
< FormItem >
< div className = "flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "civico_secondario" >
Civico Secondario
< / FormLabel >
< FormMessage / >
< / div >
< FormControl >
< Input
placeholder = ""
{ . . . field }
id = "civico_secondario"
value = { field . value || undefined }
/ >
< / FormControl >
< / FormItem >
) }
/ >
}
/ >
< DualInputLayout
children1 = {
< FormField
control = { form . control }
name = "lat_secondario"
render = { ( { field } ) = > (
< FormItem >
< div className = "flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "lat_secondario" >
Lat Secondario
< / FormLabel >
< FormMessage / >
< / div >
< FormControl >
< Input
placeholder = ""
{ . . . field }
id = "lat_secondario"
value = { field . value || undefined }
/ >
< / FormControl >
< / FormItem >
) }
/ >
}
children2 = {
< FormField
control = { form . control }
name = "lon_secondario"
render = { ( { field } ) = > (
< FormItem >
< div className = "flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "lon_secondario" >
Lon Secondario
< / FormLabel >
< FormMessage / >
< / div >
< FormControl >
< Input
placeholder = ""
{ . . . field }
id = "lon_secondario"
value = { field . value || undefined }
/ >
< / FormControl >
< / FormItem >
) }
/ >
}
/ >
< p >
< Link
href = { ` https://www.google.com/maps/place/ ${ form . getValues ( "lat_secondario" ) } , ${ form . getValues ( "lon_secondario" ) } ` }
target = "_blank"
>
🗺 ️ < span className = "underline" > Vedi su maps < / span >
< / Link >
< / p >
< / CardContent >
< / Card >
< Card >
< CardHeader >
< CardTitle > Dati Annuncio < / CardTitle >
< / CardHeader >
< CardContent className = "space-y-4" >
< DualInputLayout
children1 = {
< FormField
control = { form . control }
name = "tipo"
render = { ( { field } ) = > (
< FormItem >
< div className = "flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "select-tipo" >
Tipo annuncio
< / FormLabel > { " " }
< FormMessage / >
< / div >
< FormControl >
< MultiSelect
defaultValue = {
field . value
? tipoOptions . filter ( ( o ) = >
field . value ? . includes ( o . value ) ,
)
: undefined
}
2025-08-29 16:18:32 +02:00
elementId = "select-tipo"
elementName = "tipo"
isMulti = { false }
2025-08-28 18:27:07 +02:00
onValueChange = { async ( value ) = > {
field . onChange ( value . value ) ;
} }
2025-08-29 16:18:32 +02:00
options = { tipoOptions }
2025-08-28 18:27:07 +02:00
placeholder = "Seleziona..."
/ >
< / FormControl >
< / FormItem >
) }
/ >
}
children2 = {
< FormField
control = { form . control }
name = "categorie"
render = { ( { field } ) = > (
< FormItem >
< div className = "flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "categorie" > Categorie < / FormLabel >
< FormMessage / >
< / div >
< p className = "h-[42px]" id = "categorie" >
{ field . value ? . join ( ", " ) }
< / p >
< / FormItem >
) }
/ >
}
/ >
< DualInputLayout
children1 = {
< FormField
control = { form . control }
name = "prezzo"
2025-11-21 14:09:06 +01:00
render = { ( { field } ) = > {
const { value , onChange , . . . rest } = field ;
2025-08-28 18:27:07 +02:00
2025-11-21 14:09:06 +01:00
return (
< FormItem >
< div className = "flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "prezzo" > Prezzo < / FormLabel > { " " }
< FormMessage / >
< / div >
< FormControl >
< NumberInput
decimalScale = { 2 }
{ . . . rest }
decimalSeparator = ","
defaultValue = { Number ( value ) / 100 }
fixedDecimalScale
id = "prezzo"
min = { 0 }
onValueChange = { ( v ) = > {
onChange ( ( Number ( v ) || 0 ) * 100 ) ;
} }
suffix = " €"
/ >
< / FormControl >
< / FormItem >
) ;
} }
2025-08-28 18:27:07 +02:00
/ >
}
children2 = {
< FormField
control = { form . control }
name = "disponibile_da"
render = { ( { field } ) = > (
< FormItem >
< div className = "flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "disponibile_da" >
Disponibile Da
< / FormLabel >
< FormMessage / >
< / div >
< Popover >
< PopoverTrigger asChild >
< FormControl >
< Button
className = { cn (
"h-[42px] w-full pl-3 text-left font-medium" ,
! field . value && "text-muted-foreground" ,
2025-11-14 17:21:21 +01:00
"rounded-lg border border-neutral-300 shadow-xs outline-hidden file:border-0 file:bg-transparent file:font-medium file:text-sm disabled:cursor-not-allowed disabled:opacity-50 dark:focus:border-transparent" ,
2025-08-28 18:27:07 +02:00
) }
2025-08-29 16:18:32 +02:00
id = "disponibile_da"
variant = { "outline" }
2025-08-28 18:27:07 +02:00
>
{ field . value ? (
format ( field . value , "PPP" , {
locale : it ,
} )
) : (
< span > Scegli < / span >
) }
< CalendarIcon className = "ml-auto size-4 opacity-50" / >
< / Button >
< / FormControl >
< / PopoverTrigger >
< PopoverContent
align = "start"
2025-08-29 16:18:32 +02:00
className = "w-auto p-0"
2025-08-28 18:27:07 +02:00
>
< Calendar
2025-08-29 16:18:32 +02:00
autoFocus
captionLayout = "dropdown"
defaultMonth = { field . value || undefined }
2025-10-30 19:39:40 +01:00
endMonth = { new Date ( 2050 , 12 ) }
2025-08-28 18:27:07 +02:00
locale = { it }
mode = "single"
onSelect = { field . onChange }
2025-08-29 16:18:32 +02:00
selected = { field . value || undefined }
2025-08-28 18:27:07 +02:00
/ >
< / PopoverContent >
< / Popover >
< / FormItem >
) }
/ >
}
/ >
< DualInputLayout
children1 = {
< 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 >
< FormControl >
< MultiSelect
defaultValue = {
field . value
? consegnaOptions . filter ( ( o ) = >
field . value ? . toString ( ) . includes ( o . value ) ,
)
: undefined
}
2025-08-29 16:18:32 +02:00
elementId = "select-consegna"
elementName = "consegna"
isMulti = { false }
2025-08-28 18:27:07 +02:00
onValueChange = { async ( value ) = > {
field . onChange ( parseInt ( value . value ) ) ;
} }
2025-08-29 16:18:32 +02:00
options = { consegnaOptions }
2025-08-28 18:27:07 +02:00
placeholder = "Seleziona..."
/ >
< / FormControl >
< / FormItem >
) }
/ >
}
children2 = {
< FormField
control = { form . control }
name = "persone"
render = { ( { field } ) = > (
< FormItem >
< div className = "flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "select-pers" > Persone < / FormLabel >
< FormMessage / >
< / div >
< FormControl >
< MultiSelect
defaultValue = {
field . value
? personeOptions . filter ( ( o ) = >
field . value ? . includes ( o . value ) ,
)
: undefined
}
2025-08-29 16:18:32 +02:00
elementId = "select-pers"
elementName = "persone"
isMulti = { true }
2025-08-28 18:27:07 +02:00
onValueChange = { async ( value ) = > {
field . onChange ( value . map ( ( v ) = > v . value ) ) ;
} }
2025-08-29 16:18:32 +02:00
options = { personeOptions }
2025-08-28 18:27:07 +02:00
placeholder = "Seleziona..."
/ >
< / FormControl >
< / FormItem >
) }
/ >
}
/ >
< FormField
control = { form . control }
name = "permanenza"
render = { ( { field } ) = > (
< FormItem >
< div className = "flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "select-perm" > Permanenza < / FormLabel >
< FormMessage / >
< / div >
< FormControl >
< MultiSelect
defaultValue = {
field . value
? permanenzaOptions . filter ( ( o ) = >
field . value ? . includes ( parseInt ( o . value ) ) ,
)
: undefined
}
2025-08-29 16:18:32 +02:00
elementId = "select-perm"
elementName = "permanenza"
isMulti = { true }
2025-08-28 18:27:07 +02:00
onValueChange = { async ( value ) = > {
field . onChange ( value . map ( ( v ) = > parseInt ( v . value ) ) ) ;
} }
2025-08-29 16:18:32 +02:00
options = { permanenzaOptions }
2025-08-28 18:27:07 +02:00
placeholder = "Seleziona..."
/ >
< / FormControl >
< / FormItem >
) }
/ >
< / CardContent >
< / Card >
< Card >
< CardHeader >
< CardTitle > Altri Dati Immobile < / CardTitle >
< / CardHeader >
< CardContent className = "space-y-4" >
< div className = "flex w-full flex-col flex-wrap items-start justify-between gap-4 sm:flex-row" >
< FormField
control = { form . control }
name = "anno"
render = { ( { field } ) = > (
< FormItem >
< div className = "flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "anno" > Anno costruzione < / FormLabel > { " " }
< FormMessage / >
< / div >
< FormControl >
< Input
placeholder = ""
{ . . . field }
id = "anno"
onChange = { ( e ) = >
field . onChange (
e . target . value !== "" ? e.target.value : null ,
)
}
2025-08-29 16:18:32 +02:00
value = { field . value || undefined }
2025-08-28 18:27:07 +02:00
/ >
< / FormControl >
< / FormItem >
) }
/ >
< FormField
control = { form . control }
name = "classe"
render = { ( { field } ) = > (
< FormItem >
< div className = "flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "classe" > Classe < / FormLabel > { " " }
< FormMessage / >
< / div >
< FormControl >
< Input
placeholder = ""
{ . . . field }
id = "classe"
onChange = { ( e ) = >
field . onChange (
e . target . value !== "" ? e.target.value : null ,
)
}
2025-08-29 16:18:32 +02:00
value = { field . value || undefined }
2025-08-28 18:27:07 +02:00
/ >
< / FormControl >
< / FormItem >
) }
/ >
< FormField
control = { form . control }
name = "mq"
2025-11-25 12:05:14 +01:00
render = { ( { field } ) = > {
const { value , onChange , . . . rest } = field ;
2025-12-03 14:51:39 +01:00
const mqValue =
typeof value === "string" ? parseFloat ( value ) : value ;
2025-11-25 12:05:14 +01:00
return (
< FormItem >
< div className = "flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "mq" > Metri Quadri < / FormLabel > { " " }
< FormMessage / >
< / div >
2025-08-28 18:27:07 +02:00
2025-11-25 12:05:14 +01:00
< FormControl >
< NumberInput
decimalScale = { 2 }
{ . . . rest }
decimalSeparator = ","
2025-12-03 14:51:39 +01:00
defaultValue = { mqValue || undefined }
2025-11-25 12:05:14 +01:00
fixedDecimalScale
id = "mq"
min = { 0 }
onValueChange = { ( v ) = > {
onChange ( v || null ) ;
} }
/ >
< / FormControl >
< / FormItem >
) ;
} }
2025-08-28 18:27:07 +02:00
/ >
< FormField
control = { form . control }
name = "piano"
render = { ( { field } ) = > (
< FormItem >
< div className = "flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "piano" > Piano < / FormLabel > { " " }
< FormMessage / >
< / div >
< FormControl >
< Input
placeholder = ""
{ . . . field }
id = "piano"
onChange = { ( e ) = >
field . onChange (
e . target . value !== "" ? e.target.value : null ,
)
}
2025-08-29 16:18:32 +02:00
value = { field . value || undefined }
2025-08-28 18:27:07 +02:00
/ >
< / FormControl >
< / FormItem >
) }
/ >
< FormField
control = { form . control }
name = "piano_palazzo"
render = { ( { field } ) = > (
< FormItem >
< div className = "relative flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "piano_palazzo" >
Piani Palazzo
< / FormLabel >
{ field . value !== null && field . value !== 0 && (
< Button
2025-10-10 16:18:43 +02:00
className = "-top-2 absolute right-0 flex items-center gap-1"
2025-08-28 18:27:07 +02:00
onClick = { ( ) = > {
form . setValue ( "piano_palazzo" , null ) ;
} }
2025-08-29 16:18:32 +02:00
size = "sm"
type = "button"
variant = "link"
2025-08-28 18:27:07 +02:00
>
< RotateCw className = "size-4" / >
Reset
< / Button >
) }
< FormMessage / >
< / div >
< FormControl >
< Input
placeholder = ""
type = "number"
{ . . . field }
id = "piano_palazzo"
onChange = { ( e ) = >
field . onChange (
e . target . value === "0" || e . target . value === ""
? null
: parseInt ( e . target . value ) ,
)
}
2025-08-29 16:18:32 +02:00
value = { field . value || 0 }
2025-08-28 18:27:07 +02:00
/ >
< / FormControl >
< / FormItem >
) }
/ >
< FormField
control = { form . control }
name = "unita_condominio"
render = { ( { field } ) = > (
< FormItem >
< div className = "relative flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "unita_condominio" >
Unità Condominio
< / FormLabel >
{ field . value !== null && field . value !== 0 && (
< Button
2025-10-10 16:18:43 +02:00
className = "-top-2 absolute right-0 flex items-center gap-1"
2025-08-28 18:27:07 +02:00
onClick = { ( ) = > {
form . setValue ( "unita_condominio" , null ) ;
} }
2025-08-29 16:18:32 +02:00
size = "sm"
type = "button"
variant = "link"
2025-08-28 18:27:07 +02:00
>
< RotateCw className = "size-4" / >
Reset
< / Button >
) }
< FormMessage / >
< / div >
< FormControl >
< Input
placeholder = ""
type = "number"
{ . . . field }
id = "unita_condominio"
onChange = { ( e ) = >
field . onChange (
e . target . value === "0" || e . target . value === ""
? null
: parseInt ( e . target . value ) ,
)
}
2025-08-29 16:18:32 +02:00
value = { field . value || 0 }
2025-08-28 18:27:07 +02:00
/ >
< / FormControl >
< / FormItem >
) }
/ >
< FormField
control = { form . control }
name = "numero_vani"
render = { ( { field } ) = > (
< FormItem >
< div className = "relative flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "numero_vani" >
Numero Vani
< / FormLabel >
{ field . value !== null && field . value !== 0 && (
< Button
2025-10-10 16:18:43 +02:00
className = "-top-2 absolute right-0 flex items-center gap-1"
2025-08-28 18:27:07 +02:00
onClick = { ( ) = > {
form . setValue ( "numero_vani" , null ) ;
} }
2025-08-29 16:18:32 +02:00
size = "sm"
type = "button"
variant = "link"
2025-08-28 18:27:07 +02:00
>
< RotateCw className = "size-4" / >
Reset
< / Button >
) }
< FormMessage / >
< / div >
< FormControl >
< Input
placeholder = ""
type = "number"
{ . . . field }
id = "numero_vani"
onChange = { ( e ) = >
field . onChange (
e . target . value === "0" || e . target . value === ""
? null
: parseInt ( e . target . value ) ,
)
}
2025-08-29 16:18:32 +02:00
value = { field . value || 0 }
2025-08-28 18:27:07 +02:00
/ >
< / FormControl >
< / FormItem >
) }
/ >
< FormField
control = { form . control }
name = "numero_camere"
render = { ( { field } ) = > (
< FormItem >
< div className = "relative flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "numero_camere" >
Numero Camere
< / FormLabel >
{ field . value !== null && field . value !== 0 && (
< Button
2025-10-10 16:18:43 +02:00
className = "-top-2 absolute right-0 flex items-center gap-1"
2025-08-28 18:27:07 +02:00
onClick = { ( ) = > {
form . setValue ( "numero_camere" , null ) ;
} }
2025-08-29 16:18:32 +02:00
size = "sm"
type = "button"
variant = "link"
2025-08-28 18:27:07 +02:00
>
< RotateCw className = "size-4" / >
Reset
< / Button >
) }
< FormMessage / >
< / div >
< FormControl >
< Input
placeholder = ""
type = "number"
{ . . . field }
id = "numero_camere"
onChange = { ( e ) = >
field . onChange (
e . target . value === "0" || e . target . value === ""
? null
: parseInt ( e . target . value ) ,
)
}
2025-08-29 16:18:32 +02:00
value = { field . value || 0 }
2025-08-28 18:27:07 +02:00
/ >
< / FormControl >
< / FormItem >
) }
/ >
< FormField
control = { form . control }
name = "numero_bagni"
render = { ( { field } ) = > (
< FormItem >
< div className = "relative flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "numero_bagni" >
Numero Bagni
< / FormLabel >
{ field . value !== null && field . value !== 0 && (
< Button
2025-10-10 16:18:43 +02:00
className = "-top-2 absolute right-0 flex items-center gap-1"
2025-08-28 18:27:07 +02:00
onClick = { ( ) = > {
form . setValue ( "numero_bagni" , null ) ;
} }
2025-08-29 16:18:32 +02:00
size = "sm"
type = "button"
variant = "link"
2025-08-28 18:27:07 +02:00
>
< RotateCw className = "size-4" / >
Reset
< / Button >
) }
< FormMessage / >
< / div >
< FormControl >
< Input
placeholder = ""
type = "number"
{ . . . field }
id = "numero_bagni"
onChange = { ( e ) = >
field . onChange (
e . target . value === "0" || e . target . value === ""
? null
: parseInt ( e . target . value ) ,
)
}
2025-08-29 16:18:32 +02:00
value = { field . value || 0 }
2025-08-28 18:27:07 +02:00
/ >
< / FormControl >
< / FormItem >
) }
/ >
< FormField
control = { form . control }
name = "numero_balconi"
render = { ( { field } ) = > (
< FormItem >
< div className = "relative flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "numero_balconi" >
Numero Balconi
< / FormLabel >
{ field . value !== null && field . value !== 0 && (
< Button
2025-10-10 16:18:43 +02:00
className = "-top-2 absolute right-0 flex items-center gap-1"
2025-08-28 18:27:07 +02:00
onClick = { ( ) = > {
form . setValue ( "numero_balconi" , null ) ;
} }
2025-08-29 16:18:32 +02:00
size = "sm"
type = "button"
variant = "link"
2025-08-28 18:27:07 +02:00
>
< RotateCw className = "size-4" / >
Reset
< / Button >
) }
< FormMessage / >
< / div >
< FormControl >
< Input
placeholder = ""
type = "number"
{ . . . field }
id = "numero_balconi"
onChange = { ( e ) = >
field . onChange (
e . target . value === "0" || e . target . value === ""
? null
: parseInt ( e . target . value ) ,
)
}
2025-08-29 16:18:32 +02:00
value = { field . value || 0 }
2025-08-28 18:27:07 +02:00
/ >
< / FormControl >
< / FormItem >
) }
/ >
< FormField
control = { form . control }
name = "numero_terrazzi"
render = { ( { field } ) = > (
< FormItem >
< div className = "relative flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "numero_terrazzi" >
Numero Terrazzi
< / FormLabel >
{ field . value !== null && field . value !== 0 && (
< Button
2025-10-10 16:18:43 +02:00
className = "-top-2 absolute right-0 flex items-center gap-1"
2025-08-28 18:27:07 +02:00
onClick = { ( ) = > {
form . setValue ( "numero_terrazzi" , null ) ;
} }
2025-08-29 16:18:32 +02:00
size = "sm"
type = "button"
variant = "link"
2025-08-28 18:27:07 +02:00
>
< RotateCw className = "size-4" / >
Reset
< / Button >
) }
< FormMessage / >
< / div >
< FormControl >
< Input
placeholder = ""
type = "number"
{ . . . field }
id = "numero_terrazzi"
onChange = { ( e ) = >
field . onChange (
e . target . value === "0" || e . target . value === ""
? null
: parseInt ( e . target . value ) ,
)
}
2025-08-29 16:18:32 +02:00
value = { field . value || 0 }
2025-08-28 18:27:07 +02:00
/ >
< / FormControl >
< / FormItem >
) }
/ >
< FormField
control = { form . control }
name = "numero_box"
render = { ( { field } ) = > (
< FormItem >
< div className = "relative flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "numero_box" >
Numero Box Auto
< / FormLabel >
{ field . value !== null && field . value !== 0 && (
< Button
2025-10-10 16:18:43 +02:00
className = "-top-2 absolute right-0 flex items-center gap-1"
2025-08-28 18:27:07 +02:00
onClick = { ( ) = > {
form . setValue ( "numero_box" , null ) ;
} }
2025-08-29 16:18:32 +02:00
size = "sm"
type = "button"
variant = "link"
2025-08-28 18:27:07 +02:00
>
< RotateCw className = "size-4" / >
Reset
< / Button >
) }
< FormMessage / >
< / div >
< FormControl >
< Input
placeholder = ""
type = "number"
{ . . . field }
id = "numero_box"
onChange = { ( e ) = >
field . onChange (
e . target . value === "0" || e . target . value === ""
? null
: parseInt ( e . target . value ) ,
)
}
2025-08-29 16:18:32 +02:00
value = { field . value || 0 }
2025-08-28 18:27:07 +02:00
/ >
< / FormControl >
< / FormItem >
) }
/ >
< FormField
control = { form . control }
name = "numero_postiauto"
render = { ( { field } ) = > (
< FormItem >
< div className = "relative flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "numero_postiauto" >
Numero Posti Auto
< / FormLabel >
{ field . value !== null && field . value !== 0 && (
< Button
2025-10-10 16:18:43 +02:00
className = "-top-2 absolute right-0 flex items-center gap-1"
2025-08-28 18:27:07 +02:00
onClick = { ( ) = > {
form . setValue ( "numero_postiauto" , null ) ;
} }
2025-08-29 16:18:32 +02:00
size = "sm"
type = "button"
variant = "link"
2025-08-28 18:27:07 +02:00
>
< RotateCw className = "size-4" / >
Reset
< / Button >
) }
< FormMessage / >
< / div >
< FormControl >
< Input
placeholder = ""
type = "number"
{ . . . field }
id = "numero_postiauto"
onChange = { ( e ) = >
field . onChange (
e . target . value === "0" || e . target . value === ""
? null
: parseInt ( e . target . value ) ,
)
}
2025-08-29 16:18:32 +02:00
value = { field . value || 0 }
2025-08-28 18:27:07 +02:00
/ >
< / FormControl >
< / FormItem >
) }
/ >
< / div >
< FormField
control = { form . control }
name = "accessori"
render = { ( { field } ) = > (
< FormItem >
< div className = "flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "accessori" > Accessori < / FormLabel >
< FormMessage / >
< / div >
< FormControl >
< p className = "h-[42px]" id = "accessori" >
{ field . value ? . join ( ", " ) }
< / p >
< / FormControl >
< / FormItem >
) }
/ >
< FormField
control = { form . control }
name = "caratteristiche"
render = { ( { field } ) = > (
< FormItem >
< div className = "flex flex-wrap items-center gap-x-2" >
< FormLabel htmlFor = "caratteristiche" >
Caratteristiche
< / FormLabel >
< FormMessage / >
< / div >
< FormControl >
< p className = "h-[42px]" id = "caratteristiche" >
{ field . value
? filteredCaratteristiche ( field . value )
. map ( ( v ) = > v . text )
. join ( ", " )
: "" }
< / p >
< / FormControl >
< / FormItem >
) }
/ >
< / CardContent >
< / Card >
< Card >
< CardHeader >
< CardTitle > Media < / CardTitle >
< / CardHeader >
< CardContent className = "space-y-4" >
< div className = "flex w-full flex-col items-start justify-between gap-4 sm:flex-row" > < / div >
< / CardContent >
< / Card >
< / div >
< / form >
< / Form >
< / >
) ;
2025-08-28 13:19:43 +02:00
} ;