refactor: streamline AnnuncioCard and CompatibiliDialog components, enhance data handling and styling
This commit is contained in:
parent
b741f7ce72
commit
de034c0eb7
5 changed files with 155 additions and 291 deletions
|
|
@ -1,53 +1,17 @@
|
||||||
import { ExternalLink, UnfoldVertical } from "lucide-react";
|
import { ExternalLink } from "lucide-react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import {
|
|
||||||
Credenza,
|
|
||||||
CredenzaBody,
|
|
||||||
CredenzaClose,
|
|
||||||
CredenzaContent,
|
|
||||||
CredenzaDescription,
|
|
||||||
CredenzaFooter,
|
|
||||||
CredenzaHeader,
|
|
||||||
CredenzaTitle,
|
|
||||||
CredenzaTrigger,
|
|
||||||
} from "~/components/custom_ui/credenza";
|
|
||||||
import { ImageFlbk } from "~/components/ImageWithFallback";
|
import { ImageFlbk } from "~/components/ImageWithFallback";
|
||||||
import { AnnuncioActions } from "~/components/servizio/annuncio_actions";
|
import { AnnuncioActions } from "~/components/servizio/annuncio_actions";
|
||||||
import { Interactions } from "~/components/servizio/interactions";
|
import { Interactions } from "~/components/servizio/interactions";
|
||||||
import { Button } from "~/components/ui/button";
|
import { Button } from "~/components/ui/button";
|
||||||
import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card";
|
import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card";
|
||||||
import {
|
|
||||||
Carousel,
|
|
||||||
CarouselContent,
|
|
||||||
CarouselItem,
|
|
||||||
CarouselNext,
|
|
||||||
CarouselPrevious,
|
|
||||||
} from "~/components/ui/carousel";
|
|
||||||
import { handleConsegna } from "~/lib/annuncio_details";
|
import { handleConsegna } from "~/lib/annuncio_details";
|
||||||
import { replaceWithBr } from "~/lib/newlineToBr";
|
|
||||||
import { cn, formatCurrency } from "~/lib/utils";
|
import { cn, formatCurrency } from "~/lib/utils";
|
||||||
import { useTranslation } from "~/providers/I18nProvider";
|
import { useTranslation } from "~/providers/I18nProvider";
|
||||||
import { useServizioAnnuncio } from "~/providers/ServizioProvider";
|
import { useServizioAnnuncio } from "~/providers/ServizioProvider";
|
||||||
import type { Annunci } from "~/schemas/public/Annunci";
|
import type { AnnuncioRicerca } from "~/server/controllers/annunci.controller";
|
||||||
import { Badge } from "../ui/badge";
|
import { AnnuncioDettaglio, TipoBadge } from "./annuncio_dettaglio";
|
||||||
|
|
||||||
type AnnuncioData = Pick<
|
|
||||||
Annunci,
|
|
||||||
| "id"
|
|
||||||
| "codice"
|
|
||||||
| "prezzo"
|
|
||||||
| "desc_en"
|
|
||||||
| "desc_it"
|
|
||||||
| "titolo_en"
|
|
||||||
| "titolo_it"
|
|
||||||
| "tipo"
|
|
||||||
| "consegna"
|
|
||||||
| "stato"
|
|
||||||
| "web"
|
|
||||||
| "media_updated_at"
|
|
||||||
> & {
|
|
||||||
images: Pick<{ img: string; thumb: string }, "img">[];
|
|
||||||
};
|
|
||||||
export const AnnuncioCard = ({ className }: { className?: string }) => {
|
export const AnnuncioCard = ({ className }: { className?: string }) => {
|
||||||
const { data } = useServizioAnnuncio();
|
const { data } = useServizioAnnuncio();
|
||||||
|
|
||||||
|
|
@ -57,6 +21,7 @@ export const AnnuncioCard = ({ className }: { className?: string }) => {
|
||||||
className={className}
|
className={className}
|
||||||
data={{
|
data={{
|
||||||
...data,
|
...data,
|
||||||
|
modificato_il: data.modificato_il ? new Date(data.modificato_il) : null,
|
||||||
media_updated_at: data.media_updated_at
|
media_updated_at: data.media_updated_at
|
||||||
? new Date(data.media_updated_at)
|
? new Date(data.media_updated_at)
|
||||||
: null,
|
: null,
|
||||||
|
|
@ -74,7 +39,7 @@ export const BasicAnnuncioCard = ({
|
||||||
actions?: React.ReactNode;
|
actions?: React.ReactNode;
|
||||||
interactions?: React.ReactNode;
|
interactions?: React.ReactNode;
|
||||||
className?: string;
|
className?: string;
|
||||||
data: AnnuncioData;
|
data: AnnuncioRicerca;
|
||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
|
@ -136,125 +101,3 @@ export const BasicAnnuncioCard = ({
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const TipoBadge = ({ tipo }: { tipo: Annunci["tipo"] }) => {
|
|
||||||
return (
|
|
||||||
<Badge
|
|
||||||
className={cn(
|
|
||||||
"font-semibold text-md",
|
|
||||||
tipo === "Transitorio" && "bg-transitorio",
|
|
||||||
tipo === "Stabile" && "bg-stabile",
|
|
||||||
tipo === "Cessione" && "bg-blue-400",
|
|
||||||
tipo === "Vendita" && "bg-green-400",
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
Affitto {tipo}
|
|
||||||
</Badge>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const AnnuncioDettaglio = ({ data }: { data: AnnuncioData }) => {
|
|
||||||
const { locale, t } = useTranslation();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Credenza>
|
|
||||||
<CredenzaTrigger asChild>
|
|
||||||
<Button aria-label="Dettagli Annuncio" variant="outline">
|
|
||||||
<UnfoldVertical className="size-6" /> Dettagli annuncio
|
|
||||||
</Button>
|
|
||||||
</CredenzaTrigger>
|
|
||||||
<CredenzaContent className="max-h-[90vh] md:max-w-6xl">
|
|
||||||
<CredenzaHeader>
|
|
||||||
<CredenzaTitle className="text-xl">
|
|
||||||
Annuncio {data.codice}
|
|
||||||
</CredenzaTitle>
|
|
||||||
<CredenzaDescription className="sr-only">
|
|
||||||
Annuncio {data.codice}
|
|
||||||
</CredenzaDescription>
|
|
||||||
</CredenzaHeader>
|
|
||||||
<CredenzaBody className="scrollbar-default max-h-[80vh] overflow-y-auto pb-5">
|
|
||||||
<div className="flex flex-col gap-2 px-2">
|
|
||||||
<Carousel opts={{ loop: true }}>
|
|
||||||
<CarouselContent>
|
|
||||||
{data?.images?.map((img, idx) => (
|
|
||||||
<CarouselItem key={img.img}>
|
|
||||||
<ImageFlbk
|
|
||||||
alt={`${data.codice} - ${idx}`}
|
|
||||||
className={"h-80 w-full object-contain sm:h-[35rem]"}
|
|
||||||
height={200}
|
|
||||||
priority={idx === 0}
|
|
||||||
src={`/storage-api/get/${img.img}?image=true&${data.media_updated_at?.toString() || new Date().toString()}`}
|
|
||||||
width={400}
|
|
||||||
/>
|
|
||||||
</CarouselItem>
|
|
||||||
))}
|
|
||||||
</CarouselContent>
|
|
||||||
<div
|
|
||||||
className="block opacity-0 transition-all duration-200 group-hover:opacity-60 disabled:group-hover:opacity-0"
|
|
||||||
onClick={(e) => e.preventDefault()}
|
|
||||||
onKeyDown={(e) => e.stopPropagation()}
|
|
||||||
role="button"
|
|
||||||
tabIndex={0}
|
|
||||||
>
|
|
||||||
<CarouselPrevious
|
|
||||||
className="left-2 cursor-pointer"
|
|
||||||
disabled={!data.images || data.images.length === 1}
|
|
||||||
/>
|
|
||||||
<CarouselNext
|
|
||||||
className="right-2 cursor-pointer"
|
|
||||||
disabled={!data.images || data.images.length === 1}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</Carousel>
|
|
||||||
<div>
|
|
||||||
<TipoBadge tipo={data.tipo} />
|
|
||||||
|
|
||||||
<div className="mt-1 space-y-2">
|
|
||||||
<div className="flex flex-row justify-around">
|
|
||||||
<div className="text-center">
|
|
||||||
<dt className="sr-only">{t.card.codice}</dt>
|
|
||||||
|
|
||||||
<dd className="font-semibold text-lg">
|
|
||||||
Cod: {data.codice}
|
|
||||||
</dd>
|
|
||||||
</div>
|
|
||||||
<div className="text-center">
|
|
||||||
<dt className="sr-only">{t.card.prezzo}</dt>
|
|
||||||
|
|
||||||
<dd className="font-semibold text-lg">
|
|
||||||
{formatCurrency(data.prezzo / 1e2)}
|
|
||||||
</dd>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="mb-3">
|
|
||||||
<dt className="sr-only">{t.card.titolo}</dt>
|
|
||||||
|
|
||||||
<dd className="font-semibold text-base md:text-lg">
|
|
||||||
{locale === "it" ? data.titolo_it : data.titolo_en}
|
|
||||||
</dd>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="mb-3">
|
|
||||||
<dd
|
|
||||||
className="text-base"
|
|
||||||
dangerouslySetInnerHTML={{
|
|
||||||
__html: replaceWithBr(
|
|
||||||
(locale === "it" ? data.desc_it : data.desc_en) || "",
|
|
||||||
),
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</CredenzaBody>
|
|
||||||
<CredenzaFooter>
|
|
||||||
<CredenzaClose asChild>
|
|
||||||
<Button aria-label="Chiudi Credenza">{t.chiudi}</Button>
|
|
||||||
</CredenzaClose>
|
|
||||||
</CredenzaFooter>
|
|
||||||
</CredenzaContent>
|
|
||||||
</Credenza>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
|
||||||
118
apps/infoalloggi/src/components/servizio/annuncio_dettaglio.tsx
Normal file
118
apps/infoalloggi/src/components/servizio/annuncio_dettaglio.tsx
Normal file
|
|
@ -0,0 +1,118 @@
|
||||||
|
import { ExternalLink, UnfoldVertical } from "lucide-react";
|
||||||
|
import Link from "next/link";
|
||||||
|
import { replaceWithBr } from "~/lib/newlineToBr";
|
||||||
|
import { cn, formatCurrency } from "~/lib/utils";
|
||||||
|
import { useTranslation } from "~/providers/I18nProvider";
|
||||||
|
import type { Annunci } from "~/schemas/public/Annunci";
|
||||||
|
import type { AnnuncioRicerca } from "~/server/controllers/annunci.controller";
|
||||||
|
import { CarouselAnnuncio } from "../annuncio_card";
|
||||||
|
import { Badge } from "../ui/badge";
|
||||||
|
import { Button } from "../ui/button";
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogDescription,
|
||||||
|
DialogHeader,
|
||||||
|
DialogTitle,
|
||||||
|
DialogTrigger,
|
||||||
|
} from "../ui/dialog";
|
||||||
|
|
||||||
|
export const TipoBadge = ({ tipo }: { tipo: Annunci["tipo"] }) => {
|
||||||
|
return (
|
||||||
|
<Badge
|
||||||
|
className={cn(
|
||||||
|
"font-semibold text-md",
|
||||||
|
tipo === "Transitorio" && "bg-transitorio",
|
||||||
|
tipo === "Stabile" && "bg-stabile",
|
||||||
|
tipo === "Cessione" && "bg-blue-400",
|
||||||
|
tipo === "Vendita" && "bg-green-400",
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
Affitto {tipo}
|
||||||
|
</Badge>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const AnnuncioDettaglio = ({ data }: { data: AnnuncioRicerca }) => {
|
||||||
|
const { locale, t } = useTranslation();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog>
|
||||||
|
<DialogTrigger asChild>
|
||||||
|
<Button aria-label="Dettagli Annuncio" variant="outline">
|
||||||
|
<UnfoldVertical className="size-6" /> Dettagli annuncio
|
||||||
|
</Button>
|
||||||
|
</DialogTrigger>
|
||||||
|
<DialogContent className="max-h-[70vh] max-w-xl overflow-y-auto sm:max-w-6xl">
|
||||||
|
<DialogHeader className="flex-row items-center gap-4">
|
||||||
|
<DialogTitle className="text-xl">Annuncio {data.codice}</DialogTitle>
|
||||||
|
<Link href={`/annuncio/${data.codice}`} target="_blank">
|
||||||
|
<Button size="sm" variant="info">
|
||||||
|
<span>Vai alla pagina completa</span>{" "}
|
||||||
|
<ExternalLink className="size-4" />
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
<DialogDescription className="sr-only">
|
||||||
|
Annuncio {data.codice}
|
||||||
|
</DialogDescription>
|
||||||
|
</DialogHeader>
|
||||||
|
<div className="flex flex-col gap-2 px-2">
|
||||||
|
<div className="w-full contain-inline-size">
|
||||||
|
<CarouselAnnuncio
|
||||||
|
immagini={data.images.map((img) => img.img)}
|
||||||
|
updated_at={data.media_updated_at}
|
||||||
|
videos={data.url_video}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div className="flex items-center gap-4">
|
||||||
|
<TipoBadge tipo={data.tipo} />
|
||||||
|
{data.stato === "Trattativa" && (
|
||||||
|
<Badge className="bg-violet-500 font-semibold text-md">
|
||||||
|
Annuncio in Trattativa
|
||||||
|
</Badge>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-1 space-y-2">
|
||||||
|
<div className="flex flex-row justify-around">
|
||||||
|
<div className="text-center">
|
||||||
|
<dt className="sr-only">{t.card.codice}</dt>
|
||||||
|
|
||||||
|
<dd className="font-semibold text-lg">Cod: {data.codice}</dd>
|
||||||
|
</div>
|
||||||
|
<div className="text-center">
|
||||||
|
<dt className="sr-only">{t.card.prezzo}</dt>
|
||||||
|
|
||||||
|
<dd className="font-semibold text-lg">
|
||||||
|
{formatCurrency(data.prezzo / 1e2)}
|
||||||
|
</dd>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mb-3">
|
||||||
|
<dt className="sr-only">{t.card.titolo}</dt>
|
||||||
|
|
||||||
|
<dd className="font-semibold text-base md:text-lg">
|
||||||
|
{locale === "it" ? data.titolo_it : data.titolo_en}
|
||||||
|
</dd>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mb-3">
|
||||||
|
<dd
|
||||||
|
className="text-base"
|
||||||
|
dangerouslySetInnerHTML={{
|
||||||
|
__html: replaceWithBr(
|
||||||
|
(locale === "it" ? data.desc_it : data.desc_en) || "",
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
@ -1,17 +1,9 @@
|
||||||
import { ExternalLink, UnfoldVertical } from "lucide-react";
|
|
||||||
import Link from "next/link";
|
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { replaceWithBr } from "~/lib/newlineToBr";
|
|
||||||
import { cn, formatCurrency } from "~/lib/utils";
|
|
||||||
import { useTranslation } from "~/providers/I18nProvider";
|
|
||||||
import { useServizio } from "~/providers/ServizioProvider";
|
import { useServizio } from "~/providers/ServizioProvider";
|
||||||
import type { Annunci } from "~/schemas/public/Annunci";
|
|
||||||
import type { AnnuncioRicerca } from "~/server/controllers/annunci.controller";
|
|
||||||
import { api } from "~/utils/api";
|
import { api } from "~/utils/api";
|
||||||
import { CardAnnuncio, CarouselAnnuncio } from "../annuncio_card";
|
import { CardAnnuncio } from "../annuncio_card";
|
||||||
import { InteressatoButtonServizio } from "../annuncio-interactions/annuncio_interactions";
|
import { InteressatoButtonServizio } from "../annuncio-interactions/annuncio_interactions";
|
||||||
import { LoadingPage } from "../loading";
|
import { LoadingPage } from "../loading";
|
||||||
import { Badge } from "../ui/badge";
|
|
||||||
import { Button } from "../ui/button";
|
import { Button } from "../ui/button";
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
|
|
@ -25,6 +17,7 @@ import {
|
||||||
} from "../ui/dialog";
|
} from "../ui/dialog";
|
||||||
import { Label } from "../ui/label";
|
import { Label } from "../ui/label";
|
||||||
import { Switch } from "../ui/switch";
|
import { Switch } from "../ui/switch";
|
||||||
|
import { AnnuncioDettaglio } from "./annuncio_dettaglio";
|
||||||
|
|
||||||
export const AnnunciCompatibili = () => {
|
export const AnnunciCompatibili = () => {
|
||||||
const { servizioId, isAdmin } = useServizio();
|
const { servizioId, isAdmin } = useServizio();
|
||||||
|
|
@ -36,7 +29,7 @@ export const AnnunciCompatibili = () => {
|
||||||
return (
|
return (
|
||||||
<Dialog>
|
<Dialog>
|
||||||
<DialogTrigger asChild>
|
<DialogTrigger asChild>
|
||||||
<Button className="w-full bg-purple-500 sm:w-fit">
|
<Button className="w-full bg-purple-500 hover:bg-purple-600 sm:w-fit dark:text-white">
|
||||||
Esplora Annunci Compatibili
|
Esplora Annunci Compatibili
|
||||||
</Button>
|
</Button>
|
||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
|
|
@ -67,12 +60,10 @@ export const AnnunciCompatibili = () => {
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
{!data || data.length === 0 ? (
|
{!data || data.length === 0 ? (
|
||||||
<div className="flex items-center justify-center gap-1 rounded-md bg-white p-4 sm:flex">
|
|
||||||
<span>
|
<span>
|
||||||
Nessun annuncio compatibile trovato. Amplia la ricerca per
|
Nessun annuncio compatibile trovato. Amplia la ricerca per
|
||||||
trovare annunci compatibili.
|
trovare annunci compatibili.
|
||||||
</span>
|
</span>
|
||||||
</div>
|
|
||||||
) : (
|
) : (
|
||||||
<div className="relative z-0 mx-auto grid max-w-full grid-flow-row grid-cols-1 gap-4 sm:grid-cols-2 sm:gap-6 sm:gap-y-10 lg:grid-cols-3 2xl:grid-cols-4">
|
<div className="relative z-0 mx-auto grid max-w-full grid-flow-row grid-cols-1 gap-4 sm:grid-cols-2 sm:gap-6 sm:gap-y-10 lg:grid-cols-3 2xl:grid-cols-4">
|
||||||
{data.map((annuncio) => (
|
{data.map((annuncio) => (
|
||||||
|
|
@ -109,106 +100,3 @@ export const AnnunciCompatibili = () => {
|
||||||
</Dialog>
|
</Dialog>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const TipoBadge = ({ tipo }: { tipo: Annunci["tipo"] }) => {
|
|
||||||
return (
|
|
||||||
<Badge
|
|
||||||
className={cn(
|
|
||||||
"font-semibold text-md",
|
|
||||||
tipo === "Transitorio" && "bg-transitorio",
|
|
||||||
tipo === "Stabile" && "bg-stabile",
|
|
||||||
tipo === "Cessione" && "bg-blue-400",
|
|
||||||
tipo === "Vendita" && "bg-green-400",
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
Affitto {tipo}
|
|
||||||
</Badge>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const AnnuncioDettaglio = ({ data }: { data: AnnuncioRicerca }) => {
|
|
||||||
const { locale, t } = useTranslation();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Dialog>
|
|
||||||
<DialogTrigger asChild>
|
|
||||||
<Button aria-label="Dettagli Annuncio" variant="outline">
|
|
||||||
<UnfoldVertical className="size-6" /> Dettagli annuncio
|
|
||||||
</Button>
|
|
||||||
</DialogTrigger>
|
|
||||||
<DialogContent className="max-h-[70vh] max-w-xl overflow-y-auto sm:max-w-6xl">
|
|
||||||
<DialogHeader className="flex-row items-center gap-4">
|
|
||||||
<DialogTitle className="text-xl">Annuncio {data.codice}</DialogTitle>
|
|
||||||
<Link href={`/annuncio/${data.codice}`} target="_blank">
|
|
||||||
<Button size="sm" variant="info">
|
|
||||||
<span>Vai alla pagina completa</span>{" "}
|
|
||||||
<ExternalLink className="size-4" />
|
|
||||||
</Button>
|
|
||||||
</Link>
|
|
||||||
<DialogDescription className="sr-only">
|
|
||||||
Annuncio {data.codice}
|
|
||||||
</DialogDescription>
|
|
||||||
</DialogHeader>
|
|
||||||
<div className="flex flex-col gap-2 px-2">
|
|
||||||
<div className="w-full contain-inline-size">
|
|
||||||
<CarouselAnnuncio
|
|
||||||
immagini={data.images.map((img) => img.img)}
|
|
||||||
updated_at={data.media_updated_at}
|
|
||||||
videos={data.url_video}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<div className="flex items-center gap-4">
|
|
||||||
<TipoBadge tipo={data.tipo} />
|
|
||||||
{data.stato === "Trattativa" && (
|
|
||||||
<Badge className="bg-violet-500 font-semibold text-md">
|
|
||||||
Annuncio in Trattativa
|
|
||||||
</Badge>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="mt-1 space-y-2">
|
|
||||||
<div className="flex flex-row justify-around">
|
|
||||||
<div className="text-center">
|
|
||||||
<dt className="sr-only">{t.card.codice}</dt>
|
|
||||||
|
|
||||||
<dd className="font-semibold text-lg">Cod: {data.codice}</dd>
|
|
||||||
</div>
|
|
||||||
<div className="text-center">
|
|
||||||
<dt className="sr-only">{t.card.prezzo}</dt>
|
|
||||||
|
|
||||||
<dd className="font-semibold text-lg">
|
|
||||||
{formatCurrency(data.prezzo / 1e2)}
|
|
||||||
</dd>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="mb-3">
|
|
||||||
<dt className="sr-only">{t.card.titolo}</dt>
|
|
||||||
|
|
||||||
<dd className="font-semibold text-base md:text-lg">
|
|
||||||
{locale === "it" ? data.titolo_it : data.titolo_en}
|
|
||||||
</dd>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="mb-3">
|
|
||||||
<dd
|
|
||||||
className="text-base"
|
|
||||||
dangerouslySetInnerHTML={{
|
|
||||||
__html: replaceWithBr(
|
|
||||||
(locale === "it" ? data.desc_it : data.desc_en) || "",
|
|
||||||
),
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<DialogFooter>
|
|
||||||
<DialogClose asChild></DialogClose>
|
|
||||||
</DialogFooter>
|
|
||||||
</DialogContent>
|
|
||||||
</Dialog>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
|
||||||
|
|
@ -93,16 +93,23 @@ export const intrestsRouter = createTRPCRouter({
|
||||||
.select((eb) => [
|
.select((eb) => [
|
||||||
"annunci.id",
|
"annunci.id",
|
||||||
"annunci.codice",
|
"annunci.codice",
|
||||||
|
"annunci.comune",
|
||||||
|
"annunci.provincia",
|
||||||
"annunci.prezzo",
|
"annunci.prezzo",
|
||||||
|
"annunci.consegna",
|
||||||
|
"annunci.numero_camere",
|
||||||
|
"annunci.mq",
|
||||||
|
"annunci.tipo",
|
||||||
|
"annunci.titolo_it",
|
||||||
|
"annunci.titolo_en",
|
||||||
"annunci.desc_en",
|
"annunci.desc_en",
|
||||||
"annunci.desc_it",
|
"annunci.desc_it",
|
||||||
"annunci.titolo_en",
|
"annunci.modificato_il",
|
||||||
"annunci.titolo_it",
|
|
||||||
"annunci.tipo",
|
|
||||||
"annunci.consegna",
|
|
||||||
"annunci.stato",
|
"annunci.stato",
|
||||||
"annunci.web",
|
"annunci.url_video",
|
||||||
"annunci.media_updated_at",
|
"annunci.media_updated_at",
|
||||||
|
"annunci.homepage",
|
||||||
|
"annunci.web",
|
||||||
jsonArrayFrom(
|
jsonArrayFrom(
|
||||||
eb
|
eb
|
||||||
.selectFrom("images_refs")
|
.selectFrom("images_refs")
|
||||||
|
|
|
||||||
|
|
@ -605,6 +605,7 @@ export const setupSaldoConsulenzaServizio = async ({
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ServizioData = Awaited<
|
export type ServizioData = Awaited<
|
||||||
ReturnType<typeof getAllServizioAnnunci>
|
ReturnType<typeof getAllServizioAnnunci>
|
||||||
>[number];
|
>[number];
|
||||||
|
|
@ -679,16 +680,23 @@ export const getAllServizioAnnunci = async (userId: UsersId) => {
|
||||||
.select((eb) => [
|
.select((eb) => [
|
||||||
"annunci.id",
|
"annunci.id",
|
||||||
"annunci.codice",
|
"annunci.codice",
|
||||||
|
"annunci.comune",
|
||||||
|
"annunci.provincia",
|
||||||
"annunci.prezzo",
|
"annunci.prezzo",
|
||||||
|
"annunci.consegna",
|
||||||
|
"annunci.numero_camere",
|
||||||
|
"annunci.mq",
|
||||||
|
"annunci.tipo",
|
||||||
|
"annunci.titolo_it",
|
||||||
|
"annunci.titolo_en",
|
||||||
"annunci.desc_en",
|
"annunci.desc_en",
|
||||||
"annunci.desc_it",
|
"annunci.desc_it",
|
||||||
"annunci.titolo_en",
|
"annunci.modificato_il",
|
||||||
"annunci.titolo_it",
|
|
||||||
"annunci.tipo",
|
|
||||||
"annunci.consegna",
|
|
||||||
"annunci.stato",
|
"annunci.stato",
|
||||||
"annunci.web",
|
"annunci.url_video",
|
||||||
"annunci.media_updated_at",
|
"annunci.media_updated_at",
|
||||||
|
"annunci.homepage",
|
||||||
|
"annunci.web",
|
||||||
jsonArrayFrom(
|
jsonArrayFrom(
|
||||||
eb
|
eb
|
||||||
.selectFrom("images_refs")
|
.selectFrom("images_refs")
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue