diff --git a/apps/infoalloggi/src/lib/result.ts b/apps/infoalloggi/src/lib/result.ts new file mode 100644 index 0000000..ae3a847 --- /dev/null +++ b/apps/infoalloggi/src/lib/result.ts @@ -0,0 +1,3 @@ +export type Result = + | { success: true; data: T } + | { success: false; message: string }; diff --git a/apps/infoalloggi/src/pages/annuncio-non-trovato.tsx b/apps/infoalloggi/src/pages/annuncio-non-trovato.tsx new file mode 100644 index 0000000..916cdd6 --- /dev/null +++ b/apps/infoalloggi/src/pages/annuncio-non-trovato.tsx @@ -0,0 +1,4 @@ +import FailedAnnuncioLoading from "~/components/failed-loading"; +export default function AnnuncioNotFound() { + return ; +} diff --git a/apps/infoalloggi/src/pages/annuncio/[cod].tsx b/apps/infoalloggi/src/pages/annuncio/[cod].tsx index 7be1947..5cfa7a4 100644 --- a/apps/infoalloggi/src/pages/annuncio/[cod].tsx +++ b/apps/infoalloggi/src/pages/annuncio/[cod].tsx @@ -66,18 +66,13 @@ import { useTranslation } from "~/providers/I18nProvider"; import { buildRicercaUrl } from "~/providers/RicercaProvider"; import { useSession } from "~/providers/SessionProvider"; import TipologiaPosizioneEnum from "~/schemas/public/TipologiaPosizioneEnum"; +import type { AnnuncioData } from "~/server/controllers/annunci.controller"; import { generateSSGHelper } from "~/server/utils/ssgHelper"; import { api } from "~/utils/api"; type AnnuncioProps = { - cod: string; + data: AnnuncioData; flag: string; - meta: { - ogImage: string; - title: string; - description: string; - ogUrl: string; - } | null; }; /** @@ -85,25 +80,22 @@ type AnnuncioProps = { * Questa pagina mostra i dettagli di un annuncio specifico, identificato dal codice (cod) passato come parametro. Utilizza getStaticProps per prefetchare i dati dell'annuncio e le relative informazioni meta per SEO e condivisione sui social media. Se l'annuncio รจ in stato "Sospeso" o se si verifica un errore durante il caricamento, viene mostrata una pagina di errore. */ const AnnuncioDettaglio: NextPage = ({ - cod, + data, flag, - meta, }: AnnuncioProps) => { return (
- - {meta ? `${cod} | ${meta.title}` : "Annuncio non trovato"} - - - + {`${data.codice} | ${data.titolo_it}`} + + - - + + = ({ property="og:logo" /> - + - +
); }; -const AnnuncioView = ({ cod, flag }: Omit) => { +const AnnuncioView = ({ data, flag }: AnnuncioProps) => { const session = useSession(); useStaleImageReload(); - const { data, isLoading } = api.annunci.getAnnuncioData.useQuery( - { - cod: cod, - }, - { refetchOnMount: false }, - ); - const isDesktop = useMediaQuery("(min-width: 768px)"); - if (isLoading || session.status === "pending") return ; if ( !data || session.status === "error" || @@ -156,7 +140,9 @@ const AnnuncioView = ({ cod, flag }: Omit) => {
@@ -221,21 +207,31 @@ export async function getStaticProps( const cod = context.params?.cod; if (typeof cod !== "string") { return { - notFound: true, + redirect: { + destination: "/annuncio-non-trovato", + permanent: false, + }, + }; + } + const annuncio = await ssg.annunci.getAnnuncioData.fetch({ cod: cod }); + if (!annuncio.success || annuncio.data.stato === "Sospeso") { + return { + redirect: { + destination: "/annuncio-non-trovato", + permanent: false, + }, }; } - await ssg.annunci.getAnnuncioData.prefetch({ cod: cod }); - - const meta = await ssg.annunci.getAnnuncioMeta.fetch({ cod: cod }); const flag = await ssg.flags.GetFlagValue.fetch({ id: "ANNUNCIO_INTERACTIONS_DISABLED", }); return { props: { - cod, + data: annuncio.data, + //cod, flag, - meta, + //meta, trpcState: ssg.dehydrate(), }, revalidate: 21600, // 6 hours - ensures fresh data 4x per day @@ -674,7 +670,7 @@ const AnnuncioFooter = () => { coverImage={getStorageUrl({ storageId: video.thumb, params: { - cacheKey: media_updated_at?.toISOString(), + cacheKey: media_updated_at || undefined, media: "image", }, })} @@ -682,7 +678,7 @@ const AnnuncioFooter = () => { videoSrc={getStorageUrl({ storageId: video.video, params: { - cacheKey: media_updated_at?.toISOString(), + cacheKey: media_updated_at || undefined, media: "video", }, })} diff --git a/apps/infoalloggi/src/server/api/routers/annunci.ts b/apps/infoalloggi/src/server/api/routers/annunci.ts index bfc5efb..83eff1e 100644 --- a/apps/infoalloggi/src/server/api/routers/annunci.ts +++ b/apps/infoalloggi/src/server/api/routers/annunci.ts @@ -13,7 +13,6 @@ import { get_AnnunciPositionsHandler, getAnnunciById_rawImgUrls, getAnnunciListHandler, - getAnnunciMetaByCod, getAnnuncioData, getAnnunciRicerca, getCodici_AnnunciHandler, @@ -58,6 +57,7 @@ export const annunciRouter = createTRPCRouter({ cod: z.string(), }), ) + .query(async ({ input }) => { return await getAnnuncioData({ ...input }); }), @@ -83,16 +83,6 @@ export const annunciRouter = createTRPCRouter({ .query(async ({ input }) => { return await getAnnunciById_rawImgUrls({ ...input }); }), - - getAnnuncioMeta: publicProcedure - .input( - z.object({ - cod: z.string(), - }), - ) - .query(async ({ input }) => { - return await getAnnunciMetaByCod({ ...input }); - }), getCodici: publicProcedure.query(async () => { return await getCodici_AnnunciHandler(); }), diff --git a/apps/infoalloggi/src/server/controllers/annunci.controller.ts b/apps/infoalloggi/src/server/controllers/annunci.controller.ts index 932e4cf..fb36c4b 100644 --- a/apps/infoalloggi/src/server/controllers/annunci.controller.ts +++ b/apps/infoalloggi/src/server/controllers/annunci.controller.ts @@ -1,5 +1,6 @@ import { TRPCError } from "@trpc/server"; import { env } from "~/env"; +import type { Result } from "~/lib/result"; import { getStorageUrl } from "~/lib/storage_utils"; import type { Annunci, @@ -72,8 +73,48 @@ export const getCodici_AnnunciHandler = async (): Promise => { } }; -export type AnnuncioData = Awaited>; -export const getAnnuncioData = async ({ cod }: { cod: string }) => { +export type AnnuncioData = Pick< + Annunci, + | "anno" + | "accessori" + | "caratteristiche" + | "categorie" + | "desc_en" + | "desc_it" + | "titolo_it" + | "titolo_en" + | "stato" + | "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" +> & { + tipo: string; + media_updated_at: string | null; + images: Pick[]; + videos: Pick[]; + ogUrl: string; + ogImage: string; +}; +export const getAnnuncioData = async ({ + cod, +}: { + cod: string; +}): Promise> => { try { const annuncio = await db .selectFrom("annunci") @@ -107,43 +148,18 @@ export const getAnnuncioData = async ({ cod }: { cod: string }) => { "piano_palazzo", "lat_secondario", "lon_secondario", - "media_updated_at", ]) .select((_eb) => [withImages(), withVideos()]) .where("annunci.web", "=", true) .where("tipo", "is not", null) .where("codice", "=", cod) - .executeTakeFirstOrThrow( - () => new Error(`Annuncio non trovato - codice: ${cod}`), - ); - const { tipo, ...rest } = annuncio; - if (tipo === null) { - return null; - } - return { tipo, ...rest }; - } catch (e) { - throw new TRPCError({ - cause: (e as Error).cause, - code: "INTERNAL_SERVER_ERROR", - message: `Errore query getAnnunciByCod: ${(e as Error).message}`, - }); - } -}; -export const getAnnunciMetaByCod = async ({ cod }: { cod: string }) => { - try { - const annuncio = await db - .selectFrom("annunci") - .select((_eb) => [ - "titolo_it", - "desc_it", - withImages(), - "media_updated_at", - ]) - .where("annunci.web", "=", true) - .where("codice", "=", cod) .executeTakeFirst(); if (!annuncio) { - return null; + return { success: false, message: "Annuncio non trovato" }; + } + const { tipo, media_updated_at, ...rest } = annuncio; + if (tipo === null) { + return { success: false, message: "Annuncio non trovato" }; } const ogImage = annuncio.images && annuncio.images.length > 0 && annuncio.images[0] @@ -156,17 +172,21 @@ export const getAnnunciMetaByCod = async ({ cod }: { cod: string }) => { host: env.BASE_URL, }) : `${env.BASE_URL}/og.jpg`; - return { - description: annuncio.desc_it || "", - ogImage, - ogUrl: `${env.BASE_URL}/annuncio/${cod}`, - title: annuncio.titolo_it || "", + success: true, + data: { + ...rest, + media_updated_at: media_updated_at?.toISOString() || null, + tipo, + ogUrl: `${env.BASE_URL}/annuncio/${cod}`, + ogImage, + }, }; } catch (e) { throw new TRPCError({ + cause: (e as Error).cause, code: "INTERNAL_SERVER_ERROR", - message: `Errore query getAnnunciMetaByCod: ${(e as Error).message}`, + message: `Errore query getAnnunciByCod: ${(e as Error).message}`, }); } }; @@ -493,7 +513,7 @@ export const getProprietarioDataHandler = async ({ "lon", "numero", "locatore", - "tipo_locatore" + "tipo_locatore", ]) .where("id", "=", annuncioId) .executeTakeFirstOrThrow(() => {