import type { GetServerSideProps } from "next"; import Head from "next/head"; import { useEffect, useMemo, useState } from "react"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "~/components/ui/select"; import { LoadingPage } from "~/components/loading"; import { Button } from "~/components/ui/button"; import { Label } from "~/components/ui/label"; import { cn } from "~/lib/utils"; import { ChevronDown, ChevronRight, ChevronsRight, ChevronUp, Filter, FilterX, MapIcon, RotateCcwIcon, Table, } from "lucide-react"; import { useTranslation } from "~/providers/I18nProvider"; import { AnnunciGrid } from "~/components/annunci_grid"; import { Status500 } from "~/components/status-page"; import { CodiceBox } from "~/components/codiceRicerca"; import { generateSSGHelper } from "~/server/utils/ssgHelper"; import { MapSection } from "~/components/annunci_map"; import { api } from "~/utils/api"; import { DropdownMenu, DropdownMenuContent, DropdownMenuTrigger, } from "~/components/ui/dropdown-menu"; import { Badge } from "~/components/ui/badge"; import { RicercaProvider, useRicerca, type AnnunciOptions, type SortTypes, } from "~/providers/RicercaProvider"; import { AccordionComp } from "~/components/accordionComp"; import { CTA_TipologiaModal } from "~/components/annunci_tutorial"; import { keepPreviousData } from "@tanstack/react-query"; type AnnunciPageProps = { options: AnnunciOptions; }; const Annunci = ({ options }: AnnunciPageProps) => { const { t } = useTranslation(); return ( {t.heads.annunci_titolo} {t.annunci.titolo} ); }; export default Annunci; export const getServerSideProps = (async () => { const helper = generateSSGHelper(); const options = await helper.annunci.getAnnunciOptions.fetch(); return { props: { options, }, }; }) satisfies GetServerSideProps; const Ricerca = () => { const { map, page } = useRicerca(); useEffect(() => { window.scrollTo({ top: 0, behavior: "smooth" }); }, [page]); return ( <> {map ? : } > ); }; const RicercaFilters = () => { const { t } = useTranslation(); const { map, setMap, tipo, setTipo, comune, setComune, consegna, setConsegna, sort, setSort, comuniOptions, tipologieOptions, consegnaOptions, ResetParams, nFiltri, } = useRicerca(); const [open, setOpen] = useState(false); const mappedConsegnaOptions = useMemo( () => consegnaOptions.map((m) => t.preferenze.mesi[m]!).filter(Boolean), [consegnaOptions, t.preferenze.mesi], ); return ( {nFiltri} {" "} {nFiltri === 1 ? t.annunci.filtro_attivo : t.annunci.filtri_attivi} {open ? : } { await setTipo(value); }} placeholder={t.seleziona_placeholder} handleReset={async () => { await setTipo(""); }} /> { await setComune(value); }} placeholder={t.seleziona_placeholder} handleReset={async () => { await setComune(null); }} /> { if (value === "") { await setConsegna(null); return; } if (t.preferenze.mesi.includes(value)) { await setConsegna(t.preferenze.mesi.indexOf(value)); return; } else { console.warn("Value not found in preferenze.mesi"); await setConsegna(null); } }} placeholder={t.seleziona_placeholder} handleReset={async () => { await setConsegna(null); }} /> { await setSort(value); }} placeholder={t.seleziona_placeholder} handleReset={async () => { await setSort(""); }} /> {t.annunci.filtri_reset} { await setMap((v) => !v); }} className="flex w-fit flex-row gap-2" > {!map ? ( <> {" "} Mappa > ) : ( <> Lista > )} ); }; const AnnunciList = () => { const { tipo, comune, consegna, sort, map, page, setPage, isLoading: ricercaLoading, } = useRicerca(); const { data, status, isPlaceholderData } = api.annunci.getWithCursor.useQuery( { page, pageSize: 6, tipologia: tipo || undefined, comune: comune || undefined, consegna: consegna || undefined, sort: sort || undefined, }, { placeholderData: keepPreviousData, enabled: !map, staleTime: 5000, }, ); const utils = api.useUtils(); useEffect(() => { const prefetchData = async () => { if (!isPlaceholderData && data?.hasMore) { await utils.annunci.getWithCursor.prefetch({ page: page + 1, pageSize: 6, tipologia: tipo || undefined, comune: comune || undefined, consegna: consegna || undefined, sort: sort || undefined, }); } }; prefetchData().catch((err) => { console.error("Error prefetching next page:", err); }); }, [data, isPlaceholderData, page]); if (ricercaLoading) return ; if (status === "error") return ; return ( <> {status === "pending" ? ( ) : ( )} { await setPage(0); }} disabled={page < 2} > { await setPage((old) => (old ? Math.max(old - 1, 0) : 0)); }} disabled={page === 0} > {page + 1} { await setPage((old) => old ? (data?.hasMore ? old + 1 : old) : 1, ); }} disabled={isPlaceholderData || !data?.hasMore} > > ); }; interface SelectFilterProps { label: string; options: string[]; defaultValue?: T; value: T | undefined; onValueChange: (value: T) => void; handleReset: () => void; placeholder: string; } export const SelectFilter = ({ label, options, defaultValue, value, onValueChange, placeholder, handleReset, }: SelectFilterProps) => { return ( {label} {value !== "" && ( )} {options.map((option) => ( {option} ))} ); };