import { BedDouble, CalendarClock, MapPin, Maximize2, Ruler, Siren, Star, TrafficCone, } from "lucide-react"; import Image from "next/image"; import Link from "next/link"; import { type RefObject, useEffect, useRef, useState } from "react"; import { useIntersection } from "react-use"; import { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, } from "~/components/ui/carousel"; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, } from "~/components/ui/dialog"; import { camereTesti, handleConsegna } from "~/lib/annuncio_details"; import { getStorageUrl } from "~/lib/storage_utils"; import { cn, formatCurrency } from "~/lib/utils"; import { useTranslation } from "~/providers/I18nProvider"; import type { ImagesRefs } from "~/schemas/public/ImagesRefs"; import type { VideosRefs } from "~/schemas/public/VideosRefs"; import type { AnnuncioRicerca } from "~/server/controllers/annunci.controller"; import { Badge } from "./ui/badge"; import { Skeleton } from "./ui/skeleton"; import { VideoPlayer } from "./videoPlayer"; type CardAnnuncioProps = AnnuncioRicerca & { className?: string; noLink?: boolean; onlyFirstImage?: boolean; eager?: boolean; }; export const LazyCardAnnuncio = (props: CardAnnuncioProps) => { const { eager = false } = props; const intersectionRef = useRef(null); const hasRenderedRef = useRef(eager); const [shouldRender, setShouldRender] = useState(eager); const intersection = useIntersection( intersectionRef as RefObject, { root: null, rootMargin: "300px", threshold: 0.01, }, ); useEffect(() => { if ( !hasRenderedRef.current && intersection && intersection.intersectionRatio > 0 ) { hasRenderedRef.current = true; setShouldRender(true); } }, [intersection]); return (
{ e.preventDefault(); e.stopPropagation(); }} onKeyDown={(e) => e.stopPropagation()} ref={intersectionRef} role="button" tabIndex={0} > {shouldRender ? : }
); }; const SkeletonCardAnnuncio = () => { return (
); }; export const CardAnnuncio = ({ id, codice, prezzo, titolo_it, titolo_en, mq, comune, provincia, consegna, numero_camere: camere, tipo, stato, className, videos, media_updated_at, images, homepage, noLink = false, onlyFirstImage = false, }: CardAnnuncioProps) => { const { t, locale } = useTranslation(); const currentMonth = new Date().getMonth() + 1; const isAvailableNow = consegna === 0 || consegna === currentMonth; const Wrapper = ({ children }: { children: React.ReactNode }) => { if (noLink) { return
{children}
; } return ( {children} ); }; return (
{stato !== "Trattativa" && homepage && (
svg]:size-4.5", isAvailableNow ? "bg-dasubito" : "bg-evidenza text-primary dark:text-accent", )} > {isAvailableNow ? ( <> Libero Subito ) : ( <> In Evidenza )}
)} {stato === "Trattativa" && (
svg]:size-4.5", )} > In Trattativa
)} {!onlyFirstImage ? ( {images?.map((img, idx) => ( {t.card.alt_immagine} ))} {videos?.map((video) => { return ( { e.preventDefault(); e.stopPropagation(); }} > ); })}
{ e.preventDefault(); e.stopPropagation(); }} onKeyDown={(e) => e.stopPropagation()} role="button" tabIndex={0} >
) : ( <> {images && images.length > 0 && images[0] ? ( {t.card.alt_immagine} ) : (
)} )}
Affitto {tipo}
{t.card.codice} Cod: {codice}
{t.card.prezzo} {formatCurrency(prezzo / 1e2)}
{t.card.titolo} {locale === "it" ? titolo_it : titolo_en}
{t.card.indirizzo} {comune && provincia && `${comune} (${provincia})`}

{mq ? Number(mq).toLocaleString("it-IT") : "--"}{" "} m2

{camereTesti({ camere: camere, testi: t.card })}

{handleConsegna({ aggiornamento: t.card.in_aggiornamento, consegna: consegna, consegna_da: t.card.consegna_da, mesi: t.parametri.mesi, subito: t.card.consegna_subito, })}

); }; export const CarouselAnnuncio = ({ single, immagini, videos, updated_at, }: { single?: boolean; immagini: Pick[]; videos: Pick[]; updated_at: Date | null; }) => { const [openModal, setOpenModal] = useState(false); const [idxModal, setIdxModal] = useState(0); function handleOpenModal(position: number) { setIdxModal(position); setOpenModal(true); } return ( <>
{immagini?.map((img, idx) => ( {img.img} handleOpenModal(idx)} priority={idx === 0} src={getStorageUrl({ storageId: img.img, params: { cacheKey: updated_at?.toISOString(), media: "image", }, })} width={800} /> handleOpenModal(idx)} /> ))} {videos?.map((video, idx) => { return ( idx }-${openModal}`} videoSrc={getStorageUrl({ storageId: video.video, params: { cacheKey: updated_at?.toISOString(), media: "video", }, })} /> handleOpenModal(immagini?.length || 0 + idx) } /> ); })}
Image Dialog Immagine {immagini?.map((img, idx) => ( {`carousel-img-${idx}`} ))} {videos?.map((video) => { return ( ); })} ); };