From 85457a34d58d403b61da39c8705ccdda1c08a14a Mon Sep 17 00:00:00 2001 From: Ruslan Bakiev <572431+veikab@users.noreply.github.com> Date: Fri, 6 Feb 2026 17:57:23 +0700 Subject: [PATCH] Make ETA and pricing more realistic --- app/components/catalog/OfferResultCard.vue | 53 +++++++++++++--------- i18n/locales/en/catalogOfferCard.json | 4 +- i18n/locales/ru/catalogOfferCard.json | 4 +- 3 files changed, 33 insertions(+), 28 deletions(-) diff --git a/app/components/catalog/OfferResultCard.vue b/app/components/catalog/OfferResultCard.vue index 027e9be..b5b7ae3 100644 --- a/app/components/catalog/OfferResultCard.vue +++ b/app/components/catalog/OfferResultCard.vue @@ -140,19 +140,10 @@ const formatDistance = (km?: number | null) => { return t('catalogOfferCard.labels.distance_km', { km: formatted }) } -const formatDuration = (seconds?: number | null) => { - if (!seconds) return null - const hours = Math.floor(seconds / 3600) - const minutes = Math.floor((seconds % 3600) / 60) - if (hours >= 24) { - const days = Math.floor(hours / 24) - const remainingHours = hours % 24 - return `${days}${t('catalogOfferCard.labels.time_days_short')} ${remainingHours}${t('catalogOfferCard.labels.time_hours_short')}` - } - if (hours > 0) { - return `${hours}${t('catalogOfferCard.labels.time_hours_short')} ${minutes}${t('catalogOfferCard.labels.time_minutes_short')}` - } - return `${minutes}${t('catalogOfferCard.labels.time_minutes_short')}` +const formatDurationDays = (days?: number | null) => { + if (!days) return null + const rounded = Math.max(1, Math.ceil(days)) + return t('catalogOfferCard.labels.duration_days', { days: rounded }) } const getTransportIcon = (type?: string | null) => { @@ -171,13 +162,26 @@ const getTransportIcon = (type?: string | null) => { const getTransportRate = (type?: string | null) => { switch (type) { case 'rail': - return 0.18 - case 'sea': return 0.12 + case 'sea': + return 0.06 case 'road': case 'auto': default: - return 0.35 + return 0.22 + } +} + +const getTransportSpeedPerDay = (type?: string | null) => { + switch (type) { + case 'rail': + return 900 + case 'sea': + return 800 + case 'road': + case 'auto': + default: + return 600 } } @@ -186,18 +190,23 @@ const logisticsCost = computed(() => { return props.stages.reduce((sum, stage) => { const km = stage?.distanceKm if (km == null) return sum - return sum + km * getTransportRate(stage?.transportType) + return sum + km * getTransportRate(stage?.transportType) + 40 }, 0) }) -const totalTimeSeconds = computed(() => { - if (props.totalTimeSeconds != null) return props.totalTimeSeconds +const totalDurationDays = computed(() => { if (!props.stages?.length) return null - const sum = props.stages.reduce((acc, stage) => acc + (stage?.travelTimeSeconds || 0), 0) - return sum > 0 ? sum : null + const stageDays = props.stages.reduce((sum, stage) => { + const km = stage?.distanceKm + if (km == null) return sum + return sum + km / getTransportSpeedPerDay(stage?.transportType) + }, 0) + const transfers = Math.max(0, props.stages.length - 1) * 0.5 + const buffer = 1 + return stageDays + transfers + buffer }) -const durationDisplay = computed(() => formatDuration(totalTimeSeconds.value)) +const durationDisplay = computed(() => formatDurationDays(totalDurationDays.value)) const routeRows = computed(() => (props.stages || []) diff --git a/i18n/locales/en/catalogOfferCard.json b/i18n/locales/en/catalogOfferCard.json index 994987c..20d149e 100644 --- a/i18n/locales/en/catalogOfferCard.json +++ b/i18n/locales/en/catalogOfferCard.json @@ -6,9 +6,7 @@ "unit_kg": "kg", "distance_km": "{km} km", "duration_label": "ETA", - "time_days_short": "d", - "time_hours_short": "h", - "time_minutes_short": "m", + "duration_days": "{days} d", "country_unknown": "Not specified", "supplier_unknown": "Supplier", "origin_label": "From", diff --git a/i18n/locales/ru/catalogOfferCard.json b/i18n/locales/ru/catalogOfferCard.json index d77bb43..ee257c0 100644 --- a/i18n/locales/ru/catalogOfferCard.json +++ b/i18n/locales/ru/catalogOfferCard.json @@ -6,9 +6,7 @@ "unit_kg": "кг", "distance_km": "{km} км", "duration_label": "Срок", - "time_days_short": "д", - "time_hours_short": "ч", - "time_minutes_short": "м", + "duration_days": "{days} дн", "country_unknown": "Не указана", "supplier_unknown": "Поставщик", "origin_label": "Откуда",