Files
webapp/app/components/CompanySearchRussia.vue
2026-01-07 09:10:35 +07:00

138 lines
3.5 KiB
Vue

<template>
<div class="relative">
<input
v-model="query"
@input="onInput"
@focus="showDropdown = true"
class="input input-bordered w-full"
placeholder="Enter organization name or INN..."
autocomplete="off"
/>
<!-- Dropdown with suggestions -->
<div
v-if="showDropdown && suggestions.length > 0"
class="absolute top-full left-0 right-0 z-50 bg-base-100 border border-base-300 rounded-box shadow-lg max-h-60 overflow-y-auto"
>
<div
v-for="(suggestion, index) in suggestions"
:key="index"
@click="selectCompany(suggestion)"
class="p-3 cursor-pointer hover:bg-base-200 transition-colors border-b border-base-300 last:border-b-0"
>
<div class="font-medium text-base-content">{{ suggestion.value }}</div>
<div class="text-sm text-base-content/80">
INN: {{ suggestion.data.inn }}
<span v-if="suggestion.data.kpp"> KPP: {{ suggestion.data.kpp }}</span>
</div>
<div v-if="suggestion.data.address" class="text-xs text-base-content/60 mt-1">
{{ suggestion.data.address.value }}
</div>
</div>
</div>
<!-- Loading indicator -->
<div v-if="loading" class="absolute right-3 top-1/2 -translate-y-1/2">
<span class="loading loading-spinner loading-xs text-primary"></span>
</div>
</div>
</template>
<script setup lang="ts">
interface CompanyData {
companyName: string
companyFullName: string
inn: string
kpp: string
ogrn: string
address: string
}
interface Props {
modelValue?: CompanyData
}
interface Emits {
(e: 'update:modelValue', value: CompanyData): void
(e: 'select', company: any): void
}
const props = withDefaults(defineProps<Props>(), {
modelValue: () => ({
companyName: '',
companyFullName: '',
inn: '',
kpp: '',
ogrn: '',
address: ''
})
})
const emit = defineEmits<Emits>()
const query = ref('')
const suggestions = ref([])
const loading = ref(false)
const showDropdown = ref(false)
// Hide dropdown when clicking outside
onMounted(() => {
document.addEventListener('click', (e) => {
if (!e.target?.closest('.relative')) {
showDropdown.value = false
}
})
})
const onInput = async () => {
if (query.value.length < 2) {
suggestions.value = []
showDropdown.value = false
return
}
loading.value = true
try {
const response = await fetch('https://suggestions.dadata.ru/suggestions/api/4_1/rs/suggest/party', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Token 8de30547fe1e228dd5d7289439b71f5a97cf7357'
},
body: JSON.stringify({
query: query.value,
count: 10
})
})
const data = await response.json()
suggestions.value = data.suggestions || []
showDropdown.value = true
} catch (error) {
console.error('DADATA error:', error)
suggestions.value = []
} finally {
loading.value = false
}
}
const selectCompany = (company: any) => {
query.value = company.value
showDropdown.value = false
const companyData: CompanyData = {
companyName: company.value,
companyFullName: company.unrestricted_value,
inn: company.data.inn,
kpp: company.data.kpp || '',
ogrn: company.data.ogrn || '',
address: company.data.address?.value || ''
}
emit('update:modelValue', companyData)
emit('select', company)
}
</script>