refactor: set country based on user data
This commit is contained in:
@@ -13,11 +13,99 @@ export const SUPPORTED_CURRENCIES = {
|
||||
|
||||
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);
|
||||
@@ -25,7 +113,6 @@ export const CurrencyProvider = ({ children }) => {
|
||||
|
||||
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);
|
||||
@@ -33,40 +120,22 @@ export const CurrencyProvider = ({ children }) => {
|
||||
}
|
||||
|
||||
try {
|
||||
const currencies = Object.keys(SUPPORTED_CURRENCIES)
|
||||
.filter((key) => key !== "INR")
|
||||
.join(",");
|
||||
|
||||
const response = await axios.get("https://apilayer.net/api/live", {
|
||||
params: {
|
||||
access_key: "9bcb30907dee1cda9866f7b49f0f8def",
|
||||
currencies: currencies,
|
||||
source: "INR",
|
||||
format: 1,
|
||||
},
|
||||
});
|
||||
|
||||
const response = await axios.get(`https://open.er-api.com/v6/latest/${selectedCurrency}`);
|
||||
const data = response.data;
|
||||
|
||||
if (!data.success) {
|
||||
throw new Error(data.error?.info || "API request failed");
|
||||
if (!data.rates) {
|
||||
throw new Error("API request failed - no rates returned");
|
||||
}
|
||||
|
||||
const rates = Object.keys(SUPPORTED_CURRENCIES).reduce(
|
||||
(acc, currency) => {
|
||||
if (currency === "INR") {
|
||||
acc[currency] = 1;
|
||||
} else {
|
||||
const rate = data.quotes?.[`INR${currency}`];
|
||||
if (!rate) {
|
||||
throw new Error(`Rate not found for ${currency}`);
|
||||
}
|
||||
acc[currency] = rate;
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{}
|
||||
);
|
||||
|
||||
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",
|
||||
@@ -94,6 +163,7 @@ export const CurrencyProvider = ({ children }) => {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const convertPrice = (price) => {
|
||||
if (!price || typeof price !== "number") return price;
|
||||
if (!exchangeRates || !exchangeRates[selectedCurrency]) return price;
|
||||
@@ -112,7 +182,7 @@ export const CurrencyProvider = ({ children }) => {
|
||||
const convertedPrice = convertPrice(price);
|
||||
|
||||
if (typeof convertedPrice !== "number")
|
||||
return `${SUPPORTED_CURRENCIES[selectedCurrency].symbol}0.00`;
|
||||
return `${SUPPORTED_CURRENCIES[selectedCurrency]?.symbol || "$"}0.00`;
|
||||
|
||||
try {
|
||||
return new Intl.NumberFormat(getLocaleFromCurrency(selectedCurrency), {
|
||||
@@ -121,7 +191,7 @@ export const CurrencyProvider = ({ children }) => {
|
||||
}).format(convertedPrice);
|
||||
} catch (err) {
|
||||
return `${
|
||||
SUPPORTED_CURRENCIES[selectedCurrency].symbol
|
||||
SUPPORTED_CURRENCIES[selectedCurrency]?.symbol || "$"
|
||||
}${convertedPrice.toFixed(2)}`;
|
||||
}
|
||||
};
|
||||
@@ -129,18 +199,58 @@ export const CurrencyProvider = ({ children }) => {
|
||||
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,
|
||||
@@ -150,6 +260,9 @@ export const CurrencyProvider = ({ children }) => {
|
||||
error,
|
||||
SUPPORTED_CURRENCIES,
|
||||
refreshRates: fetchExchangeRates,
|
||||
allCountries,
|
||||
setUserCountry,
|
||||
userCountry
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -158,10 +271,11 @@ export const CurrencyProvider = ({ children }) => {
|
||||
</CurrencyContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const useCurrency = () => {
|
||||
const context = useContext(CurrencyContext);
|
||||
if (!context) {
|
||||
throw new Error('useCurrency must be used within a CurrencyProvider');
|
||||
}
|
||||
return context;
|
||||
};
|
||||
const context = useContext(CurrencyContext);
|
||||
if (!context) {
|
||||
throw new Error('useCurrency must be used within a CurrencyProvider');
|
||||
}
|
||||
return context;
|
||||
};
|
||||
|
||||
@@ -27,6 +27,7 @@ export const ContextProvider = ({ children }) => {
|
||||
console.log("Login Successful:", response.data);
|
||||
setToken(response.data.token)
|
||||
localStorage.setItem('token', response.data.token)
|
||||
localStorage.setItem('userCountry', response.data.country)
|
||||
toast.success('Login Successful');
|
||||
router.push('/')
|
||||
|
||||
|
||||
Reference in New Issue
Block a user