From b45f9885abb5cb8a17396ef9be4ba7adebfd5936 Mon Sep 17 00:00:00 2001 From: Sergey Bolshakov Date: Sun, 14 Dec 2025 23:24:18 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A4=D0=B8=D0=BB=D1=8C=D1=82=D1=80=D1=8B=20?= =?UTF-8?q?=D0=B2=20=D0=BA=D0=B0=D1=82=D0=B0=D0=BB=D0=BE=D0=B3=D0=B5,=20?= =?UTF-8?q?=D0=B8=D0=BD=D1=82=D0=B5=D0=B3=D1=80=D0=B0=D1=86=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/catalog/page.tsx | 54 ++++++++++++++++++++++++------- src/app/components/Hero.tsx | 29 ++++++++++++++--- src/components/ui/date-picker.tsx | 9 ++++-- 3 files changed, 74 insertions(+), 18 deletions(-) diff --git a/src/app/catalog/page.tsx b/src/app/catalog/page.tsx index 1378b81..f44eae7 100644 --- a/src/app/catalog/page.tsx +++ b/src/app/catalog/page.tsx @@ -203,6 +203,12 @@ export default function CatalogPage() { params.set("arrivalTime", filters.arrivalTime); } + // Сохраняем сортировку, если она установлена + const sortByPrice = searchParams.get("sortByPrice"); + if (sortByPrice) { + params.set("sortByPrice", sortByPrice); + } + // Обновляем URL без прокрутки страницы const newUrl = params.toString() ? `${pathname}?${params.toString()}` @@ -219,11 +225,29 @@ export default function CatalogPage() { useEffect(() => { (async () => { - const params: Record = { + const allParams: Record = { search: searchParams.get("search") ?? "", + minLength: searchParams.get("lengthMin") ?? "", + maxLength: searchParams.get("lengthMax") ?? "", + minPrice: searchParams.get("priceMin") ?? "", + maxPrice: searchParams.get("priceMax") ?? "", + minYear: searchParams.get("yearMin") ?? "", + maxYear: searchParams.get("yearMax") ?? "", + guests: searchParams.get("adults") && searchParams.get("children") ? `${Number(searchParams.get("adults")) + Number(searchParams.get("children"))}` : "", + paymentType: searchParams.get("paymentType") ?? "", + quickBooking: searchParams.get("quickBooking") ?? "", + hasToilet: searchParams.get("hasToilet") ?? "", + date: searchParams.get("date") ?? "", + departureTime: searchParams.get("departureTime") ?? "", + arrivalTime: searchParams.get("arrivalTime") ?? "", + sortByPrice: searchParams.get("sortByPrice") ?? "", }; - const response = await client.get("/catalog/filtered/", { + const params = Object.fromEntries( + Object.entries(allParams).filter(([_, value]) => value !== "") + ); + + const response = await client.get("/catalog/filter/", { params, }); @@ -346,7 +370,21 @@ export default function CatalogPage() {
Сортировка:
- { + const params = new URLSearchParams(searchParams.toString()); + if (value === "default") { + params.delete("sortByPrice"); + } else { + params.set("sortByPrice", value); + } + const newUrl = params.toString() + ? `${pathname}?${params.toString()}` + : pathname; + router.replace(newUrl, { scroll: false }); + }} + > По умолчанию - + Цена: по возрастанию - + Цена: по убыванию - - Длина: по возрастанию - - - Длина: по убыванию - diff --git a/src/app/components/Hero.tsx b/src/app/components/Hero.tsx index beab6fd..679b7c0 100644 --- a/src/app/components/Hero.tsx +++ b/src/app/components/Hero.tsx @@ -12,6 +12,9 @@ import Link from "next/link"; export default function Hero() { const [adults, setAdults] = useState(0); const [children, setChildren] = useState(0); + const [selectedDate, setSelectedDate] = useState(null); + const [departureTime, setDepartureTime] = useState("12:00"); + const [arrivalTime, setArrivalTime] = useState("13:00"); return (
- + setSelectedDate(date || null)} + onDepartureTimeChange={setDepartureTime} + onArrivalTimeChange={setArrivalTime} + /> {/* Количество гостей */} @@ -79,9 +89,20 @@ export default function Hero() { {/* Кнопка поиска */} - + { + const params = new URLSearchParams(); + if (adults > 0) params.append('adults', adults.toString()); + if (children > 0) params.append('children', children.toString()); + if (selectedDate) params.append('date', selectedDate.toString()); + if (departureTime && departureTime !== "12:00") params.append('departureTime', departureTime); + if (arrivalTime && arrivalTime !== "13:00") params.append('arrivalTime', arrivalTime); + const queryString = params.toString(); + return queryString ? `/catalog?${queryString}` : '/catalog'; + })()}> + + diff --git a/src/components/ui/date-picker.tsx b/src/components/ui/date-picker.tsx index 92af2fa..0632a52 100644 --- a/src/components/ui/date-picker.tsx +++ b/src/components/ui/date-picker.tsx @@ -42,6 +42,9 @@ export function DatePicker({ const [internalArrivalTime, setInternalArrivalTime] = React.useState("13:00"); const [open, setOpen] = React.useState(false); + // Определяем, является ли компонент контролируемым + const isControlled = value !== undefined || externalDepartureTime !== undefined || externalArrivalTime !== undefined; + // Используем внешние значения, если они предоставлены, иначе внутренние const date = value !== undefined ? (value || undefined) : internalDate; const departureTime = externalDepartureTime !== undefined ? externalDepartureTime : internalDepartureTime; @@ -50,7 +53,7 @@ export function DatePicker({ const handleDateChange = (newDate: Date | undefined) => { if (onDateChange) { onDateChange(newDate); - } else { + } else if (!isControlled) { setInternalDate(newDate); } }; @@ -58,7 +61,7 @@ export function DatePicker({ const handleDepartureTimeChange = (time: string) => { if (onDepartureTimeChange) { onDepartureTimeChange(time); - } else { + } else if (!isControlled) { setInternalDepartureTime(time); } }; @@ -66,7 +69,7 @@ export function DatePicker({ const handleArrivalTimeChange = (time: string) => { if (onArrivalTimeChange) { onArrivalTimeChange(time); - } else { + } else if (!isControlled) { setInternalArrivalTime(time); } };