2025-11-11 15:41:20 +01:00
|
|
|
import { CircleUser, Navigation, Phone, TriangleAlert } from "lucide-react";
|
2025-10-29 09:39:06 +01:00
|
|
|
import Link from "next/link";
|
2025-11-11 15:41:20 +01:00
|
|
|
import { useMemo, useState } from "react";
|
2025-10-29 09:39:06 +01:00
|
|
|
import toast from "react-hot-toast";
|
|
|
|
|
import { useTranslation } from "~/providers/I18nProvider";
|
|
|
|
|
import { useServizio, useServizioAnnuncio } from "~/providers/ServizioProvider";
|
|
|
|
|
import type { UsersStorageUserStorageId } from "~/schemas/public/UsersStorage";
|
|
|
|
|
import { api } from "~/utils/api";
|
2025-11-11 15:41:20 +01:00
|
|
|
import { DocumentiUploadSection } from "../area-riservata/documenti_personali";
|
2025-10-29 09:39:06 +01:00
|
|
|
import {
|
|
|
|
|
Credenza,
|
|
|
|
|
CredenzaBody,
|
|
|
|
|
CredenzaClose,
|
|
|
|
|
CredenzaContent,
|
|
|
|
|
CredenzaDescription,
|
|
|
|
|
CredenzaFooter,
|
|
|
|
|
CredenzaHeader,
|
|
|
|
|
CredenzaTitle,
|
|
|
|
|
CredenzaTrigger,
|
|
|
|
|
} from "../custom_ui/credenza";
|
|
|
|
|
import { LoadingPage } from "../loading";
|
|
|
|
|
import { WhatsAppIcon2 } from "../svgs";
|
2026-03-18 18:01:02 +01:00
|
|
|
import { Button } from "../ui/button";
|
2025-10-29 09:39:06 +01:00
|
|
|
|
|
|
|
|
export const ContattiProprietarioModal = () => {
|
|
|
|
|
const { servizio } = useServizio();
|
2025-11-11 15:41:20 +01:00
|
|
|
const [open, setOpen] = useState(false);
|
2025-10-29 09:39:06 +01:00
|
|
|
const { data } = useServizioAnnuncio();
|
2026-02-25 15:30:53 +01:00
|
|
|
const { t, locale } = useTranslation();
|
2025-11-03 10:59:45 +01:00
|
|
|
const isUnlocked = data.open_contatti_at != null;
|
2025-12-30 17:25:37 +01:00
|
|
|
|
2025-11-03 10:59:45 +01:00
|
|
|
const needsDocuments =
|
|
|
|
|
!servizio.skipControlloDoc &&
|
|
|
|
|
(!servizio.doc_personale_fronte || !servizio.doc_personale_retro);
|
2025-12-30 17:25:37 +01:00
|
|
|
|
2025-10-29 09:39:06 +01:00
|
|
|
return (
|
2025-11-11 15:41:20 +01:00
|
|
|
<Credenza
|
|
|
|
|
onOpenChange={(o) => {
|
|
|
|
|
setOpen(o);
|
|
|
|
|
}}
|
|
|
|
|
open={open}
|
|
|
|
|
>
|
2025-10-29 09:39:06 +01:00
|
|
|
<CredenzaTrigger asChild>
|
2025-11-11 15:41:20 +01:00
|
|
|
{isUnlocked ? (
|
2025-10-29 09:39:06 +01:00
|
|
|
<Button
|
|
|
|
|
aria-label="Vedi contatti proprietario"
|
2025-12-15 18:58:13 +01:00
|
|
|
className="w-full md:w-fit"
|
2025-10-29 09:39:06 +01:00
|
|
|
variant="success"
|
|
|
|
|
>
|
2026-01-16 15:47:38 +01:00
|
|
|
<CircleUser />
|
2026-02-25 15:30:53 +01:00
|
|
|
{locale === "it" ? "Contatti" : "Contacts"}
|
2025-10-29 09:39:06 +01:00
|
|
|
</Button>
|
|
|
|
|
) : (
|
|
|
|
|
<Button
|
|
|
|
|
aria-label="Contatta proprietario"
|
2025-12-15 18:58:13 +01:00
|
|
|
className="w-full md:w-fit"
|
2025-10-29 09:39:06 +01:00
|
|
|
variant="warning"
|
|
|
|
|
>
|
2026-01-16 15:47:38 +01:00
|
|
|
<CircleUser />
|
2026-02-25 15:30:53 +01:00
|
|
|
{locale === "it" ? "Ottieni i contatti" : "Get contacts"}
|
2025-10-29 09:39:06 +01:00
|
|
|
</Button>
|
|
|
|
|
)}
|
|
|
|
|
</CredenzaTrigger>
|
2025-11-03 10:59:45 +01:00
|
|
|
<CredenzaContent className="max-h-[90vh] sm:max-w-2xl">
|
2025-10-29 09:39:06 +01:00
|
|
|
<CredenzaHeader>
|
2025-11-03 10:59:45 +01:00
|
|
|
<CredenzaTitle className="text-xl">{t.contatto.title}</CredenzaTitle>
|
2025-10-29 09:39:06 +01:00
|
|
|
<CredenzaDescription className="sr-only">
|
|
|
|
|
{t.contatto.descrizione}
|
|
|
|
|
</CredenzaDescription>
|
|
|
|
|
</CredenzaHeader>
|
2025-12-30 17:25:37 +01:00
|
|
|
{needsDocuments ? (
|
|
|
|
|
<DocCheckpoint />
|
2025-11-03 10:59:45 +01:00
|
|
|
) : isUnlocked ? (
|
2025-10-29 09:39:06 +01:00
|
|
|
<PostUnlock />
|
2025-11-03 10:59:45 +01:00
|
|
|
) : (
|
|
|
|
|
<PreUnlock />
|
2025-10-29 09:39:06 +01:00
|
|
|
)}
|
|
|
|
|
</CredenzaContent>
|
|
|
|
|
</Credenza>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
2025-12-30 17:25:37 +01:00
|
|
|
const DocCheckpoint = () => {
|
2026-02-25 15:30:53 +01:00
|
|
|
const { t, locale } = useTranslation();
|
2025-11-11 15:41:20 +01:00
|
|
|
const { userId, servizio, isAdmin } = useServizio();
|
2025-10-29 09:39:06 +01:00
|
|
|
const utils = api.useUtils();
|
2025-11-10 16:27:15 +01:00
|
|
|
const { mutate, isPending } = api.users.editUserAnagrafica.useMutation({
|
2025-10-29 09:39:06 +01:00
|
|
|
onSuccess: async () => {
|
2026-03-08 01:02:57 +01:00
|
|
|
await utils.servizio.invalidate();
|
2025-10-29 09:39:06 +01:00
|
|
|
await utils.storage.retrieveUserFileData.invalidate({ userId });
|
|
|
|
|
},
|
|
|
|
|
onError: (err) => {
|
|
|
|
|
toast.error(`Errore aggiornamento servizio: ${err.message}`);
|
|
|
|
|
},
|
|
|
|
|
});
|
2025-11-03 10:59:45 +01:00
|
|
|
const handleUpload = (
|
|
|
|
|
field: "doc_personale_fronte_ref" | "doc_personale_retro_ref",
|
2025-11-06 17:03:42 +01:00
|
|
|
id: UsersStorageUserStorageId,
|
2025-11-03 10:59:45 +01:00
|
|
|
) => {
|
|
|
|
|
mutate({
|
2025-11-10 16:27:15 +01:00
|
|
|
userId,
|
|
|
|
|
data: {
|
|
|
|
|
[field]: id,
|
|
|
|
|
},
|
2025-11-03 10:59:45 +01:00
|
|
|
});
|
|
|
|
|
};
|
2025-10-29 09:39:06 +01:00
|
|
|
return (
|
|
|
|
|
<>
|
|
|
|
|
<CredenzaBody className="max-h-[80vh] overflow-auto pb-5">
|
2025-12-16 11:22:56 +01:00
|
|
|
<div className="flex flex-col flex-wrap gap-4">
|
2025-11-11 15:41:20 +01:00
|
|
|
<div>
|
2026-02-25 15:30:53 +01:00
|
|
|
<p className="font-semibold">
|
|
|
|
|
{locale === "it"
|
|
|
|
|
? "Carica i tuoi documenti"
|
|
|
|
|
: "Upload your documents"}
|
|
|
|
|
</p>
|
2025-11-11 15:41:20 +01:00
|
|
|
<p>
|
2026-02-25 15:30:53 +01:00
|
|
|
{locale === "it"
|
|
|
|
|
? "se si ha una scansione unica fronte/retro dei doc, caricarla due volte."
|
|
|
|
|
: "if you have a single front/back scan of the documents, upload it twice."}
|
2025-11-11 15:41:20 +01:00
|
|
|
</p>
|
2025-10-29 09:39:06 +01:00
|
|
|
</div>
|
|
|
|
|
|
2025-12-16 11:22:56 +01:00
|
|
|
<div className="flex flex-col flex-wrap justify-around gap-x-10 gap-y-4 sm:flex-row">
|
|
|
|
|
<DocumentiUploadSection
|
|
|
|
|
caricatoNote
|
|
|
|
|
document={servizio.doc_personale_fronte}
|
|
|
|
|
isAdmin={isAdmin}
|
|
|
|
|
isPending={isPending}
|
|
|
|
|
onRemove={() =>
|
|
|
|
|
mutate({
|
|
|
|
|
userId,
|
|
|
|
|
data: { doc_personale_fronte_ref: null },
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
onUpload={(id) => handleUpload("doc_personale_fronte_ref", id)}
|
|
|
|
|
title="Documento d'identità - Fronte"
|
|
|
|
|
userId={userId}
|
|
|
|
|
/>
|
2025-11-11 15:41:20 +01:00
|
|
|
|
2025-12-16 11:22:56 +01:00
|
|
|
<DocumentiUploadSection
|
|
|
|
|
caricatoNote
|
|
|
|
|
document={servizio.doc_personale_retro}
|
|
|
|
|
isAdmin={isAdmin}
|
|
|
|
|
isPending={isPending}
|
|
|
|
|
onRemove={() =>
|
|
|
|
|
mutate({
|
|
|
|
|
userId,
|
|
|
|
|
data: { doc_personale_retro_ref: null },
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
onUpload={(id) => handleUpload("doc_personale_retro_ref", id)}
|
|
|
|
|
title="Documento d'identità - Retro"
|
|
|
|
|
userId={userId}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
2025-11-11 15:41:20 +01:00
|
|
|
|
2025-10-29 09:39:06 +01:00
|
|
|
<p className="text-muted-foreground text-sm">
|
2026-02-25 15:30:53 +01:00
|
|
|
{locale === "it"
|
|
|
|
|
? "I tuoi dati saranno conservati solamente per la durata del servizio, in conformità con la nostra "
|
|
|
|
|
: "Your data will be stored only for the duration of the service, in accordance with our "}
|
2025-10-29 09:39:06 +01:00
|
|
|
<Link className="underline" href="/privacy-policy" target="_blank">
|
2026-02-25 15:30:53 +01:00
|
|
|
{locale === "it" ? "Informativa sulla Privacy" : "Privacy Policy"}
|
2025-10-29 09:39:06 +01:00
|
|
|
</Link>
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
</CredenzaBody>
|
|
|
|
|
<CredenzaFooter>
|
|
|
|
|
<CredenzaClose asChild>
|
2025-11-03 10:59:45 +01:00
|
|
|
<Button aria-label="Chiudi" disabled={isPending} variant="outline">
|
2025-10-29 09:39:06 +01:00
|
|
|
{t.chiudi}
|
|
|
|
|
</Button>
|
|
|
|
|
</CredenzaClose>
|
|
|
|
|
</CredenzaFooter>
|
|
|
|
|
</>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const PreUnlock = () => {
|
2026-03-08 01:02:57 +01:00
|
|
|
const { servizioId } = useServizio();
|
2025-10-29 09:39:06 +01:00
|
|
|
const { annuncioId } = useServizioAnnuncio();
|
2026-02-25 15:30:53 +01:00
|
|
|
const { t, locale } = useTranslation();
|
2025-10-29 09:39:06 +01:00
|
|
|
|
|
|
|
|
const utils = api.useUtils();
|
|
|
|
|
|
2025-11-03 10:59:45 +01:00
|
|
|
const { mutate, isPending } = api.servizio.unlockServizioContatti.useMutation(
|
|
|
|
|
{
|
|
|
|
|
onError: (err) => {
|
|
|
|
|
toast.error(err.message, {
|
2025-10-29 09:39:06 +01:00
|
|
|
id: "unlock-contacts",
|
|
|
|
|
});
|
2025-11-03 10:59:45 +01:00
|
|
|
},
|
|
|
|
|
onMutate: () => {
|
|
|
|
|
toast.loading("Caricamento ...", {
|
|
|
|
|
id: "unlock-contacts",
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
onSuccess: async (data) => {
|
|
|
|
|
if (!data) {
|
|
|
|
|
toast.error("Limite di sblocchi raggiunto", {
|
|
|
|
|
id: "unlock-contacts",
|
|
|
|
|
});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
toast.success("Successo", {
|
|
|
|
|
id: "unlock-contacts",
|
|
|
|
|
});
|
2026-03-08 01:02:57 +01:00
|
|
|
await utils.servizio.invalidate();
|
2025-11-03 10:59:45 +01:00
|
|
|
},
|
2025-10-29 09:39:06 +01:00
|
|
|
},
|
2025-11-03 10:59:45 +01:00
|
|
|
);
|
2025-10-29 09:39:06 +01:00
|
|
|
|
2025-11-03 10:59:45 +01:00
|
|
|
const currentHour = new Date().getHours();
|
|
|
|
|
const isOutsideBusinessHours = currentHour < 9 || currentHour >= 20;
|
2025-10-29 09:39:06 +01:00
|
|
|
return (
|
|
|
|
|
<>
|
|
|
|
|
<CredenzaBody className="max-h-[80vh] overflow-auto pb-5">
|
|
|
|
|
<div className="space-y-5">
|
|
|
|
|
<p>{t.contatto.disclaimer}</p>
|
|
|
|
|
<p>{t.contatto.disclaimer2}</p>
|
|
|
|
|
<p className="text-muted-foreground text-xs">
|
|
|
|
|
{t.contatto.disclaimer3}
|
|
|
|
|
</p>
|
2025-11-03 10:59:45 +01:00
|
|
|
{isOutsideBusinessHours && (
|
2025-10-29 09:39:06 +01:00
|
|
|
<div className="flex items-center gap-2 rounded-md bg-yellow-200 p-2">
|
|
|
|
|
<TriangleAlert className="size-8" />
|
|
|
|
|
<p>
|
2026-02-25 15:30:53 +01:00
|
|
|
{locale === "it"
|
|
|
|
|
? "Il proprietario riceverà la notifica alle ore 9.00"
|
|
|
|
|
: "The owner will receive the notification at 9:00 AM"}{" "}
|
|
|
|
|
{currentHour >= 20 &&
|
|
|
|
|
(locale === "it" ? "di domani" : "tomorrow")}
|
2025-10-29 09:39:06 +01:00
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
</CredenzaBody>
|
|
|
|
|
<CredenzaFooter>
|
|
|
|
|
<Button
|
|
|
|
|
aria-label="Contatta proprietario"
|
2025-11-03 10:59:45 +01:00
|
|
|
disabled={isPending}
|
2025-10-29 09:39:06 +01:00
|
|
|
onClick={() =>
|
|
|
|
|
mutate({
|
|
|
|
|
annuncioId,
|
|
|
|
|
servizioId,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
variant="success"
|
|
|
|
|
>
|
|
|
|
|
{t.accetta}
|
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
|
|
<CredenzaClose asChild>
|
2025-11-03 10:59:45 +01:00
|
|
|
<Button
|
|
|
|
|
aria-label="Chiudi modal credenza"
|
|
|
|
|
disabled={isPending}
|
|
|
|
|
variant="outline"
|
|
|
|
|
>
|
2025-10-29 09:39:06 +01:00
|
|
|
{t.chiudi}
|
|
|
|
|
</Button>
|
|
|
|
|
</CredenzaClose>
|
|
|
|
|
</CredenzaFooter>
|
|
|
|
|
</>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
function getNavigationUrl(lat: string, lon: string): string {
|
2025-11-03 10:59:45 +01:00
|
|
|
if (typeof window === "undefined") {
|
|
|
|
|
return `https://www.google.com/maps/dir/?api=1&travelmode=driving&layer=traffic&destination=${lat},${lon}`;
|
2025-10-29 09:39:06 +01:00
|
|
|
}
|
2025-11-03 10:59:45 +01:00
|
|
|
const isIOS = /iPad|iPhone|iPod|Mac/.test(navigator.userAgent);
|
|
|
|
|
const protocol = isIOS ? "maps" : "https";
|
|
|
|
|
|
|
|
|
|
return `${protocol}://www.google.com/maps/dir/?api=1&travelmode=driving&layer=traffic&destination=${lat},${lon}`;
|
2025-10-29 09:39:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const PostUnlock = () => {
|
|
|
|
|
const { servizioId } = useServizio();
|
2026-03-19 14:07:36 +01:00
|
|
|
const { annuncioId, data: annuncio } = useServizioAnnuncio();
|
2025-10-29 09:39:06 +01:00
|
|
|
const { data, isLoading } = api.annunci.getProprietarioData.useQuery({
|
|
|
|
|
annuncioId,
|
|
|
|
|
servizioId,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const { t } = useTranslation();
|
|
|
|
|
|
|
|
|
|
// Memoize navigation URL
|
|
|
|
|
const navigationUrl = useMemo(() => {
|
|
|
|
|
if (!data?.propData || !data.propData.lat || !data.propData.lon)
|
|
|
|
|
return undefined;
|
|
|
|
|
return getNavigationUrl(data.propData.lat, data.propData.lon);
|
|
|
|
|
}, [data?.propData]);
|
|
|
|
|
|
|
|
|
|
if (isLoading) {
|
|
|
|
|
return (
|
2025-11-03 10:59:45 +01:00
|
|
|
<CredenzaBody className="flex justify-center p-8">
|
2025-10-29 09:39:06 +01:00
|
|
|
<LoadingPage />
|
2025-11-03 10:59:45 +01:00
|
|
|
</CredenzaBody>
|
2025-10-29 09:39:06 +01:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
if (!data || !data.propData) {
|
2025-11-03 10:59:45 +01:00
|
|
|
return (
|
|
|
|
|
<CredenzaBody>
|
|
|
|
|
<p className="text-destructive">{t.contatto.error}</p>
|
|
|
|
|
</CredenzaBody>
|
|
|
|
|
);
|
2025-10-29 09:39:06 +01:00
|
|
|
}
|
2025-11-03 10:59:45 +01:00
|
|
|
const { opened_at, propData } = data;
|
2025-10-29 09:39:06 +01:00
|
|
|
return (
|
|
|
|
|
<>
|
2025-11-03 10:59:45 +01:00
|
|
|
<CredenzaBody className="max-h-[80vh] overflow-auto pb-5 sm:max-w-xl">
|
|
|
|
|
<div className="space-y-10">
|
|
|
|
|
{/* Proprietario Section */}
|
2026-03-19 14:07:36 +01:00
|
|
|
{annuncio.stato === "Sospeso" ? (
|
|
|
|
|
<section>
|
|
|
|
|
<h3 className="mb-2 font-semibold">{t.contatto.propietario}:</h3>
|
|
|
|
|
<p className="mb-2">{t.contatto.nome}: INFOALLOGGI (delegato)</p>
|
|
|
|
|
<div className="flex flex-wrap items-center gap-5">
|
|
|
|
|
<a
|
|
|
|
|
className="flex items-center gap-2 text-blue-600 hover:underline"
|
|
|
|
|
href={`tel:3453944827`}
|
|
|
|
|
>
|
|
|
|
|
<Phone className="size-4" />
|
|
|
|
|
<span>+39 3453944827</span>
|
|
|
|
|
</a>
|
|
|
|
|
<Link href={`https://wa.me/3453944827`} target="_blank">
|
|
|
|
|
<Button size="sm" variant="success">
|
|
|
|
|
<WhatsAppIcon2 className="size-4 fill-white" />
|
|
|
|
|
WhatsApp
|
|
|
|
|
</Button>
|
|
|
|
|
</Link>
|
|
|
|
|
</div>
|
|
|
|
|
</section>
|
|
|
|
|
) : (
|
|
|
|
|
<section>
|
|
|
|
|
<h3 className="mb-2 font-semibold">{t.contatto.propietario}:</h3>
|
|
|
|
|
<p className="mb-2">
|
|
|
|
|
{t.contatto.nome}: {propData.locatore}
|
|
|
|
|
{propData.tipo_locatore ? ` (${propData.tipo_locatore})` : ""}
|
|
|
|
|
</p>
|
|
|
|
|
<div className="flex flex-wrap items-center gap-5">
|
|
|
|
|
<a
|
|
|
|
|
className="flex items-center gap-2 text-blue-600 hover:underline"
|
|
|
|
|
href={`tel:${propData.numero}`}
|
|
|
|
|
>
|
|
|
|
|
<Phone className="size-4" />
|
|
|
|
|
<span>{propData.numero}</span>
|
|
|
|
|
</a>
|
|
|
|
|
<Link href={`https://wa.me/${propData.numero}`} target="_blank">
|
|
|
|
|
<Button size="sm" variant="success">
|
|
|
|
|
<WhatsAppIcon2 className="size-4 fill-white" />
|
|
|
|
|
WhatsApp
|
|
|
|
|
</Button>
|
|
|
|
|
</Link>
|
|
|
|
|
</div>
|
|
|
|
|
</section>
|
|
|
|
|
)}
|
2025-11-03 10:59:45 +01:00
|
|
|
|
|
|
|
|
{/* Immobile Section */}
|
|
|
|
|
<section>
|
|
|
|
|
<h3 className="mb-2 font-semibold">{t.contatto.immobile}:</h3>
|
|
|
|
|
<p className="mb-2">
|
|
|
|
|
{t.contatto.indirizzo}: {propData.indirizzo}, {propData.civico}{" "}
|
|
|
|
|
{propData.comune} ({propData.provincia})
|
|
|
|
|
</p>
|
|
|
|
|
{navigationUrl && (
|
2026-03-18 18:01:02 +01:00
|
|
|
<Link href={navigationUrl} rel="noreferrer" target="_blank">
|
|
|
|
|
<Button variant="info">
|
|
|
|
|
<Navigation className="size-4" />
|
|
|
|
|
<span>{t.contatto.apri_nav}</span>
|
|
|
|
|
</Button>
|
|
|
|
|
</Link>
|
2025-11-03 10:59:45 +01:00
|
|
|
)}
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
{/* Warning */}
|
|
|
|
|
<div className="flex w-fit items-start gap-3 rounded-md bg-red-500 p-2 text-white">
|
|
|
|
|
<TriangleAlert className="size-6 shrink-0" />
|
|
|
|
|
<div className="space-y-1">
|
|
|
|
|
<p className="font-medium">{t.contatto.contatta}</p>
|
|
|
|
|
<p className="text-sm">{t.contatto.orari}</p>
|
|
|
|
|
</div>
|
2025-10-29 09:39:06 +01:00
|
|
|
</div>
|
|
|
|
|
|
2025-11-03 10:59:45 +01:00
|
|
|
{/* Metadata */}
|
|
|
|
|
<p className="text-muted-foreground text-sm">
|
2025-10-29 09:39:06 +01:00
|
|
|
{t.contatto.sbloccato_il}:{" "}
|
2025-11-03 10:59:45 +01:00
|
|
|
{opened_at.toLocaleString("it", {
|
2025-10-29 09:39:06 +01:00
|
|
|
day: "2-digit",
|
|
|
|
|
month: "2-digit",
|
|
|
|
|
year: "numeric",
|
2025-11-03 10:59:45 +01:00
|
|
|
hour: "2-digit",
|
|
|
|
|
minute: "2-digit",
|
2025-10-29 09:39:06 +01:00
|
|
|
})}
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
</CredenzaBody>
|
|
|
|
|
<CredenzaFooter>
|
|
|
|
|
<CredenzaClose asChild>
|
|
|
|
|
<Button aria-label="Chiudi modal credenza" variant="outline">
|
|
|
|
|
{t.chiudi}
|
|
|
|
|
</Button>
|
|
|
|
|
</CredenzaClose>
|
|
|
|
|
</CredenzaFooter>
|
|
|
|
|
</>
|
|
|
|
|
);
|
|
|
|
|
};
|