Files
rudarksh-frontend/app/contexts/currencyContext.js

356 lines
14 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"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 (
<CurrencyContext.Provider value={value}>
{children}
</CurrencyContext.Provider>
);
};
export const useCurrency = () => {
const context = useContext(CurrencyContext);
if (!context) {
throw new Error('useCurrency must be used within a CurrencyProvider');
}
return context;
};