"use client"; import React, { createContext, useContext, useState, useEffect } from "react"; import axios from 'axios'; const CurrencyContext = createContext(); export const SUPPORTED_CURRENCIES = { INR: { symbol: "₹", name: "Indian Rupee", country: "India" }, MYR: { symbol: "RM", name: "Malaysian Ringgit", country: "Malaysia" }, NPR: { symbol: "रू", name: "Nepalese Rupee", country: "Nepal" }, ERN: { symbol: "Nfk", name: "Eritrean nakfa", country: "Eritrea" }, XAF: { symbol: "Fr", name: "Central African CFA franc", country: "Cameroon" }, EUR: { symbol: "€", name: "Euro", country: "Montenegro" }, FJD: { symbol: "$", name: "Fijian dollar", country: "Fiji" }, TND: { symbol: "د.ت", name: "Tunisian dinar", country: "Tunisia" }, XOF: { symbol: "Fr", name: "West African CFA franc", country: "Senegal" }, GBP: { symbol: "£", name: "British pound", country: "South Georgia" }, BRL: { symbol: "R$", name: "Brazilian real", country: "Brazil" }, CHF: { symbol: "Fr", name: "Swiss franc", country: "Liechtenstein" }, MXN: { symbol: "$", name: "Mexican peso", country: "Mexico" }, EGP: { symbol: "E£", name: "Egyptian pound", country: "Palestine" }, DKK: { symbol: "kr.", name: "krone", country: "Greenland" }, USD: { symbol: "$", name: "United States dollar", country: "United States Minor Outlying Islands" }, TRY: { symbol: "₺", name: "Turkish lira", country: "Turkey" }, HNL: { symbol: "L", name: "Honduran lempira", country: "Honduras" }, RON: { symbol: "lei", name: "Romanian leu", country: "Romania" }, NAD: { symbol: "$", name: "Namibian dollar", country: "Namibia" }, RWF: { symbol: "Fr", name: "Rwandan franc", country: "Rwanda" }, XCD: { symbol: "$", name: "Eastern Caribbean dollar", country: "Saint Vincent and the Grenadines" }, BGN: { symbol: "лв", name: "Bulgarian lev", country: "Bulgaria" }, COP: { symbol: "$", name: "Colombian peso", country: "Colombia" }, SRD: { symbol: "$", name: "Surinamese dollar", country: "Suriname" }, ZWL: { symbol: "$", name: "Zimbabwean dollar", country: "Zimbabwe" }, VES: { symbol: "Bs.S.", name: "Venezuelan bolívar soberano", country: "Venezuela" }, SZL: { symbol: "L", name: "Swazi lilangeni", country: "Eswatini" }, PHP: { symbol: "₱", name: "Philippine peso", country: "Philippines" }, TMT: { symbol: "m", name: "Turkmenistan manat", country: "Turkmenistan" }, DZD: { symbol: "د.ج", name: "Algerian dinar", country: "Algeria" }, JMD: { symbol: "$", name: "Jamaican dollar", country: "Jamaica" }, AMD: { symbol: "֏", name: "Armenian dram", country: "Armenia" }, SBD: { symbol: "$", name: "Solomon Islands dollar", country: "Solomon Islands" }, CUC: { symbol: "$", name: "Cuban convertible peso", country: "Cuba" }, LRD: { symbol: "$", name: "Liberian dollar", country: "Liberia" }, SDG: { symbol: "ج.س", name: "Sudanese pound", country: "Sudan" }, TZS: { symbol: "Sh", name: "Tanzanian shilling", country: "Tanzania" }, BZD: { symbol: "$", name: "Belize dollar", country: "Belize" }, BBD: { symbol: "$", name: "Barbadian dollar", country: "Barbados" }, LBP: { symbol: "ل.ل", name: "Lebanese pound", country: "Lebanon" }, MDL: { symbol: "L", name: "Moldovan leu", country: "Moldova" }, TWD: { symbol: "$", name: "New Taiwan dollar", country: "Taiwan" }, VND: { symbol: "₫", name: "Vietnamese đồng", country: "Vietnam" }, XPF: { symbol: "₣", name: "CFP franc", country: "French Polynesia" }, NZD: { symbol: "$", name: "New Zealand dollar", country: "Tokelau" }, UGX: { symbol: "Sh", name: "Ugandan shilling", country: "Uganda" }, ANG: { symbol: "ƒ", name: "Netherlands Antillean guilder", country: "Sint Maarten" }, KZT: { symbol: "₸", name: "Kazakhstani tenge", country: "Kazakhstan" }, SSP: { symbol: "£", name: "South Sudanese pound", country: "South Sudan" }, TJS: { symbol: "ЅМ", name: "Tajikistani somoni", country: "Tajikistan" }, CVE: { symbol: "Esc", name: "Cape Verdean escudo", country: "Cape Verde" }, MVR: { symbol: ".ރ", name: "Maldivian rufiyaa", country: "Maldives" }, YER: { symbol: "﷼", name: "Yemeni rial", country: "Yemen" }, KPW: { symbol: "₩", name: "North Korean won", country: "North Korea" }, GEL: { symbol: "₾", name: "lari", country: "Georgia" }, UZS: { symbol: "so'm", name: "Uzbekistani soʻm", country: "Uzbekistan" }, DOP: { symbol: "$", name: "Dominican peso", country: "Dominican Republic" }, MZN: { symbol: "MT", name: "Mozambican metical", country: "Mozambique" }, THB: { symbol: "฿", name: "Thai baht", country: "Thailand" }, ILS: { symbol: "₪", name: "Israeli new shekel", country: "Israel" }, FKP: { symbol: "£", name: "Falkland Islands pound", country: "Falkland Islands" }, IDR: { symbol: "Rp", name: "Indonesian rupiah", country: "Indonesia" }, PGK: { symbol: "K", name: "Papua New Guinean kina", country: "Papua New Guinea" }, BHD: { symbol: ".د.ب", name: "Bahraini dinar", country: "Bahrain" }, MOP: { symbol: "P", name: "Macanese pataca", country: "Macau" }, SYP: { symbol: "£", name: "Syrian pound", country: "Syria" }, PLN: { symbol: "zł", name: "Polish złoty", country: "Poland" }, ZMW: { symbol: "ZK", name: "Zambian kwacha", country: "Zambia" }, AUD: { symbol: "$", name: "Australian dollar", country: "Kiribati" }, PEN: { symbol: "S/ ", name: "Peruvian sol", country: "Peru" }, UYU: { symbol: "$", name: "Uruguayan peso", country: "Uruguay" }, IRR: { symbol: "﷼", name: "Iranian rial", country: "Iran" }, HUF: { symbol: "Ft", name: "Hungarian forint", country: "Hungary" }, WST: { symbol: "T", name: "Samoan tālā", country: "Samoa" }, NGN: { symbol: "₦", name: "Nigerian naira", country: "Nigeria" }, IQD: { symbol: "ع.د", name: "Iraqi dinar", country: "Iraq" }, KWD: { symbol: "د.ك", name: "Kuwaiti dinar", country: "Kuwait" }, CZK: { symbol: "Kč", name: "Czech koruna", country: "Czechia" }, MAD: { symbol: "د.م.", name: "Moroccan dirham", country: "Morocco" } }; export const CurrencyProvider = ({ children }) => { const [selectedCurrency, setSelectedCurrency] = useState("INR"); useEffect(() => { const fetchCurrencyForCountry = async () => { try { let userCountry = localStorage.getItem('userCountry') || "India"; const response = await axios.get(`https://restcountries.com/v3.1/name/${userCountry}`); if (response.data && response.data.length > 0) { const countryData = response.data[0]; if (countryData.currencies) { const currencyCode = Object.keys(countryData.currencies)[0]; if (currencyCode) { setSelectedCurrency(currencyCode); } } } } catch (error) { console.error("Error fetching currency for country:", error); setSelectedCurrency("INR") } }; fetchCurrencyForCountry(); }, []); const [exchangeRates, setExchangeRates] = useState(null); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); const [userCountry, setUserCountry] = useState(null); const [allCountries, setAllCountries] = useState([]); const [countryCurrencyMap, setCountryCurrencyMap] = useState({}); // Fetch all countries and their currencies const fetchCountriesAndCurrencies = async () => { try { // First, get the list of countries const countriesResponse = await fetch('https://countriesnow.space/api/v0.1/countries/'); const countriesData = await countriesResponse.json(); if (!countriesData.error) { setAllCountries(countriesData.data); const currencyResponse = await fetch('https://restcountries.com/v3.1/all?fields=name,currencies'); const currencyData = await currencyResponse.json(); const currencyMap = {}; const currencyDetails = {}; currencyData.forEach(country => { const countryName = country.name.common; if (country.currencies) { const currencyCode = Object.keys(country.currencies)[0]; if (currencyCode) { currencyMap[countryName] = currencyCode; if (!currencyDetails[currencyCode]) { const currencyInfo = country.currencies[currencyCode]; currencyDetails[currencyCode] = { symbol: currencyInfo.symbol || currencyCode, name: currencyInfo.name || `${currencyCode} Currency`, country: countryName }; } } } }); Object.keys(currencyDetails).forEach(code => { if (!SUPPORTED_CURRENCIES[code]) { SUPPORTED_CURRENCIES[code] = currencyDetails[code]; } }); setCountryCurrencyMap(currencyMap); // Check if we have a stored country and set the currency accordingly const storedCountry = localStorage.getItem('userCountry'); if (storedCountry && currencyMap[storedCountry]) { const currencyCode = currencyMap[storedCountry]; if (currencyCode) { setSelectedCurrency(currencyCode); localStorage.setItem('selectedCurrency', currencyCode); } } } } catch (error) { console.error("Error fetching countries and currencies:", error); } }; const fetchExchangeRates = async () => { try { setIsLoading(true); setError(null); const cachedData = localStorage.getItem("exchangeRates"); const cached = cachedData ? JSON.parse(cachedData) : null; if (cached && new Date().getTime() - cached.timestamp < 24 * 60 * 60 * 1000) { setExchangeRates(cached.rates); setIsLoading(false); return; } try { const response = await axios.get(`https://open.er-api.com/v6/latest/${selectedCurrency}`); const data = response.data; if (!data.rates) { throw new Error("API request failed - no rates returned"); } const rates = {}; rates["INR"] = 1; // Base currency Object.keys(SUPPORTED_CURRENCIES).forEach(currencyCode => { if (currencyCode !== "INR" && data.rates[currencyCode]) { rates[currencyCode] = data.rates[currencyCode]; } }); localStorage.setItem( "exchangeRates", JSON.stringify({ rates, timestamp: new Date().getTime() }) ); setExchangeRates(rates); } catch (error) { console.error("Error fetching exchange rates:", error); setError("Failed to load currency conversion rates. Please try again later."); if (cached) { console.log("Using older cached rates as fallback"); setExchangeRates(cached.rates); } else { setExchangeRates(null); } } setIsLoading(false); } catch (error) { console.error("Error in exchange rate handling:", error); setError("Failed to load currency conversion rates"); setIsLoading(false); } }; const convertPrice = (price) => { if (!price || typeof price !== "number") return price; if (!exchangeRates || !exchangeRates[selectedCurrency]) return price; if (selectedCurrency === "INR") return price; try { const rate = exchangeRates[selectedCurrency]; return rate ? Number((price * rate).toFixed(2)) : price; } catch (err) { console.error("Price conversion error:", err); return price; } }; const formatPrice = (price) => { const convertedPrice = convertPrice(price); if (typeof convertedPrice !== "number") return `${SUPPORTED_CURRENCIES[selectedCurrency]?.symbol || "$"}0.00`; try { return new Intl.NumberFormat(getLocaleFromCurrency(selectedCurrency), { style: "currency", currency: selectedCurrency, }).format(convertedPrice); } catch (err) { return `${ SUPPORTED_CURRENCIES[selectedCurrency]?.symbol || "$" }${convertedPrice.toFixed(2)}`; } }; const getLocaleFromCurrency = (currency) => { const localeMap = { INR: "en-IN", USD: "en-US", GBP: "en-GB", EUR: "de-DE", JPY: "ja-JP", AUD: "en-AU", CAD: "en-CA", SGD: "en-SG", MYR: "ms-MY", NPR: "ne-NP", IDR: "id-ID", THB: "th-TH", PHP: "fil-PH", VND: "vi-VN", KRW: "ko-KR", }; return localeMap[currency] || "en-US"; }; const setUserCurrencyFromCountry = (country) => { if (country && countryCurrencyMap[country]) { const currencyCode = countryCurrencyMap[country]; if (currencyCode && SUPPORTED_CURRENCIES[currencyCode]) { setSelectedCurrency(currencyCode); localStorage.setItem('selectedCurrency', currencyCode); } } }; useEffect(() => { const storedCountry = localStorage.getItem('userCountry'); if (storedCountry) { setUserCountry(storedCountry); } fetchCountriesAndCurrencies(); fetchExchangeRates(); const savedCurrency = localStorage.getItem('selectedCurrency'); if (savedCurrency && SUPPORTED_CURRENCIES[savedCurrency]) { setSelectedCurrency(savedCurrency); } const interval = setInterval(fetchExchangeRates, 24 * 60 * 60 * 1000); return () => clearInterval(interval); }, []); useEffect(() => { if (userCountry && countryCurrencyMap[userCountry]) { setUserCurrencyFromCountry(userCountry); } }, [userCountry, countryCurrencyMap]); const value = { selectedCurrency, setSelectedCurrency, convertPrice, formatPrice, isLoading, error, SUPPORTED_CURRENCIES, refreshRates: fetchExchangeRates, allCountries, setUserCountry, userCountry }; return ( {children} ); }; export const useCurrency = () => { const context = useContext(CurrencyContext); if (!context) { throw new Error('useCurrency must be used within a CurrencyProvider'); } return context; };