refactor: update consegna handling to support multiple values and adjust related components

This commit is contained in:
Marco Pedone 2025-12-29 18:33:00 +01:00
parent 2082ea2c62
commit c6b325368a
6 changed files with 112 additions and 38 deletions

View file

@ -50,7 +50,7 @@ const MapDisplay = memo(
}: {
selectTipo: string;
selectComune: string;
selectConsegna: number | null;
selectConsegna: number[] | null;
setSelected: Dispatch<SetStateAction<AnnuncioRicercaWPosition | null>>;
}) => {
const { data, isLoading } = api.annunci.getMapping.useQuery({

View file

@ -289,7 +289,7 @@ export const it: LangDict = {
Faqs.come_confermare,
],
comune: "Comune",
consegna: "Consegna",
consegna: "Disponibile da",
filtri_attivi: "Filtri attivi",
filtri_reset: "Reset filtri",
filtro_attivo: "Filtro attivo",

View file

@ -123,21 +123,14 @@ const Filters = () => {
setTipo,
comune,
setComune,
consegna,
setConsegna,
sort,
setSort,
comuniOptions,
tipologieOptions,
consegnaOptions,
ResetParams,
nFiltri,
} = useRicerca();
const mappedConsegnaOptions = useMemo(
// biome-ignore lint/style/noNonNullAssertion: <known lenght>
() => consegnaOptions.map((m) => t.parametri.mesi[m]!).filter(Boolean),
[consegnaOptions, t.parametri.mesi],
);
return (
<>
<SelectFilter
@ -166,7 +159,8 @@ const Filters = () => {
placeholder={t.seleziona_placeholder}
value={comune}
/>
<SelectFilter
<ConsegnaFilter />
{/* <SelectFilter
defaultValue={""}
handleReset={async () => {
await setConsegna(null);
@ -187,7 +181,7 @@ const Filters = () => {
options={mappedConsegnaOptions}
placeholder={t.seleziona_placeholder}
value={consegna ? t.parametri.mesi[consegna] || "" : ""}
/>
/> */}
<SelectFilter
defaultValue={sort}
handleReset={async () => {
@ -274,7 +268,7 @@ const RicercaHeader = () => {
<div className="flex w-full items-center gap-2 sm:w-auto">
<DrowdownFilters />
<Button
className="flex w-fit flex-row items-center gap-2"
className="flex w-fit flex-row items-center gap-2 md:w-24"
onClick={async () => {
await setMap((v) => !v);
}}
@ -416,3 +410,78 @@ export const SelectFilter = <T extends string>({
</div>
);
};
const ConsegnaFilter = () => {
const { t } = useTranslation();
const {
consegna: consegna2,
setConsegna: setConsegna2,
consegnaOptions,
} = useRicerca();
const mappedConsegnaOptions = useMemo(() => {
if (consegnaOptions.length === 0) return [];
return consegnaOptions
.map((c) =>
t.parametri.mesi[c] ? { value: c, label: t.parametri.mesi[c] } : null,
)
.filter((v) => v !== null);
}, [consegnaOptions, t.parametri.mesi]);
const onValueChange = async (value: number) => {
if (consegna2?.includes(value)) {
// Remove value
const newConsegna2 = consegna2.filter((c) => c !== value);
await setConsegna2(newConsegna2.length > 0 ? newConsegna2 : null);
return;
}
// Add value
const newConsegna2 = consegna2 ? [...consegna2, value] : [value];
await setConsegna2(newConsegna2);
return;
};
return (
<div className="flex flex-col gap-2">
<div className="flex h-4 flex-row gap-4 px-1">
<Label
className={cn(
"font-semibold text-muted-foreground",
consegna2 !== null && consegna2.length > 0 && "text-primary",
)}
>
{t.annunci.consegna}
</Label>
{consegna2 !== null && consegna2.length > 0 && (
<button
className="cursor-pointer"
onClick={async () => {
await setConsegna2(null);
}}
type="button"
>
<RotateCcwIcon className="size-4" />
</button>
)}
</div>
<div className="flex flex-wrap gap-1 rounded-md bg-background p-1">
{mappedConsegnaOptions.map(({ value, label }) => (
<Button
className={cn(
consegna2?.includes(value) && "border border-primary",
)}
key={value}
onClick={async () => {
await onValueChange(value);
}}
size="sm"
variant={consegna2?.includes(value) ? "default" : "outline"}
>
<span className="text-sm">{label.substring(0, 3)}</span>
</Button>
))}
</div>
</div>
);
};

View file

@ -1,5 +1,6 @@
"use client";
import {
parseAsArrayOf,
parseAsBoolean,
parseAsInteger,
parseAsString,
@ -28,9 +29,10 @@ type RicercaContextType = {
setComune: (
value: string | ((old: string) => string | null) | null,
) => Promise<URLSearchParams>;
consegna: number | null;
consegna: number[] | null;
setConsegna: (
value: number | ((old: number | null) => number | null) | null,
value: number[] | ((old: number[] | null) => number[] | null) | null,
) => Promise<URLSearchParams>;
sort: SortTypes;
setSort: (
@ -88,7 +90,7 @@ export const RicercaProvider: FC<{
);
const [consegna, setConsegna] = useQueryState(
"consegna",
parseAsInteger.withOptions({ startTransition }),
parseAsArrayOf(parseAsInteger).withOptions({ startTransition }),
);
const [sort, setSort] = useQueryState(
"sort",
@ -101,7 +103,7 @@ export const RicercaProvider: FC<{
const set = new Set<string>();
options.forEach((item) => {
if (!comune || item.comune === comune) {
if (!consegna || item.consegna === consegna) {
if (!consegna || consegna.includes(item.consegna)) {
set.add(item.tipo);
}
}
@ -113,7 +115,7 @@ export const RicercaProvider: FC<{
const set = new Set<string>();
options.forEach((item) => {
if (!tipo || item.tipo === tipo) {
if (!consegna || item.consegna === consegna) {
if (!consegna || consegna.includes(item.consegna)) {
set.add(item.comune);
}
}
@ -159,24 +161,27 @@ export const RicercaProvider: FC<{
<RicercaContext.Provider
value={{
comune,
comuniOptions,
consegna,
consegnaOptions,
isLoading,
map,
nFiltri,
ResetParams,
setComune,
comuniOptions,
consegna,
setConsegna,
consegnaOptions,
tipo,
setTipo,
tipologieOptions,
sort,
setSort,
sortOptions: sortOptions,
map,
setMap,
setSort,
setTipo,
sort,
sortOptions: sortOptions,
tipo,
tipologieOptions,
nFiltri,
isLoading,
ResetParams,
}}
>
{children}

View file

@ -71,7 +71,7 @@ export const annunciRouter = createTRPCRouter({
.input(
z.object({
comune: z.string().optional(),
consegna: z.number().optional(),
consegna: z.number().array().optional(),
tipologia: z.string().optional(),
}),
)
@ -94,7 +94,7 @@ export const annunciRouter = createTRPCRouter({
.input(
z.object({
comune: z.string().optional(),
consegna: z.number().optional(),
consegna: z.number().array().optional(),
sort: z.enum(["Recenti", "Prezzo", "Consegna", "Mq"]).optional(),
tipologia: z.string().optional(),
}),

View file

@ -180,7 +180,7 @@ export const get_AnnunciPositionsHandler = async ({
}: {
tipologia?: string;
comune?: string;
consegna?: number;
consegna?: number[];
}): Promise<AnnuncioRicercaWPosition[]> => {
try {
let query = db
@ -222,7 +222,7 @@ export const get_AnnunciPositionsHandler = async ({
query = query.where("comune", "like", comune);
}
if (consegna) {
query = query.where("consegna", "=", consegna);
query = query.where("consegna", "in", consegna);
}
const annunci = await query.execute();
@ -273,7 +273,7 @@ export const getAnnunciRicerca = async ({
}: {
tipologia?: string;
comune?: string;
consegna?: number;
consegna?: number[];
sort?: "Recenti" | "Prezzo" | "Consegna" | "Mq";
}): Promise<AnnuncioRicerca[]> => {
try {
@ -313,7 +313,7 @@ export const getAnnunciRicerca = async ({
query = query.where("comune", "like", comune);
}
if (consegna) {
query = query.where("consegna", "=", consegna);
query = query.where("consegna", "in", consegna);
}
switch (sort) {