-
-
Notifications
You must be signed in to change notification settings - Fork 843
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
play: implementing currency converter with real-time rate fetching (#…
…1492) *play: implementing currency converter with real-time rate fetching (#1492) * fix(currencyConverter): resolve ui issue with layout
- Loading branch information
1 parent
862d977
commit 68ff1fd
Showing
8 changed files
with
236 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import PlayHeader from 'common/playlists/PlayHeader'; | ||
import { useState } from 'react'; | ||
import InputBox from './InputBox'; | ||
import useCurrencyInfo from './hooks/useCurrencyInfo'; | ||
|
||
// WARNING: Do not change the entry componenet name | ||
function Currencyconverter(props) { | ||
// State for input values | ||
const [from, setFrom] = useState('bdt'); | ||
const [to, setTo] = useState('usd'); | ||
const [amount, setAmount] = useState(0); | ||
const [convertedAmount, setConvertedAmount] = useState(0); | ||
|
||
// Fetch currency info based on 'from' currency | ||
const currencyInfo = useCurrencyInfo(from); | ||
const options = Object.keys(currencyInfo); | ||
|
||
// Function to swap 'from' and 'to' currencies | ||
const swap = () => { | ||
setFrom(to); | ||
setTo(from); | ||
setConvertedAmount(amount); | ||
setAmount(convertedAmount); | ||
}; | ||
|
||
// Function to convert currency | ||
const convert = () => { | ||
setConvertedAmount(amount * currencyInfo[to]); | ||
}; | ||
|
||
return ( | ||
<> | ||
<div className="play-details"> | ||
{/* Play header */} | ||
<PlayHeader play={props} /> | ||
<div className="play-details-body"> | ||
{/* Main Container */} | ||
<div className="w-full flex flex-wrap justify-around items-center"> | ||
<div className="border border-gray-60 rounded-lg p-5 backdrop-blur-sm bg-white/30"> | ||
<form | ||
onSubmit={(e) => { | ||
e.preventDefault(); | ||
convert(); | ||
}} | ||
> | ||
{/* Input box for 'from' currency */} | ||
<div className="w-full mb-1"> | ||
<InputBox | ||
amount={amount} | ||
currencyOptions={options} | ||
label="From" | ||
selectCurrency={from} | ||
onAmountChange={(amount) => setAmount(amount)} | ||
onCurrencyChange={() => setAmount(amount)} | ||
/> | ||
</div> | ||
<div className="relative w-full h-0.5"> | ||
{/* Button to swap 'from' and 'to' currencies */} | ||
<button | ||
className="absolute left-1/2 -translate-x-1/2 -translate-y-1/2 border-2 border-white rounded-md bg-blue-600 text-white px-2 py-0.5" | ||
type="button" | ||
onClick={swap} | ||
> | ||
SWAP | ||
</button> | ||
</div> | ||
<div className="w-full mt-1 mb-4"> | ||
{/* Input box for 'to' currency */} | ||
<InputBox | ||
amountDisable | ||
amount={convertedAmount} | ||
currencyOptions={options} | ||
label="To" | ||
selectCurrency={to} | ||
onCurrencyChange={(currency) => setTo(currency)} | ||
/> | ||
</div> | ||
{/* Button to initiate currency conversion */} | ||
<button | ||
className="w-full bg-blue-600 text-white px-4 py-3 rounded-lg" | ||
type="submit" | ||
> | ||
Convert {from.toUpperCase()} TO {to.toUpperCase()} | ||
</button> | ||
</form> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</> | ||
); | ||
} | ||
|
||
export default Currencyconverter; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import { useId } from 'react'; | ||
|
||
const InputBox = ({ | ||
label, | ||
amount, | ||
onAmountChange, | ||
onCurrencyChange, | ||
currencyOptions = [], | ||
selectCurrency = 'usd', | ||
amountDisable = false, | ||
currencyDisable = false, | ||
className = '' | ||
}) => { | ||
// Generate a unique ID for the input field | ||
const amountInputId = useId(); | ||
|
||
return ( | ||
<div className={`bg-white p-3 rounded-lg text-sm flex ${className}`}> | ||
{/* Input field for the amount */} | ||
<div className="w-1/2"> | ||
<label className="text-black/40 mb-2 inline-block" htmlFor={amountInputId}> | ||
{label} | ||
</label> | ||
<input | ||
className="outline-none w-full bg-transparent py-1.5" | ||
disabled={amountDisable} | ||
id={amountInputId} | ||
placeholder="Amount" | ||
type="number" | ||
value={amount} | ||
onChange={(e) => onAmountChange && onAmountChange(Number(e.target.value))} | ||
/> | ||
</div> | ||
|
||
{/* Currency Selection */} | ||
<div className="w-1/2 flex flex-wrap justify-end text-right"> | ||
<p className="text-black/40 mb-2 w-full">Currency Type</p> | ||
{/* Dropdown for selecting currency */} | ||
<select | ||
className="rounded-lg px-1 py-1 bg-gray-100 cursor-pointer outline-none" | ||
disabled={currencyDisable} | ||
value={selectCurrency} | ||
onChange={(e) => onCurrencyChange && onCurrencyChange(e.target.value)} | ||
> | ||
{/* Mapping through currency options */} | ||
{currencyOptions.map((currency, index) => ( | ||
<option key={index} value={currency}> | ||
{currency} | ||
</option> | ||
))} | ||
</select> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default InputBox; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# currencyConverter | ||
|
||
Develop a web-based currency converter. Users input an amount and select currencies to convert. Real-time exchange rates are fetched via an API. | ||
|
||
## Play Demographic | ||
|
||
- Language: js | ||
- Level: Intermediate | ||
|
||
## Creator Information | ||
|
||
- User: sabbir2809 | ||
- Gihub Link: https://github.com/sabbir2809 | ||
- Blog: | ||
- Video: | ||
|
||
## Implementation Details | ||
|
||
- useState: Keep track of user inputs and app data. | ||
- useEffect: Fetch exchange rates when the app starts or when the user changes currencies. | ||
- Fetch: Get exchange rates from an online service. | ||
- Async/Await: Wait for exchange rate data to be ready before using it. | ||
- API: Special online service providing exchange rates. | ||
- Tailwind: Make your app look nice without hard-coding styles. | ||
- Custom Hooks: Reuse code for common tasks like fetching data. | ||
|
||
## Consideration | ||
|
||
## Resources | ||
|
||
- React Documentation: Learn useState, useEffect, and custom hooks. | ||
- Tailwind CSS Documentation: Style your app with utility classes. | ||
- Async/Await in JavaScript: Handle asynchronous operations. | ||
- API Documentation: Fetch exchange rates from APIs. |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { useEffect, useState } from 'react'; | ||
|
||
// Custom hook to fetch currency information | ||
const useCurrencyInfo = (currency) => { | ||
// State to hold currency data | ||
const [data, setData] = useState({}); | ||
|
||
// Fetch currency data when currency changes | ||
useEffect(() => { | ||
fetch( | ||
`https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@latest/v1/currencies/${currency}.json` | ||
) | ||
.then((response) => { | ||
// If not successful, throw an error | ||
if (!response.ok) { | ||
throw new Error('Failed to fetch currency data'); | ||
} | ||
|
||
// Parse response JSON | ||
return response.json(); | ||
}) | ||
.then(({ [currency]: currencyData }) => setData(currencyData)) | ||
.catch((error) => { | ||
console.error('Error fetching currency data:', error); | ||
}); | ||
}, [currency]); // Dependency array with currency | ||
|
||
// Return currency data | ||
return data; | ||
}; | ||
|
||
export default useCurrencyInfo; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters