Add KycProfileCard component with full company info
Some checks failed
Build Docker Image / build (push) Has been cancelled
Some checks failed
Build Docker Image / build (push) Has been cancelled
- New KycProfileCard shows full KYC profile data (INN, OGRN, director, capital, activities) - Added to offer detail page /catalog/suppliers/[supplierId]/[productId]/[hubId] - Uses kycProfileFull endpoint for authorized detailed company info
This commit is contained in:
@@ -27,6 +27,7 @@
|
||||
:unit="getOfferData(option.sourceUuid)?.unit"
|
||||
:stages="getRouteStages(option)"
|
||||
:kyc-profile-uuid="getKycProfileUuid(option.sourceUuid)"
|
||||
@select="navigateToOffer(option.sourceUuid)"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -68,6 +69,7 @@ import type { RouteStageItem } from '~/components/RouteStagesList.vue'
|
||||
import { GetOfferDocument, GetSupplierProfileByTeamDocument } from '~/composables/graphql/public/exchange-generated'
|
||||
|
||||
const route = useRoute()
|
||||
const localePath = useLocalePath()
|
||||
const searchStore = useSearchStore()
|
||||
const { execute } = useGraphQL()
|
||||
|
||||
@@ -175,6 +177,16 @@ const getKycProfileUuid = (offerUuid?: string | null) => {
|
||||
return supplier?.kycProfileUuid || null
|
||||
}
|
||||
|
||||
// Navigate to offer detail page
|
||||
const navigateToOffer = (offerUuid?: string | null) => {
|
||||
if (!offerUuid) return
|
||||
const offer = offersData.value.get(offerUuid)
|
||||
if (!offer?.teamUuid || !productUuid.value || !destinationUuid.value) return
|
||||
|
||||
// Navigate to /catalog/suppliers/[supplierId]/[productId]/[hubId]
|
||||
navigateTo(localePath(`/catalog/suppliers/${offer.teamUuid}/${productUuid.value}/${destinationUuid.value}`))
|
||||
}
|
||||
|
||||
// Load offer details for prices
|
||||
const loadOfferDetails = async (options: ProductRouteOption[]) => {
|
||||
if (options.length === 0) {
|
||||
|
||||
155
app/components/KycProfileCard.vue
Normal file
155
app/components/KycProfileCard.vue
Normal file
@@ -0,0 +1,155 @@
|
||||
<template>
|
||||
<Card v-if="kycProfileUuid" padding="md">
|
||||
<!-- Loading -->
|
||||
<div v-if="pending" class="flex items-center gap-2">
|
||||
<Spinner size="sm" />
|
||||
<Text tone="muted" size="sm">Загрузка данных о компании...</Text>
|
||||
</div>
|
||||
|
||||
<!-- Error or no data -->
|
||||
<div v-else-if="!profileData" class="text-sm text-base-content/60">
|
||||
Данные о компании недоступны
|
||||
</div>
|
||||
|
||||
<!-- Profile data -->
|
||||
<Stack v-else gap="4">
|
||||
<!-- Header -->
|
||||
<div class="flex items-start justify-between">
|
||||
<div>
|
||||
<Text weight="semibold" size="lg">{{ profileData.name }}</Text>
|
||||
<div class="flex items-center gap-2 mt-1">
|
||||
<span v-if="profileData.companyType" class="badge badge-outline badge-sm">
|
||||
{{ profileData.companyType }}
|
||||
</span>
|
||||
<span v-if="profileData.registrationYear" class="text-xs text-base-content/60">
|
||||
с {{ profileData.registrationYear }} г.
|
||||
</span>
|
||||
<span v-if="profileData.isActive" class="badge badge-success badge-xs">Активна</span>
|
||||
<span v-else class="badge badge-error badge-xs">Неактивна</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Details grid -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<!-- INN -->
|
||||
<div v-if="profileData.inn">
|
||||
<Text tone="muted" size="sm">ИНН</Text>
|
||||
<Text weight="medium">{{ profileData.inn }}</Text>
|
||||
</div>
|
||||
|
||||
<!-- OGRN -->
|
||||
<div v-if="profileData.ogrn">
|
||||
<Text tone="muted" size="sm">ОГРН</Text>
|
||||
<Text weight="medium">{{ profileData.ogrn }}</Text>
|
||||
</div>
|
||||
|
||||
<!-- Director -->
|
||||
<div v-if="profileData.director">
|
||||
<Text tone="muted" size="sm">Руководитель</Text>
|
||||
<Text weight="medium">{{ profileData.director }}</Text>
|
||||
</div>
|
||||
|
||||
<!-- Capital -->
|
||||
<div v-if="profileData.capital">
|
||||
<Text tone="muted" size="sm">Уставный капитал</Text>
|
||||
<Text weight="medium">{{ profileData.capital }}</Text>
|
||||
</div>
|
||||
|
||||
<!-- Address -->
|
||||
<div v-if="profileData.address" class="md:col-span-2">
|
||||
<Text tone="muted" size="sm">Адрес</Text>
|
||||
<Text weight="medium">{{ profileData.address }}</Text>
|
||||
</div>
|
||||
|
||||
<!-- Activities -->
|
||||
<div v-if="profileData.activities?.length" class="md:col-span-2">
|
||||
<Text tone="muted" size="sm">Виды деятельности</Text>
|
||||
<div class="flex flex-wrap gap-1 mt-1">
|
||||
<span
|
||||
v-for="(activity, idx) in profileData.activities.slice(0, 5)"
|
||||
:key="idx"
|
||||
class="badge badge-ghost badge-sm"
|
||||
>
|
||||
{{ activity }}
|
||||
</span>
|
||||
<span v-if="profileData.activities.length > 5" class="text-xs text-base-content/60">
|
||||
+{{ profileData.activities.length - 5 }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Footer: sources and last updated -->
|
||||
<div class="flex items-center justify-between text-xs text-base-content/50 pt-2 border-t border-base-200">
|
||||
<span v-if="profileData.sources?.length">
|
||||
Источники: {{ profileData.sources.join(', ') }}
|
||||
</span>
|
||||
<span v-if="profileData.lastUpdated">
|
||||
Обновлено: {{ formatDate(profileData.lastUpdated) }}
|
||||
</span>
|
||||
</div>
|
||||
</Stack>
|
||||
</Card>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { GetKycProfileFullDocument } from '~/composables/graphql/public/kyc-generated'
|
||||
|
||||
const props = defineProps<{
|
||||
kycProfileUuid?: string | null
|
||||
}>()
|
||||
|
||||
const { execute } = useGraphQL()
|
||||
|
||||
const profileData = ref<{
|
||||
inn?: string | null
|
||||
ogrn?: string | null
|
||||
name?: string | null
|
||||
companyType?: string | null
|
||||
registrationYear?: number | null
|
||||
isActive?: boolean | null
|
||||
address?: string | null
|
||||
director?: string | null
|
||||
capital?: string | null
|
||||
activities?: string[] | null
|
||||
sources?: string[] | null
|
||||
lastUpdated?: string | null
|
||||
} | null>(null)
|
||||
|
||||
const pending = ref(false)
|
||||
|
||||
const loadProfile = async () => {
|
||||
if (!props.kycProfileUuid) return
|
||||
pending.value = true
|
||||
try {
|
||||
const data = await execute(
|
||||
GetKycProfileFullDocument,
|
||||
{ profileUuid: props.kycProfileUuid },
|
||||
'public',
|
||||
'kyc'
|
||||
)
|
||||
profileData.value = data?.kycProfileFull || null
|
||||
} catch (error) {
|
||||
console.error('Error loading KYC profile:', error)
|
||||
} finally {
|
||||
pending.value = false
|
||||
}
|
||||
}
|
||||
|
||||
watch(() => props.kycProfileUuid, (uuid) => {
|
||||
if (uuid) {
|
||||
loadProfile()
|
||||
} else {
|
||||
profileData.value = null
|
||||
}
|
||||
}, { immediate: true })
|
||||
|
||||
const formatDate = (dateStr: string) => {
|
||||
try {
|
||||
return new Date(dateStr).toLocaleDateString('ru-RU')
|
||||
} catch {
|
||||
return dateStr
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -45,11 +45,12 @@
|
||||
<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>
|
||||
|
||||
<!-- KYC Profile Card (full company info) -->
|
||||
<KycProfileCard v-if="supplier?.kycProfileUuid" :kyc-profile-uuid="supplier.kycProfileUuid" />
|
||||
|
||||
<!-- Price Chart -->
|
||||
<Card padding="md">
|
||||
<div class="h-48">
|
||||
|
||||
Reference in New Issue
Block a user