All checks were successful
Build Docker Image / build (push) Successful in 5m8s
- Remove all Storybook files and configuration - Add type declarations for @vueuse/core, @formkit/core, vue3-apexcharts - Fix TypeScript configuration (typeRoots, include paths) - Fix Sentry config - move settings to plugin - Fix nullable prop assignments with ?? operator - Fix type narrowing issues with explicit type assertions - Fix Card component linkable computed properties - Update codegen with operationResultSuffix - Fix GraphQL operation type definitions
156 lines
4.8 KiB
Vue
156 lines
4.8 KiB
Vue
<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)[] | null
|
||
sources?: (string | null)[] | 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>
|