aboutsummaryrefslogtreecommitdiffstats
path: root/apps/Calculator/components/App.js
blob: df467511d4e12073a9537338b6eab56f000b11af (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import { useState } from 'react';
import styles from '../styles/Calculator.module.scss'

const App = () => {
  const [display, setDisplay] = useState('0')
  const [memory, setMemory] = useState([])
  const [result, setResult] = useState([])

  const onClear = () => {
    setDisplay('0')
    setMemory([])
  }
  const onNumber = n => setDisplay(p => display === '0' ? n.toString() : p+n)
  const onMath = m => {
    if (display !== '0') {
      if (!result) {
        setMemory(p => [
          ...p,
          { type: 'n', value: display },
          { type: 'm', value: m },
        ]);
      } else {
        setResult(false)
        setMemory([
          { type: 'n', value: display },
          { type: 'm', value: m },
        ]);
      }
      setDisplay('0')
    } else if (memory[memory.length - 1].type === 'm') {
      setMemory(p => [...p.slice(0, -1), { type: 'm', value: m }]);
    }
  }

  const newVal = (prevVal, curVal) => {
    if (!prevVal || !prevVal.m) return 0;

    if (prevVal.m === '+') {
      return `${Number(prevVal.value) + Number(curVal.value)}`
    }
    if (prevVal.m === '-') {
      return `${Number(prevVal.value) - Number(curVal.value)}`
    }
    if (prevVal.m === '*') {
      return `${Number(prevVal.value) * Number(curVal.value)}`
    }
    if (prevVal.m === '/') {
      return prevVal.value !== '0' && curVal.value !== '0'
        ? `${Number(prevVal.value) / Number(curVal.value)}`
        : '0'
    }
  }

  const onResult = () => {
    if (memory.length > 2 || (memory.length > 1 && display !== '0')) {
      const actions = display === 0
        ? memory
        : [...memory, { type: 'n', value: display }]
      const result = actions.reduce((prevVal, curVal) => {
        return curVal.type === 'n'
          ? ({ value: newVal(prevVal, curVal), m: null })
          : ({ value: prevVal.value, m: curVal.value })
      })
      setDisplay(result?.value || 0);
      setResult(true)
      if (display !== 0) {
        setMemory(p => [...p, { type: 'n', value: display }])
      }
    }
  }

  return (
    <>
      <div className='window__submenu'>
        <div>
          <div onClick={onClear}>
            Clear
          </div>
        </div>
      </div>
      <div className={styles.calculator}>
        <div className={styles.display}>
          <div>
            { memory.map(o => o.value).join(' ') }
          </div>
          <div>
            {display}
          </div>
        </div>
        <div className={styles.keys}>
          <div>
            { [...Array(10).keys()].map(k => (
              <div key={k} onClick={() => onNumber(k)}>{k}</div>
            )) }
            <div onClick={() => setDisplay(p => p+'.')}>.</div>
            <div onClick={onResult}>=</div>
          </div>
          <div>
            {['+','-','*','/'].map(m => (
              <div key={m} onClick={() => onMath(m)}>{m}</div>
            ))}
          </div>
        </div>
      </div>
    </>
  )
}

export default App