Skip to content

Commit

Permalink
[#2PlaysAMonth]: Basic calculator is made with react.js (reactplay#1005)
Browse files Browse the repository at this point in the history
* 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
bahnisikhadhar and atapas committed Feb 28, 2023
1 parent 8da750f commit 2914555
Show file tree
Hide file tree
Showing 12 changed files with 352 additions and 24 deletions.
168 changes: 168 additions & 0 deletions src/plays/basic-calculator/BasicCalculator.js
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;
55 changes: 55 additions & 0 deletions src/plays/basic-calculator/CalculatorBody.js
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>
);
}
9 changes: 9 additions & 0 deletions src/plays/basic-calculator/DigitButton.js
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>
);
}
9 changes: 9 additions & 0 deletions src/plays/basic-calculator/OperationButton.js
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>
);
}
27 changes: 27 additions & 0 deletions src/plays/basic-calculator/Readme.md
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)
Binary file added src/plays/basic-calculator/cover.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
51 changes: 51 additions & 0 deletions src/plays/basic-calculator/styles.css
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;
}
10 changes: 5 additions & 5 deletions src/plays/notehack/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@
- ### **This app is fully responsive across all the devices 📱**
- ### **This app has multiple themes 💯**
- ### **User can add, update & delete the notes 🥳**
- ### **This app has localStorage feature. Notes & themes will be saved to local storage ⚡**
- ### **This app has localStorage feature. Notes & themes will be saved to local storage ⚡**

## Project Screenshot

- ### **Theme 1**
- ### **Theme 1**

<div align="center">
<img src="https://i.postimg.cc/MpR2510f/SS1.png" alt="NoteHack Screenshot" width="100%" target="_blank" />
<br>
</div>

- ### **Theme 2**
- ### **Theme 2**
<div align="center">
<img src="https://i.postimg.cc/k5cHYs2G/SS2.png" alt="NoteHack Screenshot" width="100%" target="_blank" />
<br>
Expand All @@ -31,7 +31,7 @@

## Creator Information

- ### **Bobby Sadhwani** - **[Linkedin](https://www.linkedin.com/in/bobby-sadhwani)**, **[Twitter](https://twitter.com/BOBBY__SADHWANI)**, **[Github](https://github.com/Bobby-coder)**, **[Portfolio](https://bobby-sadhwani.netlify.app)**
- ### **Bobby Sadhwani** - **[Linkedin](https://www.linkedin.com/in/bobby-sadhwani)**, **[Twitter](https://twitter.com/BOBBY__SADHWANI)**, **[Github](https://github.com/Bobby-coder)**, **[Portfolio](https://bobby-sadhwani.netlify.app)**

## Video

Expand All @@ -41,4 +41,4 @@

- ### **[React Icons](https://react-icons.github.io/react-icons/)**

### **Happy Coding!** 🤩
### **Happy Coding!** 🤩
Loading

0 comments on commit 2914555

Please sign in to comment.