diff --git a/apps/infoalloggi/src/components/Layout.tsx b/apps/infoalloggi/src/components/Layout.tsx index 3706033..6e5d1cb 100644 --- a/apps/infoalloggi/src/components/Layout.tsx +++ b/apps/infoalloggi/src/components/Layout.tsx @@ -27,6 +27,7 @@ import { WhatsAppIcon2 } from "~/components/svgs"; import { Button } from "~/components/ui/button"; import { Separator } from "~/components/ui/separator"; import { UserViewContext, UserViewProvider } from "~/lib/userViewContext"; +import { cn } from "~/lib/utils"; import { useTranslation } from "~/providers/I18nProvider"; import { EnforcedSessionContext, @@ -37,41 +38,55 @@ import type { ValidSession } from "~/server/api/trpc"; import { api } from "~/utils/api"; interface Props { + bodyClassName?: string; + containerClassName?: string; children: ReactNode; noFooter?: boolean; + footerClassName?: string; } -export const Layout = ({ children, noFooter }: Props) => { +export const Layout = ({ + children, + noFooter, + bodyClassName, + containerClassName, + footerClassName, +}: Props) => { const { data: bannerData } = api.settings.getBannerData.useQuery({ area_riservata: false, }); return ( -
+
{bannerData?.map((banner) => (
{BannerFactory(banner)}
))} -
{children}
+
+ {children} +
- {!noFooter &&
} + {!noFooter &&
} {/* */}
); }; +interface AreaRiservataLayoutProps extends Props { + ignoreSessionCheck?: boolean; + noSidebar?: boolean; +} + export const AreaRiservataLayout = ({ children, noSidebar, noFooter, ignoreSessionCheck, -}: { - children: ReactNode; - noSidebar?: boolean; - noFooter?: boolean; - ignoreSessionCheck?: boolean; -}) => { + bodyClassName, + containerClassName, + footerClassName, +}: AreaRiservataLayoutProps) => { const { data: bannerData } = api.settings.getBannerData.useQuery({ area_riservata: true, }); @@ -79,43 +94,70 @@ export const AreaRiservataLayout = ({ if (!ignoreSessionCheck) { if (session.status === "pending") return ( -
+
-
+
- {!noFooter && } + {!noFooter && }
); if (session.status !== "success" || !session.user) { window.location.reload(); return ( -
+
-
+
- {!noFooter && } + {!noFooter && }
); } } return ( -
+
{bannerData?.map((banner) => (
{BannerFactory(banner)}
))} -
+
{noSidebar ? null : (
- {!noFooter && } + {!noFooter && } {/* */}
diff --git a/apps/infoalloggi/src/components/accordionComp.tsx b/apps/infoalloggi/src/components/accordionComp.tsx index da021a0..a7eb2ca 100644 --- a/apps/infoalloggi/src/components/accordionComp.tsx +++ b/apps/infoalloggi/src/components/accordionComp.tsx @@ -10,6 +10,7 @@ import { cn } from "~/lib/utils"; interface AccordionCompProps extends InputHTMLAttributes { texts: Faq[]; + defaultOpen?: number; } /** @@ -29,7 +30,7 @@ interface AccordionCompProps extends InputHTMLAttributes { * ``` */ export const AccordionComp = forwardRef( - ({ texts, className }, ref) => { + ({ texts, defaultOpen, className }, ref) => { if (!texts || texts.length === 0) { return null; // Return null if no texts are provided } @@ -38,7 +39,14 @@ export const AccordionComp = forwardRef( className={cn("mx-auto flex max-w-xl justify-center", className)} ref={ref} > - + {texts.map((text, index) => ( // biome-ignore lint/suspicious/noArrayIndexKey: diff --git a/apps/infoalloggi/src/components/annunci_grid.tsx b/apps/infoalloggi/src/components/annunci_grid.tsx index 12b4c03..cafbdf9 100644 --- a/apps/infoalloggi/src/components/annunci_grid.tsx +++ b/apps/infoalloggi/src/components/annunci_grid.tsx @@ -1,11 +1,9 @@ -import { CardAnnuncio } from "~/components/annuncio_card2"; -import { getTitoloTranslation } from "~/lib/annuncio_details"; -import { useTranslation } from "~/providers/I18nProvider"; +import { CardAnnuncio } from "~/components/annuncio_card"; import type { AnnuncioRicerca } from "~/server/controllers/annunci.controller"; export const AnnunciGrid = ({ pagedata }: { pagedata: AnnuncioRicerca[] }) => { return ( -
+
{pagedata.map((annuncio) => ( ))} diff --git a/apps/infoalloggi/src/components/annuncio_card.tsx b/apps/infoalloggi/src/components/annuncio_card.tsx index 09a5b9a..da64e0a 100644 --- a/apps/infoalloggi/src/components/annuncio_card.tsx +++ b/apps/infoalloggi/src/components/annuncio_card.tsx @@ -1,4 +1,13 @@ -import { BedDouble, CalendarClock, Maximize2, Ruler } from "lucide-react"; +import { + BedDouble, + CalendarClock, + MapPin, + Maximize2, + Ruler, + Siren, + Star, + TrafficCone, +} from "lucide-react"; import Image from "next/image"; import Link from "next/link"; import { useState } from "react"; @@ -20,69 +29,95 @@ import { import { camereTesti, handleConsegna } from "~/lib/annuncio_details"; import { cn, formatCurrency } from "~/lib/utils"; import { useTranslation } from "~/providers/I18nProvider"; - +import type { AnnuncioRicerca } from "~/server/controllers/annunci.controller"; +import { Badge } from "./ui/badge"; import { VideoPlayer } from "./videoPlayer"; -type CardAnnuncioProps = { - id: number; - codice: string; - prezzo: number; - titolo: string | null; - mq: string | null; - comune: string | null; - provincia: string | null; - consegna: number | null; - camere: number | null; - //immagini: string[] | undefined; - tipo: string | null; - stato: string | null; +type CardAnnuncioProps = AnnuncioRicerca & { className?: string; - videos?: string[] | undefined; - updated_at: Date | null; - images: { img: string; thumb: string }[]; }; export const CardAnnuncio = ({ id, codice, prezzo, - titolo, + titolo_it, + titolo_en, mq, comune, provincia, consegna, - camere, - //immagini, + numero_camere: camere, tipo, stato, className, - videos, + url_video: videos, updated_at, images, + homepage, }: CardAnnuncioProps) => { - const { t } = useTranslation(); + const { t, locale } = useTranslation(); + const currentMonth = new Date().getMonth() + 1; + const isAvailableNow = consegna === 0 || consegna === currentMonth; return (
-
+
+
+ {stato !== "Trattativa" && homepage && ( +
+ svg]:size-4.5", + isAvailableNow ? "bg-green-500" : "bg-blue-500", + )} + > + {isAvailableNow ? ( + <> + Disponibile Subito + + + ) : ( + <> + In Evidenza + + + )} + +
+ )} {stato === "Trattativa" && ( -
-
-
- Annuncio in Trattativa -
-
+
+ svg]:size-4.5", + )} + > + In Trattativa + +
)} @@ -93,7 +128,7 @@ export const CardAnnuncio = ({
-
-
{tipo}
-
-
-
-
+
+
+
Affitto {tipo}
+
+
+
{t.card.codice} - + Cod: {codice}
-
+
{t.card.prezzo} @@ -177,58 +212,61 @@ export const CardAnnuncio = ({
+
+
+ {t.card.titolo} -
- {t.card.titolo} - - - {titolo} - -
-
- {t.card.indirizzo} - - - {comune && provincia && `${comune} (${provincia})`} - -
-
- -
-
- - -
-

- {mq ? Number.parseFloat(mq) : 0}{" "} - - m2 + + {locale === "it" ? titolo_it : titolo_en} + +

+
+
+ {t.card.indirizzo} + + + {comune && provincia && `${comune} (${provincia})`} -

-
-
-
- +
-
-

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

-
-
-
- +
+
+ -
-

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

+
+

+ {mq ? Number.parseFloat(mq) : 0}{" "} + + m2 + +

+
+
+
+ + +
+

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

+
+
+
+ + +
+

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

+
+
+
@@ -273,7 +311,7 @@ export const CarouselAnnuncio = ({ { - const { t } = useTranslation(); - - return ( -
- -
-
- Cod: {codice} -
- {stato === "Trattativa" && ( -
-
-
- Annuncio in Trattativa -
-
-
- )} - - - - {images?.map((img, idx) => ( - - - - ))} - {videos?.map((video) => { - if (!video) return null; - if (video.includes("youtu")) { - return null; - } - return ( - { - e.preventDefault(); - e.stopPropagation(); - }} - > - - - ); - })} - - -
e.preventDefault()} - onKeyDown={(e) => e.stopPropagation()} - role="button" - tabIndex={0} - > - - -
-
-
-
-
{tipo}
-
-
-
-
- {t.card.codice} - - - Cod: {codice} - -
-
- {t.card.prezzo} - - - {formatCurrency(prezzo / 1e2)} - -
-
- -
- {t.card.titolo} - - - {titolo} - -
-
- {t.card.indirizzo} - - - {comune && provincia && `${comune} (${provincia})`} - -
-
- -
-
- - -
-

- {mq ? Number.parseFloat(mq) : 0}{" "} - - m2 - -

-
-
-
- - -
-

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

-
-
-
- - -
-

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

-
-
-
- -
- ); -}; - -export const CarouselAnnuncio = ({ - single, - immagini, - videos, - updated_at, -}: { - single?: boolean; - immagini: string[] | null; - videos: string[] | null; - 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) => ( - - handleOpenModal(idx)} - priority={idx === 0} - src={`/storage-api/get/${img}?image=true&${updated_at?.toString() || new Date().toString()}`} - width={800} - /> - handleOpenModal(idx)} - /> - - ))} - {videos?.map((video, idx) => { - if (!video) return null; - if (video.includes("youtu")) { - return null; - } - return ( - - - - - handleOpenModal(immagini?.length || 0 + idx) - } - /> - - ); - })} - - - - - -
-
- - - - Image Dialog - Immagine - - - - {immagini?.map((img, idx) => ( - - {`carousel-img-${idx}`} - - ))} - {videos?.map((video) => { - if (!video) return null; - if (video.includes("youtu")) { - return null; - } - return ( - - - - ); - })} - - - - - - - - - ); -}; diff --git a/apps/infoalloggi/src/components/footer.tsx b/apps/infoalloggi/src/components/footer.tsx index a4c6780..0c7f3b1 100644 --- a/apps/infoalloggi/src/components/footer.tsx +++ b/apps/infoalloggi/src/components/footer.tsx @@ -1,12 +1,22 @@ import Link from "next/link"; import BlurryDivider from "~/components/blurry_divider"; import { LogoSvg } from "~/components/svgs"; +import { cn } from "~/lib/utils"; import { useTranslation } from "~/providers/I18nProvider"; -export const Footer = () => { + +type FooterProps = { + className?: string; +}; +export const Footer = ({ className }: FooterProps) => { const { t } = useTranslation(); return (
-