Files
bewell-in-ua/app/[locale]/(root)/(shop)/cart/nova-post.tsx
2025-03-11 02:54:09 +02:00

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>
)
}