612 lines
19 KiB
TypeScript
612 lines
19 KiB
TypeScript
|
|
import Link from "next/link";
|
||
|
|
import { Button, type ButtonConfigs } from "~/components/ui/button";
|
||
|
|
import { useTranslation } from "~/providers/I18nProvider";
|
||
|
|
import { api } from "~/utils/api";
|
||
|
|
import toast from "react-hot-toast";
|
||
|
|
import {
|
||
|
|
Credenza,
|
||
|
|
CredenzaBody,
|
||
|
|
CredenzaClose,
|
||
|
|
CredenzaContent,
|
||
|
|
CredenzaDescription,
|
||
|
|
CredenzaFooter,
|
||
|
|
CredenzaHeader,
|
||
|
|
CredenzaTitle,
|
||
|
|
CredenzaTrigger,
|
||
|
|
} from "~/components/custom_ui/credenza";
|
||
|
|
import {
|
||
|
|
CircleCheck,
|
||
|
|
CircleUser,
|
||
|
|
FileBadge,
|
||
|
|
FileText,
|
||
|
|
Handshake,
|
||
|
|
Navigation,
|
||
|
|
PackageCheck,
|
||
|
|
Phone,
|
||
|
|
Pointer,
|
||
|
|
TriangleAlert,
|
||
|
|
} from "lucide-react";
|
||
|
|
import LoadingButton from "~/components/custom_ui/loading-button";
|
||
|
|
import { LoadingPage } from "~/components/loading";
|
||
|
|
import { useRouter } from "next/router";
|
||
|
|
import { cn } from "~/lib/utils";
|
||
|
|
import { useEffect, useState } from "react";
|
||
|
|
import { useServizio, useServizioAnnuncio } from "~/providers/ServizioProvider";
|
||
|
|
import {
|
||
|
|
Tooltip,
|
||
|
|
TooltipContent,
|
||
|
|
TooltipProvider,
|
||
|
|
TooltipTrigger,
|
||
|
|
} from "~/components/ui/tooltip";
|
||
|
|
import type { AnnunciId } from "~/schemas/public/Annunci";
|
||
|
|
|
||
|
|
export const Interactions = () => {
|
||
|
|
const { servizio, servizioId } = useServizio();
|
||
|
|
const { data, annuncioId } = useServizioAnnuncio();
|
||
|
|
|
||
|
|
return (
|
||
|
|
<>
|
||
|
|
<ContattiProprietarioModal />
|
||
|
|
{data.open_contatti_at !== null && data.user_confirmed_at == null && (
|
||
|
|
<AnnuncioConfirm />
|
||
|
|
)}
|
||
|
|
{data.user_confirmed_at && !data.hasConfermaAdmin && (
|
||
|
|
<ConfermaLavorazioneModal />
|
||
|
|
)}
|
||
|
|
{data.doc_conferma_added &&
|
||
|
|
data.accettato_conferma_at == null &&
|
||
|
|
data.hasConfermaAdmin &&
|
||
|
|
(data.doc_conferma_ref ? (
|
||
|
|
<Link
|
||
|
|
aria-label="Conferma immobile"
|
||
|
|
href={`/servizio/conferma-immobile/${servizioId}/${annuncioId}`}
|
||
|
|
>
|
||
|
|
<Button variant="success" className="flex w-fit items-center gap-2">
|
||
|
|
<Pointer className="size-6" />
|
||
|
|
Confermato - Procedi ora
|
||
|
|
</Button>
|
||
|
|
</Link>
|
||
|
|
) : (
|
||
|
|
<TooltipProvider delayDuration={0}>
|
||
|
|
<Tooltip>
|
||
|
|
<TooltipTrigger asChild>
|
||
|
|
<Button
|
||
|
|
variant="success"
|
||
|
|
className="flex w-fit cursor-not-allowed items-center gap-2 opacity-50"
|
||
|
|
>
|
||
|
|
<Pointer className="size-6" />
|
||
|
|
Confermato - Procedi ora
|
||
|
|
</Button>
|
||
|
|
</TooltipTrigger>
|
||
|
|
<TooltipContent>
|
||
|
|
<p>Il documento non è più disponibile</p>
|
||
|
|
<p>Se hai bisogno di una copia, contattaci via email o chat.</p>
|
||
|
|
</TooltipContent>
|
||
|
|
</Tooltip>
|
||
|
|
</TooltipProvider>
|
||
|
|
))}
|
||
|
|
{!servizio.isOkSaldo && data.accettato_conferma_at != null && (
|
||
|
|
<div className="flex flex-col gap-1">
|
||
|
|
<h3 className="font-semibold">
|
||
|
|
Questo annuncio è stato confermato, procedi al saldo:
|
||
|
|
</h3>
|
||
|
|
<SaldoButton annuncioId={annuncioId} />
|
||
|
|
</div>
|
||
|
|
)}
|
||
|
|
{data.accettato_conferma_at != null && (
|
||
|
|
<Link
|
||
|
|
aria-label="Conferma immobile"
|
||
|
|
href={`/servizio/riapri-conferma/${servizioId}/${annuncioId}`}
|
||
|
|
>
|
||
|
|
<Button variant="success" className="flex w-fit items-center gap-2">
|
||
|
|
<Pointer className="size-6" />
|
||
|
|
Rivedi la conferma
|
||
|
|
</Button>
|
||
|
|
</Link>
|
||
|
|
)}
|
||
|
|
{servizio.isOkSaldo &&
|
||
|
|
data.accettato_conferma_at != null &&
|
||
|
|
data.doc_contratto_added == null && (
|
||
|
|
<div className="flex flex-col gap-1">
|
||
|
|
<h3 className="font-semibold text-green-500">
|
||
|
|
Ci siamo quasi! Stiamo preparando il contratto per te.
|
||
|
|
</h3>
|
||
|
|
<h3 className="font-semibold">
|
||
|
|
Una volta pronto, riceverai una notifica via email.
|
||
|
|
</h3>
|
||
|
|
</div>
|
||
|
|
)}
|
||
|
|
{servizio.isOkSaldo &&
|
||
|
|
data.accettato_conferma_at != null &&
|
||
|
|
data.doc_contratto_added && (
|
||
|
|
<div className="flex flex-col gap-2">
|
||
|
|
<h3 className="font-semibold">
|
||
|
|
{servizio.isOkConsulenza
|
||
|
|
? "Il contratto è pronto, puoi visualizzarlo:"
|
||
|
|
: "Il contratto è pronto, puoi visualizzarlo e procedere al saldo:"}
|
||
|
|
</h3>
|
||
|
|
<div className="flex flex-wrap gap-2">
|
||
|
|
{data.doc_contratto_ref ? (
|
||
|
|
<Link
|
||
|
|
aria-label="Visualizza contratto"
|
||
|
|
href={`/servizio/contratto/${servizioId}/${annuncioId}`}
|
||
|
|
target="_blank"
|
||
|
|
>
|
||
|
|
<Button className="flex w-fit items-center gap-2">
|
||
|
|
<FileText className="size-6" />
|
||
|
|
Visualizza il contratto
|
||
|
|
</Button>
|
||
|
|
</Link>
|
||
|
|
) : (
|
||
|
|
<TooltipProvider delayDuration={0}>
|
||
|
|
<Tooltip>
|
||
|
|
<TooltipTrigger asChild>
|
||
|
|
<Button className="flex w-fit cursor-not-allowed items-center gap-2 opacity-50">
|
||
|
|
<FileText className="size-6" />
|
||
|
|
Visualizza il contratto
|
||
|
|
</Button>
|
||
|
|
</TooltipTrigger>
|
||
|
|
<TooltipContent>
|
||
|
|
<p>Il documento non è più disponibile</p>
|
||
|
|
<p>
|
||
|
|
Se hai bisogno di una copia, contattaci via email o
|
||
|
|
chat.
|
||
|
|
</p>
|
||
|
|
</TooltipContent>
|
||
|
|
</Tooltip>
|
||
|
|
</TooltipProvider>
|
||
|
|
)}
|
||
|
|
|
||
|
|
{!servizio.isOkConsulenza && data.contratto_tipo && (
|
||
|
|
<SaldoConsulenzaButton />
|
||
|
|
)}
|
||
|
|
|
||
|
|
{data.doc_registrazione_added &&
|
||
|
|
(data.doc_registrazione_ref ? (
|
||
|
|
<Link
|
||
|
|
aria-label="Visualizza registrazione"
|
||
|
|
href={`/servizio/contratto-registrazione/${servizioId}/${annuncioId}`}
|
||
|
|
target="_blank"
|
||
|
|
>
|
||
|
|
<Button className="flex w-fit items-center gap-2">
|
||
|
|
<FileBadge className="size-6" />
|
||
|
|
Visualizza la registrazione
|
||
|
|
</Button>
|
||
|
|
</Link>
|
||
|
|
) : (
|
||
|
|
<TooltipProvider delayDuration={0}>
|
||
|
|
<Tooltip>
|
||
|
|
<TooltipTrigger asChild>
|
||
|
|
<Button className="flex w-fit cursor-not-allowed items-center gap-2 opacity-50">
|
||
|
|
<FileBadge className="size-6" />
|
||
|
|
Visualizza la registrazione
|
||
|
|
</Button>
|
||
|
|
</TooltipTrigger>
|
||
|
|
<TooltipContent>
|
||
|
|
<p>Il documento non è più disponibile</p>
|
||
|
|
<p>
|
||
|
|
Se hai bisogno di una copia, contattaci via email o
|
||
|
|
chat.
|
||
|
|
</p>
|
||
|
|
</TooltipContent>
|
||
|
|
</Tooltip>
|
||
|
|
</TooltipProvider>
|
||
|
|
))}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
)}
|
||
|
|
</>
|
||
|
|
);
|
||
|
|
};
|
||
|
|
|
||
|
|
export const SaldoButton = ({
|
||
|
|
annuncioId,
|
||
|
|
variant = "info",
|
||
|
|
className,
|
||
|
|
}: {
|
||
|
|
annuncioId: AnnunciId;
|
||
|
|
variant?: ButtonConfigs["variant"];
|
||
|
|
className?: string;
|
||
|
|
}) => {
|
||
|
|
const { servizioId } = useServizio();
|
||
|
|
const router = useRouter();
|
||
|
|
|
||
|
|
const { mutate } = api.servizio.setupSaldoServizio.useMutation({
|
||
|
|
onMutate: () => {
|
||
|
|
toast.loading("Caricamento ...", { id: "preparazioneSaldo" });
|
||
|
|
},
|
||
|
|
onSuccess: async (data) => {
|
||
|
|
toast.success("Pagamento saldo preparato", {
|
||
|
|
id: "preparazioneSaldo",
|
||
|
|
});
|
||
|
|
|
||
|
|
await router.push(`/servizio/pagamento/${data}`);
|
||
|
|
},
|
||
|
|
});
|
||
|
|
return (
|
||
|
|
<Button
|
||
|
|
aria-label="Procedi al saldo"
|
||
|
|
variant={variant}
|
||
|
|
className={cn("flex w-fit items-center gap-2", className)}
|
||
|
|
onClick={() => {
|
||
|
|
mutate({
|
||
|
|
servizioId,
|
||
|
|
annuncioId,
|
||
|
|
});
|
||
|
|
}}
|
||
|
|
>
|
||
|
|
<PackageCheck className="size-6" />
|
||
|
|
Procedi al saldo
|
||
|
|
</Button>
|
||
|
|
);
|
||
|
|
};
|
||
|
|
|
||
|
|
const SaldoConsulenzaButton = ({
|
||
|
|
variant = "info",
|
||
|
|
className,
|
||
|
|
}: {
|
||
|
|
variant?: ButtonConfigs["variant"];
|
||
|
|
className?: string;
|
||
|
|
}) => {
|
||
|
|
const { annuncioId } = useServizioAnnuncio();
|
||
|
|
const { servizioId } = useServizio();
|
||
|
|
const router = useRouter();
|
||
|
|
|
||
|
|
const { mutate } = api.servizio.setupSaldoConsulenzaServizio.useMutation({
|
||
|
|
onMutate: () => {
|
||
|
|
toast.loading("Caricamento ...", { id: "preparazioneSaldo" });
|
||
|
|
},
|
||
|
|
onSuccess: async (data) => {
|
||
|
|
toast.success("Pagamento saldo preparato", {
|
||
|
|
id: "preparazioneSaldo",
|
||
|
|
});
|
||
|
|
|
||
|
|
await router.push(`/servizio/pagamento/${data}`);
|
||
|
|
},
|
||
|
|
});
|
||
|
|
return (
|
||
|
|
<Button
|
||
|
|
aria-label="Procedi al saldo consulenza"
|
||
|
|
variant={variant}
|
||
|
|
className={cn("flex w-fit items-center gap-2", className)}
|
||
|
|
onClick={() => {
|
||
|
|
mutate({
|
||
|
|
servizioId,
|
||
|
|
annuncioId,
|
||
|
|
});
|
||
|
|
}}
|
||
|
|
>
|
||
|
|
<PackageCheck className="size-6" />
|
||
|
|
Procedi al saldo della consulenza
|
||
|
|
</Button>
|
||
|
|
);
|
||
|
|
};
|
||
|
|
|
||
|
|
const AnnuncioConfirm = () => {
|
||
|
|
const { userId, servizioId } = useServizio();
|
||
|
|
const { annuncioId } = useServizioAnnuncio();
|
||
|
|
const { t } = useTranslation();
|
||
|
|
const [open, setOpen] = useState(false);
|
||
|
|
const utils = api.useUtils();
|
||
|
|
const { mutate, isPending } = api.servizio.userConfirmImmobile.useMutation({
|
||
|
|
onMutate: () => {
|
||
|
|
toast.loading("Conferma in corso", { id: "updateRichiestaToast" });
|
||
|
|
},
|
||
|
|
onError: (err) => {
|
||
|
|
toast.error(err.message, { id: "updateRichiestaToast" });
|
||
|
|
},
|
||
|
|
onSuccess: async () => {
|
||
|
|
toast.success("Richiesta confermata con successo", {
|
||
|
|
id: "updateRichiestaToast",
|
||
|
|
});
|
||
|
|
|
||
|
|
await utils.servizio.getAllServizioAnnunci.invalidate({ userId });
|
||
|
|
setOpen(false);
|
||
|
|
},
|
||
|
|
});
|
||
|
|
return (
|
||
|
|
<Credenza open={open} onOpenChange={setOpen}>
|
||
|
|
<CredenzaTrigger asChild>
|
||
|
|
<Button
|
||
|
|
className="flex w-fit items-center gap-2"
|
||
|
|
aria-label="Conferma immobile"
|
||
|
|
>
|
||
|
|
<Handshake className="size-6" /> Conferma immobile
|
||
|
|
</Button>
|
||
|
|
</CredenzaTrigger>
|
||
|
|
<CredenzaContent className="max-h-[90vh]">
|
||
|
|
<CredenzaHeader>
|
||
|
|
<CredenzaTitle> {t.richieste.conf_title}</CredenzaTitle>
|
||
|
|
<CredenzaDescription className="sr-only">
|
||
|
|
{t.richieste.conf_desc}
|
||
|
|
</CredenzaDescription>
|
||
|
|
</CredenzaHeader>
|
||
|
|
<CredenzaBody className="max-h-[80vh] overflow-auto pb-5">
|
||
|
|
<p>{t.richieste.conferma_txt}</p>
|
||
|
|
</CredenzaBody>
|
||
|
|
<CredenzaFooter>
|
||
|
|
<LoadingButton
|
||
|
|
aria-label="Conferma immobile"
|
||
|
|
loading={isPending}
|
||
|
|
variant="success"
|
||
|
|
onClick={() => {
|
||
|
|
mutate({
|
||
|
|
annuncioId,
|
||
|
|
servizioId,
|
||
|
|
});
|
||
|
|
}}
|
||
|
|
>
|
||
|
|
{t.conferma}
|
||
|
|
</LoadingButton>
|
||
|
|
<CredenzaClose asChild>
|
||
|
|
<Button aria-label="Chiudi modal credenza">Chiudi</Button>
|
||
|
|
</CredenzaClose>
|
||
|
|
</CredenzaFooter>
|
||
|
|
</CredenzaContent>
|
||
|
|
</Credenza>
|
||
|
|
);
|
||
|
|
};
|
||
|
|
const ConfermaLavorazioneModal = () => {
|
||
|
|
const { t } = useTranslation();
|
||
|
|
const { data } = useServizioAnnuncio();
|
||
|
|
return (
|
||
|
|
<Credenza>
|
||
|
|
<CredenzaTrigger asChild>
|
||
|
|
<Button
|
||
|
|
className="flex w-fit items-center gap-2"
|
||
|
|
aria-label="Conferma in lavorazione"
|
||
|
|
>
|
||
|
|
<CircleCheck className="size-7" />
|
||
|
|
Conferma in lavorazione
|
||
|
|
</Button>
|
||
|
|
</CredenzaTrigger>
|
||
|
|
<CredenzaContent className="max-h-[90vh]">
|
||
|
|
<CredenzaHeader>
|
||
|
|
<CredenzaTitle>In attesa di conferma</CredenzaTitle>
|
||
|
|
<CredenzaDescription className="sr-only">
|
||
|
|
Consegna status modal
|
||
|
|
</CredenzaDescription>
|
||
|
|
</CredenzaHeader>
|
||
|
|
<CredenzaBody className="prose max-h-[80vh] overflow-auto pb-5">
|
||
|
|
<p>
|
||
|
|
Richiesta di conferma inviata il:{" "}
|
||
|
|
{data.user_confirmed_at &&
|
||
|
|
new Date(data.user_confirmed_at).toLocaleString("it", {
|
||
|
|
day: "2-digit",
|
||
|
|
month: "2-digit",
|
||
|
|
year: "numeric",
|
||
|
|
hour: "2-digit",
|
||
|
|
minute: "2-digit",
|
||
|
|
})}
|
||
|
|
</p>
|
||
|
|
<p>
|
||
|
|
La conferma è ancora in lavorazione. Stiamo verificando con i
|
||
|
|
proprietari le condizioni e dettagli della conferma per riferirteli.
|
||
|
|
Attendi una comunicazione.
|
||
|
|
</p>
|
||
|
|
</CredenzaBody>
|
||
|
|
|
||
|
|
<CredenzaFooter>
|
||
|
|
<CredenzaClose asChild>
|
||
|
|
<Button variant="outline" aria-label="Chiudi modal credenza">
|
||
|
|
{t.chiudi}
|
||
|
|
</Button>
|
||
|
|
</CredenzaClose>
|
||
|
|
</CredenzaFooter>
|
||
|
|
</CredenzaContent>
|
||
|
|
</Credenza>
|
||
|
|
);
|
||
|
|
};
|
||
|
|
|
||
|
|
const ContattiProprietarioModal = () => {
|
||
|
|
const { servizioId, userId } = useServizio();
|
||
|
|
const { data, annuncioId } = useServizioAnnuncio();
|
||
|
|
const { t } = useTranslation();
|
||
|
|
const [showContacts, setShowContacts] = useState<boolean>(
|
||
|
|
data.open_contatti_at != null,
|
||
|
|
);
|
||
|
|
const utils = api.useUtils();
|
||
|
|
|
||
|
|
const { mutate } = api.servizio.unlockServizioContatti.useMutation({
|
||
|
|
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",
|
||
|
|
});
|
||
|
|
await utils.servizio.getAllServizioAnnunci.invalidate({
|
||
|
|
userId,
|
||
|
|
});
|
||
|
|
setShowContacts(true);
|
||
|
|
},
|
||
|
|
onError: (err) => {
|
||
|
|
toast.error(err.message, {
|
||
|
|
id: "unlock-contacts",
|
||
|
|
});
|
||
|
|
},
|
||
|
|
});
|
||
|
|
|
||
|
|
const d = new Date();
|
||
|
|
const tooEarly = d.getHours() < 9;
|
||
|
|
const tooLate = d.getHours() >= 20;
|
||
|
|
|
||
|
|
return (
|
||
|
|
<Credenza>
|
||
|
|
<CredenzaTrigger asChild>
|
||
|
|
{showContacts ? (
|
||
|
|
<Button
|
||
|
|
variant="success"
|
||
|
|
className="flex w-fit items-center gap-2"
|
||
|
|
aria-label="Vedi contatti proprietario"
|
||
|
|
>
|
||
|
|
<CircleUser className="size-7" />
|
||
|
|
Vedi i contatti
|
||
|
|
</Button>
|
||
|
|
) : (
|
||
|
|
<Button
|
||
|
|
variant="warning"
|
||
|
|
className="flex w-fit items-center gap-2"
|
||
|
|
aria-label="Contatta proprietario"
|
||
|
|
>
|
||
|
|
<CircleUser className="size-7" />
|
||
|
|
Ottieni i contatti
|
||
|
|
</Button>
|
||
|
|
)}
|
||
|
|
</CredenzaTrigger>
|
||
|
|
<CredenzaContent className="max-h-[90vh]">
|
||
|
|
<CredenzaHeader>
|
||
|
|
<CredenzaTitle>{t.contatto.title}</CredenzaTitle>
|
||
|
|
<CredenzaDescription className="sr-only">
|
||
|
|
{t.contatto.descrizione}
|
||
|
|
</CredenzaDescription>
|
||
|
|
</CredenzaHeader>
|
||
|
|
<CredenzaBody className="max-h-[80vh] overflow-auto pb-5">
|
||
|
|
{showContacts ? (
|
||
|
|
<ContattiProprietarioData />
|
||
|
|
) : (
|
||
|
|
<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>
|
||
|
|
{(tooEarly || tooLate) && (
|
||
|
|
<div className="flex items-center gap-2 rounded-md bg-yellow-200 p-2">
|
||
|
|
<TriangleAlert className="size-8" />
|
||
|
|
{/*TODO testare */}
|
||
|
|
<p>
|
||
|
|
Il proprietario riceverà la notifica alle ore 9.00{" "}
|
||
|
|
{tooLate && "di domani"}
|
||
|
|
</p>
|
||
|
|
</div>
|
||
|
|
)}
|
||
|
|
</div>
|
||
|
|
)}
|
||
|
|
</CredenzaBody>
|
||
|
|
<CredenzaFooter>
|
||
|
|
{!showContacts && (
|
||
|
|
<Button
|
||
|
|
aria-label="Contatta proprietario"
|
||
|
|
variant="success"
|
||
|
|
onClick={() =>
|
||
|
|
mutate({
|
||
|
|
servizioId,
|
||
|
|
annuncioId,
|
||
|
|
})
|
||
|
|
}
|
||
|
|
>
|
||
|
|
{t.accetta}
|
||
|
|
</Button>
|
||
|
|
)}
|
||
|
|
<CredenzaClose asChild>
|
||
|
|
<Button variant="outline" aria-label="Chiudi modal credenza">
|
||
|
|
{t.chiudi}
|
||
|
|
</Button>
|
||
|
|
</CredenzaClose>
|
||
|
|
</CredenzaFooter>
|
||
|
|
</CredenzaContent>
|
||
|
|
</Credenza>
|
||
|
|
);
|
||
|
|
};
|
||
|
|
|
||
|
|
const ContattiProprietarioData = () => {
|
||
|
|
const { servizioId } = useServizio();
|
||
|
|
const { annuncioId } = useServizioAnnuncio();
|
||
|
|
const { data, isLoading } = api.annunci.getProprietarioData.useQuery({
|
||
|
|
annuncioId,
|
||
|
|
servizioId,
|
||
|
|
});
|
||
|
|
const [navigationUrl, setNavigationUrl] = useState<string | undefined>(
|
||
|
|
undefined,
|
||
|
|
);
|
||
|
|
const { t } = useTranslation();
|
||
|
|
useEffect(() => {
|
||
|
|
if (!data || !data.propData) return;
|
||
|
|
if (typeof window === "undefined") return;
|
||
|
|
if (
|
||
|
|
navigator.userAgent.toUpperCase().includes("MAC") ||
|
||
|
|
navigator.userAgent.toUpperCase().includes("IPAD") ||
|
||
|
|
navigator.userAgent.toUpperCase().includes("IPHONE") ||
|
||
|
|
navigator.userAgent.toUpperCase().includes("IOS") ||
|
||
|
|
navigator.userAgent.toUpperCase().includes("IPOD")
|
||
|
|
) {
|
||
|
|
setNavigationUrl(
|
||
|
|
`maps://www.google.com/maps/dir/?api=1&travelmode=driving&layer=traffic&destination=${data.propData.lat},${data.propData.lon}`,
|
||
|
|
);
|
||
|
|
} else {
|
||
|
|
setNavigationUrl(
|
||
|
|
`https://www.google.com/maps/dir/?api=1&travelmode=driving&layer=traffic&destination=${data.propData.lat},${data.propData.lon}`,
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}, [data]);
|
||
|
|
|
||
|
|
if (isLoading) {
|
||
|
|
return (
|
||
|
|
<div className="flex justify-center">
|
||
|
|
<LoadingPage />
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|
||
|
|
if (!data || !data.propData) {
|
||
|
|
return <p>{t.contatto.error}</p>;
|
||
|
|
}
|
||
|
|
|
||
|
|
return (
|
||
|
|
<div className="flex flex-col gap-2">
|
||
|
|
<h3 className="font-semibold">{t.contatto.propietario}:</h3>
|
||
|
|
<p>
|
||
|
|
{t.contatto.nome}: {data.propData.locatore}
|
||
|
|
</p>
|
||
|
|
<a
|
||
|
|
href={`tel:${data.propData.numero}`}
|
||
|
|
className="flex items-center gap-2"
|
||
|
|
>
|
||
|
|
<Phone />:
|
||
|
|
<span className="text-blue-600 underline">{data.propData.numero}</span>
|
||
|
|
</a>
|
||
|
|
<br />
|
||
|
|
<h3 className="font-semibold">{t.contatto.immobile}:</h3>
|
||
|
|
<p>
|
||
|
|
{t.contatto.indirizzo}: {data.propData.indirizzo},{" "}
|
||
|
|
{data.propData.civico} {data.propData.comune} ({data.propData.provincia}
|
||
|
|
)
|
||
|
|
</p>
|
||
|
|
<a
|
||
|
|
target="_blank"
|
||
|
|
rel="noreferrer"
|
||
|
|
href={navigationUrl}
|
||
|
|
className="border-border flex w-fit items-center gap-2 rounded-md border px-3 py-2"
|
||
|
|
>
|
||
|
|
<Navigation /> <span>{t.contatto.apri_nav}</span>
|
||
|
|
</a>
|
||
|
|
<br />
|
||
|
|
<p>
|
||
|
|
{t.contatto.sbloccato_il}:{" "}
|
||
|
|
{data.opened_at.toLocaleString("it", {
|
||
|
|
day: "2-digit",
|
||
|
|
month: "2-digit",
|
||
|
|
year: "numeric",
|
||
|
|
hour: "2-digit",
|
||
|
|
minute: "2-digit",
|
||
|
|
})}
|
||
|
|
</p>
|
||
|
|
<div className="flex items-center gap-2 rounded-md bg-sky-200 p-2">
|
||
|
|
<TriangleAlert className="size-8" />
|
||
|
|
<div>
|
||
|
|
<p>{t.contatto.contatta}</p>
|
||
|
|
<p className="font-semibold">{t.contatto.orari}</p>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
};
|