// Currency Switcher configuration types and constants export interface Currency { id: string code: string name: string symbol: string rate: number rateType: 'fixed' | 'auto' fee: number feeType: 'fixed' | 'percentage' flagCode: string decimals: number thousandSeparator: string decimalSeparator: string position: 'left' | 'right' | 'left_space' | 'right_space' isDefault: boolean enabled: boolean roundingType: 'none' | 'up' | 'down' | 'nearest' roundingValue: number isWooCommerceDefault?: boolean } export interface SwitcherStyle { id: string name: string description: string preview: string isPro?: boolean alwaysVisible?: boolean } export interface ShortcodeSettings { showFlags: boolean showCurrencyName: boolean showCurrencyCode: boolean showCurrencySymbol: boolean layout: 'dropdown' | 'buttons' | 'list' flagStyle: 'circle' | 'square' | 'rounded' flagSize: 'small' | 'medium' | 'large' fontSize: string borderRadius: string backgroundColor: string textColor: string borderColor: string hoverBackgroundColor: string hoverTextColor: string dropdownWidth: string alignment: 'left' | 'center' | 'right' } export interface AdvancedSettings { autoUpdateRates: boolean updateInterval: 'hourly' | 'daily' | 'weekly' exchangeRateApi: 'exchangerate-api' | 'openexchangerates' | 'currencylayer' | 'fixer' apiKey: string priceRounding: boolean cacheEnabled: boolean cacheDuration: number excludeProducts: number[] excludeCategories: number[] priceFormat: 'converted' | 'both' | 'original_converted' cookieDuration: number } export interface AutoCurrencySettings { enabled: boolean detectionMethod: 'ip' | 'browser' | 'both' fallbackCurrency: string geoIpProvider: 'ipapi' | 'maxmind' | 'ip2location' geoApiKey: string countryMapping: Record respectUserChoice: boolean rememberDuration: number testMode: boolean testCountry: string } export interface CustomizationSettings { selectedPreset: string mobileBreakpoint: number showOnMobile: boolean mobileLayout: 'dropdown' | 'modal' | 'bottom-sheet' animationType: 'none' | 'fade' | 'slide' | 'scale' animationDuration: number zIndex: number } export interface CurrencySwitcherSettings { enabled: boolean defaultCurrency: string currencies: Currency[] shortcode: ShortcodeSettings advanced: AdvancedSettings autoCurrency: AutoCurrencySettings customization: CustomizationSettings } // Complete list of all WooCommerce-supported world currencies with flag codes // Based on WooCommerce's get_woocommerce_currencies() function export const commonCurrencies: Omit[] = [ // Major World Currencies { code: 'USD', name: 'US Dollar', symbol: '$', flagCode: 'us', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'EUR', name: 'Euro', symbol: '€', flagCode: 'eu', decimals: 2, thousandSeparator: '.', decimalSeparator: ',', position: 'left' }, { code: 'GBP', name: 'British Pound', symbol: '£', flagCode: 'gb', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'JPY', name: 'Japanese Yen', symbol: '¥', flagCode: 'jp', decimals: 0, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'AUD', name: 'Australian Dollar', symbol: 'A$', flagCode: 'au', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'CAD', name: 'Canadian Dollar', symbol: 'C$', flagCode: 'ca', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'CHF', name: 'Swiss Franc', symbol: 'CHF', flagCode: 'ch', decimals: 2, thousandSeparator: "'", decimalSeparator: '.', position: 'left' }, { code: 'CNY', name: 'Chinese Yuan', symbol: '¥', flagCode: 'cn', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'INR', name: 'Indian Rupee', symbol: '₹', flagCode: 'in', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, // Americas { code: 'ARS', name: 'Argentine Peso', symbol: '$', flagCode: 'ar', decimals: 2, thousandSeparator: '.', decimalSeparator: ',', position: 'left' }, { code: 'BOB', name: 'Bolivian Boliviano', symbol: 'Bs.', flagCode: 'bo', decimals: 2, thousandSeparator: '.', decimalSeparator: ',', position: 'left' }, { code: 'BRL', name: 'Brazilian Real', symbol: 'R$', flagCode: 'br', decimals: 2, thousandSeparator: '.', decimalSeparator: ',', position: 'left' }, { code: 'BSD', name: 'Bahamian Dollar', symbol: '$', flagCode: 'bs', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'BZD', name: 'Belize Dollar', symbol: 'BZ$', flagCode: 'bz', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'CLP', name: 'Chilean Peso', symbol: '$', flagCode: 'cl', decimals: 0, thousandSeparator: '.', decimalSeparator: ',', position: 'left' }, { code: 'COP', name: 'Colombian Peso', symbol: '$', flagCode: 'co', decimals: 0, thousandSeparator: '.', decimalSeparator: ',', position: 'left' }, { code: 'CRC', name: 'Costa Rican Colón', symbol: '₡', flagCode: 'cr', decimals: 2, thousandSeparator: '.', decimalSeparator: ',', position: 'left' }, { code: 'CUC', name: 'Cuban Convertible Peso', symbol: 'CUC$', flagCode: 'cu', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'CUP', name: 'Cuban Peso', symbol: '$MN', flagCode: 'cu', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'DOP', name: 'Dominican Peso', symbol: 'RD$', flagCode: 'do', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'GTQ', name: 'Guatemalan Quetzal', symbol: 'Q', flagCode: 'gt', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'GYD', name: 'Guyanese Dollar', symbol: '$', flagCode: 'gy', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'HNL', name: 'Honduran Lempira', symbol: 'L', flagCode: 'hn', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'HTG', name: 'Haitian Gourde', symbol: 'G', flagCode: 'ht', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'JMD', name: 'Jamaican Dollar', symbol: 'J$', flagCode: 'jm', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'MXN', name: 'Mexican Peso', symbol: 'MX$', flagCode: 'mx', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'NIO', name: 'Nicaraguan Córdoba', symbol: 'C$', flagCode: 'ni', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'PAB', name: 'Panamanian Balboa', symbol: 'B/.', flagCode: 'pa', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'PEN', name: 'Peruvian Sol', symbol: 'S/', flagCode: 'pe', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'PYG', name: 'Paraguayan Guaraní', symbol: '₲', flagCode: 'py', decimals: 0, thousandSeparator: '.', decimalSeparator: ',', position: 'left' }, { code: 'SRD', name: 'Surinamese Dollar', symbol: '$', flagCode: 'sr', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'TTD', name: 'Trinidad & Tobago Dollar', symbol: 'TT$', flagCode: 'tt', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'UYU', name: 'Uruguayan Peso', symbol: '$U', flagCode: 'uy', decimals: 2, thousandSeparator: '.', decimalSeparator: ',', position: 'left' }, { code: 'VES', name: 'Venezuelan Bolívar', symbol: 'Bs.S', flagCode: 've', decimals: 2, thousandSeparator: '.', decimalSeparator: ',', position: 'left' }, // Europe { code: 'ALL', name: 'Albanian Lek', symbol: 'L', flagCode: 'al', decimals: 2, thousandSeparator: ' ', decimalSeparator: ',', position: 'right' }, { code: 'AMD', name: 'Armenian Dram', symbol: '֏', flagCode: 'am', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'right' }, { code: 'AZN', name: 'Azerbaijani Manat', symbol: '₼', flagCode: 'az', decimals: 2, thousandSeparator: ' ', decimalSeparator: ',', position: 'right' }, { code: 'BAM', name: 'Bosnia-Herzegovina Mark', symbol: 'KM', flagCode: 'ba', decimals: 2, thousandSeparator: '.', decimalSeparator: ',', position: 'right' }, { code: 'BGN', name: 'Bulgarian Lev', symbol: 'лв.', flagCode: 'bg', decimals: 2, thousandSeparator: ' ', decimalSeparator: ',', position: 'right' }, { code: 'BYN', name: 'Belarusian Ruble', symbol: 'Br', flagCode: 'by', decimals: 2, thousandSeparator: ' ', decimalSeparator: ',', position: 'right' }, { code: 'CZK', name: 'Czech Koruna', symbol: 'Kč', flagCode: 'cz', decimals: 2, thousandSeparator: ' ', decimalSeparator: ',', position: 'right_space' }, { code: 'DKK', name: 'Danish Krone', symbol: 'kr', flagCode: 'dk', decimals: 2, thousandSeparator: '.', decimalSeparator: ',', position: 'right_space' }, { code: 'GEL', name: 'Georgian Lari', symbol: '₾', flagCode: 'ge', decimals: 2, thousandSeparator: ' ', decimalSeparator: ',', position: 'right' }, { code: 'HRK', name: 'Croatian Kuna', symbol: 'kn', flagCode: 'hr', decimals: 2, thousandSeparator: '.', decimalSeparator: ',', position: 'right_space' }, { code: 'HUF', name: 'Hungarian Forint', symbol: 'Ft', flagCode: 'hu', decimals: 0, thousandSeparator: ' ', decimalSeparator: ',', position: 'right_space' }, { code: 'ISK', name: 'Icelandic Króna', symbol: 'kr', flagCode: 'is', decimals: 0, thousandSeparator: '.', decimalSeparator: ',', position: 'right_space' }, { code: 'MDL', name: 'Moldovan Leu', symbol: 'L', flagCode: 'md', decimals: 2, thousandSeparator: ' ', decimalSeparator: ',', position: 'right' }, { code: 'MKD', name: 'Macedonian Denar', symbol: 'ден', flagCode: 'mk', decimals: 2, thousandSeparator: '.', decimalSeparator: ',', position: 'right' }, { code: 'NOK', name: 'Norwegian Krone', symbol: 'kr', flagCode: 'no', decimals: 2, thousandSeparator: ' ', decimalSeparator: ',', position: 'right_space' }, { code: 'PLN', name: 'Polish Zloty', symbol: 'zł', flagCode: 'pl', decimals: 2, thousandSeparator: ' ', decimalSeparator: ',', position: 'right_space' }, { code: 'RON', name: 'Romanian Leu', symbol: 'lei', flagCode: 'ro', decimals: 2, thousandSeparator: '.', decimalSeparator: ',', position: 'right_space' }, { code: 'RSD', name: 'Serbian Dinar', symbol: 'дин.', flagCode: 'rs', decimals: 2, thousandSeparator: '.', decimalSeparator: ',', position: 'right' }, { code: 'RUB', name: 'Russian Ruble', symbol: '₽', flagCode: 'ru', decimals: 2, thousandSeparator: ' ', decimalSeparator: ',', position: 'right_space' }, { code: 'SEK', name: 'Swedish Krona', symbol: 'kr', flagCode: 'se', decimals: 2, thousandSeparator: ' ', decimalSeparator: ',', position: 'right_space' }, { code: 'TRY', name: 'Turkish Lira', symbol: '₺', flagCode: 'tr', decimals: 2, thousandSeparator: '.', decimalSeparator: ',', position: 'left' }, { code: 'UAH', name: 'Ukrainian Hryvnia', symbol: '₴', flagCode: 'ua', decimals: 2, thousandSeparator: ' ', decimalSeparator: ',', position: 'right' }, // Asia & Pacific { code: 'AFN', name: 'Afghan Afghani', symbol: '؋', flagCode: 'af', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'BDT', name: 'Bangladeshi Taka', symbol: '৳', flagCode: 'bd', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'BND', name: 'Brunei Dollar', symbol: '$', flagCode: 'bn', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'BTN', name: 'Bhutanese Ngultrum', symbol: 'Nu.', flagCode: 'bt', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'FJD', name: 'Fijian Dollar', symbol: '$', flagCode: 'fj', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'HKD', name: 'Hong Kong Dollar', symbol: 'HK$', flagCode: 'hk', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'IDR', name: 'Indonesian Rupiah', symbol: 'Rp', flagCode: 'id', decimals: 0, thousandSeparator: '.', decimalSeparator: ',', position: 'left' }, { code: 'KGS', name: 'Kyrgyzstani Som', symbol: 'с', flagCode: 'kg', decimals: 2, thousandSeparator: ' ', decimalSeparator: ',', position: 'right' }, { code: 'KHR', name: 'Cambodian Riel', symbol: '៛', flagCode: 'kh', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'right' }, { code: 'KPW', name: 'North Korean Won', symbol: '₩', flagCode: 'kp', decimals: 0, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'KRW', name: 'South Korean Won', symbol: '₩', flagCode: 'kr', decimals: 0, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'KZT', name: 'Kazakhstani Tenge', symbol: '₸', flagCode: 'kz', decimals: 2, thousandSeparator: ' ', decimalSeparator: ',', position: 'right' }, { code: 'LAK', name: 'Lao Kip', symbol: '₭', flagCode: 'la', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'LKR', name: 'Sri Lankan Rupee', symbol: 'Rs', flagCode: 'lk', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'MMK', name: 'Myanmar Kyat', symbol: 'K', flagCode: 'mm', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'MNT', name: 'Mongolian Tugrik', symbol: '₮', flagCode: 'mn', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'MOP', name: 'Macanese Pataca', symbol: 'MOP$', flagCode: 'mo', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'MVR', name: 'Maldivian Rufiyaa', symbol: 'Rf', flagCode: 'mv', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'MYR', name: 'Malaysian Ringgit', symbol: 'RM', flagCode: 'my', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'NPR', name: 'Nepalese Rupee', symbol: 'Rs', flagCode: 'np', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'NZD', name: 'New Zealand Dollar', symbol: 'NZ$', flagCode: 'nz', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'PGK', name: 'Papua New Guinean Kina', symbol: 'K', flagCode: 'pg', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'PHP', name: 'Philippine Peso', symbol: '₱', flagCode: 'ph', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'PKR', name: 'Pakistani Rupee', symbol: 'Rs', flagCode: 'pk', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'SGD', name: 'Singapore Dollar', symbol: 'S$', flagCode: 'sg', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'THB', name: 'Thai Baht', symbol: '฿', flagCode: 'th', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'TJS', name: 'Tajikistani Somoni', symbol: 'SM', flagCode: 'tj', decimals: 2, thousandSeparator: ' ', decimalSeparator: ',', position: 'right' }, { code: 'TMT', name: 'Turkmenistani Manat', symbol: 'm', flagCode: 'tm', decimals: 2, thousandSeparator: ' ', decimalSeparator: ',', position: 'right' }, { code: 'TWD', name: 'New Taiwan Dollar', symbol: 'NT$', flagCode: 'tw', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'UZS', name: 'Uzbekistani Som', symbol: 'сўм', flagCode: 'uz', decimals: 2, thousandSeparator: ' ', decimalSeparator: ',', position: 'right' }, { code: 'VND', name: 'Vietnamese Dong', symbol: '₫', flagCode: 'vn', decimals: 0, thousandSeparator: '.', decimalSeparator: ',', position: 'right' }, { code: 'WST', name: 'Samoan Tala', symbol: 'T', flagCode: 'ws', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, // Middle East { code: 'AED', name: 'UAE Dirham', symbol: 'د.إ', flagCode: 'ae', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'right' }, { code: 'BHD', name: 'Bahraini Dinar', symbol: '.د.ب', flagCode: 'bh', decimals: 3, thousandSeparator: ',', decimalSeparator: '.', position: 'right' }, { code: 'ILS', name: 'Israeli New Shekel', symbol: '₪', flagCode: 'il', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'IQD', name: 'Iraqi Dinar', symbol: 'ع.د', flagCode: 'iq', decimals: 3, thousandSeparator: ',', decimalSeparator: '.', position: 'right' }, { code: 'IRR', name: 'Iranian Rial', symbol: '﷼', flagCode: 'ir', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'right' }, { code: 'JOD', name: 'Jordanian Dinar', symbol: 'د.ا', flagCode: 'jo', decimals: 3, thousandSeparator: ',', decimalSeparator: '.', position: 'right' }, { code: 'KWD', name: 'Kuwaiti Dinar', symbol: 'د.ك', flagCode: 'kw', decimals: 3, thousandSeparator: ',', decimalSeparator: '.', position: 'right' }, { code: 'LBP', name: 'Lebanese Pound', symbol: 'ل.ل', flagCode: 'lb', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'right' }, { code: 'OMR', name: 'Omani Rial', symbol: 'ر.ع.', flagCode: 'om', decimals: 3, thousandSeparator: ',', decimalSeparator: '.', position: 'right' }, { code: 'QAR', name: 'Qatari Rial', symbol: 'ر.ق', flagCode: 'qa', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'right' }, { code: 'SAR', name: 'Saudi Riyal', symbol: 'ر.س', flagCode: 'sa', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'right' }, { code: 'SYP', name: 'Syrian Pound', symbol: 'ل.س', flagCode: 'sy', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'right' }, { code: 'YER', name: 'Yemeni Rial', symbol: '﷼', flagCode: 'ye', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'right' }, // Africa { code: 'AOA', name: 'Angolan Kwanza', symbol: 'Kz', flagCode: 'ao', decimals: 2, thousandSeparator: ' ', decimalSeparator: ',', position: 'right' }, { code: 'BWP', name: 'Botswanan Pula', symbol: 'P', flagCode: 'bw', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'CDF', name: 'Congolese Franc', symbol: 'FC', flagCode: 'cd', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'right' }, { code: 'DZD', name: 'Algerian Dinar', symbol: 'د.ج', flagCode: 'dz', decimals: 2, thousandSeparator: ' ', decimalSeparator: ',', position: 'right' }, { code: 'EGP', name: 'Egyptian Pound', symbol: 'E£', flagCode: 'eg', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'ETB', name: 'Ethiopian Birr', symbol: 'Br', flagCode: 'et', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'GHS', name: 'Ghanaian Cedi', symbol: 'GH₵', flagCode: 'gh', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'GMD', name: 'Gambian Dalasi', symbol: 'D', flagCode: 'gm', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'GNF', name: 'Guinean Franc', symbol: 'FG', flagCode: 'gn', decimals: 0, thousandSeparator: ',', decimalSeparator: '.', position: 'right' }, { code: 'KES', name: 'Kenyan Shilling', symbol: 'KSh', flagCode: 'ke', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'LYD', name: 'Libyan Dinar', symbol: 'ل.د', flagCode: 'ly', decimals: 3, thousandSeparator: ',', decimalSeparator: '.', position: 'right' }, { code: 'MAD', name: 'Moroccan Dirham', symbol: 'د.م.', flagCode: 'ma', decimals: 2, thousandSeparator: ' ', decimalSeparator: ',', position: 'right' }, { code: 'MGA', name: 'Malagasy Ariary', symbol: 'Ar', flagCode: 'mg', decimals: 2, thousandSeparator: ' ', decimalSeparator: ',', position: 'left' }, { code: 'MRU', name: 'Mauritanian Ouguiya', symbol: 'UM', flagCode: 'mr', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'right' }, { code: 'MUR', name: 'Mauritian Rupee', symbol: 'Rs', flagCode: 'mu', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'MWK', name: 'Malawian Kwacha', symbol: 'MK', flagCode: 'mw', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'MZN', name: 'Mozambican Metical', symbol: 'MT', flagCode: 'mz', decimals: 2, thousandSeparator: ' ', decimalSeparator: ',', position: 'right' }, { code: 'NAD', name: 'Namibian Dollar', symbol: 'N$', flagCode: 'na', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'NGN', name: 'Nigerian Naira', symbol: '₦', flagCode: 'ng', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'RWF', name: 'Rwandan Franc', symbol: 'FRw', flagCode: 'rw', decimals: 0, thousandSeparator: ' ', decimalSeparator: ',', position: 'right' }, { code: 'SCR', name: 'Seychellois Rupee', symbol: 'Rs', flagCode: 'sc', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'SDG', name: 'Sudanese Pound', symbol: 'ج.س', flagCode: 'sd', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'right' }, { code: 'SOS', name: 'Somali Shilling', symbol: 'Sh', flagCode: 'so', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'SSP', name: 'South Sudanese Pound', symbol: '£', flagCode: 'ss', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'STN', name: 'São Tomé & Príncipe Dobra', symbol: 'Db', flagCode: 'st', decimals: 2, thousandSeparator: ' ', decimalSeparator: ',', position: 'right' }, { code: 'SZL', name: 'Swazi Lilangeni', symbol: 'E', flagCode: 'sz', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'TND', name: 'Tunisian Dinar', symbol: 'د.ت', flagCode: 'tn', decimals: 3, thousandSeparator: ' ', decimalSeparator: ',', position: 'right' }, { code: 'TZS', name: 'Tanzanian Shilling', symbol: 'TSh', flagCode: 'tz', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'UGX', name: 'Ugandan Shilling', symbol: 'USh', flagCode: 'ug', decimals: 0, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'XAF', name: 'Central African CFA Franc', symbol: 'FCFA', flagCode: 'cm', decimals: 0, thousandSeparator: ' ', decimalSeparator: ',', position: 'right' }, { code: 'XOF', name: 'West African CFA Franc', symbol: 'CFA', flagCode: 'sn', decimals: 0, thousandSeparator: ' ', decimalSeparator: ',', position: 'right' }, { code: 'ZAR', name: 'South African Rand', symbol: 'R', flagCode: 'za', decimals: 2, thousandSeparator: ' ', decimalSeparator: ',', position: 'left' }, { code: 'ZMW', name: 'Zambian Kwacha', symbol: 'ZK', flagCode: 'zm', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'ZWL', name: 'Zimbabwean Dollar', symbol: 'Z$', flagCode: 'zw', decimals: 2, thousandSeparator: ' ', decimalSeparator: ',', position: 'left' }, // Caribbean & Other Islands { code: 'AWG', name: 'Aruban Florin', symbol: 'ƒ', flagCode: 'aw', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'BBD', name: 'Barbadian Dollar', symbol: 'Bds$', flagCode: 'bb', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'BMD', name: 'Bermudian Dollar', symbol: '$', flagCode: 'bm', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'KYD', name: 'Cayman Islands Dollar', symbol: 'CI$', flagCode: 'ky', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'XCD', name: 'East Caribbean Dollar', symbol: 'EC$', flagCode: 'ag', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'ANG', name: 'Netherlands Antillean Guilder', symbol: 'ƒ', flagCode: 'cw', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left' }, { code: 'XPF', name: 'CFP Franc', symbol: '₣', flagCode: 'pf', decimals: 0, thousandSeparator: ' ', decimalSeparator: ',', position: 'right' }, ] // Switcher preset styles export const switcherPresets: SwitcherStyle[] = [ { id: 'default', name: 'Default', description: 'Balanced storefront control', preview: '/assets/presets/default.png', }, { id: 'minimal', name: 'Minimal', description: 'Quiet borderless control', preview: '/assets/presets/minimal.png', }, { id: 'flags-only', name: 'Flags Only', description: 'Compact visual choices', preview: '/assets/presets/flags-only.png', }, { id: 'pill', name: 'Pill Style', description: 'Rounded pill-shaped buttons', preview: '/assets/presets/pill.png', isPro: true, }, { id: 'modern', name: 'Modern', description: 'Contemporary design with shadows', preview: '/assets/presets/modern.png', isPro: true, }, { id: 'classic', name: 'Classic', description: 'Traditional bordered select', preview: '/assets/presets/classic.png', isPro: true, }, { id: 'custom', name: 'Custom', description: 'Use your saved design controls', preview: '/assets/presets/custom.png', isPro: true, alwaysVisible: true, }, ] // Exchange rate update intervals export const updateIntervalOptions = [ { value: 'hourly', label: 'Every Hour' }, { value: 'daily', label: 'Once Daily' }, { value: 'weekly', label: 'Once Weekly' }, ] // Exchange rate API providers export const exchangeRateProviders = [ { value: 'exchangerate-api', label: 'ExchangeRate-API', requiresKey: false }, { value: 'openexchangerates', label: 'Open Exchange Rates', requiresKey: true }, { value: 'currencylayer', label: 'CurrencyLayer', requiresKey: true }, { value: 'fixer', label: 'Fixer.io', requiresKey: true }, ] // GeoIP providers export const geoIpProviders = [ { value: 'ipapi', label: 'IP-API (Free)', requiresKey: false }, { value: 'maxmind', label: 'MaxMind GeoIP2', requiresKey: true }, { value: 'ip2location', label: 'IP2Location', requiresKey: true }, ] // Flag sizes export const flagSizeOptions = [ { value: 'small', label: 'Small (16px)', size: 16 }, { value: 'medium', label: 'Medium (24px)', size: 24 }, { value: 'large', label: 'Large (32px)', size: 32 }, ] // Layout options export const layoutOptions = [ { value: 'dropdown', label: 'Dropdown Select' }, { value: 'buttons', label: 'Button Group' }, { value: 'list', label: 'Vertical List' }, ] // Flag styles export const flagStyleOptions = [ { value: 'circle', label: 'Circle' }, { value: 'square', label: 'Square' }, { value: 'rounded', label: 'Rounded' }, ] // Mobile layouts export const mobileLayoutOptions = [ { value: 'dropdown', label: 'Dropdown' }, { value: 'modal', label: 'Full Modal' }, { value: 'bottom-sheet', label: 'Bottom Sheet' }, ] // Animation types export const animationOptions = [ { value: 'none', label: 'None' }, { value: 'fade', label: 'Fade' }, { value: 'slide', label: 'Slide' }, { value: 'scale', label: 'Scale' }, ] // Default settings export const defaultCurrencySwitcherSettings: CurrencySwitcherSettings = { enabled: false, defaultCurrency: 'USD', currencies: [ { id: 'usd', code: 'USD', name: 'US Dollar', symbol: '$', rate: 1, rateType: 'fixed', fee: 0, feeType: 'fixed', flagCode: 'us', decimals: 2, thousandSeparator: ',', decimalSeparator: '.', position: 'left', isDefault: true, enabled: true, roundingType: 'none', roundingValue: 0, }, ], shortcode: { showFlags: true, showCurrencyName: true, showCurrencyCode: true, showCurrencySymbol: true, layout: 'dropdown', flagStyle: 'circle', flagSize: 'medium', fontSize: '14px', borderRadius: '6px', backgroundColor: '#ffffff', textColor: '#1f2937', borderColor: '#e5e7eb', hoverBackgroundColor: '#f3f4f6', hoverTextColor: '#111827', dropdownWidth: '200px', alignment: 'left', }, advanced: { autoUpdateRates: false, updateInterval: 'daily', exchangeRateApi: 'exchangerate-api', apiKey: '', priceRounding: true, cacheEnabled: true, cacheDuration: 3600, excludeProducts: [], excludeCategories: [], priceFormat: 'converted', cookieDuration: 30, }, autoCurrency: { enabled: false, detectionMethod: 'ip', fallbackCurrency: 'USD', geoIpProvider: 'ipapi', geoApiKey: '', countryMapping: {}, respectUserChoice: true, rememberDuration: 30, testMode: false, testCountry: '', }, customization: { selectedPreset: 'default', mobileBreakpoint: 768, showOnMobile: true, mobileLayout: 'dropdown', animationType: 'fade', animationDuration: 200, zIndex: 1000, }, } // Generate a unique ID export function generateCurrencyId(): string { return `currency_${Date.now()}_${Math.random().toString(36).substr(2, 9)}` } // Format price with currency export function formatPrice( amount: number, currency: Currency ): string { const formattedNumber = amount .toFixed(currency.decimals) .replace('.', currency.decimalSeparator) .replace(/\B(?=(\d{3})+(?!\d))/g, currency.thousandSeparator) switch (currency.position) { case 'left': return `${currency.symbol}${formattedNumber}` case 'right': return `${formattedNumber}${currency.symbol}` case 'left_space': return `${currency.symbol} ${formattedNumber}` case 'right_space': return `${formattedNumber} ${currency.symbol}` default: return `${currency.symbol}${formattedNumber}` } } // Convert price between currencies export function convertPrice( amount: number, fromCurrency: Currency, toCurrency: Currency ): number { // Convert to base (default) currency first, then to target const baseAmount = amount / fromCurrency.rate let convertedAmount = baseAmount * toCurrency.rate // Apply fee if any if (toCurrency.fee > 0) { if (toCurrency.feeType === 'percentage') { convertedAmount += convertedAmount * (toCurrency.fee / 100) } else { convertedAmount += toCurrency.fee } } // Apply rounding if (toCurrency.roundingType !== 'none') { const roundingValue = toCurrency.roundingValue || 1 switch (toCurrency.roundingType) { case 'up': convertedAmount = Math.ceil(convertedAmount / roundingValue) * roundingValue break case 'down': convertedAmount = Math.floor(convertedAmount / roundingValue) * roundingValue break case 'nearest': convertedAmount = Math.round(convertedAmount / roundingValue) * roundingValue break } } return convertedAmount } // Common countries for currency mapping export interface Country { code: string name: string flagCode: string } export const commonCountries: Country[] = [ { code: 'US', name: 'United States', flagCode: 'us' }, { code: 'GB', name: 'United Kingdom', flagCode: 'gb' }, { code: 'CA', name: 'Canada', flagCode: 'ca' }, { code: 'AU', name: 'Australia', flagCode: 'au' }, { code: 'DE', name: 'Germany', flagCode: 'de' }, { code: 'FR', name: 'France', flagCode: 'fr' }, { code: 'IT', name: 'Italy', flagCode: 'it' }, { code: 'ES', name: 'Spain', flagCode: 'es' }, { code: 'NL', name: 'Netherlands', flagCode: 'nl' }, { code: 'BE', name: 'Belgium', flagCode: 'be' }, { code: 'AT', name: 'Austria', flagCode: 'at' }, { code: 'PT', name: 'Portugal', flagCode: 'pt' }, { code: 'IE', name: 'Ireland', flagCode: 'ie' }, { code: 'FI', name: 'Finland', flagCode: 'fi' }, { code: 'GR', name: 'Greece', flagCode: 'gr' }, { code: 'SE', name: 'Sweden', flagCode: 'se' }, { code: 'NO', name: 'Norway', flagCode: 'no' }, { code: 'DK', name: 'Denmark', flagCode: 'dk' }, { code: 'CH', name: 'Switzerland', flagCode: 'ch' }, { code: 'PL', name: 'Poland', flagCode: 'pl' }, { code: 'CZ', name: 'Czech Republic', flagCode: 'cz' }, { code: 'HU', name: 'Hungary', flagCode: 'hu' }, { code: 'RO', name: 'Romania', flagCode: 'ro' }, { code: 'BG', name: 'Bulgaria', flagCode: 'bg' }, { code: 'HR', name: 'Croatia', flagCode: 'hr' }, { code: 'SK', name: 'Slovakia', flagCode: 'sk' }, { code: 'SI', name: 'Slovenia', flagCode: 'si' }, { code: 'LT', name: 'Lithuania', flagCode: 'lt' }, { code: 'LV', name: 'Latvia', flagCode: 'lv' }, { code: 'EE', name: 'Estonia', flagCode: 'ee' }, { code: 'JP', name: 'Japan', flagCode: 'jp' }, { code: 'CN', name: 'China', flagCode: 'cn' }, { code: 'KR', name: 'South Korea', flagCode: 'kr' }, { code: 'IN', name: 'India', flagCode: 'in' }, { code: 'SG', name: 'Singapore', flagCode: 'sg' }, { code: 'HK', name: 'Hong Kong', flagCode: 'hk' }, { code: 'TW', name: 'Taiwan', flagCode: 'tw' }, { code: 'MY', name: 'Malaysia', flagCode: 'my' }, { code: 'TH', name: 'Thailand', flagCode: 'th' }, { code: 'ID', name: 'Indonesia', flagCode: 'id' }, { code: 'PH', name: 'Philippines', flagCode: 'ph' }, { code: 'VN', name: 'Vietnam', flagCode: 'vn' }, { code: 'NZ', name: 'New Zealand', flagCode: 'nz' }, { code: 'MX', name: 'Mexico', flagCode: 'mx' }, { code: 'BR', name: 'Brazil', flagCode: 'br' }, { code: 'AR', name: 'Argentina', flagCode: 'ar' }, { code: 'CL', name: 'Chile', flagCode: 'cl' }, { code: 'CO', name: 'Colombia', flagCode: 'co' }, { code: 'PE', name: 'Peru', flagCode: 'pe' }, { code: 'ZA', name: 'South Africa', flagCode: 'za' }, { code: 'AE', name: 'United Arab Emirates', flagCode: 'ae' }, { code: 'SA', name: 'Saudi Arabia', flagCode: 'sa' }, { code: 'IL', name: 'Israel', flagCode: 'il' }, { code: 'TR', name: 'Turkey', flagCode: 'tr' }, { code: 'RU', name: 'Russia', flagCode: 'ru' }, { code: 'UA', name: 'Ukraine', flagCode: 'ua' }, { code: 'EG', name: 'Egypt', flagCode: 'eg' }, { code: 'NG', name: 'Nigeria', flagCode: 'ng' }, { code: 'KE', name: 'Kenya', flagCode: 'ke' }, { code: 'PK', name: 'Pakistan', flagCode: 'pk' }, { code: 'BD', name: 'Bangladesh', flagCode: 'bd' }, ] // Flag URL helper - uses bundled local flags for reliability // Flags are stored in assets/img/flags/{code}.png at 24x18 size declare const swiftCommerceData: { pluginUrl: string } | undefined export function getFlagUrl(flagCode: string): string { // In admin context, use local bundled flags if (typeof swiftCommerceData !== 'undefined' && swiftCommerceData.pluginUrl) { return `${swiftCommerceData.pluginUrl}assets/img/flags/${flagCode.toLowerCase()}.png` } // Fallback to CDN if plugin URL not available (should not happen in practice) return `https://flagcdn.com/24x18/${flagCode.toLowerCase()}.png` }