From b01a1dec8193adc221fca791959bac6fcf61df0b Mon Sep 17 00:00:00 2001 From: object <110488133+oobjectt@users.noreply.github.com> Date: Sat, 14 Jan 2023 06:48:51 +0100 Subject: [PATCH] #58 - Autocomplete friend gift (#111) --- src/components/catalog/CatalogView.scss | 28 +++++++++ .../catalog/views/gift/CatalogGiftView.tsx | 61 +++++++++++++++---- 2 files changed, 76 insertions(+), 13 deletions(-) diff --git a/src/components/catalog/CatalogView.scss b/src/components/catalog/CatalogView.scss index 1e77c4f7..824ddb7d 100644 --- a/src/components/catalog/CatalogView.scss +++ b/src/components/catalog/CatalogView.scss @@ -127,4 +127,32 @@ height: 60px; } +.autocomplete-gift-container { + background: #fff; + padding: 8px; + list-style-type: none; + min-width: 307px; + border-radius: 0.2rem; + position: absolute; + font-size: 0.7875rem; + top: 81px; + left: 8px; + border: 1px solid #b6c1ce; + margin: 0; + border-radius: 2px; + margin: 0; + box-sizing: border-box; + max-height: 280px; + overflow-y: auto; + z-index: 1; + + .autocomplete-gift-item { + width: 100%; + box-sizing: border-box; + &:hover { + background-color: #ebf4ff; + } + } +} + @import './views/targeted-offer/Offer.scss'; diff --git a/src/components/catalog/views/gift/CatalogGiftView.tsx b/src/components/catalog/views/gift/CatalogGiftView.tsx index fe4888f3..64e1dd17 100644 --- a/src/components/catalog/views/gift/CatalogGiftView.tsx +++ b/src/components/catalog/views/gift/CatalogGiftView.tsx @@ -1,10 +1,10 @@ import { GiftReceiverNotFoundEvent, PurchaseFromCatalogAsGiftComposer } from '@nitrots/nitro-renderer'; -import { FC, useCallback, useEffect, useMemo, useState } from 'react'; +import { ChangeEvent, FC, useCallback, useEffect, useMemo, useState } from 'react'; import { FaChevronLeft, FaChevronRight } from 'react-icons/fa'; -import { ColorUtils, GetSessionDataManager, LocalizeText, ProductTypeEnum, SendMessageComposer } from '../../../../api'; +import { ColorUtils, GetSessionDataManager, LocalizeText, MessengerFriend, ProductTypeEnum, SendMessageComposer } from '../../../../api'; import { Base, Button, ButtonGroup, classNames, Column, Flex, FormGroup, LayoutCurrencyIcon, LayoutFurniImageView, LayoutGiftTagView, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../common'; import { CatalogEvent, CatalogInitGiftEvent, CatalogPurchasedEvent } from '../../../../events'; -import { useCatalog, useMessageEvent, useUiEvent } from '../../../../hooks'; +import { useCatalog, useFriends, useMessageEvent, useUiEvent } from '../../../../hooks'; export const CatalogGiftView: FC<{}> = props => { @@ -23,8 +23,11 @@ export const CatalogGiftView: FC<{}> = props => const [ maxRibbonIndex, setMaxRibbonIndex ] = useState(0); const [ receiverNotFound, setReceiverNotFound ] = useState(false); const { catalogOptions = null } = useCatalog(); + const { friends } = useFriends(); const { giftConfiguration = null } = catalogOptions; const [ boxTypes, setBoxTypes ] = useState([]); + const [ suggestions, setSuggestions ] = useState([]); + const [ isAutocompleteVisible, setIsAutocompleteVisible ] = useState(true); const onClose = useCallback(() => { @@ -37,6 +40,8 @@ export const CatalogGiftView: FC<{}> = props => setMessage(''); setSelectedBoxIndex(0); setSelectedRibbonIndex(0); + setIsAutocompleteVisible(false); + setSuggestions([]); if(colors.length) setSelectedColorId(colors[0].id); }, [ colors ]); @@ -56,19 +61,42 @@ export const CatalogGiftView: FC<{}> = props => const isColorable = useMemo(() => { if (!giftConfiguration) return false; - + if (isBoxDefault) return false; const boxType = boxTypes[selectedBoxIndex]; return (boxType === 8 || (boxType >= 3 && boxType <= 6)) ? false : true; }, [ giftConfiguration, selectedBoxIndex, isBoxDefault, boxTypes ]); - + const colourId = useMemo(() => { return isBoxDefault ? boxTypes[selectedBoxIndex] : selectedColorId; },[ isBoxDefault, boxTypes, selectedBoxIndex, selectedColorId ]) + const allFriends = friends.filter( (friend: MessengerFriend) => friend.id !== -1 ); + + const onTextChanged = (e: ChangeEvent) => + { + const value = e.target.value; + + let suggestions = []; + + if (value.length > 0) + { + suggestions = allFriends.sort().filter((friend: MessengerFriend) => friend.name.includes(value)); + } + + setReceiverName(value); + setIsAutocompleteVisible(true); + setSuggestions(suggestions); + }; + + const selectedReceiverName = (friendName: string) => + { + setReceiverName(friendName); + setIsAutocompleteVisible(false); + } const handleAction = useCallback((action: string) => { @@ -113,7 +141,7 @@ export const CatalogGiftView: FC<{}> = props => const castedEvent = (event as CatalogInitGiftEvent); onClose(); - + setPageId(castedEvent.pageId); setOfferId(castedEvent.offerId); setExtraData(castedEvent.extraData); @@ -126,20 +154,20 @@ export const CatalogGiftView: FC<{}> = props => { setReceiverNotFound(false); }, [ receiverName ]); - + const createBoxTypes = useCallback(() => { if (!giftConfiguration) return; - + setBoxTypes(prev => { let newPrev = [ ...giftConfiguration.boxTypes ]; - + newPrev.push(giftConfiguration.defaultStuffTypes[ Math.floor((Math.random() * (giftConfiguration.defaultStuffTypes.length - 1))) ]); setMaxBoxIndex(newPrev.length- 1); setMaxRibbonIndex(newPrev.length - 1); - + return newPrev; }) },[ giftConfiguration ]) @@ -167,9 +195,9 @@ export const CatalogGiftView: FC<{}> = props => setColors(newColors); } }, [ giftConfiguration, createBoxTypes ]); - + useEffect(() => - { + { if (!isVisible) return; createBoxTypes(); @@ -187,7 +215,14 @@ export const CatalogGiftView: FC<{}> = props => { LocalizeText('catalog.gift_wrapping.receiver') } - setReceiverName(e.target.value) } /> + onTextChanged(e) } /> + { (suggestions.length > 0 && isAutocompleteVisible) && + + { suggestions.map((friend: MessengerFriend) => ( + selectedReceiverName(friend.name) }>{ friend.name } + )) } + + } { receiverNotFound && { LocalizeText('catalog.gift_wrapping.receiver_not_found.title') } }