Add price and supplier info to offer page
Some checks failed
Build Docker Image / build (push) Failing after 1m23s
Some checks failed
Build Docker Image / build (push) Failing after 1m23s
This commit is contained in:
@@ -19,6 +19,38 @@
|
|||||||
<template #header>
|
<template #header>
|
||||||
<Text v-if="!isLoading && (!supplier || !product || !hub)" tone="muted">Данные не найдены</Text>
|
<Text v-if="!isLoading && (!supplier || !product || !hub)" tone="muted">Данные не найдены</Text>
|
||||||
<Stack v-else-if="!isLoading" gap="4">
|
<Stack v-else-if="!isLoading" gap="4">
|
||||||
|
<!-- Offer Info Card -->
|
||||||
|
<Card padding="md">
|
||||||
|
<Stack gap="3">
|
||||||
|
<!-- Price -->
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<Text weight="semibold" size="lg">{{ product?.name }}</Text>
|
||||||
|
<Text v-if="offerData?.pricePerUnit" weight="bold" class="text-primary text-xl">
|
||||||
|
{{ formatPrice(offerData.pricePerUnit, offerData.currency, offerData.unit) }}
|
||||||
|
</Text>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Supplier Info -->
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<div v-if="supplier?.logoUrl" class="w-10 h-10 rounded-full overflow-hidden bg-base-200">
|
||||||
|
<img :src="supplier.logoUrl" :alt="supplier.name" class="w-full h-full object-cover" />
|
||||||
|
</div>
|
||||||
|
<div v-else class="w-10 h-10 rounded-full bg-base-200 flex items-center justify-center">
|
||||||
|
<Icon name="lucide:building-2" size="20" class="text-base-content/40" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<Text weight="medium">{{ supplier?.name }}</Text>
|
||||||
|
<Text v-if="supplier?.country" tone="muted" size="sm">{{ supplier.country }}</Text>
|
||||||
|
</div>
|
||||||
|
<div v-if="supplier?.isVerified" class="badge badge-success badge-sm ml-auto">Верифицирован</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- KYC Info -->
|
||||||
|
<SupplierInfoBlock v-if="supplier?.kycProfileUuid" :kyc-profile-uuid="supplier.kycProfileUuid" />
|
||||||
|
</Stack>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<!-- Price Chart -->
|
||||||
<Card padding="md">
|
<Card padding="md">
|
||||||
<div class="h-48">
|
<div class="h-48">
|
||||||
<ClientOnly>
|
<ClientOnly>
|
||||||
@@ -92,6 +124,7 @@ const hub = ref<any>(null)
|
|||||||
const sourceLocation = ref<{ uuid: string; name: string; latitude?: number; longitude?: number } | null>(null)
|
const sourceLocation = ref<{ uuid: string; name: string; latitude?: number; longitude?: number } | null>(null)
|
||||||
const routeData = ref<any>(null)
|
const routeData = ref<any>(null)
|
||||||
const hoveredPointUuid = ref<string>()
|
const hoveredPointUuid = ref<string>()
|
||||||
|
const offerData = ref<any>(null) // Full offer data with price
|
||||||
|
|
||||||
const supplierId = computed(() => routeRef.params.supplierId as string)
|
const supplierId = computed(() => routeRef.params.supplierId as string)
|
||||||
const productId = computed(() => routeRef.params.productId as string)
|
const productId = computed(() => routeRef.params.productId as string)
|
||||||
@@ -175,6 +208,38 @@ const routeStages = computed(() => {
|
|||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Format price
|
||||||
|
const formatPrice = (price?: number | null, currency?: string | null, unit?: string | null) => {
|
||||||
|
if (!price) return ''
|
||||||
|
const currSymbol = getCurrencySymbol(currency)
|
||||||
|
const unitName = getUnitName(unit)
|
||||||
|
return `${currSymbol}${price.toLocaleString()}/${unitName}`
|
||||||
|
}
|
||||||
|
|
||||||
|
const getCurrencySymbol = (currency?: string | null) => {
|
||||||
|
switch (currency?.toUpperCase()) {
|
||||||
|
case 'USD': return '$'
|
||||||
|
case 'EUR': return '€'
|
||||||
|
case 'RUB': return '₽'
|
||||||
|
case 'CNY': return '¥'
|
||||||
|
default: return '$'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getUnitName = (unit?: string | null) => {
|
||||||
|
switch (unit?.toLowerCase()) {
|
||||||
|
case 'т':
|
||||||
|
case 'ton':
|
||||||
|
case 'tonne':
|
||||||
|
return 'т'
|
||||||
|
case 'кг':
|
||||||
|
case 'kg':
|
||||||
|
return 'кг'
|
||||||
|
default:
|
||||||
|
return 'т'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Format distance
|
// Format distance
|
||||||
const formatDistance = (km?: number | null) => {
|
const formatDistance = (km?: number | null) => {
|
||||||
if (!km) return t('common.values.not_available')
|
if (!km) return t('common.values.not_available')
|
||||||
@@ -335,6 +400,9 @@ try {
|
|||||||
// Use first offer for product info and source location
|
// Use first offer for product info and source location
|
||||||
if (offers.length > 0) {
|
if (offers.length > 0) {
|
||||||
const firstOffer = offers[0]
|
const firstOffer = offers[0]
|
||||||
|
// Store full offer data (including price)
|
||||||
|
offerData.value = firstOffer
|
||||||
|
|
||||||
if (firstOffer?.productUuid && firstOffer?.productName) {
|
if (firstOffer?.productUuid && firstOffer?.productName) {
|
||||||
product.value = { uuid: firstOffer.productUuid, name: firstOffer.productName }
|
product.value = { uuid: firstOffer.productUuid, name: firstOffer.productName }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user