Skip to content

Commit 72b5a1f

Browse files
authored
Feat: Realtime Currency Converter Project using API.
1 parent 7b05683 commit 72b5a1f

4 files changed

Lines changed: 386 additions & 0 deletions

File tree

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
export const currency_list = [
2+
"AED",
3+
"AFN",
4+
"ALL",
5+
"AMD",
6+
"ANG",
7+
"AOA",
8+
"ARS",
9+
"AUD",
10+
"AWG",
11+
"AZN",
12+
"BAM",
13+
"BBD",
14+
"BGN",
15+
"BHD",
16+
"BIF",
17+
"BMD",
18+
"BOB",
19+
"BRL",
20+
"BSD",
21+
"BWP",
22+
"BYN",
23+
"BZD",
24+
"CDF",
25+
"CHF",
26+
"CLP",
27+
"CNY",
28+
"COP",
29+
"CRC",
30+
"CUP",
31+
"CZK",
32+
"DJF",
33+
"DKK",
34+
"DOP",
35+
"DZD",
36+
"EGP",
37+
"ERN",
38+
"EUR",
39+
"FJD",
40+
"FKP",
41+
"FOK",
42+
"GBP",
43+
"GEL",
44+
"GGP",
45+
"GHS",
46+
"GIP",
47+
"GMD",
48+
"GNF",
49+
"GTQ",
50+
"GYD",
51+
"HKD",
52+
"HNL",
53+
"HRK",
54+
"HTG",
55+
"HUF",
56+
"IDR",
57+
"ILS",
58+
"IMP",
59+
"INR",
60+
"IQD",
61+
"IRR",
62+
"ISK",
63+
"JEP",
64+
"JMD",
65+
"JOD",
66+
"JPY",
67+
"KES",
68+
"KGS",
69+
"KHR",
70+
"KID",
71+
"KMF",
72+
"KRW",
73+
"KWD",
74+
"KYD",
75+
"KZT",
76+
"LAK",
77+
"LBP",
78+
"LKR",
79+
"LRD",
80+
"LSL",
81+
"LYD",
82+
"MAD",
83+
"MDL",
84+
"MGA",
85+
"MKD",
86+
"MMK",
87+
"MNT",
88+
"MOP",
89+
"MRU",
90+
"MUR",
91+
"MVR",
92+
"MWK",
93+
"MXN",
94+
"MYR",
95+
"MZN",
96+
"NAD",
97+
"NGN",
98+
"NIO",
99+
"NOK",
100+
"NPR",
101+
"NZD",
102+
"OMR",
103+
"PAB",
104+
"PGK",
105+
"PHP",
106+
"PKR",
107+
"PLN",
108+
"PYG",
109+
"QAR",
110+
"RON",
111+
"RSD",
112+
"RUB",
113+
"RWF",
114+
"SAR",
115+
"SBD",
116+
"SCR",
117+
"SDG",
118+
"SEK",
119+
"SGD",
120+
"SHP",
121+
"SLE",
122+
"SLL",
123+
"SOS",
124+
"SRD",
125+
"SSP",
126+
"STN",
127+
"SYP",
128+
"SZL",
129+
"THB",
130+
"TJS",
131+
"TMT",
132+
"TND",
133+
"TOP",
134+
"TRY",
135+
"TTD",
136+
"TVD",
137+
"TWD",
138+
"TZS",
139+
"UAH",
140+
"UGX",
141+
"USD",
142+
"UYU",
143+
"UZS",
144+
"VES",
145+
"VND",
146+
"VUV",
147+
"WST",
148+
"XAF",
149+
"XCD",
150+
"XOF",
151+
"XPF",
152+
"YER",
153+
"ZAR",
154+
"ZMW",
155+
"ZWL"
156+
];
157+
158+
export const api = "7643a9379eac5ef74dfef2d6";
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
7+
<title>Realtime Currency Converter</title>
8+
<!-- CSS File -->
9+
<link rel="stylesheet" href="./style.css">
10+
</head>
11+
<body>
12+
13+
<div class="container">
14+
<h1 id="title">Realtime Currency Converter</h1>
15+
<img src="./coinExchangeSticker.png" id="coinSticker" alt="coin exchange sticker">
16+
17+
<input type="number" id="userValue" min="1" name="userInput" placeholder="100">
18+
19+
<div class="selecterContainer">
20+
<select id="fromCurrency" name="fromCurrency" title="Convert From"></select>
21+
22+
<button type="button" id="switchCurrency">🔁</button>
23+
24+
<select id="toCurrency" name="toCurrency" title="Convert To"></select>
25+
</div>
26+
27+
<p id="status"></p>
28+
29+
<button type="button" id="btn">Convert</button>
30+
31+
<p id="result"></p>
32+
</div>
33+
34+
<!-- JavaScript File -->
35+
<script type="module" src="./script.js" defer></script>
36+
</body>
37+
</html>
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// importing currency codes list and API Key
2+
import { currency_list, api } from "./currencyCodes.js";
3+
4+
const fromCurrencySelectTag = document.querySelector("#fromCurrency");
5+
const toCurrencySelectTag = document.querySelector("#toCurrency");
6+
const resultTag = document.querySelector("#result");
7+
const btn = document.querySelector("#btn");
8+
const status = document.querySelector("#status");
9+
10+
// append the curreny codes list to the list and select defaults
11+
currency_list.forEach((code) => {
12+
const newElement = document.createElement("option");
13+
newElement.value = code;
14+
newElement.textContent = code;
15+
16+
if (code === "USD")
17+
newElement.selected = true;
18+
19+
fromCurrencySelectTag.append(newElement);
20+
21+
const newElementTo = newElement.cloneNode(true);
22+
23+
if (code === "INR")
24+
newElementTo.selected = true;
25+
26+
toCurrencySelectTag.append(newElementTo);
27+
});
28+
29+
// Swap currency on "click"
30+
document.getElementById("switchCurrency").onclick = () => {
31+
32+
const fromValue = fromCurrencySelectTag.value;
33+
fromCurrencySelectTag.value = toCurrencySelectTag.value;
34+
toCurrencySelectTag.value = fromValue;
35+
36+
};
37+
38+
// handle "click" event for conversion
39+
btn.onclick = () => {
40+
41+
const numberInputField = document.getElementById("userValue");
42+
const userEnteredAmount = numberInputField.value;
43+
44+
if(userEnteredAmount < 1 || isNaN(userEnteredAmount)) {
45+
numberInputField.style.border = "1px solid red";
46+
resultTag.style.color = "red";
47+
resultTag.textContent = "Error: Only numeric values greater than 0 are allowed.";
48+
}
49+
else {
50+
numberInputField.style.border = "1px solid gray";
51+
resultTag.style.color = "black";
52+
btn.textContent = "Processing: have patients...";
53+
54+
btn.disabled = true;
55+
btn.style.color = "gray";
56+
btn.style.cursor = "not-allowed";
57+
58+
convertAmount(userEnteredAmount);
59+
}
60+
}
61+
62+
// convert the amount to different currency using Fetch API
63+
function convertAmount(amount) {
64+
65+
fetchData(`https://v6.exchangerate-api.com/v6/${api}/latest/USD`)
66+
.then(data => {
67+
68+
const fromRates = data.conversion_rates[fromCurrencySelectTag.value];
69+
const toRates = data.conversion_rates[toCurrencySelectTag.value];
70+
71+
const perRate = (1 * (toRates / fromRates)).toFixed(2);
72+
const convertedAmount = (amount * (toRates / fromRates)).toFixed(2);
73+
74+
resultTag.style.color = "black";
75+
status.textContent = `1 ${fromCurrencySelectTag.value} = ${perRate} ${toCurrencySelectTag.value}`;
76+
resultTag.textContent = `${amount} ${fromCurrencySelectTag.value} = ${convertedAmount} ${toCurrencySelectTag.value}`;
77+
78+
btn.disabled = false;
79+
btn.style.color = "black";
80+
btn.style.cursor = "pointer";
81+
btn.textContent = "Convert";
82+
})
83+
.catch(error => console.log(`Additional information about error: ${error}`));
84+
}
85+
86+
// Fetch API Data with proper validation
87+
async function fetchData(url) {
88+
89+
try {
90+
const response = await fetch(url);
91+
92+
if (!response.ok)
93+
throw new Error(`HTTP error! Status: ${response.status}`);
94+
95+
const data = await response.json();
96+
return data;
97+
}
98+
catch (error) {
99+
resultTag.style.color = "red";
100+
resultTag.textContent = `Fetch API Error: ${error}`;
101+
102+
throw error;
103+
}
104+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
* {
2+
margin: 0;
3+
padding: 0;
4+
box-sizing: border-box;
5+
font-family:'Trebuchet MS', Arial, sans-serif;
6+
}
7+
body {
8+
height: 100vh;
9+
background-color: rgb(77, 223, 231);
10+
display: grid;
11+
place-items: center;
12+
overflow: hidden;
13+
}
14+
.container {
15+
width: 300px;
16+
border-radius: 6px;
17+
padding: 8px;
18+
background-color: white;
19+
}
20+
#title {
21+
text-align: center;
22+
padding: 4px 0;
23+
border-bottom: 1px solid black;
24+
}
25+
#coinSticker {
26+
width: 100px;
27+
height: 100px;
28+
display: block;
29+
margin: auto;
30+
}
31+
#userValue {
32+
display: block;
33+
width: 100%;
34+
padding: 10px 8px;
35+
margin: 12px 0;
36+
border-radius: 4px;
37+
border: 1px solid gray;
38+
outline: transparent;
39+
font-family: monospace;
40+
}
41+
.selecterContainer {
42+
display: flex;
43+
justify-content: space-between;
44+
align-items: center;
45+
padding: 4px 0;
46+
}
47+
.selecterContainer select {
48+
padding: 2px;
49+
border-radius: 4px;
50+
outline: transparent;
51+
}
52+
#switchCurrency {
53+
font-size: 22px;
54+
border: 0;
55+
outline: transparent;
56+
}
57+
#status {
58+
text-align: center;
59+
font-size: 14px;
60+
margin-top: 12px;
61+
color: rgb(143, 132, 132);
62+
text-transform: capitalize;
63+
}
64+
#btn {
65+
width: 100%;
66+
background-color: rgb(77, 223, 231);
67+
border: none;
68+
border-radius: 6px;
69+
padding: 12px 16px;
70+
margin: 12px 0;
71+
font-size: 16px;
72+
font-weight: bold;
73+
letter-spacing: 0.8px;
74+
cursor: pointer;
75+
transition: box-shadow 0.2s, transform 0.14s;
76+
}
77+
#btn:hover {
78+
box-shadow: 0 0 0 2px #fff, 0 0 0 4px rgb(77, 223, 231);
79+
}
80+
#result {
81+
width: 100%;
82+
padding: 12px 16px;
83+
font-weight: 550;
84+
text-align: center;
85+
border-radius: 6px;
86+
background-color: rgba(77, 223, 231, 0.3);
87+
}

0 commit comments

Comments
 (0)