refactor: remove pagination logic and related state management from Annunci and RicercaProvider components
This commit is contained in:
parent
4c4397d0ee
commit
47f35c3bbe
4 changed files with 14 additions and 199 deletions
|
|
@ -75,8 +75,6 @@ const Annunci = ({ options }: AnnunciPageProps) => {
|
||||||
{t.annunci.titolo}
|
{t.annunci.titolo}
|
||||||
</Badge>
|
</Badge>
|
||||||
|
|
||||||
<GoBackButton />
|
|
||||||
|
|
||||||
<Ricerca />
|
<Ricerca />
|
||||||
<AccordionComp
|
<AccordionComp
|
||||||
className="max-w-6xl px-4 py-4 md:py-8"
|
className="max-w-6xl px-4 py-4 md:py-8"
|
||||||
|
|
@ -87,22 +85,7 @@ const Annunci = ({ options }: AnnunciPageProps) => {
|
||||||
</RicercaProvider>
|
</RicercaProvider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
const GoBackButton = () => {
|
|
||||||
const { page, setPage } = useRicerca();
|
|
||||||
if (page >= 2) {
|
|
||||||
return (
|
|
||||||
<Button
|
|
||||||
className="absolute right-0 h-auto py-0 text-base text-neutral-600 underline underline-offset-1 sm:hidden"
|
|
||||||
onClick={async () => {
|
|
||||||
await setPage(0);
|
|
||||||
}}
|
|
||||||
variant="link"
|
|
||||||
>
|
|
||||||
Torna all'inizio
|
|
||||||
</Button>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
export default Annunci;
|
export default Annunci;
|
||||||
|
|
||||||
Annunci.getLayout = (page: React.ReactNode) => {
|
Annunci.getLayout = (page: React.ReactNode) => {
|
||||||
|
|
@ -127,10 +110,7 @@ export const getServerSideProps = (async () => {
|
||||||
}) satisfies GetServerSideProps<AnnunciPageProps>;
|
}) satisfies GetServerSideProps<AnnunciPageProps>;
|
||||||
|
|
||||||
const Ricerca = () => {
|
const Ricerca = () => {
|
||||||
const { map, page } = useRicerca();
|
const { map } = useRicerca();
|
||||||
useEffect(() => {
|
|
||||||
window.scrollTo({ behavior: "smooth", top: 0 });
|
|
||||||
}, [page]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx-auto w-full space-y-5">
|
<div className="mx-auto w-full space-y-5">
|
||||||
|
|
@ -343,21 +323,13 @@ const AnnunciList = () => {
|
||||||
consegna,
|
consegna,
|
||||||
sort,
|
sort,
|
||||||
map,
|
map,
|
||||||
page,
|
|
||||||
isLoading: ricercaLoading,
|
isLoading: ricercaLoading,
|
||||||
annunciNumber,
|
|
||||||
} = useRicerca();
|
} = useRicerca();
|
||||||
|
|
||||||
const {
|
const { data, status } = api.annunci.annunciRicerca.useQuery(
|
||||||
data,
|
|
||||||
status,
|
|
||||||
//isPlaceholderData
|
|
||||||
} = api.annunci.getWithCursor.useQuery(
|
|
||||||
{
|
{
|
||||||
comune: comune || undefined,
|
comune: comune || undefined,
|
||||||
consegna: consegna || undefined,
|
consegna: consegna || undefined,
|
||||||
page,
|
|
||||||
pageSize: annunciNumber,
|
|
||||||
sort: sort || undefined,
|
sort: sort || undefined,
|
||||||
tipologia: tipo || undefined,
|
tipologia: tipo || undefined,
|
||||||
},
|
},
|
||||||
|
|
@ -368,58 +340,6 @@ const AnnunciList = () => {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
/*
|
|
||||||
DISABILITATO FUNZIONALITA PAGING E PAGE SIZE
|
|
||||||
|
|
||||||
const utils = api.useUtils();
|
|
||||||
useEffect(() => {
|
|
||||||
const prefetchData = async () => {
|
|
||||||
if (!isPlaceholderData && data?.hasMore) {
|
|
||||||
await utils.annunci.getWithCursor.prefetch({
|
|
||||||
comune: comune || undefined,
|
|
||||||
consegna: consegna || undefined,
|
|
||||||
page: page + 1,
|
|
||||||
pageSize: annunciNumber,
|
|
||||||
sort: sort || undefined,
|
|
||||||
tipologia: tipo || undefined,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
prefetchData().catch((err) => {
|
|
||||||
console.error("Error prefetching next page:", err);
|
|
||||||
});
|
|
||||||
}, [data, isPlaceholderData, page, annunciNumber]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
// Reset to page 0 if current page has no data or less than page size
|
|
||||||
const checkPage = async () => {
|
|
||||||
if (data) {
|
|
||||||
if (data.annunci.length === 0 && page !== 0) {
|
|
||||||
await setPage(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
checkPage().catch((err) => {
|
|
||||||
console.error("Error checking data for page reset:", err);
|
|
||||||
});
|
|
||||||
}, [data, tipo, comune, consegna, sort, setPage, annunciNumber]);
|
|
||||||
|
|
||||||
const [debouncedAnnunciNumber, setDebouncedAnnunciNumber] =
|
|
||||||
useState(annunciNumber);
|
|
||||||
|
|
||||||
useDebounce(
|
|
||||||
async () => {
|
|
||||||
console.log("Setting annunciNumber to", debouncedAnnunciNumber);
|
|
||||||
console.log("Current annunciNumber is", annunciNumber);
|
|
||||||
if (debouncedAnnunciNumber !== annunciNumber) {
|
|
||||||
await setAnnunciNumber(debouncedAnnunciNumber);
|
|
||||||
await setPage(0);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
500,
|
|
||||||
[debouncedAnnunciNumber],
|
|
||||||
);
|
|
||||||
*/
|
|
||||||
if (ricercaLoading) return <LoadingPage />;
|
if (ricercaLoading) return <LoadingPage />;
|
||||||
if (status === "error") return <Status500 />;
|
if (status === "error") return <Status500 />;
|
||||||
|
|
||||||
|
|
@ -429,7 +349,7 @@ const AnnunciList = () => {
|
||||||
<LoadingPage />
|
<LoadingPage />
|
||||||
) : (
|
) : (
|
||||||
<div className="relative z-0 mx-auto grid w-full grid-flow-row grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4">
|
<div className="relative z-0 mx-auto grid w-full grid-flow-row grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4">
|
||||||
{data.annunci.map((annuncio, idx) => (
|
{data.map((annuncio, idx) => (
|
||||||
<LazyCardAnnuncio
|
<LazyCardAnnuncio
|
||||||
key={annuncio.codice}
|
key={annuncio.codice}
|
||||||
{...annuncio}
|
{...annuncio}
|
||||||
|
|
@ -439,69 +359,6 @@ const AnnunciList = () => {
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* <div className="relative flex items-center justify-center gap-2">
|
|
||||||
<div className="absolute left-0 flex items-center gap-2">
|
|
||||||
<span className="text-muted-foreground text-sm">
|
|
||||||
annunci per pagina:
|
|
||||||
</span>
|
|
||||||
<NumberInput
|
|
||||||
allowNegative={false}
|
|
||||||
className="w-16 bg-white"
|
|
||||||
min={0}
|
|
||||||
onValueChange={(val) => {
|
|
||||||
if (val !== undefined) {
|
|
||||||
setDebouncedAnnunciNumber(val);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
value={debouncedAnnunciNumber}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="flex w-24 items-center justify-end gap-2">
|
|
||||||
{page >= 2 && (
|
|
||||||
<Button
|
|
||||||
aria-label="Go to first page"
|
|
||||||
onClick={async () => {
|
|
||||||
await setPage(0);
|
|
||||||
}}
|
|
||||||
title="Go to first page"
|
|
||||||
variant="outline"
|
|
||||||
>
|
|
||||||
<ChevronsLeft className="h-4 w-4" />
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<Button
|
|
||||||
aria-label="Previous page"
|
|
||||||
disabled={page === 0}
|
|
||||||
onClick={async () => {
|
|
||||||
await setPage((old) => (old ? Math.max(old - 1, 0) : 0));
|
|
||||||
}}
|
|
||||||
title="Previous page"
|
|
||||||
variant="outline"
|
|
||||||
>
|
|
||||||
<ChevronLeft className="h-4 w-4" />
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
<div className="mx-4 w-12 rounded-md bg-white py-2 text-center font-medium text-lg">
|
|
||||||
{page + 1}
|
|
||||||
</div>
|
|
||||||
<div className="flex w-24 items-center justify-start gap-2">
|
|
||||||
<Button
|
|
||||||
aria-label="Next page"
|
|
||||||
disabled={isPlaceholderData || !data?.hasMore}
|
|
||||||
onClick={async () => {
|
|
||||||
await setPage((old) =>
|
|
||||||
old ? (data?.hasMore ? old + 1 : old) : 1,
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
title="Next page"
|
|
||||||
variant="outline"
|
|
||||||
>
|
|
||||||
<ChevronRight className="h-4 w-4" />
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div> */}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -41,15 +41,8 @@ type RicercaContextType = {
|
||||||
tipologieOptions: string[];
|
tipologieOptions: string[];
|
||||||
consegnaOptions: number[];
|
consegnaOptions: number[];
|
||||||
sortOptions: typeof sortOptions;
|
sortOptions: typeof sortOptions;
|
||||||
page: number;
|
|
||||||
setPage: (
|
|
||||||
value: number | ((old: number | null) => number | null) | null,
|
|
||||||
) => Promise<URLSearchParams>;
|
|
||||||
ResetParams: () => Promise<void>;
|
ResetParams: () => Promise<void>;
|
||||||
annunciNumber: number;
|
|
||||||
setAnnunciNumber: (
|
|
||||||
value: number | ((old: number) => number | null) | null,
|
|
||||||
) => Promise<URLSearchParams>;
|
|
||||||
nFiltri: number;
|
nFiltri: number;
|
||||||
isLoading: boolean;
|
isLoading: boolean;
|
||||||
};
|
};
|
||||||
|
|
@ -104,15 +97,6 @@ export const RicercaProvider: FC<{
|
||||||
.withOptions({ startTransition }),
|
.withOptions({ startTransition }),
|
||||||
);
|
);
|
||||||
|
|
||||||
const [page, setPage] = useQueryState(
|
|
||||||
"p",
|
|
||||||
parseAsInteger.withDefault(0).withOptions({ clearOnDefault: true }),
|
|
||||||
);
|
|
||||||
const [annunciNumber, setAnnunciNumber] = useQueryState(
|
|
||||||
"n",
|
|
||||||
parseAsInteger.withDefault(1000).withOptions({ startTransition }),
|
|
||||||
);
|
|
||||||
|
|
||||||
const tipologieOptions = useMemo(() => {
|
const tipologieOptions = useMemo(() => {
|
||||||
const set = new Set<string>();
|
const set = new Set<string>();
|
||||||
options.forEach((item) => {
|
options.forEach((item) => {
|
||||||
|
|
@ -161,7 +145,6 @@ export const RicercaProvider: FC<{
|
||||||
await setComune("");
|
await setComune("");
|
||||||
await setConsegna(null);
|
await setConsegna(null);
|
||||||
await setSort("Recenti");
|
await setSort("Recenti");
|
||||||
//await setPage(0);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const nFiltri =
|
const nFiltri =
|
||||||
|
|
@ -182,22 +165,18 @@ export const RicercaProvider: FC<{
|
||||||
isLoading,
|
isLoading,
|
||||||
map,
|
map,
|
||||||
nFiltri,
|
nFiltri,
|
||||||
page,
|
|
||||||
|
|
||||||
ResetParams,
|
ResetParams,
|
||||||
setComune,
|
setComune,
|
||||||
setConsegna,
|
setConsegna,
|
||||||
setMap,
|
setMap,
|
||||||
setPage,
|
|
||||||
setSort,
|
setSort,
|
||||||
setTipo,
|
setTipo,
|
||||||
sort,
|
sort,
|
||||||
sortOptions: sortOptions,
|
sortOptions: sortOptions,
|
||||||
tipo,
|
tipo,
|
||||||
tipologieOptions,
|
tipologieOptions,
|
||||||
|
|
||||||
annunciNumber,
|
|
||||||
setAnnunciNumber,
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,8 @@ import {
|
||||||
getAnnunciById_rawImgUrls,
|
getAnnunciById_rawImgUrls,
|
||||||
getAnnunciListHandler,
|
getAnnunciListHandler,
|
||||||
getAnnunciMetaByCod,
|
getAnnunciMetaByCod,
|
||||||
|
getAnnunciRicerca,
|
||||||
getCodici_AnnunciHandler,
|
getCodici_AnnunciHandler,
|
||||||
getCursor_AnnunciHandler,
|
|
||||||
getOptions_AnnunciHandler,
|
getOptions_AnnunciHandler,
|
||||||
getProprietarioDataHandler,
|
getProprietarioDataHandler,
|
||||||
} from "~/server/controllers/annunci.controller";
|
} from "~/server/controllers/annunci.controller";
|
||||||
|
|
@ -89,19 +89,18 @@ export const annunciRouter = createTRPCRouter({
|
||||||
servizioId: input.servizioId,
|
servizioId: input.servizioId,
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
getWithCursor: publicProcedure
|
|
||||||
|
annunciRicerca: publicProcedure
|
||||||
.input(
|
.input(
|
||||||
z.object({
|
z.object({
|
||||||
comune: z.string().optional(),
|
comune: z.string().optional(),
|
||||||
consegna: z.number().optional(),
|
consegna: z.number().optional(),
|
||||||
page: z.number().optional(),
|
|
||||||
pageSize: z.number(),
|
|
||||||
sort: z.enum(["Recenti", "Prezzo", "Consegna", "Mq"]).optional(),
|
sort: z.enum(["Recenti", "Prezzo", "Consegna", "Mq"]).optional(),
|
||||||
tipologia: z.string().optional(),
|
tipologia: z.string().optional(),
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.query(async ({ input }) => {
|
.query(async ({ input }) => {
|
||||||
return await getCursor_AnnunciHandler({
|
return await getAnnunciRicerca({
|
||||||
...input,
|
...input,
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
|
|
|
||||||
|
|
@ -257,24 +257,17 @@ export type AnnuncioRicerca = Pick<
|
||||||
videos: Pick<VideosRefs, "video" | "thumb">[];
|
videos: Pick<VideosRefs, "video" | "thumb">[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getCursor_AnnunciHandler = async ({
|
export const getAnnunciRicerca = async ({
|
||||||
page = 0,
|
|
||||||
pageSize,
|
|
||||||
tipologia,
|
tipologia,
|
||||||
comune,
|
comune,
|
||||||
consegna,
|
consegna,
|
||||||
sort,
|
sort,
|
||||||
}: {
|
}: {
|
||||||
page?: number;
|
|
||||||
pageSize: number;
|
|
||||||
tipologia?: string;
|
tipologia?: string;
|
||||||
comune?: string;
|
comune?: string;
|
||||||
consegna?: number;
|
consegna?: number;
|
||||||
sort?: "Recenti" | "Prezzo" | "Consegna" | "Mq";
|
sort?: "Recenti" | "Prezzo" | "Consegna" | "Mq";
|
||||||
}): Promise<{
|
}): Promise<AnnuncioRicerca[]> => {
|
||||||
annunci: AnnuncioRicerca[];
|
|
||||||
hasMore: boolean;
|
|
||||||
}> => {
|
|
||||||
try {
|
try {
|
||||||
let query = db
|
let query = db
|
||||||
.selectFrom("annunci")
|
.selectFrom("annunci")
|
||||||
|
|
@ -334,24 +327,11 @@ export const getCursor_AnnunciHandler = async ({
|
||||||
|
|
||||||
query = query.orderBy("id", "asc");
|
query = query.orderBy("id", "asc");
|
||||||
|
|
||||||
const annunci = await query
|
return await query.execute();
|
||||||
.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
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
annunci,
|
|
||||||
hasMore,
|
|
||||||
};
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new TRPCError({
|
throw new TRPCError({
|
||||||
code: "INTERNAL_SERVER_ERROR",
|
code: "INTERNAL_SERVER_ERROR",
|
||||||
message: `Errore query getWithCursor: ${(e as Error).message}`,
|
message: `Errore query ricercaAnnunci: ${(e as Error).message}`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue