feat: allow deselecting the current neighborhood on the location search screen

Shows a clear/deselect row (only when a location is actually set) that
wipes the location cookie and returns to the unfiltered all-stores view.
Also highlights the currently selected neighborhood in the suggested/
results list with a checkmark, since it's now shown there too.
This commit is contained in:
Afra ‌ 2026-08-19 10:12:09 +03:30
parent e5b00c4d55
commit bc6d66423c
2 changed files with 34 additions and 7 deletions

View file

@ -1,4 +1,5 @@
import { winofyFetch, type PaginatedResponse } from "@/lib/api/winofy"; import { winofyFetch, type PaginatedResponse } from "@/lib/api/winofy";
import { getLocationServer } from "@/lib/location/server";
import type { Neighborhood } from "@/types/api"; import type { Neighborhood } from "@/types/api";
import { NeighborhoodSearch } from "@/components/location/neighborhood-search"; import { NeighborhoodSearch } from "@/components/location/neighborhood-search";
@ -11,6 +12,7 @@ async function getNeighborhoods() {
} }
export default async function NeighborhoodSearchPage() { export default async function NeighborhoodSearchPage() {
const neighborhoods = await getNeighborhoods(); const [neighborhoods, location] = await Promise.all([getNeighborhoods(), getLocationServer()]);
return <NeighborhoodSearch neighborhoods={neighborhoods} />; const selectedNeighborhoodUuid = location?.mode === "manual" ? location.neighborhoodUuid : null;
return <NeighborhoodSearch neighborhoods={neighborhoods} selectedNeighborhoodUuid={selectedNeighborhoodUuid} />;
} }

View file

@ -2,13 +2,19 @@
import { useMemo, useState } from "react"; import { useMemo, useState } from "react";
import { useRouter, useSearchParams } from "next/navigation"; import { useRouter, useSearchParams } from "next/navigation";
import { ArrowRight, MapPin, Search, SearchX } from "lucide-react"; import { ArrowRight, Check, MapPin, Search, SearchX, X } from "lucide-react";
import { setLocation } from "@/lib/location/client"; import { setLocation, clearLocation } from "@/lib/location/client";
import type { Neighborhood } from "@/types/api"; import type { Neighborhood } from "@/types/api";
// L06 (+ neighborhood-search-results) unified — winofyfrontenddoc (1).md §4.3. // L06 (+ neighborhood-search-results) unified — winofyfrontenddoc (1).md §4.3.
// idle / results / empty share ~90% of layout, per the doc's own recommendation. // idle / results / empty share ~90% of layout, per the doc's own recommendation.
export function NeighborhoodSearch({ neighborhoods }: { neighborhoods: Neighborhood[] }) { export function NeighborhoodSearch({
neighborhoods,
selectedNeighborhoodUuid,
}: {
neighborhoods: Neighborhood[];
selectedNeighborhoodUuid: string | null;
}) {
const router = useRouter(); const router = useRouter();
const searchParams = useSearchParams(); const searchParams = useSearchParams();
const next = searchParams.get("next") ?? "/"; const next = searchParams.get("next") ?? "/";
@ -37,17 +43,25 @@ export function NeighborhoodSearch({ neighborhoods }: { neighborhoods: Neighborh
router.refresh(); router.refresh();
} }
function deselectNeighborhood() {
clearLocation();
router.push(next);
router.refresh();
}
function NeighborhoodRow({ n }: { n: Neighborhood }) { function NeighborhoodRow({ n }: { n: Neighborhood }) {
const isSelected = n.uuid === selectedNeighborhoodUuid;
return ( return (
<button <button
type="button" type="button"
onClick={() => selectNeighborhood(n)} onClick={() => selectNeighborhood(n)}
className="flex w-full items-center gap-3 border-b border-gray-300 py-4 text-right" className="flex w-full items-center gap-3 border-b border-gray-300 py-4 text-right"
> >
<MapPin className="h-5 w-5 shrink-0 text-gray-500" /> <MapPin className={isSelected ? "h-5 w-5 shrink-0 text-primary-action" : "h-5 w-5 shrink-0 text-gray-500"} />
<span className="text-body-large text-foreground"> <span className={isSelected ? "flex-1 text-body-large font-semibold text-primary-action" : "flex-1 text-body-large text-foreground"}>
{n.city.name}، {n.name} {n.city.name}، {n.name}
</span> </span>
{isSelected && <Check className="h-5 w-5 shrink-0 text-primary-action" />}
</button> </button>
); );
} }
@ -81,6 +95,17 @@ export function NeighborhoodSearch({ neighborhoods }: { neighborhoods: Neighborh
/> />
</div> </div>
{selectedNeighborhoodUuid && (
<button
type="button"
onClick={deselectNeighborhood}
className="mt-4 flex w-full items-center gap-3 rounded-xl border border-gray-300 bg-white py-3 px-3 text-right"
>
<X className="h-5 w-5 shrink-0 text-gray-500" />
<span className="flex-1 text-body-large text-foreground">حذف محله انتخاب‌شده و نمایش همه فروشگاه‌ها</span>
</button>
)}
{state === "empty" && ( {state === "empty" && (
<div className="flex flex-col items-center gap-2 py-8 text-center"> <div className="flex flex-col items-center gap-2 py-8 text-center">
<SearchX className="h-12 w-12 text-gray-400" /> <SearchX className="h-12 w-12 text-gray-400" />