diff --git a/apps/infoalloggi/src/pages/_app.tsx b/apps/infoalloggi/src/pages/_app.tsx
index 88707ba..875c82b 100644
--- a/apps/infoalloggi/src/pages/_app.tsx
+++ b/apps/infoalloggi/src/pages/_app.tsx
@@ -73,7 +73,10 @@ const MyApp = ({
`}
-
+ {!router.pathname.startsWith("/annunci") && (
+
+ )}
+
{getLayout()}
diff --git a/apps/infoalloggi/src/pages/annunci.tsx b/apps/infoalloggi/src/pages/annunci.tsx
index f1973ab..cb5bb99 100644
--- a/apps/infoalloggi/src/pages/annunci.tsx
+++ b/apps/infoalloggi/src/pages/annunci.tsx
@@ -29,10 +29,7 @@ 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 { useRouter } from "next/router";
-import toast from "react-hot-toast";
import {
DropdownMenu,
DropdownMenuContent,
@@ -47,6 +44,7 @@ import {
} 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;
@@ -265,7 +263,6 @@ const RicercaFilters = () => {
};
const AnnunciList = () => {
- const router = useRouter();
const {
tipo,
comune,
@@ -274,68 +271,110 @@ const AnnunciList = () => {
map,
page,
setPage,
- lastPageCount,
- setlastPageCount,
isLoading: ricercaLoading,
} = useRicerca();
- const { data, fetchNextPage, isLoading, hasNextPage } =
- api.annunci.getWithCursor.useInfiniteQuery(
+ const { data, status, isPlaceholderData } =
+ api.annunci.getWithCursor.useQuery(
{
- limit: 6,
+ page,
+ pageSize: 6,
tipologia: tipo || undefined,
comune: comune || undefined,
consegna: consegna || undefined,
sort: sort || undefined,
},
{
- getNextPageParam: (lastPage) => lastPage.nextCursor,
+ placeholderData: keepPreviousData,
enabled: !map,
+ staleTime: 5000,
},
);
-
- const handlePageReset = () => {
- setPage(0);
- };
-
- const handleFetchNextPage = async () => {
- try {
- await fetchNextPage();
- setPage((prev) => prev + 1);
- } catch {
- await router.push("/annunci");
- toast.error("Errore caricamento annunci");
- }
- };
-
- const handleFetchPreviousPage = () => {
- setPage((prev) => prev - 1);
- };
-
+ const utils = api.useUtils();
useEffect(() => {
- if (
- hasNextPage !== undefined &&
- hasNextPage === false &&
- lastPageCount === 100
- ) {
- setlastPageCount(page);
- }
- }, [hasNextPage, page, lastPageCount]);
+ 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 (isLoading || ricercaLoading) return ;
- if ((!isLoading && !data) || !data) return ;
+ if (ricercaLoading) return ;
+ if (status === "error") return ;
return (
<>
-
+ {status === "pending" ? (
+
+ ) : (
+
+ )}
-
+
+
+
+
+
+
+
+
+
+
+ {page + 1}
+
+
+
+
+
+
>
);
};
@@ -396,73 +435,3 @@ export const SelectFilter = ({
);
};
-
-const PaginationHandler = ({
- handleFetchNextPage,
- handleFetchPreviousPage,
- handlePageReset,
- page,
- hasNextPage,
-}: {
- handleFetchNextPage: () => Promise;
- handleFetchPreviousPage: () => void;
- handlePageReset: () => void;
- page: number;
- hasNextPage: string | undefined;
-}) => {
- const [attivo, setAttivo] = useState(true);
- const fetchNextPage = async () => {
- setAttivo(false);
- await handleFetchNextPage();
- setAttivo(true);
- };
-
- return (
-
-
-
-
-
-
-
-
-
- {page + 1}
-
-
-
-
-
-
- );
-};
diff --git a/apps/infoalloggi/src/providers/RicercaProvider.tsx b/apps/infoalloggi/src/providers/RicercaProvider.tsx
index ef23fa1..e29dfd1 100644
--- a/apps/infoalloggi/src/providers/RicercaProvider.tsx
+++ b/apps/infoalloggi/src/providers/RicercaProvider.tsx
@@ -3,12 +3,9 @@ import {
createContext,
useContext,
useMemo,
- useState,
useTransition,
- type Dispatch,
type FC,
type ReactNode,
- type SetStateAction,
} from "react";
import {
parseAsBoolean,
@@ -45,9 +42,9 @@ type RicercaContextType = {
consegnaOptions: number[];
sortOptions: typeof sortOptions;
page: number;
- setPage: Dispatch>;
- lastPageCount: number;
- setlastPageCount: Dispatch>;
+ setPage: (
+ value: number | ((old: number | null) => number | null) | null,
+ ) => Promise;
ResetParams: () => Promise;
nFiltri: number;
isLoading: boolean;
@@ -103,8 +100,10 @@ export const RicercaProvider: FC<{
.withOptions({ startTransition }),
);
- const [page, setPage] = useState(0);
- const [lastPageCount, setlastPageCount] = useState(100);
+ const [page, setPage] = useQueryState(
+ "p",
+ parseAsInteger.withDefault(0).withOptions({ clearOnDefault: true }),
+ );
const tipologieOptions = useMemo(() => {
const set = new Set();
@@ -147,7 +146,7 @@ export const RicercaProvider: FC<{
await setComune("");
await setConsegna(null);
await setSort("");
- setPage(0);
+ await setPage(0);
};
const nFiltri =
@@ -176,8 +175,6 @@ export const RicercaProvider: FC<{
page,
setPage,
- lastPageCount,
- setlastPageCount,
ResetParams,
nFiltri,
isLoading,
diff --git a/apps/infoalloggi/src/server/api/routers/annunci.ts b/apps/infoalloggi/src/server/api/routers/annunci.ts
index 56517d8..27e6cab 100644
--- a/apps/infoalloggi/src/server/api/routers/annunci.ts
+++ b/apps/infoalloggi/src/server/api/routers/annunci.ts
@@ -57,8 +57,8 @@ export const annunciRouter = createTRPCRouter({
getWithCursor: publicProcedure
.input(
z.object({
- limit: z.number().min(1).max(100).optional(),
- cursor: z.string().optional(),
+ page: z.number().optional(),
+ pageSize: z.number(),
tipologia: z.string().optional(),
comune: z.string().optional(),
consegna: z.number().optional(),
@@ -66,13 +66,9 @@ export const annunciRouter = createTRPCRouter({
}),
)
.query(async ({ input }) => {
- const { annunci, nextCursor } = await getCursor_AnnunciHandler({
- input,
+ return await getCursor_AnnunciHandler({
+ ...input,
});
- return {
- annunci,
- nextCursor,
- };
}),
getMapping: publicProcedure
.input(
diff --git a/apps/infoalloggi/src/server/controllers/annunci.controller.ts b/apps/infoalloggi/src/server/controllers/annunci.controller.ts
index 3c07fa3..6920300 100644
--- a/apps/infoalloggi/src/server/controllers/annunci.controller.ts
+++ b/apps/infoalloggi/src/server/controllers/annunci.controller.ts
@@ -233,34 +233,20 @@ export type AnnuncioRicerca = Pick<
>;
export const getCursor_AnnunciHandler = async ({
- input,
+ page = 0,
+ pageSize,
+ tipologia,
+ comune,
+ consegna,
+ sort,
}: {
- input: {
- limit?: number;
- cursor?: string;
- tipologia?: string;
- comune?: string;
- consegna?: number;
- sort?: "Recenti" | "Prezzo" | "Consegna" | "Mq";
- };
-}): Promise<{
- annunci: AnnuncioRicerca[];
- nextCursor: string | undefined;
-}> => {
- const limit = input.limit ?? 50;
- const [cursor, sortCursor] = input.cursor?.split("_") ?? [0, undefined];
- function sortType(sort: "Recenti" | "Prezzo" | "Consegna" | "Mq") {
- switch (sort) {
- case "Recenti":
- return { col: "modificato_il", opr: "desc" };
- case "Prezzo":
- return { col: "prezzo", opr: "asc" };
- case "Consegna":
- return { col: "consegna", opr: "asc" };
- case "Mq":
- return { col: "mq", opr: "asc" };
- }
- }
+ page?: number;
+ pageSize: number;
+ tipologia?: string;
+ comune?: string;
+ consegna?: number;
+ sort?: "Recenti" | "Prezzo" | "Consegna" | "Mq";
+}) => {
try {
let query = db
.selectFrom("annunci")
@@ -283,35 +269,18 @@ export const getCursor_AnnunciHandler = async ({
.where("web", "=", true)
.where("stato", "!=", "Sospeso");
- if (sortCursor && input.sort !== undefined) {
- const { col: sortColumn, opr } = sortType(input.sort) as {
- col: keyof Annunci;
- opr: string;
- };
- query = query.where((eb) =>
- eb.or([
- eb.and([
- eb("id", ">=", (cursor as AnnunciId) ?? 0),
- eb(sortColumn, "=", sortCursor.toString()),
- ]),
- eb(sortColumn, opr === "desc" ? "<" : ">", sortCursor.toString()),
- ]),
- );
- } else {
- query = query.where("id", ">=", (cursor as AnnunciId) ?? 0);
- }
- if (input.tipologia && input.tipologia !== "") {
- query = query.where("tipo", "=", input.tipologia);
+ if (tipologia && tipologia !== "") {
+ query = query.where("tipo", "=", tipologia);
}
- if (input.comune && input.comune !== "") {
- query = query.where("comune", "like", input.comune);
+ if (comune && comune !== "") {
+ query = query.where("comune", "like", comune);
}
- if (input.consegna) {
- query = query.where("consegna", "=", input.consegna);
+ if (consegna) {
+ query = query.where("consegna", "=", consegna);
}
- if (input.sort) {
- switch (input.sort) {
+ if (sort) {
+ switch (sort) {
case "Recenti":
query = query.orderBy("modificato_il", "desc");
break;
@@ -328,32 +297,13 @@ export const getCursor_AnnunciHandler = async ({
}
query = query.orderBy("id", "asc");
- const itemsraw = await query.limit(limit + 1).execute();
- const annunci = itemsraw;
- let nextCursor: string | undefined = undefined;
-
- if (annunci.length > limit) {
- const nextItem = annunci.pop(); // return the last item from the array
- if (!nextItem) {
- throw new TRPCError({
- code: "INTERNAL_SERVER_ERROR",
- message: "Errore interno",
- });
- }
- if (!input.sort) {
- nextCursor = nextItem.id.toString();
- } else {
- const { col: sortColumn } = sortType(input.sort);
- if (sortColumn === "modificato_il") {
- if (!nextItem.modificato_il) {
- nextCursor = `${nextItem.id.toString()}_1990-01-01`;
- } else {
- nextCursor = `${nextItem.id.toString()}_${nextItem.modificato_il.toISOString()}`;
- }
- } else {
- nextCursor = `${nextItem.id.toString()}_${nextItem[sortColumn as keyof typeof nextItem]?.toString()}`;
- }
- }
+ const annunci = await query
+ .limit(pageSize + 1)
+ .offset(page * pageSize)
+ .execute();
+ const hasMore = annunci.length > pageSize;
+ if (annunci.length > pageSize) {
+ annunci.pop(); // Remove the last item if it exceeds the page size
}
for (const annuncio of annunci) {
@@ -361,9 +311,10 @@ export const getCursor_AnnunciHandler = async ({
? createSrcset(annuncio.url_immagini)
: [];
}
+
return {
annunci,
- nextCursor,
+ hasMore,
};
} catch {
throw new TRPCError({