Files
bewell-in-ua/components/pages/cart/search-address.tsx
2025-03-11 02:54:09 +02:00

153 lines
3.9 KiB
TypeScript

'use client'
import {
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList
} from 'cmdk'
import {Check, ChevronsUpDown, MapPinCheck, MapPinPlus} from 'lucide-react'
import {useLocale, useTranslations} from 'next-intl'
import {useState} from 'react'
import {useDebouncedCallback} from 'use-debounce'
import {
type Settlement,
Street,
formatSettlement,
getApi
} from '@/lib/nova-post-helper'
import {cn, dump} from '@/lib/utils'
import {Button} from '@/ui/button'
import {Command} from '@/ui/command'
import {Popover, PopoverContent, PopoverTrigger} from '@/ui/popover'
const url = '/api/nova-post'
export default function SearchAddress({
onSelectHandler
}: {
onSelectHandler: any
}) {
const t = useTranslations('cart.post')
const locale = useLocale()
const [streets, setStreets] = useState([])
const [streetsOpen, setStreetsOpen] = useState(false)
const [streetsValue, setStreetsValue] = useState('')
const handleStreetSearch = useDebouncedCallback(
async (e: string): Promise<void> => {
if (e.length < 3) {
setStreets([])
return
}
const response = await getApi(url + `?scope=streets&q=` + encodeURI(e))
if (response.ok) {
let json = JSON.parse(JSON.stringify(await response.json()))
const {Addresses} = json[0]
setStreets(Addresses)
} else {
setStreets([])
}
},
1000
)
const streetDescription = (streetsValue: string): string => {
const street: Street | undefined = streets.find(
(street: Street) => street.Present === streetsValue
)
if (!street) {
return ''
}
return streetsValue
}
return (
<div className='py-2'>
{/*<pre>{dump(streets[0]['Addresses'])}</pre>*/}
<div>
<Popover open={streetsOpen} onOpenChange={setStreetsOpen}>
<PopoverTrigger asChild>
<Button
variant='outline'
role='combobox'
/*aria-expanded={open}*/
className='w-full justify-between border border-brand-violet'
>
<span className='inline-flex items-center gap-x-3'>
{streetsValue ? (
<>
<MapPinCheck />
{streetDescription(streetsValue)}
</>
) : (
<>
<MapPinPlus />
{locale !== 'ru' ? 'Шукати вулицю' : 'Искать улицу'}
</>
)}
</span>
<ChevronsUpDown className='opacity-50' />
</Button>
</PopoverTrigger>
<PopoverContent className='w-[640px] p-2'>
<Command>
<CommandInput
className='border border-brand-violet p-2'
placeholder={locale !== 'ru' ? 'Почати пошук' : 'Начать поиск'}
onValueChange={(e: string) => handleStreetSearch(e)}
/>
<CommandList>
<CommandEmpty className='my-1'>{t('notFount')}</CommandEmpty>
<CommandGroup className='max-h-[320px] w-full overflow-y-auto'>
{streets.map((street: Street, index: number) => (
<CommandItem
className='my-2 flex'
key={index}
value={street?.Present}
onSelect={(currentValue: string) => {
setStreetsValue(
currentValue === streetsValue ? '' : currentValue
)
onSelectHandler(
currentValue === streetsValue
? {}
: {
Ref: street.SettlementStreetRef,
Description: street.Present,
DescriptionRu:
street.SettlementStreetDescriptionRu
}
)
setStreetsOpen(false)
}}
>
{street?.Present}
<Check
className={cn(
'ml-auto',
streetsValue === street?.Present
? 'opacity-100'
: 'opacity-0'
)}
/>
</CommandItem>
))}
</CommandGroup>
</CommandList>
</Command>
</PopoverContent>
</Popover>
</div>
</div>
)
}