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

View File

@@ -19,9 +19,40 @@
<p>{{ $t('catalog.empty.noOffers') }}</p> <p>{{ $t('catalog.empty.noOffers') }}</p>
</div> </div>
<div v-else class="flex flex-col gap-2"> <div v-else class="flex flex-col gap-3">
<div <div
v-for="offer in offersWithPrice" 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" :key="offer.uuid"
class="cursor-pointer" class="cursor-pointer"
@click="emit('select-offer', offer)" @click="emit('select-offer', offer)"
@@ -39,6 +70,7 @@
/> />
</div> </div>
</div> </div>
</div>
</div> </div>
</div> </div>
</template> </template>
@@ -68,6 +100,11 @@ interface Offer {
} | null> | null } | null> | null
} }
interface OfferGroup {
id: string
offers: Offer[]
}
const emit = defineEmits<{ const emit = defineEmits<{
'select-offer': [offer: Offer] 'select-offer': [offer: Offer]
}>() }>()
@@ -75,12 +112,21 @@ const emit = defineEmits<{
const props = defineProps<{ const props = defineProps<{
loading: boolean loading: boolean
offers: Offer[] offers: Offer[]
calculations?: OfferGroup[]
}>() }>()
const offersWithPrice = computed(() => const offersWithPrice = computed(() =>
(props.offers || []).filter(o => o?.pricePerUnit != null) (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 getOfferStages = (offer: Offer) => {
const route = offer.routes?.[0] const route = offer.routes?.[0]
if (!route?.stages) return [] if (!route?.stages) return []

View File

@@ -68,6 +68,7 @@
v-else-if="showQuoteResults" v-else-if="showQuoteResults"
:loading="offersLoading" :loading="offersLoading"
:offers="offers" :offers="offers"
:calculations="quoteCalculations"
@select-offer="onSelectOffer" @select-offer="onSelectOffer"
/> />
</template> </template>
@@ -416,6 +417,14 @@ const relatedPoints = computed(() => {
// Offers data for quote results // Offers data for quote results
const offers = ref<QuoteOffer[]>([]) 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 offersLoading = ref(false)
const showQuoteResults = ref(false) const showQuoteResults = ref(false)