route page search filters
This commit is contained in:
@@ -1,8 +1,9 @@
|
|||||||
import React, { Suspense } from 'react'
|
import React from 'react'
|
||||||
import type { Metadata } from 'next'
|
import type { Metadata } from 'next'
|
||||||
import SearchCard from '../../components/SearchCard'
|
import SearchCard from '../../components/SearchCard'
|
||||||
import { SearchCardProps, RouteSearchPageProps } from '@/app/types'
|
import { SearchCardProps, RouteSearchPageProps } from '@/app/types'
|
||||||
import SearchFilters from '../../components/SearchFilters'
|
import SearchFilters from '../../components/SearchFilters'
|
||||||
|
import ClientResults from '../../components/ClientResults'
|
||||||
|
|
||||||
async function fetchSearch(category: string, from: string, to: string) {
|
async function fetchSearch(category: string, from: string, to: string) {
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
@@ -76,17 +77,7 @@ export default async function SearchPage(props: RouteSearchPageProps) {
|
|||||||
: 'Результаты не найдены'}
|
: 'Результаты не найдены'}
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<SearchFilters />
|
<ClientResults initialResults={results} />
|
||||||
|
|
||||||
<Suspense fallback={<div>Загрузка результатов...</div>}>
|
|
||||||
<div className="space-y-4">
|
|
||||||
{results.length > 0 ? (
|
|
||||||
results.map((item: SearchCardProps) => <SearchCard key={item.id} {...item} />)
|
|
||||||
) : (
|
|
||||||
<div className="text-center text-gray-500">По данному маршруту ничего не найдено</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</Suspense>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
90
frontend/app/(urls)/search/components/ClientResults.tsx
Normal file
90
frontend/app/(urls)/search/components/ClientResults.tsx
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import React, { useState, useMemo } from 'react'
|
||||||
|
import SearchCard from './SearchCard'
|
||||||
|
import { SearchCardProps } from '@/app/types'
|
||||||
|
import SearchFilters from './SearchFilters'
|
||||||
|
|
||||||
|
interface ClientResultsProps {
|
||||||
|
initialResults: SearchCardProps[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function ClientResults({ initialResults }: ClientResultsProps) {
|
||||||
|
const [selectedTransport, setSelectedTransport] = useState<number[]>([])
|
||||||
|
const [selectedPackageTypes, setSelectedPackageTypes] = useState<number[]>([])
|
||||||
|
|
||||||
|
const filteredResults = useMemo(() => {
|
||||||
|
let results = [...initialResults]
|
||||||
|
|
||||||
|
if (selectedTransport.length > 0) {
|
||||||
|
results = results.filter(item =>
|
||||||
|
selectedTransport.some(id => {
|
||||||
|
switch (id) {
|
||||||
|
case 1:
|
||||||
|
return item.type_transport === 'road'
|
||||||
|
case 2:
|
||||||
|
return item.type_transport === 'avia'
|
||||||
|
case 3:
|
||||||
|
return true // 'both' отдает все
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectedPackageTypes.length > 0) {
|
||||||
|
results = results.filter(item => {
|
||||||
|
return selectedPackageTypes.some(id => {
|
||||||
|
const match = (() => {
|
||||||
|
switch (id) {
|
||||||
|
case 1:
|
||||||
|
return item.formatted_cargo_type === 'Письмо или Документы'
|
||||||
|
case 2:
|
||||||
|
return item.formatted_cargo_type === 'Посылка (до 30кг)'
|
||||||
|
case 3:
|
||||||
|
return item.formatted_cargo_type === 'Попутчик'
|
||||||
|
case 4:
|
||||||
|
return item.formatted_cargo_type === 'Бандероль (до 5кг)'
|
||||||
|
case 5:
|
||||||
|
return item.formatted_cargo_type === 'Груз (свыше 30 кг)'
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
|
||||||
|
return match
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return results
|
||||||
|
}, [initialResults, selectedTransport, selectedPackageTypes])
|
||||||
|
|
||||||
|
const handleFiltersChange = ({
|
||||||
|
transport,
|
||||||
|
packageTypes,
|
||||||
|
}: {
|
||||||
|
transport: number[]
|
||||||
|
packageTypes: number[]
|
||||||
|
}) => {
|
||||||
|
setSelectedTransport(transport)
|
||||||
|
setSelectedPackageTypes(packageTypes)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<SearchFilters onFiltersChange={handleFiltersChange} />
|
||||||
|
|
||||||
|
<div className="space-y-4">
|
||||||
|
{filteredResults.length > 0 ? (
|
||||||
|
filteredResults.map((item: SearchCardProps) => <SearchCard key={item.id} {...item} />)
|
||||||
|
) : (
|
||||||
|
<div className="rounded-lg bg-orange-50 p-4 text-center text-orange-800">
|
||||||
|
По выбранным фильтрам ничего не найдено. Попробуйте изменить параметры поиска.
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user