Group quote results by calculation
Some checks failed
Build Docker Image / build (push) Failing after 4m9s
Some checks failed
Build Docker Image / build (push) Failing after 4m9s
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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 []
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user