'use client'; import { useState, useRef, useEffect, useCallback } from 'react'; import { useRouter, useSearchParams } from 'next/navigation'; import Image from 'next/image'; import { appConfig } from '../config/app'; import { SkinId } from '../types'; import { useLocalizedSkinName } from '../hooks/useLocalizedSkinName'; import { ChevronDownIcon } from '@heroicons/react/24/outline'; interface SkinOption { id: SkinId; name: string; image: string; } export function SkinSelector() { const router = useRouter(); const searchParams = useSearchParams(); const getLocalizedSkinName = useLocalizedSkinName(); const [isOpen, setIsOpen] = useState(false); const dropdownRef = useRef(null); const skinOptions: SkinOption[] = Object.entries(appConfig.skins).map(([id, skin]) => ({ id: id as SkinId, name: getLocalizedSkinName(id), image: skin.normal })); const skinParam = searchParams.get('skin'); // Validate that the skin exists in our config const isValidSkin = skinParam && Object.keys(appConfig.skins).includes(skinParam); // Use the skin from URL if valid, otherwise use default skin const currentSkin = (isValidSkin ? skinParam : appConfig.defaultSkin) as SkinId; const currentSkinOption = skinOptions.find(skin => skin.id === currentSkin) || skinOptions[0]; const handleSkinChange = useCallback((newSkin: SkinId) => { const params = new URLSearchParams(searchParams.toString()); if (newSkin === appConfig.defaultSkin) { params.delete('skin'); } else { params.set('skin', newSkin); } const newUrl = `${window.location.pathname}${params.toString() ? '?' + params.toString() : ''}`; router.push(newUrl); setIsOpen(false); }, [router, searchParams]); // Handle clicking outside to close dropdown useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) { setIsOpen(false); } }; if (isOpen) { document.addEventListener('mousedown', handleClickOutside); } return () => { document.removeEventListener('mousedown', handleClickOutside); }; }, [isOpen]); // Handle escape key to close dropdown useEffect(() => { const handleEscape = (event: KeyboardEvent) => { if (event.key === 'Escape') { setIsOpen(false); } }; if (isOpen) { document.addEventListener('keydown', handleEscape); } return () => { document.removeEventListener('keydown', handleEscape); }; }, [isOpen]); const toggleDropdown = () => { setIsOpen(!isOpen); }; return (
{/* Main toggle button */} {/* Dropdown menu */} {isOpen && (
{skinOptions.map((option) => ( ))}
)}
); }