import { FC, useCallback, useEffect, useRef, useState } from 'react'; import { FaPlus } from 'react-icons/fa'; import { LayoutBadgeImageView } from '../../../../../common'; import { useInventoryBadges } from '../../../../../hooks'; interface InfoStandBadgeSlotProps { slotIndex: number; badgeCode?: string; isOwnUser: boolean; } const BadgeMiniPicker: FC<{ onSelect: (badgeCode: string) => void; onClose: () => void; activeBadgeCodes: string[]; }> = ({ onSelect, onClose, activeBadgeCodes }) => { const { badgeCodes = [], requestBadges = null } = useInventoryBadges(); const ref = useRef(null); const [ search, setSearch ] = useState(''); useEffect(() => { if(badgeCodes.length === 0) requestBadges(); }, []); const availableBadges = badgeCodes.filter(code => !activeBadgeCodes.includes(code)); const filtered = search.length > 0 ? availableBadges.filter(code => code.toLowerCase().includes(search.toLowerCase())) : availableBadges; useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if(ref.current && !ref.current.contains(event.target as Node)) onClose(); }; document.addEventListener('mousedown', handleClickOutside); return () => document.removeEventListener('mousedown', handleClickOutside); }, [ onClose ]); return (
e.stopPropagation() }> setSearch(e.target.value) } /> { badgeCodes.length === 0 ? Caricamento... : (
{ filtered.slice(0, 40).map(code => (
onSelect(code) }>
)) } { filtered.length === 0 && ( Nessun badge ) }
) }
); }; export const InfoStandBadgeSlotView: FC = ({ slotIndex, badgeCode: badgeCodeFromProps, isOwnUser }) => { const { activeBadgeCodes = [], setBadgeAtSlot = null, swapBadges = null } = useInventoryBadges(); const [ isDragOver, setIsDragOver ] = useState(false); const [ showPicker, setShowPicker ] = useState(false); // For own user: use hook data if loaded, otherwise fall back to props (avatarInfo) // For other users: always use props const hookBadge = activeBadgeCodes.length > 0 ? (activeBadgeCodes[slotIndex] ?? null) : null; const badgeCode = isOwnUser ? (hookBadge ?? badgeCodeFromProps ?? null) : (badgeCodeFromProps ?? null); const onDragStart = useCallback((event: React.DragEvent) => { if(!badgeCode || !isOwnUser) return; event.dataTransfer.setData('badgeCode', badgeCode); event.dataTransfer.setData('infostandSlot', slotIndex.toString()); event.dataTransfer.effectAllowed = 'move'; }, [ badgeCode, slotIndex, isOwnUser ]); const onDragOver = useCallback((event: React.DragEvent) => { if(!isOwnUser) return; event.preventDefault(); event.dataTransfer.dropEffect = 'move'; setIsDragOver(true); }, [ isOwnUser ]); const onDragLeave = useCallback(() => setIsDragOver(false), []); const onDrop = useCallback((event: React.DragEvent) => { event.preventDefault(); setIsDragOver(false); if(!isOwnUser) return; const droppedBadgeCode = event.dataTransfer.getData('badgeCode'); const sourceSlotStr = event.dataTransfer.getData('infostandSlot'); if(!droppedBadgeCode) return; if(sourceSlotStr !== '') { // Dragged from another infostand slot -> always swap (works with empty slots too) const sourceSlot = parseInt(sourceSlotStr); if(sourceSlot !== slotIndex) swapBadges(sourceSlot, slotIndex); } else { // Dragged from inventory or external -> place at this slot setBadgeAtSlot(droppedBadgeCode, slotIndex); } }, [ isOwnUser, slotIndex, swapBadges, setBadgeAtSlot ]); const handleSlotClick = useCallback(() => { if(!isOwnUser || badgeCode) return; setShowPicker(true); }, [ isOwnUser, badgeCode ]); const handlePickerSelect = useCallback((code: string) => { setBadgeAtSlot(code, slotIndex); setShowPicker(false); }, [ setBadgeAtSlot, slotIndex ]); return (
{ badgeCode ? : isOwnUser && }
{ showPicker && ( setShowPicker(false) } onSelect={ handlePickerSelect } /> ) }
); };