feat: refactor Annuncio context and related data fetching for improved structure and clarity
This commit is contained in:
parent
337ca80fec
commit
58ea254180
4 changed files with 133 additions and 139 deletions
|
|
@ -25,7 +25,7 @@ import { TouchProvider } from "~/components/custom_ui/HybridTooltip";
|
||||||
import Input from "~/components/custom_ui/input";
|
import Input from "~/components/custom_ui/input";
|
||||||
import { ComeFunziona } from "~/components/expand_guida";
|
import { ComeFunziona } from "~/components/expand_guida";
|
||||||
import FailedAnnuncioLoading from "~/components/failed-loading";
|
import FailedAnnuncioLoading from "~/components/failed-loading";
|
||||||
import { IconMatrix, type IconType } from "~/components/IconComponents";
|
import { IconMatrix } from "~/components/IconComponents";
|
||||||
import InformationBubble from "~/components/InformationBubble";
|
import InformationBubble from "~/components/InformationBubble";
|
||||||
import { LoadingPage } from "~/components/loading";
|
import { LoadingPage } from "~/components/loading";
|
||||||
import { MappaDialogFullscreen } from "~/components/MapDialog";
|
import { MappaDialogFullscreen } from "~/components/MapDialog";
|
||||||
|
|
@ -54,10 +54,7 @@ import {
|
||||||
import { Label } from "~/components/ui/label";
|
import { Label } from "~/components/ui/label";
|
||||||
import { VideoPlayer } from "~/components/videoPlayer";
|
import { VideoPlayer } from "~/components/videoPlayer";
|
||||||
import { env } from "~/env";
|
import { env } from "~/env";
|
||||||
import {
|
import { filteredCaratteristiche } from "~/hooks/schedaAnnuncioUtils";
|
||||||
type CaratteristicheFiltered,
|
|
||||||
filteredCaratteristiche,
|
|
||||||
} from "~/hooks/schedaAnnuncioUtils";
|
|
||||||
import { useStaleImageReload } from "~/hooks/staleImage";
|
import { useStaleImageReload } from "~/hooks/staleImage";
|
||||||
import { useMediaQuery } from "~/hooks/use-media-query";
|
import { useMediaQuery } from "~/hooks/use-media-query";
|
||||||
import { handleConsegna } from "~/lib/annuncio_details";
|
import { handleConsegna } from "~/lib/annuncio_details";
|
||||||
|
|
@ -68,9 +65,7 @@ import { AnnuncioContext, useAnnuncio } from "~/providers/AnnuncioProvider";
|
||||||
import { useTranslation } from "~/providers/I18nProvider";
|
import { useTranslation } from "~/providers/I18nProvider";
|
||||||
import { buildRicercaUrl } from "~/providers/RicercaProvider";
|
import { buildRicercaUrl } from "~/providers/RicercaProvider";
|
||||||
import { useSession } from "~/providers/SessionProvider";
|
import { useSession } from "~/providers/SessionProvider";
|
||||||
import type { Annunci } from "~/schemas/public/Annunci";
|
|
||||||
import TipologiaPosizioneEnum from "~/schemas/public/TipologiaPosizioneEnum";
|
import TipologiaPosizioneEnum from "~/schemas/public/TipologiaPosizioneEnum";
|
||||||
import type { VideosRefs } from "~/schemas/public/VideosRefs";
|
|
||||||
import { generateSSGHelper } from "~/server/utils/ssgHelper";
|
import { generateSSGHelper } from "~/server/utils/ssgHelper";
|
||||||
import { api } from "~/utils/api";
|
import { api } from "~/utils/api";
|
||||||
|
|
||||||
|
|
@ -135,10 +130,9 @@ const AnnuncioDettaglio: NextPage<AnnuncioProps> = ({
|
||||||
|
|
||||||
const AnnuncioView = ({ cod, flag }: Omit<AnnuncioProps, "meta">) => {
|
const AnnuncioView = ({ cod, flag }: Omit<AnnuncioProps, "meta">) => {
|
||||||
const session = useSession();
|
const session = useSession();
|
||||||
const { locale } = useTranslation();
|
|
||||||
useStaleImageReload();
|
useStaleImageReload();
|
||||||
|
|
||||||
const { data, isLoading } = api.annunci.getAnnuncio.useQuery(
|
const { data, isLoading } = api.annunci.getAnnuncioData.useQuery(
|
||||||
{
|
{
|
||||||
cod: cod,
|
cod: cod,
|
||||||
},
|
},
|
||||||
|
|
@ -156,13 +150,6 @@ const AnnuncioView = ({ cod, flag }: Omit<AnnuncioProps, "meta">) => {
|
||||||
return <FailedAnnuncioLoading />;
|
return <FailedAnnuncioLoading />;
|
||||||
}
|
}
|
||||||
|
|
||||||
const titolo = (locale === "it" ? data.titolo_it : data.titolo_en) || "";
|
|
||||||
const description = (locale === "it" ? data.desc_it : data.desc_en) || "";
|
|
||||||
|
|
||||||
const filteredCaratt = data.caratteristiche
|
|
||||||
? filteredCaratteristiche(data.caratteristiche)
|
|
||||||
: null;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AnnuncioContext.Provider value={data}>
|
<AnnuncioContext.Provider value={data}>
|
||||||
<TouchProvider>
|
<TouchProvider>
|
||||||
|
|
@ -176,7 +163,7 @@ const AnnuncioView = ({ cod, flag }: Omit<AnnuncioProps, "meta">) => {
|
||||||
<div className="flex flex-col sm:py-8 md:flex-row-reverse md:gap-2">
|
<div className="flex flex-col sm:py-8 md:flex-row-reverse md:gap-2">
|
||||||
<div className="mb-6 flex flex-col md:mb-0 md:w-1/3">
|
<div className="mb-6 flex flex-col md:mb-0 md:w-1/3">
|
||||||
<div className="flex w-full flex-col flex-nowrap items-center justify-center gap-6">
|
<div className="flex w-full flex-col flex-nowrap items-center justify-center gap-6">
|
||||||
<CardInfos data={data} />
|
<CardInfos />
|
||||||
{session.user?.isAdmin ? (
|
{session.user?.isAdmin ? (
|
||||||
<>
|
<>
|
||||||
<Link
|
<Link
|
||||||
|
|
@ -217,21 +204,10 @@ const AnnuncioView = ({ cod, flag }: Omit<AnnuncioProps, "meta">) => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="mx-2 md:w-2/3">
|
<div className="mx-2 md:w-2/3">
|
||||||
<TestiAnnuncio
|
<TestiAnnuncio />
|
||||||
description={description}
|
|
||||||
filteredCaratt={filteredCaratt}
|
|
||||||
titolo={titolo}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<AnnuncioFooter
|
<AnnuncioFooter />
|
||||||
comune={data.comune}
|
|
||||||
consegna={data.consegna}
|
|
||||||
external_videos={data.external_videos || []}
|
|
||||||
tipo={data.tipo}
|
|
||||||
updated_at={data.media_updated_at}
|
|
||||||
videos={data.videos}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</TouchProvider>
|
</TouchProvider>
|
||||||
</AnnuncioContext.Provider>
|
</AnnuncioContext.Provider>
|
||||||
|
|
@ -248,7 +224,7 @@ export async function getStaticProps(
|
||||||
notFound: true,
|
notFound: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
await ssg.annunci.getAnnuncio.prefetch({ cod: cod });
|
await ssg.annunci.getAnnuncioData.prefetch({ cod: cod });
|
||||||
|
|
||||||
const meta = await ssg.annunci.getAnnuncioMeta.fetch({ cod: cod });
|
const meta = await ssg.annunci.getAnnuncioMeta.fetch({ cod: cod });
|
||||||
|
|
||||||
|
|
@ -388,42 +364,30 @@ const Pricing = ({ isDesktop }: { isDesktop: boolean }) => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const TestiAnnuncio = ({
|
const TestiAnnuncio = () => {
|
||||||
titolo,
|
const { locale } = useTranslation();
|
||||||
description,
|
const { titolo_it, titolo_en, desc_it, desc_en } = useAnnuncio();
|
||||||
filteredCaratt,
|
|
||||||
}: {
|
|
||||||
titolo: string;
|
|
||||||
description: string;
|
|
||||||
filteredCaratt:
|
|
||||||
| {
|
|
||||||
text: string;
|
|
||||||
icon: IconType;
|
|
||||||
value: string | null;
|
|
||||||
}[]
|
|
||||||
| null;
|
|
||||||
}) => {
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<h1 className="font-bold text-3xl uppercase">{titolo}</h1>
|
<h1 className="font-bold text-3xl uppercase">
|
||||||
|
{locale === "it" ? titolo_it : titolo_en}
|
||||||
|
</h1>
|
||||||
<h1
|
<h1
|
||||||
className="py-6"
|
className="py-6"
|
||||||
dangerouslySetInnerHTML={{
|
dangerouslySetInnerHTML={{
|
||||||
__html: replaceWithBr(description),
|
__html: replaceWithBr((locale === "it" ? desc_it : desc_en) || ""),
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
{filteredCaratt && (
|
|
||||||
<CaratteristicheAccordion filteredCaratt={filteredCaratt} />
|
<CaratteristicheAccordion />
|
||||||
)}
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const CaratteristicheAccordion = ({
|
const CaratteristicheAccordion = () => {
|
||||||
filteredCaratt,
|
const { caratteristiche } = useAnnuncio();
|
||||||
}: {
|
if (!caratteristiche) return null;
|
||||||
filteredCaratt: CaratteristicheFiltered;
|
|
||||||
}) => {
|
|
||||||
return (
|
return (
|
||||||
<Accordion
|
<Accordion
|
||||||
className="my-5"
|
className="my-5"
|
||||||
|
|
@ -437,7 +401,8 @@ const CaratteristicheAccordion = ({
|
||||||
>
|
>
|
||||||
<AccordionTrigger>Altre caratteristiche</AccordionTrigger>
|
<AccordionTrigger>Altre caratteristiche</AccordionTrigger>
|
||||||
<AccordionContent>
|
<AccordionContent>
|
||||||
{Object.entries(filteredCaratt).map(([key, scheda_value]) => {
|
{Object.entries(filteredCaratteristiche(caratteristiche)).map(
|
||||||
|
([key, scheda_value]) => {
|
||||||
const { text, icon, value } = scheda_value;
|
const { text, icon, value } = scheda_value;
|
||||||
if (value === null) return null;
|
if (value === null) return null;
|
||||||
return (
|
return (
|
||||||
|
|
@ -449,31 +414,46 @@ const CaratteristicheAccordion = ({
|
||||||
{text}: {value}
|
{text}: {value}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
},
|
||||||
|
)}
|
||||||
</AccordionContent>
|
</AccordionContent>
|
||||||
</AccordionItem>
|
</AccordionItem>
|
||||||
</Accordion>
|
</Accordion>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const CardInfos = ({ data }: { data: Annunci }) => {
|
const CardInfos = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const {
|
||||||
|
codice,
|
||||||
|
prezzo,
|
||||||
|
tipo,
|
||||||
|
numero_camere,
|
||||||
|
numero_bagni,
|
||||||
|
caratteristiche,
|
||||||
|
numero_postiauto,
|
||||||
|
mq,
|
||||||
|
piano,
|
||||||
|
stato,
|
||||||
|
consegna,
|
||||||
|
lat_secondario,
|
||||||
|
lon_secondario,
|
||||||
|
} = useAnnuncio();
|
||||||
return (
|
return (
|
||||||
<Card className="relative w-full bg-secondary text-secondary-foreground outline outline-secondary-foreground">
|
<Card className="relative w-full bg-secondary text-secondary-foreground outline outline-secondary-foreground">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="text-center font-bold text-3xl md:pl-8 lg:pl-0">
|
<CardTitle className="text-center font-bold text-3xl md:pl-8 lg:pl-0">
|
||||||
{t.annunci.codice} {data.codice}
|
{t.annunci.codice} {codice}
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="flex flex-col gap-4 p-4 py-0">
|
<CardContent className="flex flex-col gap-4 p-4 py-0">
|
||||||
<div className="grid grid-cols-2 gap-3 font-semibold">
|
<div className="grid grid-cols-2 gap-3 font-semibold">
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<div className="flex h-10 items-center justify-center rounded-md bg-primary-foreground text-center text-primary">
|
<div className="flex h-10 items-center justify-center rounded-md bg-primary-foreground text-center text-primary">
|
||||||
{data.prezzo && (data.prezzo / 1e2).toFixed(2).replace(".", ",")}{" "}
|
{prezzo && (prezzo / 1e2).toFixed(2).replace(".", ",")}{" "}
|
||||||
{t.annunci.euro_mese}
|
{t.annunci.euro_mese}
|
||||||
</div>
|
</div>
|
||||||
{data.prezzo && (
|
{prezzo && (
|
||||||
<InformationBubble
|
<InformationBubble
|
||||||
icon="euro"
|
icon="euro"
|
||||||
iconClassName="h-[19.5px] w-[19.5px] bg-orange-500 text-white rounded-full"
|
iconClassName="h-[19.5px] w-[19.5px] bg-orange-500 text-white rounded-full"
|
||||||
|
|
@ -483,7 +463,7 @@ const CardInfos = ({ data }: { data: Annunci }) => {
|
||||||
{t.annunci.prezzo_giorno}
|
{t.annunci.prezzo_giorno}
|
||||||
</span>
|
</span>
|
||||||
<div className="text-sm">
|
<div className="text-sm">
|
||||||
{(data.prezzo / 1e2 / 30).toFixed(2).replace(".", ",")}{" "}
|
{(prezzo / 1e2 / 30).toFixed(2).replace(".", ",")}{" "}
|
||||||
{t.annunci.euro_giorno}
|
{t.annunci.euro_giorno}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -494,13 +474,13 @@ const CardInfos = ({ data }: { data: Annunci }) => {
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"h-10 rounded-md bg-primary-foreground p-2 text-center text-primary outline-2",
|
"h-10 rounded-md bg-primary-foreground p-2 text-center text-primary outline-2",
|
||||||
data.tipo === "Transitorio" && "outline-transitorio",
|
tipo === "Transitorio" && "outline-transitorio",
|
||||||
data.tipo === "Stabile" && "outline-stabile",
|
tipo === "Stabile" && "outline-stabile",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{data.tipo}
|
{tipo}
|
||||||
</div>
|
</div>
|
||||||
{data.tipo === "Transitorio" && (
|
{tipo === "Transitorio" && (
|
||||||
<InformationBubble
|
<InformationBubble
|
||||||
href="/guida#faq-transitori"
|
href="/guida#faq-transitori"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
|
|
@ -516,30 +496,30 @@ const CardInfos = ({ data }: { data: Annunci }) => {
|
||||||
<BedDouble />
|
<BedDouble />
|
||||||
<span className="line-clamp-1 break-all">
|
<span className="line-clamp-1 break-all">
|
||||||
{(() => {
|
{(() => {
|
||||||
if (!data.numero_camere) return "N/A";
|
if (!numero_camere) return "N/A";
|
||||||
if (data.numero_camere > 1)
|
if (numero_camere > 1)
|
||||||
return `${data.numero_camere} ${t.card.camere2}`;
|
return `${numero_camere} ${t.card.camere2}`;
|
||||||
if (data.numero_camere === 1)
|
if (numero_camere === 1)
|
||||||
return `${data.numero_camere} ${t.card.camere1}`;
|
return `${numero_camere} ${t.card.camere1}`;
|
||||||
})()}
|
})()}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-center gap-2 rounded-md bg-primary-foreground p-2 text-primary">
|
<div className="flex justify-center gap-2 rounded-md bg-primary-foreground p-2 text-primary">
|
||||||
<Bath />
|
<Bath />
|
||||||
<span className="line-clamp-1 break-all">
|
<span className="line-clamp-1 break-all">
|
||||||
{data.numero_bagni || 0} {t.annunci.bagni}
|
{numero_bagni || 0} {t.annunci.bagni}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-center gap-2 rounded-md bg-primary-foreground p-2 text-primary">
|
<div className="flex justify-center gap-2 rounded-md bg-primary-foreground p-2 text-primary">
|
||||||
<Armchair />
|
<Armchair />
|
||||||
<span className="line-clamp-1 break-all">
|
<span className="line-clamp-1 break-all">
|
||||||
{data.caratteristiche?.Scheda_Arredi || ""}
|
{caratteristiche?.Scheda_Arredi || ""}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-center gap-2 rounded-md bg-primary-foreground p-2 text-primary">
|
<div className="flex justify-center gap-2 rounded-md bg-primary-foreground p-2 text-primary">
|
||||||
<Car />
|
<Car />
|
||||||
<span className="line-clamp-1 break-all">
|
<span className="line-clamp-1 break-all">
|
||||||
{data.numero_postiauto || 0} {t.annunci.posti_auto}
|
{numero_postiauto || 0} {t.annunci.posti_auto}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -550,21 +530,19 @@ const CardInfos = ({ data }: { data: Annunci }) => {
|
||||||
<div className="flex justify-center gap-2 rounded-md bg-primary-foreground p-2 text-primary">
|
<div className="flex justify-center gap-2 rounded-md bg-primary-foreground p-2 text-primary">
|
||||||
<Ruler />
|
<Ruler />
|
||||||
<span className="line-clamp-1 break-all">
|
<span className="line-clamp-1 break-all">
|
||||||
{data.mq ? Number(data.mq).toLocaleString("it-IT") : "--"} m
|
{mq ? Number(mq).toLocaleString("it-IT") : "--"} m<sup>2</sup>
|
||||||
<sup>2</sup>
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex justify-center gap-2 rounded-md bg-primary-foreground p-2 text-primary">
|
<div className="flex justify-center gap-2 rounded-md bg-primary-foreground p-2 text-primary">
|
||||||
{data.piano !== null && data.piano !== "" && (
|
{piano !== null && piano !== "" && (
|
||||||
<>
|
<>
|
||||||
<ArrowUp01 />
|
<ArrowUp01 />
|
||||||
<span className="line-clamp-1 break-all">
|
<span className="line-clamp-1 break-all">
|
||||||
{(() => {
|
{(() => {
|
||||||
if (data.piano === "0") return t.annunci.p_terra;
|
if (piano === "0") return t.annunci.p_terra;
|
||||||
if (data.piano === "0.5") return t.annunci.p_rialzato;
|
if (piano === "0.5") return t.annunci.p_rialzato;
|
||||||
if (data.piano)
|
if (piano) return `${piano}° ${t.annunci.piano}`;
|
||||||
return `${data.piano}° ${t.annunci.piano}`;
|
|
||||||
return "--";
|
return "--";
|
||||||
})()}
|
})()}
|
||||||
</span>
|
</span>
|
||||||
|
|
@ -575,7 +553,7 @@ const CardInfos = ({ data }: { data: Annunci }) => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="text-center font-bold text-base">
|
<div className="text-center font-bold text-base">
|
||||||
{data.stato === "Trattativa" ? (
|
{stato === "Trattativa" ? (
|
||||||
<div className="flex items-center justify-center gap-1 rounded-md py-1.5 text-trattativa outline-2 outline-trattativa dark:bg-secondary-foreground">
|
<div className="flex items-center justify-center gap-1 rounded-md py-1.5 text-trattativa outline-2 outline-trattativa dark:bg-secondary-foreground">
|
||||||
<TrafficCone className="inline-block size-5" />
|
<TrafficCone className="inline-block size-5" />
|
||||||
<span>{t.annunci.in_aggiornamento}</span>
|
<span>{t.annunci.in_aggiornamento}</span>
|
||||||
|
|
@ -587,7 +565,7 @@ const CardInfos = ({ data }: { data: Annunci }) => {
|
||||||
<span className="text-red-500">
|
<span className="text-red-500">
|
||||||
{handleConsegna({
|
{handleConsegna({
|
||||||
aggiornamento: t.card.in_aggiornamento,
|
aggiornamento: t.card.in_aggiornamento,
|
||||||
consegna: data.consegna,
|
consegna: consegna,
|
||||||
consegna_da: t.card.consegna_da,
|
consegna_da: t.card.consegna_da,
|
||||||
mesi: t.parametri.mesi,
|
mesi: t.parametri.mesi,
|
||||||
subito: t.card.consegna_subito,
|
subito: t.card.consegna_subito,
|
||||||
|
|
@ -597,10 +575,7 @@ const CardInfos = ({ data }: { data: Annunci }) => {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-row justify-around gap-3">
|
<div className="flex flex-row justify-around gap-3">
|
||||||
<MappaDialogFullscreen
|
<MappaDialogFullscreen lat={lat_secondario} long={lon_secondario} />
|
||||||
lat={data.lat_secondario}
|
|
||||||
long={data.lon_secondario}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<ShareComponent />
|
<ShareComponent />
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -677,28 +652,16 @@ const ShareComponent = () => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const AnnuncioFooter = ({
|
const AnnuncioFooter = () => {
|
||||||
tipo,
|
const { tipo, comune, consegna, videos, external_videos, media_updated_at } =
|
||||||
comune,
|
useAnnuncio();
|
||||||
consegna,
|
|
||||||
videos,
|
|
||||||
external_videos,
|
|
||||||
updated_at,
|
|
||||||
}: {
|
|
||||||
tipo: string;
|
|
||||||
comune: string | null;
|
|
||||||
consegna: number | null;
|
|
||||||
videos: Pick<VideosRefs, "video" | "thumb">[];
|
|
||||||
external_videos: string[];
|
|
||||||
updated_at: Date | null;
|
|
||||||
}) => {
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-2">
|
<div className="flex flex-col gap-2">
|
||||||
<p
|
<p
|
||||||
className={cn(
|
className={cn(
|
||||||
"px-2 font-semibold text-lg",
|
"px-2 font-semibold text-lg",
|
||||||
videos.length === 0 && external_videos.length === 0 && "hidden",
|
videos.length === 0 && external_videos?.length === 0 && "hidden",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
Video:
|
Video:
|
||||||
|
|
@ -710,17 +673,23 @@ const AnnuncioFooter = ({
|
||||||
className="h-96 max-w-96"
|
className="h-96 max-w-96"
|
||||||
coverImage={getStorageUrl({
|
coverImage={getStorageUrl({
|
||||||
storageId: video.thumb,
|
storageId: video.thumb,
|
||||||
params: { cacheKey: updated_at?.toISOString(), media: "image" },
|
params: {
|
||||||
|
cacheKey: media_updated_at?.toISOString(),
|
||||||
|
media: "image",
|
||||||
|
},
|
||||||
})}
|
})}
|
||||||
key={`videoplayer-${video.video}`} // Cache busting
|
key={`videoplayer-${video.video}`} // Cache busting
|
||||||
videoSrc={getStorageUrl({
|
videoSrc={getStorageUrl({
|
||||||
storageId: video.video,
|
storageId: video.video,
|
||||||
params: { cacheKey: updated_at?.toISOString(), media: "video" },
|
params: {
|
||||||
|
cacheKey: media_updated_at?.toISOString(),
|
||||||
|
media: "video",
|
||||||
|
},
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
{external_videos.map((videoUrl) => {
|
{external_videos?.map((videoUrl) => {
|
||||||
const embedUrl = getYouTubeEmbedUrl(videoUrl);
|
const embedUrl = getYouTubeEmbedUrl(videoUrl);
|
||||||
if (!embedUrl) return null;
|
if (!embedUrl) return null;
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,7 @@
|
||||||
import { createContext, useContext } from "react";
|
import { createContext, useContext } from "react";
|
||||||
import type { Annunci } from "~/schemas/public/Annunci";
|
import type { AnnuncioData } from "~/server/controllers/annunci.controller";
|
||||||
|
|
||||||
export const AnnuncioContext = createContext<Pick<
|
export const AnnuncioContext = createContext<AnnuncioData | null>(null);
|
||||||
Annunci,
|
|
||||||
"id" | "tipo" | "prezzo" | "codice"
|
|
||||||
> | null>(null);
|
|
||||||
|
|
||||||
export const useAnnuncio = () => {
|
export const useAnnuncio = () => {
|
||||||
const context = useContext(AnnuncioContext);
|
const context = useContext(AnnuncioContext);
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,10 @@ import {
|
||||||
import {
|
import {
|
||||||
editAnnuncioHandler,
|
editAnnuncioHandler,
|
||||||
get_AnnunciPositionsHandler,
|
get_AnnunciPositionsHandler,
|
||||||
getAnnunciByCod,
|
|
||||||
getAnnunciById_rawImgUrls,
|
getAnnunciById_rawImgUrls,
|
||||||
getAnnunciListHandler,
|
getAnnunciListHandler,
|
||||||
getAnnunciMetaByCod,
|
getAnnunciMetaByCod,
|
||||||
|
getAnnuncioData,
|
||||||
getAnnunciRicerca,
|
getAnnunciRicerca,
|
||||||
getCodici_AnnunciHandler,
|
getCodici_AnnunciHandler,
|
||||||
getOptions_AnnunciHandler,
|
getOptions_AnnunciHandler,
|
||||||
|
|
@ -52,15 +52,14 @@ export const annunciRouter = createTRPCRouter({
|
||||||
getAnnunciOptions: publicProcedure.query(async () => {
|
getAnnunciOptions: publicProcedure.query(async () => {
|
||||||
return await getOptions_AnnunciHandler();
|
return await getOptions_AnnunciHandler();
|
||||||
}),
|
}),
|
||||||
/** TODO da limitare per evitare leak */
|
getAnnuncioData: publicProcedure
|
||||||
getAnnuncio: publicProcedure
|
|
||||||
.input(
|
.input(
|
||||||
z.object({
|
z.object({
|
||||||
cod: z.string(),
|
cod: z.string(),
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.query(async ({ input }) => {
|
.query(async ({ input }) => {
|
||||||
return await getAnnunciByCod({ ...input });
|
return await getAnnuncioData({ ...input });
|
||||||
}),
|
}),
|
||||||
getAnnuncioFull: adminProcedure
|
getAnnuncioFull: adminProcedure
|
||||||
.input(
|
.input(
|
||||||
|
|
|
||||||
|
|
@ -72,26 +72,55 @@ export const getCodici_AnnunciHandler = async (): Promise<string[]> => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getAnnunciByCod = async ({
|
export type AnnuncioData = Awaited<ReturnType<typeof getAnnuncioData>>;
|
||||||
cod,
|
export const getAnnuncioData = async ({ cod }: { cod: string }) => {
|
||||||
}: {
|
|
||||||
cod: string;
|
|
||||||
}): Promise<AnnunciWithMedia | null> => {
|
|
||||||
try {
|
try {
|
||||||
const annuncio = await db
|
const annuncio = await db
|
||||||
.selectFrom("annunci")
|
.selectFrom("annunci")
|
||||||
.selectAll()
|
.select([
|
||||||
|
"anno",
|
||||||
|
"accessori",
|
||||||
|
"caratteristiche",
|
||||||
|
"categorie",
|
||||||
|
"desc_en",
|
||||||
|
"desc_it",
|
||||||
|
"tipo",
|
||||||
|
"titolo_it",
|
||||||
|
"titolo_en",
|
||||||
|
"stato",
|
||||||
|
"media_updated_at",
|
||||||
|
"id",
|
||||||
|
"codice",
|
||||||
|
"comune",
|
||||||
|
"consegna",
|
||||||
|
"external_videos",
|
||||||
|
"prezzo",
|
||||||
|
"numero_camere",
|
||||||
|
"numero_bagni",
|
||||||
|
"numero_balconi",
|
||||||
|
"numero_postiauto",
|
||||||
|
"numero_box",
|
||||||
|
"numero_vani",
|
||||||
|
"numero_terrazzi",
|
||||||
|
"mq",
|
||||||
|
"piano",
|
||||||
|
"piano_palazzo",
|
||||||
|
"lat_secondario",
|
||||||
|
"lon_secondario",
|
||||||
|
"media_updated_at",
|
||||||
|
])
|
||||||
.select((_eb) => [withImages(), withVideos()])
|
.select((_eb) => [withImages(), withVideos()])
|
||||||
.where("annunci.web", "=", true)
|
.where("annunci.web", "=", true)
|
||||||
.where("tipo", "is not", null)
|
.where("tipo", "is not", null)
|
||||||
.where("codice", "=", cod)
|
.where("codice", "=", cod)
|
||||||
.executeTakeFirst();
|
.executeTakeFirstOrThrow(
|
||||||
|
() => new Error(`Annuncio non trovato - codice: ${cod}`),
|
||||||
if (!annuncio || annuncio.tipo === null) {
|
);
|
||||||
|
const { tipo, ...rest } = annuncio;
|
||||||
|
if (tipo === null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
return { tipo, ...rest };
|
||||||
return annuncio as AnnunciWithMedia;
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
cause: (e as Error).cause,
|
cause: (e as Error).cause,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue