5180 fichiers 38.5 Mo 0 téléchargements 538 vues mis à jour il y a 8 heures ui
nitro-v36-with-renderer-v36 / src / components / catalog / views / page / common / CatalogSearchView.tsx
CatalogSearchView.tsx 4.9 Ko Télécharger le fichier
import { GetSessionDataManager } from '@octane/renderer';
import { ChangeEvent, FC, KeyboardEvent, useCallback, useEffect, useRef, useState } from 'react';
import { FaTimes } from 'react-icons/fa';
import {
    CatalogPage,
    FilterCatalogNode,
    FurnitureOffer,
    ICatalogNode,
    ICatalogPage,
    IPurchasableOffer,
    LocalizeText,
    localizeWithFallback,
    PageLocalization,
    SearchResult
} from '../../../../../api';
import { useCatalogData, useCatalogUiState } from '../../../../../hooks';
import {
    CATALOG_SEARCH_DEBOUNCE_MS,
    findCatalogFurnitureMatches,
    isCatalogSearchEnterKey,
    normalizeCatalogSearchText,
    shouldRunCatalogSearch
} from './catalogSearch.helpers';
import { BaseButton } from '../../../../../common/BaseButton';

export const CatalogSearchView: FC<{}> = () => {
    const [searchValue, setSearchValue] = useState('');
    const searchTimeout = useRef<ReturnType<typeof setTimeout>>(null);
    const { rootNode = null } = useCatalogData();
    const { currentType = null, setSearchResult = null, setCurrentPage = null } = useCatalogUiState();

    const runSearch = useCallback(
        (search: string) => {
            if (!rootNode || !shouldRunCatalogSearch(search)) return;

            const furnitureDatas = GetSessionDataManager().getAllFurnitureData();

            if (!furnitureDatas || !furnitureDatas.length) return;

            const { furniture: foundFurniture, furniLines: foundFurniLines } = findCatalogFurnitureMatches(furnitureDatas, search, currentType);

            const offers: IPurchasableOffer[] = [];

            for (const furniture of foundFurniture) {
                offers.push(new FurnitureOffer(furniture));
            }

            let nodes: ICatalogNode[] = [];

            FilterCatalogNode(search, foundFurniLines, rootNode, nodes);

            setSearchResult(
                new SearchResult(
                    search,
                    offers,
                    nodes.filter((node) => node.isVisible)
                )
            );
            setCurrentPage(
                new CatalogPage(
                    -1,
                    'default_3x3',
                    new PageLocalization([], [LocalizeText('catalog.search.results', ['count', 'needle'], [String(offers.length), search])]),
                    offers,
                    false,
                    1
                )
            );
        },
        [currentType, rootNode, setCurrentPage, setSearchResult]
    );

    const scheduleSearch = useCallback(
        (value: string, immediate = false) => {
            if (searchTimeout.current) clearTimeout(searchTimeout.current);

            const search = normalizeCatalogSearchText(value);

            if (!shouldRunCatalogSearch(search)) {
                setSearchResult(null);

                return;
            }

            if (immediate) {
                runSearch(search);

                return;
            }

            searchTimeout.current = setTimeout(() => runSearch(search), CATALOG_SEARCH_DEBOUNCE_MS);
        },
        [runSearch, setSearchResult]
    );

    const onSearchChange = (event: ChangeEvent<HTMLInputElement>) => {
        const value = event.target.value;

        setSearchValue(value);
        scheduleSearch(value);
    };

    const onSearchKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {
        if (!isCatalogSearchEnterKey(event.key, searchValue)) return;

        event.preventDefault();
        scheduleSearch(searchValue, true);
    };

    const clearSearch = () => {
        if (searchTimeout.current) clearTimeout(searchTimeout.current);

        setSearchValue('');
        setSearchResult(null);
    };

    useEffect(() => {
        if (searchValue) scheduleSearch(searchValue);
    }, [currentType, rootNode]);

    useEffect(() => () => searchTimeout.current && clearTimeout(searchTimeout.current), []);

    return (
        // AIR searchContainer: the search.helper text (catalog.search, #666666) in the box and common_small_pen on the
        // right, which turns into icons_close once something is typed.
        <div className="octane-catalog-search relative w-full">
            <input
                aria-label={LocalizeText('catalog.search')}
                className="octane-catalog-search-input w-full"
                placeholder={LocalizeText('catalog.search')}
                type="text"
                value={searchValue}
                onChange={onSearchChange}
                onKeyDown={onSearchKeyDown}
            />
            {searchValue && searchValue.length > 0 ? (
                <BaseButton
                    aria-label={localizeWithFallback('generic.clear', 'Clear')}
                    type="button"
                    className="octane-catalog-search-clear"
                    onClick={clearSearch}
                >
                    <FaTimes />
                </BaseButton>
            ) : (
                <span aria-hidden="true" className="octane-catalog-search-pen" />
            )}
        </div>
    );
};
15Sujets
1Dépôts
20Membres
4En ligne
Profile
Inscrit
Dernière visite
Messages
0
Votes positifs
0
Votes négatifs
0

Nous utilisons des cookies pour assurer le bon fonctionnement du site et améliorer votre expérience. en savoir plus

Autoriser