aboutsummaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/Calculator/components/App.js109
-rw-r--r--apps/Calculator/index.js3
-rw-r--r--apps/Calculator/styles/Calculator.module.scss1
-rw-r--r--apps/Calculator/styles/_calculator.scss92
-rw-r--r--apps/index.js1
5 files changed, 206 insertions, 0 deletions
diff --git a/apps/Calculator/components/App.js b/apps/Calculator/components/App.js
new file mode 100644
index 0000000..df46751
--- /dev/null
+++ b/apps/Calculator/components/App.js
@@ -0,0 +1,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
diff --git a/apps/Calculator/index.js b/apps/Calculator/index.js
new file mode 100644
index 0000000..4a7ef43
--- /dev/null
+++ b/apps/Calculator/index.js
@@ -0,0 +1,3 @@
+import Calculator from './components/App'
+
+export default Calculator
diff --git a/apps/Calculator/styles/Calculator.module.scss b/apps/Calculator/styles/Calculator.module.scss
new file mode 100644
index 0000000..2bc25fa
--- /dev/null
+++ b/apps/Calculator/styles/Calculator.module.scss
@@ -0,0 +1 @@
+@import "calculator";
diff --git a/apps/Calculator/styles/_calculator.scss b/apps/Calculator/styles/_calculator.scss
new file mode 100644
index 0000000..987a0ea
--- /dev/null
+++ b/apps/Calculator/styles/_calculator.scss
@@ -0,0 +1,92 @@
+.calculator {
+ width: 100%;
+ height: 100%;
+ position: relative;
+ background-color: #000;
+ display: flex;
+ flex-direction: column;
+ background-color: var(--color-window-content);
+}
+
+.display {
+ height: 20%;
+ background-color: var(--color-text);
+ color: var(--color-window-content);
+ display: flex;
+ flex-direction: column;
+ padding-right: 1em;
+
+ > div:nth-child(1) {
+ font-size: 1em;
+ padding-top: .5em;
+ white-space: nowrap;
+ text-align: right;
+ }
+
+ > div:nth-child(2) {
+ font-size: 2.5em;
+ flex-grow: 1;
+ display: flex;
+ align-items: center;
+ justify-content: flex-end;
+ }
+}
+
+.keys {
+ height: 80%;
+ width: 100%;
+ display: flex;
+
+ & > div {
+ height: 100%;
+ display: flex;
+
+ & > div {
+ height: 25%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ border: 1px solid var(--color-window-buttons);
+ transition: .3s background-color;
+ font-size: 2em;
+ }
+
+ &:nth-of-type(1) {
+ width: 75%;
+ flex-wrap: wrap;
+ background-color: var(--color-window-popup);
+
+ & > div {
+ width: 33.3%;
+ flex-grow: 1;
+
+ &:hover {
+ background-color: var(--color-window-content);
+ }
+
+ &:first-of-type {
+ order: 2;
+ }
+
+ &:nth-of-type(12) {
+ order: 3;
+ }
+ }
+ }
+
+ &:nth-of-type(2) {
+ width: 25%;
+ flex-direction: column;
+
+ & > div {
+ width: 100%;
+ background-color: var(--color-window-menu-alt);
+
+ &:hover {
+ background-color: var(--color-window-content);
+ }
+ }
+ }
+ }
+
+}
diff --git a/apps/index.js b/apps/index.js
index 465761b..eccedac 100644
--- a/apps/index.js
+++ b/apps/index.js
@@ -1,3 +1,4 @@
+export { default as Calculator } from './Calculator'
export { default as Notes } from './Notes'
export { default as Player } from './Player'
export { default as Settings } from './Settings'