feat(marketplace): add functional sort dropdown to ProductSearch

- Add sortBy state with options: price, distance, expiry
- Replace static text with interactive select dropdown
- Implement sorting logic for each option in groupedProducts memo
This commit is contained in:
Tiago Yamamoto 2025-12-23 16:19:47 -03:00
parent 1600591f86
commit 299001d8bc

View file

@ -22,6 +22,7 @@ const ProductSearch = () => {
const [maxPrice, setMaxPrice] = useState<number | ''>('') const [maxPrice, setMaxPrice] = useState<number | ''>('')
const [minExpiryDays, setMinExpiryDays] = useState<number>(0) const [minExpiryDays, setMinExpiryDays] = useState<number>(0)
const [showAdvancedFilters, setShowAdvancedFilters] = useState(false) const [showAdvancedFilters, setShowAdvancedFilters] = useState(false)
const [sortBy, setSortBy] = useState<'price' | 'distance' | 'expiry'>('price')
// Modal state // Modal state
const [selectedGroup, setSelectedGroup] = useState<GroupedProduct | null>(null) const [selectedGroup, setSelectedGroup] = useState<GroupedProduct | null>(null)
@ -89,9 +90,28 @@ const ProductSearch = () => {
} }
} }
// Sort by min price // Sort based on selected option
return Object.values(groups).sort((a, b) => a.minPriceCents - b.minPriceCents) const groupsArray = Object.values(groups)
}, [products, user?.id])
switch (sortBy) {
case 'price':
return groupsArray.sort((a, b) => a.minPriceCents - b.minPriceCents)
case 'distance':
return groupsArray.sort((a, b) => {
const minDistA = Math.min(...a.offers.map(o => o.distance_km))
const minDistB = Math.min(...b.offers.map(o => o.distance_km))
return minDistA - minDistB
})
case 'expiry':
return groupsArray.sort((a, b) => {
const minExpiryA = Math.min(...a.offers.map(o => new Date(o.expires_at).getTime()))
const minExpiryB = Math.min(...b.offers.map(o => new Date(o.expires_at).getTime()))
return minExpiryA - minExpiryB
})
default:
return groupsArray
}
}, [products, user?.id, sortBy])
const handleLocationSelect = (newLat: number, newLng: number) => { const handleLocationSelect = (newLat: number, newLng: number) => {
setLat(newLat) setLat(newLat)
@ -237,8 +257,17 @@ const ProductSearch = () => {
<h2 className="text-xl font-semibold text-gray-700"> <h2 className="text-xl font-semibold text-gray-700">
{loading ? 'Buscando...' : `${groupedProducts.length} medicamentos (${total} ofertas)`} {loading ? 'Buscando...' : `${groupedProducts.length} medicamentos (${total} ofertas)`}
</h2> </h2>
<div className="text-sm text-gray-500"> <div className="flex items-center gap-2 text-sm">
Ordenado por: <span className="font-medium text-gray-800">Menor preço</span> <span className="text-gray-500">Ordenar por:</span>
<select
value={sortBy}
onChange={(e) => setSortBy(e.target.value as 'price' | 'distance' | 'expiry')}
className="rounded-md border-gray-300 shadow-sm focus:border-primary focus:ring-primary text-sm p-1.5 border bg-white cursor-pointer"
>
<option value="price">Menor preço</option>
<option value="distance">Mais próximo</option>
<option value="expiry">Vencimento (mais próximo)</option>
</select>
</div> </div>
</div> </div>