feat(items): show Cheapest and Closest tags independent of sort order
Previously tags were tied to the active sort (only Closest showed when sorting by distance, only Cheapest when sorting by price). Now both are computed independently — Cheapest = vendor with min price, Closest = vendor with min distanceKm — and shown simultaneously when a site is selected, regardless of which sort is active. Verified with Playwright: both tags present under distance sort, price sort, and absent when no site is selected.
This commit is contained in:
parent
f1640c238a
commit
55065eafe3
1 changed files with 11 additions and 4 deletions
|
|
@ -193,6 +193,12 @@ export function ItemsTable({
|
||||||
const lowestPrice = item.vendors.length > 0 ? Math.min(...item.vendors.map((v) => v.price)) : null;
|
const lowestPrice = item.vendors.length > 0 ? Math.min(...item.vendors.map((v) => v.price)) : null;
|
||||||
const sortedVendors = getSortedVendors(item.vendors);
|
const sortedVendors = getSortedVendors(item.vendors);
|
||||||
|
|
||||||
|
// Cheapest and closest are independent of current sort order
|
||||||
|
const minPrice = sortedVendors.length > 1 ? Math.min(...sortedVendors.map((v) => v.price)) : null;
|
||||||
|
const closestVendorId = hasSite
|
||||||
|
? (sortedVendors.filter((v) => v.distanceKm !== null).sort((a, b) => a.distanceKm! - b.distanceKm!)[0]?.vendorId ?? null)
|
||||||
|
: null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment key={item.id}>
|
<Fragment key={item.id}>
|
||||||
{/* Item row */}
|
{/* Item row */}
|
||||||
|
|
@ -239,9 +245,10 @@ export function ItemsTable({
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody className="divide-y divide-neutral-100">
|
<tbody className="divide-y divide-neutral-100">
|
||||||
{sortedVendors.map((vendor, idx) => {
|
{sortedVendors.map((vendor) => {
|
||||||
const key = `${item.id}-${vendor.vendorId}`;
|
const key = `${item.id}-${vendor.vendorId}`;
|
||||||
const isFirst = idx === 0;
|
const isCheapest = minPrice !== null && vendor.price === minPrice;
|
||||||
|
const isClosest = closestVendorId !== null && vendor.vendorId === closestVendorId;
|
||||||
return (
|
return (
|
||||||
<tr key={vendor.vendorId} className="hover:bg-white">
|
<tr key={vendor.vendorId} className="hover:bg-white">
|
||||||
<td className="px-12 py-2.5">
|
<td className="px-12 py-2.5">
|
||||||
|
|
@ -256,10 +263,10 @@ export function ItemsTable({
|
||||||
{vendor.isVerified && (
|
{vendor.isVerified && (
|
||||||
<span className="rounded-full bg-success-100 px-1.5 py-0.5 text-xs font-medium text-success-700">Verified</span>
|
<span className="rounded-full bg-success-100 px-1.5 py-0.5 text-xs font-medium text-success-700">Verified</span>
|
||||||
)}
|
)}
|
||||||
{isFirst && sortBy === "distance" && vendor.distanceKm !== null && (
|
{isClosest && (
|
||||||
<span className="text-xs text-primary-600 font-medium">★ Closest</span>
|
<span className="text-xs text-primary-600 font-medium">★ Closest</span>
|
||||||
)}
|
)}
|
||||||
{isFirst && sortBy === "price" && (
|
{isCheapest && (
|
||||||
<span className="text-xs text-success-600 font-medium">Cheapest</span>
|
<span className="text-xs text-success-600 font-medium">Cheapest</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue