"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" }, }; export const CurrencyProvider = ({ children }) => { const [selectedCurrency, setSelectedCurrency] = useState("INR"); useEffect(() => { const fetchCurrencyForCountry = async () => { try { const userCountry = localStorage.getItem('userCountry'); if (!userCountry) { return; } 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; };