-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
frontend feat: complete react frontend
- Loading branch information
Showing
6 changed files
with
173 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,15 @@ | ||
import React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
|
||
const ErrorMessage = ({ message }) => ( | ||
<div className="container mt-3"> | ||
<h2>Error</h2> | ||
<p>{message}</p> | ||
</div> | ||
); | ||
|
||
ErrorMessage.propTypes = { | ||
message: PropTypes.string.isRequired, | ||
}; | ||
|
||
export default ErrorMessage; |
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,73 @@ | ||
import React, { useState } from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import 'bootstrap/dist/css/bootstrap.min.css'; | ||
|
||
const VALID_DENOMINATIONS = [0.01, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 50, 100, 1000]; | ||
|
||
const Form = ({ onSubmit }) => { | ||
const [amount, setAmount] = useState(''); | ||
const [selectedDenominations, setSelectedDenominations] = useState([]); | ||
const [validationError, setValidationError] = useState(''); | ||
|
||
const handleDenominationClick = (denomination) => { | ||
setSelectedDenominations((prev) => { | ||
if (prev.includes(denomination)) { | ||
return prev.filter((d) => d !== denomination); | ||
} else { | ||
return [...prev, denomination]; | ||
} | ||
}); | ||
}; | ||
|
||
const handleSubmit = (e) => { | ||
e.preventDefault(); | ||
setValidationError(''); | ||
|
||
if (selectedDenominations.length === 0) { | ||
setValidationError('Please select at least one denomination.'); | ||
return; | ||
} | ||
|
||
onSubmit({ amount: parseFloat(amount), denominations: selectedDenominations }); | ||
}; | ||
|
||
return ( | ||
<div className="container"> | ||
<form onSubmit={handleSubmit}> | ||
<div className="form-group"> | ||
<label>Amount:</label> | ||
<input | ||
type="number" | ||
className="form-control" | ||
value={amount} | ||
onChange={(e) => setAmount(e.target.value)} | ||
required | ||
/> | ||
</div> | ||
<div className="form-group"> | ||
<label>Denominations:</label> | ||
<div> | ||
{VALID_DENOMINATIONS.map((denomination) => ( | ||
<button | ||
key={denomination} | ||
type="button" | ||
className={`btn btn-outline-primary m-1 ${selectedDenominations.includes(denomination) ? 'active' : ''}`} | ||
onClick={() => handleDenominationClick(denomination)} | ||
> | ||
{denomination} | ||
</button> | ||
))} | ||
</div> | ||
</div> | ||
<button type="submit" className="btn btn-primary">Calculate</button> | ||
</form> | ||
{validationError && <p className="text-danger">{validationError}</p>} | ||
</div> | ||
); | ||
}; | ||
|
||
Form.propTypes = { | ||
onSubmit: PropTypes.func.isRequired, | ||
}; | ||
|
||
export default Form; |
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,15 @@ | ||
import React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
|
||
const Result = ({ coins }) => ( | ||
<div className="container mt-3"> | ||
<h2>Result</h2> | ||
<p>Coins: {coins.join(', ')}</p> | ||
</div> | ||
); | ||
|
||
Result.propTypes = { | ||
coins: PropTypes.arrayOf(PropTypes.number).isRequired, | ||
}; | ||
|
||
export default Result; |
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,21 @@ | ||
import React from 'react'; | ||
|
||
const Footer = () => ( | ||
<footer className="bg-light text-center text-lg-start mt-5"> | ||
<div className="container p-4"> | ||
<p className="mb-0">Contact me:</p> | ||
<ul className="list-unstyled"> | ||
<li><a href="mailto:[email protected]">[email protected]</a></li> | ||
<li><a href="https://keiyam.me" target="_blank" rel="noopener noreferrer">Personal Website</a> | ||
</li> | ||
<li><a href="https://github.com/arabasta" target="_blank" rel="noopener noreferrer">Github</a> | ||
</li> | ||
<li><a href="https://www.linkedin.com/in/kyi" target="_blank" rel="noopener noreferrer">LinkedIn</a> | ||
</li> | ||
<li>+65 88008405</li> | ||
</ul> | ||
</div> | ||
</footer> | ||
); | ||
|
||
export default Footer; |
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,19 @@ | ||
const handleError = (err) => { | ||
if (err.response) { | ||
if (err.response.status === 400) { | ||
if (typeof err.response.data === 'string') { | ||
return err.response.data || 'Invalid input data. Please check your values.'; | ||
} else if (typeof err.response.data === 'object') { | ||
return Object.values(err.response.data).join(', ') || 'Invalid input data. Please check your values.'; | ||
} else { | ||
return 'Invalid input data. Please check your values.'; | ||
} | ||
} else { | ||
return 'An error occurred on the server.'; | ||
} | ||
} else { | ||
return 'Failed to connect to the server.'; | ||
} | ||
}; | ||
|
||
export default handleError; |