altru calculator
This commit is contained in:
commit
b97bd7c2eb
24
.gitignore
vendored
Normal file
24
.gitignore
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
/node_modules
|
||||||
|
/.pnp
|
||||||
|
.pnp.js
|
||||||
|
|
||||||
|
# testing
|
||||||
|
/coverage
|
||||||
|
|
||||||
|
# production
|
||||||
|
/build
|
||||||
|
|
||||||
|
# misc
|
||||||
|
.DS_Store
|
||||||
|
.env.local
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
|
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
.idea
|
||||||
14645
package-lock.json
generated
Normal file
14645
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
39
package.json
Normal file
39
package.json
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
{
|
||||||
|
"name": "calc-app",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"private": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@testing-library/jest-dom": "^5.14.1",
|
||||||
|
"@testing-library/react": "^13.0.0",
|
||||||
|
"@testing-library/user-event": "^13.2.1",
|
||||||
|
"react": "^18.1.0",
|
||||||
|
"react-dom": "^18.1.0",
|
||||||
|
"react-scripts": "5.0.1",
|
||||||
|
"react-textfit": "^1.1.1",
|
||||||
|
"web-vitals": "^2.1.0"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"start": "react-scripts start",
|
||||||
|
"build": "react-scripts build",
|
||||||
|
"test": "react-scripts test",
|
||||||
|
"eject": "react-scripts eject"
|
||||||
|
},
|
||||||
|
"eslintConfig": {
|
||||||
|
"extends": [
|
||||||
|
"react-app",
|
||||||
|
"react-app/jest"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"browserslist": {
|
||||||
|
"production": [
|
||||||
|
">0.2%",
|
||||||
|
"not dead",
|
||||||
|
"not op_mini all"
|
||||||
|
],
|
||||||
|
"development": [
|
||||||
|
"last 1 chrome version",
|
||||||
|
"last 1 firefox version",
|
||||||
|
"last 1 safari version"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
public/favicon.ico
Normal file
BIN
public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.8 KiB |
20
public/index.html
Normal file
20
public/index.html
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<meta name="theme-color" content="#000000" />
|
||||||
|
<meta
|
||||||
|
name="description"
|
||||||
|
content="Web site created using create-react-app"
|
||||||
|
/>
|
||||||
|
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
||||||
|
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||||
|
<title>Basic Calculator</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||||
|
<div id="root"></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
BIN
public/logo192.png
Normal file
BIN
public/logo192.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.2 KiB |
BIN
public/logo512.png
Normal file
BIN
public/logo512.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.4 KiB |
25
public/manifest.json
Normal file
25
public/manifest.json
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"short_name": "React App",
|
||||||
|
"name": "Create React App Sample",
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "favicon.ico",
|
||||||
|
"sizes": "64x64 32x32 24x24 16x16",
|
||||||
|
"type": "image/x-icon"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "logo192.png",
|
||||||
|
"type": "image/png",
|
||||||
|
"sizes": "192x192"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "logo512.png",
|
||||||
|
"type": "image/png",
|
||||||
|
"sizes": "512x512"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"start_url": ".",
|
||||||
|
"display": "standalone",
|
||||||
|
"theme_color": "#000000",
|
||||||
|
"background_color": "#ffffff"
|
||||||
|
}
|
||||||
3
public/robots.txt
Normal file
3
public/robots.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# https://www.robotstxt.org/robotstxt.html
|
||||||
|
User-agent: *
|
||||||
|
Disallow:
|
||||||
33
src/App.js
Normal file
33
src/App.js
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import Wrapper from "./components/Wrapper";
|
||||||
|
import Screen from "./components/Screen";
|
||||||
|
import ButtonBox from './components/ButtonBox'
|
||||||
|
import Button from './components/Button'
|
||||||
|
import CalcProvider from "./context/CalcContext";
|
||||||
|
|
||||||
|
const btnValues = [
|
||||||
|
["C", "+/-", "%", "/"],
|
||||||
|
[7, 8, 9, "x"],
|
||||||
|
[4, 5, 6, "-"],
|
||||||
|
[1, 2, 3, "+"],
|
||||||
|
[0, ".", "="],
|
||||||
|
];
|
||||||
|
|
||||||
|
function App() {
|
||||||
|
return (
|
||||||
|
<CalcProvider>
|
||||||
|
<Wrapper>
|
||||||
|
<Screen />
|
||||||
|
<ButtonBox>
|
||||||
|
{btnValues.flat().map((btn, i) => (
|
||||||
|
<Button
|
||||||
|
value={btn}
|
||||||
|
key={i}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</ButtonBox>
|
||||||
|
</Wrapper>
|
||||||
|
</CalcProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default App;
|
||||||
BIN
src/calc-app.png
Normal file
BIN
src/calc-app.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 54 KiB |
62
src/components/Button.js
Normal file
62
src/components/Button.js
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import { useContext } from "react";
|
||||||
|
import { CalcContext } from '../context/CalcContext'
|
||||||
|
|
||||||
|
const getStyleName = btn => {
|
||||||
|
}
|
||||||
|
|
||||||
|
const Button = ({ value }) => {
|
||||||
|
const { calc, setCalc } = useContext(CalcContext);
|
||||||
|
|
||||||
|
const handleClickButton = () => {
|
||||||
|
const numberString = value.toString()
|
||||||
|
|
||||||
|
setCalc({
|
||||||
|
...calc,
|
||||||
|
num: numberString
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const signClick = () => {
|
||||||
|
setCalc({
|
||||||
|
sign: value,
|
||||||
|
res: !calc.res && calc.num ? calc.num : calc.res,
|
||||||
|
num: 0
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const equalsClick = () => {
|
||||||
|
if(calc.res && calc.num) {
|
||||||
|
setCalc({
|
||||||
|
res: math(calc.res, calc.num, calc.sign),
|
||||||
|
sign: '',
|
||||||
|
num: 0
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const math = (a, b, sign) => {
|
||||||
|
const result = {
|
||||||
|
'+': (a, b) => a + b
|
||||||
|
}
|
||||||
|
|
||||||
|
return result[sign](a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleBtnClick = () => {
|
||||||
|
const results = {
|
||||||
|
'+': signClick,
|
||||||
|
'=': equalsClick,
|
||||||
|
}
|
||||||
|
if(results[value]) {
|
||||||
|
return results[value]()
|
||||||
|
} else {
|
||||||
|
return handleClickButton()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button onClick={handleBtnClick} className={`${getStyleName(value)} button`}>{value}</button>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Button
|
||||||
8
src/components/ButtonBox.js
Normal file
8
src/components/ButtonBox.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
const ButtonBox = ({ children }) => {
|
||||||
|
return (
|
||||||
|
<div className="buttonBox">{children}</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ButtonBox
|
||||||
13
src/components/Screen.js
Normal file
13
src/components/Screen.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import { useContext } from "react"
|
||||||
|
import { CalcContext } from "../context/CalcContext"
|
||||||
|
import { Textfit } from 'react-textfit';
|
||||||
|
|
||||||
|
const Screen = () => {
|
||||||
|
const { calc } = useContext(CalcContext);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Textfit className="screen" max={70} mode="single">{calc.num !== 0 ? calc.num : calc.res}</Textfit>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Screen
|
||||||
8
src/components/Wrapper.js
Normal file
8
src/components/Wrapper.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
const Wrapper = ({ children }) => {
|
||||||
|
return (
|
||||||
|
<div className="wrapper">{children}</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Wrapper
|
||||||
23
src/context/CalcContext.js
Normal file
23
src/context/CalcContext.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import { createContext, useState } from "react"
|
||||||
|
|
||||||
|
export const CalcContext = createContext()
|
||||||
|
|
||||||
|
const CalcProvider = ({ children }) => {
|
||||||
|
const [calc, setCalc] = useState({
|
||||||
|
sign: "",
|
||||||
|
num: 0,
|
||||||
|
res: 0
|
||||||
|
});
|
||||||
|
|
||||||
|
const providerValue = {
|
||||||
|
calc, setCalc
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<CalcContext.Provider value={providerValue}>
|
||||||
|
{children}
|
||||||
|
</CalcContext.Provider>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CalcProvider
|
||||||
63
src/index.css
Normal file
63
src/index.css
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
@import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap');
|
||||||
|
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
height: 100vh;
|
||||||
|
background: #f4fefe;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-family: 'Roboto', sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.screen {
|
||||||
|
height: 4rem;
|
||||||
|
margin-bottom: 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wrapper {
|
||||||
|
background: #f6f8f9;
|
||||||
|
width: 20rem;
|
||||||
|
padding: 2rem;
|
||||||
|
margin-top: 4rem;
|
||||||
|
border-radius: 1rem;
|
||||||
|
box-shadow: 0px 9px 15px -3px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.buttonBox {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(4, 1fr);
|
||||||
|
gap: .5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
background: #e9f0f4;
|
||||||
|
height: 3.5rem;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 10px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
cursor: pointer;
|
||||||
|
color: #242424;
|
||||||
|
border: none;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button:hover {
|
||||||
|
border: 2px dotted #242424;
|
||||||
|
}
|
||||||
|
|
||||||
|
.equals {
|
||||||
|
background: #4bd086;
|
||||||
|
grid-column: 3/5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.opt {
|
||||||
|
background: #f79505;
|
||||||
|
}
|
||||||
11
src/index.js
Normal file
11
src/index.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import ReactDOM from 'react-dom/client';
|
||||||
|
import './index.css';
|
||||||
|
import App from './App';
|
||||||
|
|
||||||
|
const root = ReactDOM.createRoot(document.getElementById('root'));
|
||||||
|
root.render(
|
||||||
|
<React.StrictMode>
|
||||||
|
<App />
|
||||||
|
</React.StrictMode>
|
||||||
|
);
|
||||||
Loading…
x
Reference in New Issue
Block a user