nitro-v36-with-renderer-v36
/
src /
components /
catalog /
views /
page /
widgets /
CatalogBadgeSelectorWidgetView.tsx
CatalogBadgeSelectorWidgetView.tsx 6.3 Ko
Télécharger le fichier
import { StringDataType } from '@octane/renderer';
import { FC, useEffect, useMemo, useState } from 'react';
import { GetConfigurationValue, LocalizeBadgeDescription, LocalizeBadgeName, LocalizeText, localizeWithFallback } from '../../../../../api';
import { AutoGrid, AutoGridProps, ClassicScrollAreaView, LayoutBadgeImageView, LayoutGridItem } from '../../../../../common';
import { useCatalogData, useCatalogUiState, useInventoryBadges } from '../../../../../hooks';
import { BaseButton } from '../../../../../common/BaseButton';
import { NativeTextTree } from '../../../../../common/native-text/NativeTextTree';
interface CatalogBadgeSelectorWidgetViewProps extends AutoGridProps {}
const MAX_SEARCH_LENGTH = 40;
export const CatalogBadgeSelectorWidgetView: FC<CatalogBadgeSelectorWidgetViewProps> = (props) => {
const { columnCount = 0, className = '', ...rest } = props;
const [currentBadgeCode, setCurrentBadgeCode] = useState<string>(null);
const [searchText, setSearchText] = useState('');
const { currentOffer = null } = useCatalogData();
const { setPurchaseOptions = null } = useCatalogUiState();
const { badgeCodes = [], activate = null, deactivate = null } = useInventoryBadges();
const excludedBadgeCodes = useMemo(
() =>
new Set(
GetConfigurationValue<string>('badge.display.excluded.badgeCodes', '')
.split(',')
.map((badgeCode) => badgeCode.trim())
.filter(Boolean)
),
[]
);
const availableBadgeCodes = useMemo(() => badgeCodes.filter((badgeCode) => !excludedBadgeCodes.has(badgeCode)), [badgeCodes, excludedBadgeCodes]);
const filteredBadgeCodes = useMemo(() => {
const normalizedSearch = searchText.trim().toLocaleLowerCase();
if (!normalizedSearch) return availableBadgeCodes;
return availableBadgeCodes.filter((badgeCode) =>
`${badgeCode} ${LocalizeBadgeName(badgeCode)} ${LocalizeBadgeDescription(badgeCode)}`.toLocaleLowerCase().includes(normalizedSearch)
);
}, [availableBadgeCodes, searchText]);
const previewStuffData = useMemo(() => {
if (!currentBadgeCode) return null;
const stuffData = new StringDataType();
stuffData.setValue(['0', currentBadgeCode, '', '']);
return stuffData;
}, [currentBadgeCode]);
useEffect(() => {
if (!currentOffer) return;
setPurchaseOptions((prevValue) => {
const newValue = { ...prevValue };
newValue.extraParamRequired = true;
newValue.extraData = (previewStuffData && previewStuffData.getValue(1)) || null;
newValue.previewStuffData = previewStuffData;
return newValue;
});
}, [currentOffer, previewStuffData, setPurchaseOptions]);
useEffect(() => {
if (!activate) return;
const id = activate();
return () => deactivate?.(id);
}, [activate, deactivate]);
useEffect(() => {
if (!currentBadgeCode || availableBadgeCodes.includes(currentBadgeCode)) return;
setCurrentBadgeCode(null);
}, [availableBadgeCodes, currentBadgeCode]);
useEffect(() => {
if (!currentBadgeCode || filteredBadgeCodes.includes(currentBadgeCode)) return;
setCurrentBadgeCode(null);
}, [currentBadgeCode, filteredBadgeCodes]);
return (
<NativeTextTree>
<div className={`octane-catalog-badge-selector ${className}`.trim()}>
<div className="octane-catalog-badge-search">
<input
aria-label={LocalizeText('generic.search')}
maxLength={MAX_SEARCH_LENGTH}
placeholder={LocalizeText('generic.search')}
role="searchbox"
type="text"
value={searchText}
onChange={(event) => setSearchText(event.target.value.slice(0, MAX_SEARCH_LENGTH))}
onKeyDown={(event) => {
if (event.key !== 'Escape') return;
event.preventDefault();
setSearchText('');
}}
/>
{!!searchText.length && (
<BaseButton
aria-label={localizeWithFallback('generic.clear', 'Clear')}
className="octane-catalog-badge-search-clear"
type="button"
onClick={() => setSearchText('')}
>
×
</BaseButton>
)}
</div>
<ClassicScrollAreaView className="octane-catalog-badge-scroll-area" scrollStep={45}>
<AutoGrid
aria-label={LocalizeText('catalog_selectbadge')}
className="octane-catalog-badge-grid"
columnCount={columnCount}
columnMinHeight={44}
columnMinWidth={44}
overflow="visible"
role="listbox"
{...rest}
>
{filteredBadgeCodes.map((badgeCode) => (
<LayoutGridItem
key={badgeCode}
aria-label={badgeCode}
aria-selected={currentBadgeCode === badgeCode}
className="octane-catalog-badge-tile"
itemActive={currentBadgeCode === badgeCode}
role="option"
title={LocalizeBadgeName(badgeCode)}
onClick={() => setCurrentBadgeCode(badgeCode)}
>
<LayoutBadgeImageView badgeCode={badgeCode} showInfo />
</LayoutGridItem>
))}
</AutoGrid>
{!filteredBadgeCodes.length && <div className="octane-catalog-badge-empty">{LocalizeText('inventory.empty.title')}</div>}
</ClassicScrollAreaView>
</div>
</NativeTextTree>
);
};
