Add KYC profile integration and SupplierInfoBlock component
Some checks failed
Build Docker Image / build (push) Failing after 2m51s
Some checks failed
Build Docker Image / build (push) Failing after 2m51s
This commit is contained in:
@@ -26,6 +26,7 @@
|
|||||||
:currency="getOfferData(option.sourceUuid)?.currency"
|
:currency="getOfferData(option.sourceUuid)?.currency"
|
||||||
:unit="getOfferData(option.sourceUuid)?.unit"
|
:unit="getOfferData(option.sourceUuid)?.unit"
|
||||||
:stages="getRouteStages(option)"
|
:stages="getRouteStages(option)"
|
||||||
|
:kyc-profile-uuid="getKycProfileUuid(option.sourceUuid)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -64,7 +65,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { GetOffersByHubDocument } from '~/composables/graphql/public/geo-generated'
|
import { GetOffersByHubDocument } from '~/composables/graphql/public/geo-generated'
|
||||||
import type { RouteStageItem } from '~/components/RouteStagesList.vue'
|
import type { RouteStageItem } from '~/components/RouteStagesList.vue'
|
||||||
import { GetOfferDocument } from '~/composables/graphql/public/exchange-generated'
|
import { GetOfferDocument, GetSupplierProfileByTeamDocument } from '~/composables/graphql/public/exchange-generated'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const searchStore = useSearchStore()
|
const searchStore = useSearchStore()
|
||||||
@@ -76,6 +77,8 @@ const quantity = computed(() => (route.query.quantity as string) || (searchStore
|
|||||||
|
|
||||||
// Offer data for prices
|
// Offer data for prices
|
||||||
const offersData = ref<Map<string, any>>(new Map())
|
const offersData = ref<Map<string, any>>(new Map())
|
||||||
|
// Supplier data for KYC profile UUID (by team_uuid)
|
||||||
|
const suppliersData = ref<Map<string, any>>(new Map())
|
||||||
|
|
||||||
const summaryTitle = computed(() => `${productName.value} → ${locationName.value}`)
|
const summaryTitle = computed(() => `${productName.value} → ${locationName.value}`)
|
||||||
const summaryMeta = computed(() => {
|
const summaryMeta = computed(() => {
|
||||||
@@ -163,26 +166,57 @@ const getOfferData = (uuid?: string | null) => {
|
|||||||
return offersData.value.get(uuid)
|
return offersData.value.get(uuid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get KYC profile UUID by offer UUID
|
||||||
|
const getKycProfileUuid = (offerUuid?: string | null) => {
|
||||||
|
if (!offerUuid) return null
|
||||||
|
const offer = offersData.value.get(offerUuid)
|
||||||
|
if (!offer?.teamUuid) return null
|
||||||
|
const supplier = suppliersData.value.get(offer.teamUuid)
|
||||||
|
return supplier?.kycProfileUuid || null
|
||||||
|
}
|
||||||
|
|
||||||
// Load offer details for prices
|
// Load offer details for prices
|
||||||
const loadOfferDetails = async (options: ProductRouteOption[]) => {
|
const loadOfferDetails = async (options: ProductRouteOption[]) => {
|
||||||
if (options.length === 0) {
|
if (options.length === 0) {
|
||||||
offersData.value.clear()
|
offersData.value.clear()
|
||||||
|
suppliersData.value.clear()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const newOffersData = new Map<string, any>()
|
const newOffersData = new Map<string, any>()
|
||||||
|
const newSuppliersData = new Map<string, any>()
|
||||||
|
const teamUuidsToLoad = new Set<string>()
|
||||||
|
|
||||||
|
// First, load all offers
|
||||||
await Promise.all(options.map(async (option) => {
|
await Promise.all(options.map(async (option) => {
|
||||||
if (!option.sourceUuid) return
|
if (!option.sourceUuid) return
|
||||||
try {
|
try {
|
||||||
const data = await execute(GetOfferDocument, { uuid: option.sourceUuid }, 'public', 'exchange')
|
const data = await execute(GetOfferDocument, { uuid: option.sourceUuid }, 'public', 'exchange')
|
||||||
if (data?.getOffer) {
|
if (data?.getOffer) {
|
||||||
newOffersData.set(option.sourceUuid, data.getOffer)
|
newOffersData.set(option.sourceUuid, data.getOffer)
|
||||||
|
if (data.getOffer.teamUuid) {
|
||||||
|
teamUuidsToLoad.add(data.getOffer.teamUuid)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error loading offer:', option.sourceUuid, error)
|
console.error('Error loading offer:', option.sourceUuid, error)
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
// Then, load supplier profiles for all team UUIDs
|
||||||
|
await Promise.all([...teamUuidsToLoad].map(async (teamUuid) => {
|
||||||
|
try {
|
||||||
|
const data = await execute(GetSupplierProfileByTeamDocument, { teamUuid }, 'public', 'exchange')
|
||||||
|
if (data?.getSupplierProfileByTeam) {
|
||||||
|
newSuppliersData.set(teamUuid, data.getSupplierProfileByTeam)
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error loading supplier:', teamUuid, error)
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
offersData.value = newOffersData
|
offersData.value = newOffersData
|
||||||
|
suppliersData.value = newSuppliersData
|
||||||
}
|
}
|
||||||
|
|
||||||
// Watch for route options and load offers
|
// Watch for route options and load offers
|
||||||
|
|||||||
70
app/components/SupplierInfoBlock.vue
Normal file
70
app/components/SupplierInfoBlock.vue
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="kycProfileUuid && companyData" class="space-y-2">
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<span class="badge badge-outline badge-sm">{{ companyData.companyType || 'Компания' }}</span>
|
||||||
|
<span v-if="companyData.registrationYear" class="text-xs text-base-content/60">
|
||||||
|
с {{ companyData.registrationYear }} г.
|
||||||
|
</span>
|
||||||
|
<span v-if="companyData.isActive" class="badge badge-success badge-xs">Активна</span>
|
||||||
|
</div>
|
||||||
|
<div v-if="companyData.sourcesCount" class="text-xs text-base-content/60">
|
||||||
|
{{ companyData.sourcesCount }} {{ pluralize(companyData.sourcesCount, 'источник', 'источника', 'источников') }} данных
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="kycProfileUuid && pending" class="text-xs text-base-content/60">
|
||||||
|
Загрузка данных...
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { GetKycProfileTeaserDocument } from '~/composables/graphql/public/kyc-generated'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
kycProfileUuid?: string | null
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const { execute } = useGraphQL()
|
||||||
|
|
||||||
|
const companyData = ref<{
|
||||||
|
companyType?: string | null
|
||||||
|
registrationYear?: number | null
|
||||||
|
isActive?: boolean | null
|
||||||
|
sourcesCount?: number | null
|
||||||
|
} | null>(null)
|
||||||
|
|
||||||
|
const pending = ref(false)
|
||||||
|
|
||||||
|
const loadCompanyData = async () => {
|
||||||
|
if (!props.kycProfileUuid) return
|
||||||
|
pending.value = true
|
||||||
|
try {
|
||||||
|
const data = await execute(
|
||||||
|
GetKycProfileTeaserDocument,
|
||||||
|
{ profileUuid: props.kycProfileUuid },
|
||||||
|
'public',
|
||||||
|
'kyc'
|
||||||
|
)
|
||||||
|
companyData.value = data?.companyTeaserByProfile || null
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error loading company data:', error)
|
||||||
|
} finally {
|
||||||
|
pending.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(() => props.kycProfileUuid, (uuid) => {
|
||||||
|
if (uuid) {
|
||||||
|
loadCompanyData()
|
||||||
|
} else {
|
||||||
|
companyData.value = null
|
||||||
|
}
|
||||||
|
}, { immediate: true })
|
||||||
|
|
||||||
|
const pluralize = (n: number, one: string, few: string, many: string) => {
|
||||||
|
const mod10 = n % 10
|
||||||
|
const mod100 = n % 100
|
||||||
|
if (mod10 === 1 && mod100 !== 11) return one
|
||||||
|
if (mod10 >= 2 && mod10 <= 4 && (mod100 < 10 || mod100 >= 20)) return few
|
||||||
|
return many
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -11,6 +11,9 @@
|
|||||||
</Text>
|
</Text>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Supplier info -->
|
||||||
|
<SupplierInfoBlock v-if="kycProfileUuid" :kyc-profile-uuid="kycProfileUuid" class="mb-3" />
|
||||||
|
|
||||||
<!-- Route stepper -->
|
<!-- Route stepper -->
|
||||||
<RouteStepper
|
<RouteStepper
|
||||||
v-if="stages.length > 0"
|
v-if="stages.length > 0"
|
||||||
@@ -33,6 +36,7 @@ const props = withDefaults(defineProps<{
|
|||||||
stages?: RouteStage[]
|
stages?: RouteStage[]
|
||||||
startName?: string
|
startName?: string
|
||||||
endName?: string
|
endName?: string
|
||||||
|
kycProfileUuid?: string | null
|
||||||
}>(), {
|
}>(), {
|
||||||
stages: () => []
|
stages: () => []
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ const RESOURCE_MAP: Record<Api, string> = {
|
|||||||
const CLIENT_MAP: Record<string, string> = {
|
const CLIENT_MAP: Record<string, string> = {
|
||||||
'public:exchange': 'default',
|
'public:exchange': 'default',
|
||||||
'public:geo': 'publicGeo',
|
'public:geo': 'publicGeo',
|
||||||
|
'public:kyc': 'publicKyc',
|
||||||
'user:teams': 'teamsUser',
|
'user:teams': 'teamsUser',
|
||||||
'user:kyc': 'kycUser',
|
'user:kyc': 'kycUser',
|
||||||
'team:teams': 'teamsTeam',
|
'team:teams': 'teamsTeam',
|
||||||
|
|||||||
@@ -29,6 +29,12 @@ const config: CodegenConfig = {
|
|||||||
plugins,
|
plugins,
|
||||||
config: pluginConfig,
|
config: pluginConfig,
|
||||||
},
|
},
|
||||||
|
'./app/composables/graphql/public/kyc-generated.ts': {
|
||||||
|
schema: 'https://kyc.optovia.ru/graphql/public/',
|
||||||
|
documents: './graphql/operations/public/kyc/*.graphql',
|
||||||
|
plugins,
|
||||||
|
config: pluginConfig,
|
||||||
|
},
|
||||||
|
|
||||||
// User-level operations (ID Token)
|
// User-level operations (ID Token)
|
||||||
'./app/composables/graphql/user/teams-generated.ts': {
|
'./app/composables/graphql/user/teams-generated.ts': {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ query GetSupplierProfile($uuid: String!) {
|
|||||||
getSupplierProfile(uuid: $uuid) {
|
getSupplierProfile(uuid: $uuid) {
|
||||||
uuid
|
uuid
|
||||||
teamUuid
|
teamUuid
|
||||||
|
kycProfileUuid
|
||||||
name
|
name
|
||||||
description
|
description
|
||||||
country
|
country
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
query GetSupplierProfileByTeam($teamUuid: String!) {
|
||||||
|
getSupplierProfileByTeam(teamUuid: $teamUuid) {
|
||||||
|
uuid
|
||||||
|
teamUuid
|
||||||
|
kycProfileUuid
|
||||||
|
name
|
||||||
|
description
|
||||||
|
country
|
||||||
|
logoUrl
|
||||||
|
isVerified
|
||||||
|
isActive
|
||||||
|
offersCount
|
||||||
|
}
|
||||||
|
}
|
||||||
16
graphql/operations/public/kyc/GetKycProfileFull.graphql
Normal file
16
graphql/operations/public/kyc/GetKycProfileFull.graphql
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
query GetKycProfileFull($profileUuid: String!) {
|
||||||
|
companyFullByProfile(profileUuid: $profileUuid) {
|
||||||
|
inn
|
||||||
|
ogrn
|
||||||
|
name
|
||||||
|
companyType
|
||||||
|
registrationYear
|
||||||
|
isActive
|
||||||
|
address
|
||||||
|
director
|
||||||
|
capital
|
||||||
|
activities
|
||||||
|
sources
|
||||||
|
lastUpdated
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
query GetKycProfileTeaser($profileUuid: String!) {
|
||||||
|
companyTeaserByProfile(profileUuid: $profileUuid) {
|
||||||
|
companyType
|
||||||
|
registrationYear
|
||||||
|
isActive
|
||||||
|
sourcesCount
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -209,6 +209,10 @@ export default defineNuxtConfig({
|
|||||||
httpEndpoint: process.env.NUXT_PUBLIC_GEO_GRAPHQL_PUBLIC || 'https://geo.optovia.ru/graphql/public/',
|
httpEndpoint: process.env.NUXT_PUBLIC_GEO_GRAPHQL_PUBLIC || 'https://geo.optovia.ru/graphql/public/',
|
||||||
devtools: { enabled: process.dev }
|
devtools: { enabled: process.dev }
|
||||||
},
|
},
|
||||||
|
publicKyc: {
|
||||||
|
httpEndpoint: process.env.NUXT_PUBLIC_KYC_GRAPHQL_PUBLIC || 'https://kyc.optovia.ru/graphql/public/',
|
||||||
|
devtools: { enabled: process.dev }
|
||||||
|
},
|
||||||
teamsUser: {
|
teamsUser: {
|
||||||
httpEndpoint: process.env.NUXT_PUBLIC_TEAMS_GRAPHQL_USER || 'https://teams.optovia.ru/graphql/user/',
|
httpEndpoint: process.env.NUXT_PUBLIC_TEAMS_GRAPHQL_USER || 'https://teams.optovia.ru/graphql/user/',
|
||||||
devtools: { enabled: process.dev }
|
devtools: { enabled: process.dev }
|
||||||
|
|||||||
Reference in New Issue
Block a user