131 lines
5.1 KiB
JavaScript
131 lines
5.1 KiB
JavaScript
import React, { useState, useEffect } from 'react';
|
|
import { ChevronDown, AlertCircle, Search } from 'lucide-react';
|
|
|
|
const CurrencySelect = ({ selectedCurrency, setSelectedCurrency, SUPPORTED_CURRENCIES, error }) => {
|
|
const [isOpen, setIsOpen] = useState(false);
|
|
const [isMobile, setIsMobile] = useState(false);
|
|
const [selectedCurrencyName, setSelectedCurrencyName] = useState('');
|
|
const [searchTerm, setSearchTerm] = useState('');
|
|
const [filteredCurrencies, setFilteredCurrencies] = useState([]);
|
|
|
|
useEffect(() => {
|
|
const savedCurrency = localStorage.getItem('selectedCurrency');
|
|
if (savedCurrency && SUPPORTED_CURRENCIES[savedCurrency]) {
|
|
setSelectedCurrency(savedCurrency);
|
|
}
|
|
|
|
setSelectedCurrencyName(SUPPORTED_CURRENCIES[selectedCurrency]?.country || '');
|
|
|
|
const checkMobile = () => {
|
|
setIsMobile(window.innerWidth < 768);
|
|
};
|
|
|
|
checkMobile();
|
|
window.addEventListener('resize', checkMobile);
|
|
|
|
return () => window.removeEventListener('resize', checkMobile);
|
|
}, [SUPPORTED_CURRENCIES, setSelectedCurrency]);
|
|
|
|
useEffect(() => {
|
|
setSelectedCurrencyName(SUPPORTED_CURRENCIES[selectedCurrency]?.country || '');
|
|
}, [selectedCurrency, SUPPORTED_CURRENCIES]);
|
|
|
|
useEffect(() => {
|
|
if (isOpen) {
|
|
const filtered = Object.entries(SUPPORTED_CURRENCIES).filter(([code, details]) => {
|
|
const searchLower = searchTerm.toLowerCase();
|
|
return (
|
|
code.toLowerCase().includes(searchLower) ||
|
|
details.name.toLowerCase().includes(searchLower) ||
|
|
details.country.toLowerCase().includes(searchLower)
|
|
);
|
|
});
|
|
setFilteredCurrencies(filtered);
|
|
}
|
|
}, [searchTerm, SUPPORTED_CURRENCIES, isOpen]);
|
|
|
|
const handleCurrencyChange = (code) => {
|
|
localStorage.setItem('selectedCurrency', code);
|
|
|
|
setSelectedCurrency(code);
|
|
setSelectedCurrencyName(SUPPORTED_CURRENCIES[code]?.country || '');
|
|
setIsOpen(false);
|
|
setSearchTerm('');
|
|
};
|
|
|
|
return (
|
|
<div className="relative w-auto md:w-32">
|
|
<button
|
|
onClick={() => setIsOpen(!isOpen)}
|
|
className={`w-full px-2 md:px-4 py-2 md:py-2.5 bg-white border border-gray-200 rounded-lg shadow-sm
|
|
flex items-center justify-between text-sm font-medium
|
|
hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-500
|
|
transition-all duration-200 group
|
|
${error && selectedCurrency !== 'INR' ? 'text-amber-600' : 'text-gray-700'}`}
|
|
>
|
|
{isMobile ? (
|
|
<span className="text-base font-medium">
|
|
{SUPPORTED_CURRENCIES[selectedCurrency]?.symbol || ''}
|
|
{error && selectedCurrency !== 'INR' && (
|
|
<AlertCircle className="inline ml-1 w-3 h-3" />
|
|
)}
|
|
</span>
|
|
) : (
|
|
<>
|
|
{SUPPORTED_CURRENCIES[selectedCurrency]?.country || selectedCurrency}
|
|
{error && selectedCurrency !== 'INR' && (
|
|
<AlertCircle className="inline ml-1 w-3 h-3" />
|
|
)}
|
|
</>
|
|
)}
|
|
<ChevronDown
|
|
className={`w-4 h-4 ml-1 text-gray-400 transition-transform duration-200
|
|
${isOpen ? 'rotate-180' : ''} group-hover:text-gray-600`}
|
|
/>
|
|
</button>
|
|
|
|
{isOpen && (
|
|
<div
|
|
className="absolute right-0 w-64 mt-2 bg-white border border-gray-200 rounded-lg shadow-lg
|
|
overflow-hidden z-50 animate-in fade-in slide-in-from-top-2 duration-200"
|
|
>
|
|
<div className="p-2 border-b">
|
|
<div className="relative">
|
|
<Search className="absolute left-2 top-2.5 h-4 w-4 text-gray-400" />
|
|
<input
|
|
type="text"
|
|
placeholder="Search currencies..."
|
|
value={searchTerm}
|
|
onChange={(e) => setSearchTerm(e.target.value)}
|
|
className="w-full pl-8 pr-4 py-2 text-sm border border-gray-200 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="max-h-60 overflow-auto scrollbar-thin scrollbar-thumb-gray-200 hover:scrollbar-thumb-gray-300">
|
|
{filteredCurrencies.length > 0 ? (
|
|
filteredCurrencies.map(([code, { country, symbol, name }]) => (
|
|
<button
|
|
key={code}
|
|
onClick={() => handleCurrencyChange(code)}
|
|
className={`w-full px-4 py-2.5 text-left text-sm transition-colors duration-150
|
|
hover:bg-gray-50 focus:outline-none focus:bg-gray-50
|
|
${selectedCurrency === code ? 'bg-blue-50 text-blue-600 font-medium' : 'text-gray-700'}
|
|
${selectedCurrency === code ? 'hover:bg-blue-50' : 'hover:bg-gray-50'}`}
|
|
>
|
|
<span className="mr-2">{symbol}</span>
|
|
<span className="font-medium">{code}</span> - {name}
|
|
<div className="text-xs text-gray-500">{country}</div>
|
|
</button>
|
|
))
|
|
) : (
|
|
<div className="p-4 text-center text-gray-500">No currencies found</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default CurrencySelect; |