237 lines
6.3 KiB
TypeScript
237 lines
6.3 KiB
TypeScript
'use client'
|
|
|
|
import {
|
|
CommandEmpty,
|
|
CommandGroup,
|
|
CommandInput,
|
|
CommandItem,
|
|
CommandList
|
|
} from 'cmdk'
|
|
import {
|
|
Check,
|
|
ChevronsUpDown,
|
|
MapPinCheck,
|
|
MapPinPlus,
|
|
Warehouse
|
|
} from 'lucide-react'
|
|
import {useLocale, useTranslations} from 'next-intl'
|
|
import {useState} from 'react'
|
|
import {useDebouncedCallback} from 'use-debounce'
|
|
|
|
import {
|
|
type Settlement,
|
|
type Warehouse as WarehouseType,
|
|
formatSettlement,
|
|
getApi
|
|
} from '@/lib/nova-post-helper'
|
|
import {cn} from '@/lib/utils'
|
|
import {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 NovaPost({onSelectHandler}: {onSelectHandler: any}) {
|
|
const t = useTranslations('cart.post')
|
|
const [citiesOpen, setCitiesOpen] = useState(false)
|
|
const [warehousesOpen, setWarehousesOpen] = useState(false)
|
|
const [citiesValue, setCitiesValue] = useState('')
|
|
const [cityRef, setCityRef] = useState('')
|
|
//const [warehouseRef, setWarehouseRef] = useState('')
|
|
const [warehousesValue, setWarehousesValue] = useState('')
|
|
const [cities, setCities] = useState([])
|
|
const [warehouses, setWarehouses] = useState([])
|
|
const locale = useLocale()
|
|
|
|
const handleCitySearch = useDebouncedCallback(
|
|
async (e: string): Promise<void> => {
|
|
if (e.length < 3) {
|
|
setCities([])
|
|
return
|
|
}
|
|
|
|
const response = await getApi(url + `?scope=cities&q=` + encodeURI(e))
|
|
|
|
if (response.ok) {
|
|
let json = await response.json()
|
|
setCities(json)
|
|
} else {
|
|
setCities([])
|
|
}
|
|
},
|
|
1000
|
|
)
|
|
|
|
const handleWarehouseSearch = async (e: string): Promise<void> => {
|
|
const response = await getApi(`${url}?scope=warehouses&q=${e}`)
|
|
|
|
if (response.ok) {
|
|
let json = await response.json()
|
|
setWarehouses(json)
|
|
} else {
|
|
setWarehouses([])
|
|
}
|
|
}
|
|
|
|
const cityDescription = (citiesValue: string): string => {
|
|
const city: Settlement | undefined = cities.find(
|
|
(city: Settlement) => city.Description === citiesValue
|
|
)
|
|
|
|
if (!city) {
|
|
return ''
|
|
}
|
|
|
|
return formatSettlement(city, locale)
|
|
}
|
|
|
|
return (
|
|
<div className='py-2'>
|
|
<div>
|
|
<Popover open={citiesOpen} onOpenChange={setCitiesOpen}>
|
|
<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'>
|
|
{citiesValue ? (
|
|
<>
|
|
<MapPinCheck />
|
|
{cityDescription(citiesValue)}
|
|
</>
|
|
) : (
|
|
<>
|
|
<MapPinPlus />
|
|
{t('findSettlement')}
|
|
</>
|
|
)}
|
|
</span>
|
|
<ChevronsUpDown className='opacity-50' />
|
|
</Button>
|
|
</PopoverTrigger>
|
|
<PopoverContent className='w-[640px] p-2'>
|
|
<Command>
|
|
<CommandInput
|
|
className='border border-brand-violet p-2'
|
|
placeholder={t('startSearchSettlement')}
|
|
onValueChange={(e: string) => handleCitySearch(e)}
|
|
/>
|
|
<CommandList>
|
|
<CommandEmpty className='my-1'>{t('notFount')}</CommandEmpty>
|
|
<CommandGroup className='max-h-[320px] w-full overflow-y-auto'>
|
|
{cities.map((city: Settlement) => (
|
|
<CommandItem
|
|
className='my-2 flex'
|
|
key={city?.Ref}
|
|
value={city?.Description}
|
|
onSelect={(currentValue: string) => {
|
|
setCitiesValue(
|
|
currentValue === citiesValue ? '' : currentValue
|
|
)
|
|
setCityRef(
|
|
currentValue === citiesValue ? '' : city?.Ref
|
|
)
|
|
|
|
handleWarehouseSearch(
|
|
currentValue === citiesValue ? '' : city?.Ref
|
|
).then(console.log)
|
|
|
|
setCitiesOpen(false)
|
|
}}
|
|
>
|
|
{formatSettlement(city, locale)}
|
|
<Check
|
|
className={cn(
|
|
'ml-auto',
|
|
citiesValue === city?.Description
|
|
? 'opacity-100'
|
|
: 'opacity-0'
|
|
)}
|
|
/>
|
|
</CommandItem>
|
|
))}
|
|
</CommandGroup>
|
|
</CommandList>
|
|
</Command>
|
|
</PopoverContent>
|
|
</Popover>
|
|
</div>
|
|
{cityRef !== '' && (
|
|
<div className='pt-3'>
|
|
<Popover open={warehousesOpen} onOpenChange={setWarehousesOpen}>
|
|
<PopoverTrigger asChild>
|
|
<Button
|
|
variant='outline'
|
|
role='combobox'
|
|
/*aria-expanded={open}*/
|
|
className='w-full justify-between'
|
|
>
|
|
<span className='inline-flex items-center gap-x-3'>
|
|
<Warehouse />
|
|
{warehousesValue ? warehousesValue : t('selectWarehouse')}
|
|
</span>
|
|
<ChevronsUpDown className='opacity-50' />
|
|
</Button>
|
|
</PopoverTrigger>
|
|
<PopoverContent className='w-[640px] p-2'>
|
|
<Command>
|
|
<CommandInput
|
|
className='p-2'
|
|
placeholder={t('startSearchWarehouse')}
|
|
/*onValueChange={(e: string) => handleCitySearch(e)}*/
|
|
/>
|
|
<CommandList>
|
|
<CommandEmpty className='my-1'>{t('notFount')}</CommandEmpty>
|
|
<CommandGroup className='max-h-[320px] w-full overflow-y-auto'>
|
|
{warehouses.map((warehouse: WarehouseType) => (
|
|
<CommandItem
|
|
className='my-2 flex'
|
|
key={warehouse.Ref}
|
|
value={warehouse.Description}
|
|
onSelect={(currentValue: string) => {
|
|
setWarehousesValue(
|
|
currentValue === warehousesValue ? '' : currentValue
|
|
)
|
|
/*setWarehouseRef(
|
|
currentValue === warehousesValue
|
|
? ''
|
|
: warehouse.Ref
|
|
)*/
|
|
onSelectHandler(
|
|
currentValue === warehousesValue
|
|
? {}
|
|
: {
|
|
Ref: warehouse.Ref,
|
|
Description: warehouse.Description,
|
|
DescriptionRu: warehouse.DescriptionRu
|
|
}
|
|
)
|
|
setWarehousesOpen(false)
|
|
}}
|
|
>
|
|
{warehouse.Description}
|
|
<Check
|
|
className={cn(
|
|
'ml-auto',
|
|
warehousesValue === warehouse.Description
|
|
? 'opacity-100'
|
|
: 'opacity-0'
|
|
)}
|
|
/>
|
|
</CommandItem>
|
|
))}
|
|
</CommandGroup>
|
|
</CommandList>
|
|
</Command>
|
|
</PopoverContent>
|
|
</Popover>
|
|
</div>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|