Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(currency-convertor): add multi-currency support #1490

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions src/plays/currencyconvertor/Currency-convertor.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import PlayHeader from 'common/playlists/PlayHeader';
import { useState } from 'react';
import InputBox from './InputBox';
import useCurrencyInfo from './hooks/useCurrencyInfo';
import './styles.css';

function Currencyconvertor(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 h-screen flex flex-wrap justify-center items-center bg-cover bg-no-repeat bg-img">
<div className="w-full">
<div className="w-full max-w-md mx-auto 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>
</div>
</>
);
}

export default Currencyconvertor;
57 changes: 57 additions & 0 deletions src/plays/currencyconvertor/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;
27 changes: 27 additions & 0 deletions src/plays/currencyconvertor/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# currency-convertor

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: Beginner

## Creator Information

- User: sabbir2809
- Gihub Link: https://github.com/sabbir2809
- Blog: NA
- Video: NA

## Implementation Details

N/A

## Consideration

N/A

## Resources

N/A
Binary file added src/plays/currencyconvertor/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/currencyconvertor/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;
3 changes: 3 additions & 0 deletions src/plays/currencyconvertor/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.bg-img {
background-image: url('cover.png');
}
Loading