131 lines
3.3 KiB
Vue
131 lines
3.3 KiB
Vue
<template>
|
|
<div class="relative">
|
|
<input
|
|
v-model="query"
|
|
@input="onInput"
|
|
@focus="showDropdown = true"
|
|
class="input input-bordered w-full"
|
|
placeholder="Enter bank name or BIC..."
|
|
autocomplete="off"
|
|
/>
|
|
|
|
<!-- Dropdown with bank 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="selectBank(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">
|
|
BIC: {{ suggestion.data.bic }}
|
|
<span v-if="suggestion.data.correspondent_account">
|
|
• Corr. account: {{ suggestion.data.correspondent_account }}
|
|
</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 BankData {
|
|
bankName: string
|
|
bik: string
|
|
correspondentAccount: string
|
|
}
|
|
|
|
interface Props {
|
|
modelValue?: BankData
|
|
}
|
|
|
|
interface Emits {
|
|
(e: 'update:modelValue', value: BankData): void
|
|
(e: 'select', bank: any): void
|
|
}
|
|
|
|
const props = withDefaults(defineProps<Props>(), {
|
|
modelValue: () => ({
|
|
bankName: '',
|
|
bik: '',
|
|
correspondentAccount: ''
|
|
})
|
|
})
|
|
|
|
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/bank', {
|
|
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 Bank error:', error)
|
|
suggestions.value = []
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
const selectBank = (bank: any) => {
|
|
query.value = bank.value
|
|
showDropdown.value = false
|
|
|
|
const bankData: BankData = {
|
|
bankName: bank.value,
|
|
bik: bank.data.bic,
|
|
correspondentAccount: bank.data.correspondent_account || ''
|
|
}
|
|
|
|
emit('update:modelValue', bankData)
|
|
emit('select', bank)
|
|
}
|
|
</script>
|