Skip to content

Commit

Permalink
play: implementing currency converter with real-time rate fetching (#…
Browse files Browse the repository at this point in the history
…1492)

*play: implementing currency converter with real-time rate fetching (#1492)

* fix(currencyConverter): resolve ui issue with layout
  • Loading branch information
Sabbir2809 authored May 9, 2024
1 parent 862d977 commit 68ff1fd
Show file tree
Hide file tree
Showing 8 changed files with 236 additions and 18 deletions.
2 changes: 1 addition & 1 deletion src/common/search/search.css
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@
}
}

@media screen and (max-width:494px) {
@media screen and (max-width: 494px) {
.filter {
display: grid;
justify-content: center;
Expand Down
94 changes: 94 additions & 0 deletions src/plays/currencyconverter/Currencyconverter.js
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;
57 changes: 57 additions & 0 deletions src/plays/currencyconverter/InputBox.jsx
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;
34 changes: 34 additions & 0 deletions src/plays/currencyconverter/Readme.md
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.
Binary file added src/plays/currencyconverter/cover.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 32 additions & 0 deletions src/plays/currencyconverter/hooks/useCurrencyInfo.jsx
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;
8 changes: 4 additions & 4 deletions src/plays/language-translater/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ Language Translator is a web application built with React.js that allows users t

- User: Venkat-3010
- Gihub Link: https://github.com/Venkat-3010
- Blog:
- Video:
- Blog:
- Video:

## Implementation Details

Expand All @@ -31,12 +31,12 @@ The `Language Translator` is implemented with below steps.
- Translate button: Initiates the translation using `Fetch API`.
- Copy button: uses `clipboard` to copy the input and translated text.
- Listen button: Reads out the the input and translated text using `SpeechSynthesisUtterance`.
- Language Switch: Allows users to swap the source and target languages.
- Language Switch: Allows users to swap the source and target languages.

## Consideration

Update all considerations(if any)

## Resources

API source: https://mymemory.translated.net/
API source: https://mymemory.translated.net/
27 changes: 14 additions & 13 deletions src/plays/language-translater/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -115,17 +115,18 @@
}

@media (max-width: 1024px) {
.Language-Translator_body{
font-size: small;
}
.Language-Translator_container{
flex-direction: column;
align-items: center;
margin: 0;
}

.Language-Translator_sourceLang, .Language-Translator_targetLang{
width: 80vw;
height: 60%;
}
.Language-Translator_body {
font-size: small;
}
.Language-Translator_container {
flex-direction: column;
align-items: center;
margin: 0;
}

.Language-Translator_sourceLang,
.Language-Translator_targetLang {
width: 80vw;
height: 60%;
}
}

0 comments on commit 68ff1fd

Please sign in to comment.