altru calculator

This commit is contained in:
aditya.siregar 2024-11-21 14:48:17 +07:00
commit b97bd7c2eb
19 changed files with 24002 additions and 0 deletions

24
.gitignore vendored Normal file
View 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

File diff suppressed because it is too large Load Diff

39
package.json Normal file
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

20
public/index.html Normal file
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

BIN
public/logo512.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

25
public/manifest.json Normal file
View 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
View File

@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:

33
src/App.js Normal file
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

62
src/components/Button.js Normal file
View 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

View File

@ -0,0 +1,8 @@
const ButtonBox = ({ children }) => {
return (
<div className="buttonBox">{children}</div>
)
}
export default ButtonBox

13
src/components/Screen.js Normal file
View 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

View File

@ -0,0 +1,8 @@
const Wrapper = ({ children }) => {
return (
<div className="wrapper">{children}</div>
)
}
export default Wrapper

View 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
View 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
View 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>
);

9025
yarn.lock Normal file

File diff suppressed because it is too large Load Diff