<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=VT323&display=swap" rel="stylesheet">
<div id="app"></div>
body {
  background-image: url("https://as2.ftcdn.net/v2/jpg/03/16/66/51/1000_F_316665148_kVX47Jb06tVnzL14TYs1mEpur9bBnQsN.jpg");
  background-size: cover;
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  font-family: "VT323", monospace;
  font-size: 30px;
}

* {
  box-sizing: border-box;
}

#calculator {
  width: 250px;
  min-height: 400px;
  border: 2px solid red;
  background-color: #730545;
  color: white;
  display: flex;
  flex-direction: column;
  border-radius: 5px;
  box-shadow: 0 10px 20px 3px red;
}

h4 {
  margin: 0;
  margin-bottom: 10px;
  color: red;
}

#display {
  border: 2px solid black;
  min-height: 80px;
  max-height: 100px;
  margin: 5px;
  padding: 5px;
  text-align: end;
  background-color: #ffea03;
  border: 4px solid black;
  color: black;
  word-wrap: break-word;
}

#prevOp {
  font-size: 20px;
  opacity: 75%;
}

button {
  font-size: 25px;
  border: none;
  border-radius: 50%;
  height: 50px;
  width: 50px;
  margin: 5px;
  background-color: black;
  color: yellow;
  border: 2px solid yellow;
  font-family: "VT323", monospace;
  font-size: 30px;
  box-shadow: 0 3px 0 2px black;
}

button:active {
  transform: scale(95%);
  box-shadow: 0 1px 0 2px black;
}

button:hover {
  opacity: 75%;
  cursor: pointer;
}

button:focus {
  outline: none;
}

#buttons {
  display: flex;
  height: 75%;
  margin-bottom: 5px;
  margin-top: 15px;
  position: relative;
}

#num-box {
  width: 75%;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
}

#op-box {
  width: 25%;
}
#op-box button {
  background-color: #14a307;
  color: black;
}

.span-two-h {
  width: 110px;
  border-radius: 50px;
}
.span-two-v {
  height: 110px;
  border-radius: 50px;
}

.multiplication {
  position: absolute;
  right: 65px;
}
#clear {
  margin-right: 50px;
  background-color: #a60202;
}

. {
  width: 300px;
}
const nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
const operators = ["*", "-", "+", "/"];
const revNums = nums.reverse();

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      num: 0,
      last: "",
      evaluated: false,
    };

    this.handleResetClick = this.handleResetClick.bind(this);
    this.handlePointClick = this.handlePointClick.bind(this);
    this.handleEqualsClick = this.handleEqualsClick.bind(this);
  }
//everything is erased
  handleResetClick(e) {
    this.setState({
      num: 0,
      last: "",
      evaluated: true
    })
  }
//this.state.last value goes to API call and we get the answer
  handleEqualsClick() {
    this.setState({
      num: math.evaluate(this.state.last),
      last: `${this.state.last}=${math.evaluate(this.state.last)}`,
      evaluated: true,
    })
  }
//concatination of whatever we have written and decimal point
  handlePointClick(e) {
    this.setState({
      num: this.state.num + e.target.innerText, 
      last: this.state.last + e.target.innerText
    })
  }


  render() {
    const { num, last, evaluated } = this.state;

    //main logic is here whenever most buttons are pressed
    const handleClick = (e) => {
      const value = e.target.innerText;

      //for some reason this last condition doesn't work and passes 0 multiple times
      this.setState(
        this.state.num === 0 || isNaN(this.state.num) || evaluated || (this.state.num === 0 && value === "0") 
        ? ({num: value, evaluated: false}) 
        : ({num: this.state.num + value})
      );

      this.setState(
        this.state.last === "" || evaluated 
        ? ({last: value, evaluated: false})
        : ({last: this.state.last + value})
      )
    }

    return (
      <div>
        <h4>Calculator By JakChi</h4>
        
        <div id="calculator">
          <div id="display">
            <div id="prevOp">{last}</div>
            <div id="currentOp">{num}</div>
          </div>
          <div id="buttons">
            <div id="num-box">
              {/*this is reset button*/}
              <button
                id="clear"
                className="span-two-h"
                onClick={(e) => this.handleResetClick(e)}
              >
                AC
              </button>
              {/*all numbers on calculator are rendered by map method*/}
              {revNums.map((num, key) => {
                return (
                  <button
                    className={`${num === 0 ? "span-two-h" : null}`}
                    onClick={handleClick}
                    key={key}
                  >
                    {num}
                  </button>
                );
              })}
              {/*decimal point*/}
              <button
                id="decimal"
                style={{ backgroundColor: "green" }}
                onClick={(e) => this.handlePointClick(e)}
              >
                .
              </button>
            </div>
            {/*this are all signs from operators*/}
            <div id="op-box">
              {operators.map((op, key) => (
                <button
                  className={`${op === "*" ? "multiplication" : null }`}
                  onClick={handleClick}
                  key={key}
                  >
                  {op}
                </button>
              ))}
              {/*Equals operator*/}
              <button
                id="equals"
                onClick = {(e) => this.handleEqualsClick(e)}
                className = "span-two-v"
                >
                =
              </button>
            </div>
          </div>
        </div>
      </div>
    );
  }
}

const calculateValue = (current, prev, operation) => {
  const currentNum = parseInt(current);
  const prevNum = parseInt(prev);
  const result = 0;
  switch (operation) {
    case "*":
      result = prevNum * currentNum;
      break;
    case "+":
      result = prevNum + currentNum;
      break;
    case "-":
      result = prevNum - currentNum;
      break;
    case "/":
      result = prevNum / currentNum;
      break;
    default:
      result = "0000";
  }
  return result.toString();
};

ReactDOM.render(<App />, document.getElementById("app"));
View Compiled
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js
  2. https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js
  3. https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js
  4. https://cdnjs.cloudflare.com/ajax/libs/mathjs/11.10.0/math.js