Group quote results by calculation
Some checks failed
Build Docker Image / build (push) Failing after 4m9s

This commit is contained in:
Ruslan Bakiev
2026-02-06 18:44:00 +07:00
parent 87133ed37a
commit 1287ae9db7
3 changed files with 83 additions and 21 deletions

View File

@@ -1,5 +1,5 @@
<template>
<Card padding="md" interactive @click="$emit('select')">
<Card padding="md" interactive :class="groupClass" @click="$emit('select')">
<!-- Header: Supplier + Price -->
<div class="flex items-start justify-between gap-4">
<div class="flex flex-col gap-1">
@@ -68,8 +68,10 @@ const props = withDefaults(defineProps<{
stages?: RouteStage[]
totalTimeSeconds?: number | null
kycProfileUuid?: string | null
grouped?: boolean
}>(), {
stages: () => []
stages: () => [],
grouped: false
})
defineEmits<{
@@ -208,6 +210,11 @@ const totalDurationDays = computed(() => {
const durationDisplay = computed(() => formatDurationDays(totalDurationDays.value))
const groupClass = computed(() => {
if (!props.grouped) return ''
return 'rounded-none shadow-none hover:shadow-none'
})
const routeRows = computed(() =>
(props.stages || [])
.filter(stage => stage?.distanceKm != null)

View File

@@ -19,27 +19,59 @@
<p>{{ $t('catalog.empty.noOffers') }}</p>
</div>
<div v-else class="flex flex-col gap-2">
<div
v-for="offer in offersWithPrice"
:key="offer.uuid"
class="cursor-pointer"
@click="emit('select-offer', offer)"
>
<OfferResultCard
:supplier-name="offer.supplierName"
:location-name="offer.locationName || offer.locationCountry"
:product-name="offer.productName"
:price-per-unit="offer.pricePerUnit ? Number(offer.pricePerUnit) : null"
:quantity="offer.quantity"
:currency="offer.currency"
:unit="offer.unit"
:stages="getOfferStages(offer)"
:total-time-seconds="offer.routes?.[0]?.totalTimeSeconds ?? null"
/>
</div>
<div v-else class="flex flex-col gap-3">
<div
v-for="group in offerGroups"
:key="group.id"
class="flex flex-col gap-0"
>
<div
v-if="group.offers.length > 1"
class="rounded-2xl overflow-hidden border border-base-200/60 divide-y divide-base-200/60"
>
<div
v-for="offer in group.offers"
:key="offer.uuid"
class="cursor-pointer"
@click="emit('select-offer', offer)"
>
<OfferResultCard
grouped
:supplier-name="offer.supplierName"
:location-name="offer.locationName || offer.locationCountry"
:product-name="offer.productName"
:price-per-unit="offer.pricePerUnit ? Number(offer.pricePerUnit) : null"
:quantity="offer.quantity"
:currency="offer.currency"
:unit="offer.unit"
:stages="getOfferStages(offer)"
:total-time-seconds="offer.routes?.[0]?.totalTimeSeconds ?? null"
/>
</div>
</div>
<div
v-else
v-for="offer in group.offers"
:key="offer.uuid"
class="cursor-pointer"
@click="emit('select-offer', offer)"
>
<OfferResultCard
:supplier-name="offer.supplierName"
:location-name="offer.locationName || offer.locationCountry"
:product-name="offer.productName"
:price-per-unit="offer.pricePerUnit ? Number(offer.pricePerUnit) : null"
:quantity="offer.quantity"
:currency="offer.currency"
:unit="offer.unit"
:stages="getOfferStages(offer)"
:total-time-seconds="offer.routes?.[0]?.totalTimeSeconds ?? null"
/>
</div>
</div>
</div>
</div>
</div>
</template>
@@ -68,6 +100,11 @@ interface Offer {
} | null> | null
}
interface OfferGroup {
id: string
offers: Offer[]
}
const emit = defineEmits<{
'select-offer': [offer: Offer]
}>()
@@ -75,12 +112,21 @@ const emit = defineEmits<{
const props = defineProps<{
loading: boolean
offers: Offer[]
calculations?: OfferGroup[]
}>()
const offersWithPrice = computed(() =>
(props.offers || []).filter(o => o?.pricePerUnit != null)
)
const offerGroups = computed<OfferGroup[]>(() => {
if (props.calculations?.length) return props.calculations
return offersWithPrice.value.map(offer => ({
id: offer.uuid,
offers: [offer]
}))
})
const getOfferStages = (offer: Offer) => {
const route = offer.routes?.[0]
if (!route?.stages) return []

View File

@@ -68,6 +68,7 @@
v-else-if="showQuoteResults"
:loading="offersLoading"
:offers="offers"
:calculations="quoteCalculations"
@select-offer="onSelectOffer"
/>
</template>
@@ -416,6 +417,14 @@ const relatedPoints = computed(() => {
// Offers data for quote results
const offers = ref<QuoteOffer[]>([])
const quoteCalculations = computed(() => {
if (!offers.value.length) return []
return offers.value.map(offer => ({
id: offer.uuid,
offers: [offer]
}))
})
const offersLoading = ref(false)
const showQuoteResults = ref(false)