forked from reactplay/react-play
-
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.
[#2PlaysAMonth]: Basic calculator is made with react.js (reactplay#1005)
* Basic calculator is made with react.js * changes on readme * changes made as per instruction & lint error fixed * Added video link in readme file --------- Co-authored-by: Tapas Adhikary <[email protected]>
- Loading branch information
1 parent
8da750f
commit 2914555
Showing
12 changed files
with
352 additions
and
24 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
import PlayHeader from 'common/playlists/PlayHeader'; | ||
import './styles.css'; | ||
import { useReducer } from 'react'; | ||
import CalculatorBody from './CalculatorBody'; | ||
|
||
export const ACTION = { | ||
ADD_DIGIT: 'add-digit', | ||
CHOOSE_OPERATION: 'choose-operation', | ||
CLEAR: 'clear', | ||
DELETE_DIGIT: 'delete-digit', | ||
EVALUATE: 'evaluate' | ||
}; | ||
|
||
function reducer(state, { type, payload }) { | ||
switch (type) { | ||
case ACTION.ADD_DIGIT: | ||
if (state.overwrite) { | ||
return { | ||
...state, | ||
currentOperand: payload.digit, | ||
overwrite: false | ||
}; | ||
} | ||
if (payload.digit === '0' && state.currentOperand === '0') return state; | ||
if (payload.digit === '.' && state.currentOperand.includes('.')) return state; | ||
|
||
return { | ||
...state, | ||
currentOperand: `${state.currentOperand || ''}${payload.digit}` | ||
}; | ||
|
||
case ACTION.CHOOSE_OPERATION: | ||
if (state.currentOperand == null && state.previousOperand == null) { | ||
return state; | ||
} | ||
if (state.currentOperand == null) { | ||
return { | ||
...state, | ||
operation: payload.operation | ||
}; | ||
} | ||
if (state.previousOperand == null) { | ||
return { | ||
...state, | ||
operation: payload.operation, | ||
previousOperand: state.currentOperand, | ||
currentOperand: null | ||
}; | ||
} | ||
|
||
// return{ | ||
// ...state, currentOperand: `${state.currentOperand || ""}${payload.operation}` | ||
// } | ||
return { | ||
...state, | ||
previousOperand: evaluate(state), | ||
operation: payload.operation, | ||
currentOperand: null | ||
}; | ||
|
||
case ACTION.CLEAR: | ||
return {}; | ||
|
||
case ACTION.DELETE_DIGIT: | ||
if (state.overwrite) { | ||
return { | ||
...state, | ||
overwrite: false, | ||
currentOperand: null | ||
}; | ||
} | ||
if (state.currentOperand == null) return state; | ||
if (state.currentOperand.length === 1) { | ||
return { | ||
...state, | ||
currentOperand: null | ||
}; | ||
} | ||
|
||
return { | ||
...state, | ||
currentOperand: state.currentOperand.slice(0, -1) | ||
}; | ||
|
||
case ACTION.EVALUATE: | ||
if ( | ||
state.operation == null || | ||
state.currentOperand == null || | ||
state.previousOperand == null | ||
) { | ||
return state; | ||
} | ||
|
||
return { | ||
...state, | ||
overwrite: true, | ||
previousOperand: null, | ||
operation: null, | ||
currentOperand: evaluate(state) | ||
}; | ||
} | ||
} | ||
|
||
function evaluate({ currentOperand, previousOperand, operation }) { | ||
const prev = parseFloat(previousOperand); | ||
const current = parseFloat(currentOperand); | ||
if (isNaN(prev) || isNaN(current)) return ''; | ||
let computation = ''; | ||
switch (operation) { | ||
case '+': | ||
computation = prev + current; | ||
|
||
break; | ||
case '-': | ||
computation = prev - current; | ||
|
||
break; | ||
case '*': | ||
computation = prev * current; | ||
|
||
break; | ||
case '÷': | ||
computation = prev / current; | ||
|
||
break; | ||
} | ||
|
||
return computation.toString(); | ||
} | ||
|
||
const INTEGER_FORMATTER = new Intl.NumberFormat('en-us', { | ||
maximumFractionDigits: 0 | ||
}); | ||
|
||
function formatOperand(operand) { | ||
if (operand == null) return; | ||
const [integer, decimal] = operand.split('.'); | ||
if (decimal == null) return INTEGER_FORMATTER.format(integer); | ||
|
||
return `${INTEGER_FORMATTER.format(integer)}.${decimal}`; | ||
} | ||
|
||
// WARNING: Do not change the entry componenet name | ||
function BasicCalculator(props) { | ||
// Your Code Start below. | ||
const [{ currentOperand, previousOperand, operation }, dispatch] = useReducer(reducer, {}); | ||
|
||
return ( | ||
<> | ||
<div className="play-details"> | ||
<PlayHeader play={props} /> | ||
<div className="play-details-body"> | ||
{/* Your Code Starts Here */} | ||
<CalculatorBody | ||
currentOperand={currentOperand} | ||
dispatch={dispatch} | ||
formatOperand={formatOperand} | ||
operation={operation} | ||
previousOperand={previousOperand} | ||
/> | ||
{/* Your Code Ends Here */} | ||
</div> | ||
</div> | ||
</> | ||
); | ||
} | ||
|
||
export default BasicCalculator; |
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,55 @@ | ||
import { ACTION } from './BasicCalculator'; | ||
import DigitButton from './DigitButton'; | ||
import OperationButton from './OperationButton'; | ||
|
||
export default function CalculatorBody({ | ||
currentOperand, | ||
previousOperand, | ||
operation, | ||
dispatch, | ||
formatOperand | ||
}) { | ||
return ( | ||
<div className="calculator_grid_container"> | ||
<div className="calculator_grid"> | ||
<div className="output"> | ||
<div className="previous_operand"> | ||
{formatOperand(previousOperand)} {operation} | ||
</div> | ||
<div className="current_operand">{formatOperand(currentOperand)}</div> | ||
</div> | ||
<button className="span_two ac" onClick={() => dispatch({ type: ACTION.CLEAR })}> | ||
AC | ||
</button> | ||
|
||
<button onClick={() => dispatch({ type: ACTION.DELETE_DIGIT })}>DEL</button> | ||
<OperationButton dispatch={dispatch} operation="÷" /> | ||
|
||
<DigitButton digit="1" dispatch={dispatch} /> | ||
<DigitButton digit="2" dispatch={dispatch} /> | ||
<DigitButton digit="3" dispatch={dispatch} /> | ||
|
||
<OperationButton dispatch={dispatch} operation="*" /> | ||
|
||
<DigitButton digit="4" dispatch={dispatch} /> | ||
<DigitButton digit="5" dispatch={dispatch} /> | ||
<DigitButton digit="6" dispatch={dispatch} /> | ||
|
||
<OperationButton dispatch={dispatch} operation="+" /> | ||
|
||
<DigitButton digit="7" dispatch={dispatch} /> | ||
<DigitButton digit="8" dispatch={dispatch} /> | ||
<DigitButton digit="9" dispatch={dispatch} /> | ||
|
||
<OperationButton dispatch={dispatch} operation="-" /> | ||
|
||
<DigitButton digit="." dispatch={dispatch} /> | ||
<DigitButton digit="0" dispatch={dispatch} /> | ||
|
||
<button className="span_two" onClick={() => dispatch({ type: ACTION.EVALUATE })}> | ||
= | ||
</button> | ||
</div> | ||
</div> | ||
); | ||
} |
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,9 @@ | ||
import { ACTION } from './BasicCalculator'; | ||
|
||
export default function DigitButton({ dispatch, digit }) { | ||
return ( | ||
<button onClick={() => dispatch({ type: ACTION.ADD_DIGIT, payload: { digit } })}> | ||
{digit} | ||
</button> | ||
); | ||
} |
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,9 @@ | ||
import { ACTION } from './BasicCalculator'; | ||
|
||
export default function OperationButton({ dispatch, operation }) { | ||
return ( | ||
<button onClick={() => dispatch({ type: ACTION.CHOOSE_OPERATION, payload: { operation } })}> | ||
{operation} | ||
</button> | ||
); | ||
} |
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,27 @@ | ||
# Basic Calculator | ||
|
||
This is a Simple calculator where one can do addition, subtraction, multiplication, division. All clear and delete facility is also there. No external library is used to make this play | ||
|
||
## Play Demographic | ||
|
||
- Language: js | ||
- Level: Beginner | ||
|
||
## Creator Information | ||
|
||
- User: bahnisikhadhar | ||
- Gihub Link: https://github.com/bahnisikhadhar | ||
- Blog: | ||
- Video: https://www.stack-stream.com/v/basic-calculator-using-react-js-5 | ||
|
||
## Implementation Details | ||
|
||
To make this basic calculator I have used React.js, I have used useReducer Hook to implement all the functionalities. I haven't used any external libraries for this project. | ||
|
||
## Consideration | ||
|
||
It is a Basic Calculator where one can only do Addition, Subtraction, Multiplication and Division. So, here we can not do any other calculation except these four operations. | ||
|
||
## Resources | ||
|
||
Update external resources(if any) |
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,51 @@ | ||
/* enter stlyes here */ | ||
.calculator_grid_container { | ||
width: 100%; | ||
height: 100vh; | ||
background: linear-gradient(to right, yellow, green, yellow); | ||
display: grid; | ||
place-items: center; | ||
} | ||
.calculator_grid { | ||
display: grid; | ||
margin-top: 2rem; | ||
grid-template-columns: repeat(4, 6rem); | ||
grid-template-rows: minmax(7rem, auto) repeat(5, 6rem); | ||
} | ||
.calculator_grid > button { | ||
cursor: pointer; | ||
border: 0; | ||
outline: 0; | ||
border-radius: 10px; | ||
box-shadow: -8px -8px 15px rgba(255, 255, 255, 0.1), 5px 5px 15px rgba(0, 0, 0, 0.2); | ||
background: white; | ||
} | ||
.calculator_grid > button:hover, | ||
.calculator_grid > button:focus { | ||
background-color: rgba(255, 255, 255, 0.9); | ||
} | ||
.calculator_grid .span_two { | ||
grid-column: span 2; | ||
} | ||
.calculator_grid .output { | ||
grid-column: 1/ -1; | ||
background-color: rgba(0, 0, 0, 0.75); | ||
display: flex; | ||
flex-direction: column; | ||
align-items: flex-end; | ||
justify-content: space-around; | ||
padding: 0.75rem; | ||
word-wrap: break-word; | ||
word-break: break-all; | ||
border-top-right-radius: 10px; | ||
border-top-left-radius: 10px; | ||
} | ||
|
||
.calculator_grid .output .previous_operand { | ||
color: rgba(255, 255, 255, 0.75); | ||
font-size: 1.5rem; | ||
} | ||
.calculator_grid .output .current_operand { | ||
color: white; | ||
font-size: 2.5rem; | ||
} |
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
Oops, something went wrong.