Add Calculator certification project

This commit is contained in:
CherryKitten 2022-10-19 22:18:57 +02:00
parent bbbe8c0ff4
commit 0a6f1dd983
Signed by: sammy
GPG key ID: 0B696A86A853E955
10 changed files with 29302 additions and 0 deletions

View file

@ -0,0 +1,23 @@
# 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*

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,39 @@
{
"name": "4-calculator",
"version": "0.1.0",
"private": true,
"homepage": "https://cherrykitten.github.io/freecodecamp-projects/3-frontend-dev-libraries/4-calculator",
"dependencies": {
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
"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"
]
}
}

View file

@ -0,0 +1,28 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Javascript calculator made for FreeCodeCamp"
/>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css" integrity="sha512-xh6O/CkQoPOWDdYTDqeRdPCVd1SpvCA9XXcUnZS2FmJNp1coAFzvtCN9BmamE+4aHK8yyUHUSCcJHgXloTyT2A==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<title>Calculator</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>

View file

@ -0,0 +1,152 @@
body {
margin: 0;
}
.App {
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
margin: 0;
background-color: darkgrey;
}
.Calculator {
height: 600px;
width: 400px;
display: grid;
grid-template-columns: repeat(4, 0.5fr);
grid-template-rows: repeat(6, 1fr);
grid-gap: 20px;
padding: 10px;
background-color: black;
border-radius: 5px;
box-shadow: rgba(240, 46, 170, 0.4) 5px 5px, rgba(240, 46, 170, 0.3) 10px 10px, rgba(240, 46, 170, 0.2) 15px 15px, rgba(240, 46, 170, 0.1) 20px 20px, rgba(240, 46, 170, 0.05) 25px 25px;
}
.Calculator div {
color: white;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
font-size: 24px;
box-shadow: rgba(0, 0, 0, 0.17) 0px -23px 25px 0px inset, rgba(0, 0, 0, 0.15) 0px -36px 30px 0px inset, rgba(0, 0, 0, 0.1) 0px -79px 40px 0px inset, rgba(0, 0, 0, 0.06) 0px 2px 1px, rgba(0, 0, 0, 0.09) 0px 4px 2px, rgba(0, 0, 0, 0.09) 0px 8px 4px, rgba(0, 0, 0, 0.09) 0px 16px 8px, rgba(0, 0, 0, 0.09) 0px 32px 16px;
}
.Calculator #displayBox {
width: initial;
height: initial;
display: flex;
flex-direction: column;
justify-content: space-evenly;
align-items: flex-end;
}
.Calculator .number, .Calculator #decimal, .Calculator #cat {
background-color: grey;
}
.Calculator .operator, .Calculator #equals {
background-color: orange;
}
.Calculator #clear {
background-color: red;
}
.Calculator #displayBox {
grid-area: 1/1/2/5;
}
.Calculator #zero {
grid-area: 6/1/7/2;
}
.Calculator #one {
grid-area: 5/1/6/2;
}
.Calculator #two {
grid-area: 5/2/6/3;
}
.Calculator #three {
grid-area: 5/3/6/4;
}
.Calculator #four {
grid-area: 4/1/5/2;
}
.Calculator #five {
grid-area: 4/2/5/3;
}
.Calculator #six {
grid-area: 4/3/5/4;
}
.Calculator #seven {
grid-area: 3/1/4/2;
}
.Calculator #eight {
grid-area: 3/2/4/3;
}
.Calculator #nine {
grid-area: 3/3/4/4;
}
.Calculator #decimal {
grid-area: 6/3/7/4;
}
.Calculator #clear {
grid-area: 2/1/3/2;
}
.Calculator #add {
grid-area: 5/4/6/5;
}
.Calculator #subtract {
grid-area: 4/4/5/5;
}
.Calculator #multiply {
grid-area: 3/4/4/5;
}
.Calculator #divide {
grid-area: 2/4/3/5;
}
.Calculator #equals {
grid-area: 6/4/7/5;
}
.Calculator #cat {
grid-area: 6/2/7/3;
}
/* Extra small devices (phones, 600px and down) */
@media only screen and (max-width: 600px) {
.Calculator {
height: 100%;
width: 100%;
}
.Calculator div {
font-size: 12px;
}
}
/* Small devices (portrait tablets and large phones, 600px and up) */
@media only screen and (min-width: 600px) {
.Calculator {
height: 200px;
width: 133px;
}
.Calculator div {
font-size: 14px;
}
}
/* Medium devices (landscape tablets, 768px and up) */
@media only screen and (min-width: 768px) {
.Calculator {
height: 300px;
width: 200px;
}
.Calculator div {
font-size: 16px;
}
}
/* Large devices (laptops/desktops, 992px and up) */
@media only screen and (min-width: 992px) {
.Calculator {
height: 400px;
width: 266px;
}
.Calculator div {
font-size: 20px;
}
}
/*# sourceMappingURL=App.css.map */

View file

@ -0,0 +1 @@
{"version":3,"sourceRoot":"","sources":["App.scss"],"names":[],"mappings":"AAAA;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAIF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EAEA;;AAIF;EACE;EACA;EACA;EACA;EACA;EACA;;AAIF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EAAc;;AAEd;EAAQ;;AACR;EAAO;;AACP;EAAO;;AACP;EAAS;;AACT;EAAQ;;AACR;EAAQ;;AACR;EAAO;;AACP;EAAS;;AACT;EAAS;;AACT;EAAQ;;AAER;EAAW;;AAEX;EAAS;;AAET;EAAO;;AACP;EAAY;;AACZ;EAAY;;AACZ;EAAU;;AAEV;EAAU;;AAEV;EAAO;;;AAGT;AACA;EACE;IACE;IACA;;EAEA;IACE;;;AAIN;AACA;EACE;IACE;IACA;;EAEA;IACE;;;AAIN;AACA;EACE;IACE;IACA;;EACA;IACE;;;AAIN;AACA;EACE;IACE;IACA;;EACA;IACE","file":"App.css"}

View file

@ -0,0 +1,206 @@
import './App.css';
import React from "react";
import meow from './meow.mp3'
const numbers = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'];
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
input: '0',
firstNumber: '',
currentOperator: '',
display: '0',
negative: false,
}
this.clear = this.clear.bind(this);
this.handleInput = this.handleInput.bind(this);
this.handleOperator = this.handleOperator.bind(this);
this.handleDecimal = this.handleDecimal.bind(this);
this.handleEquals = this.handleEquals.bind(this);
this.updateState = this.updateState.bind(this);
}
updateState(changed){
let display;
let input = this.state.input;
let currentOperator = this.state.currentOperator;
let firstNumber = this.state.firstNumber;
let negative = this.state.negative
for (let v in changed){
// eslint-disable-next-line no-eval
eval(v + " = changed[v] ");
}
currentOperator === ''
? firstNumber === ''
? display = input
: display = firstNumber
: display = firstNumber + currentOperator + input;
this.setState({
display: display,
input: input,
currentOperator: currentOperator,
firstNumber: firstNumber,
negative: negative,
})
}
clear() {
this.setState({
input: '0',
firstNumber: '',
currentOperator: '',
display: '0',
negative: false,
})
}
handleInput(i) {
let input = this.state.input;
let firstNumber = this.state.firstNumber;
let currentOperator = this.state.currentOperator;
let negative = this.state.negative;
if (input === '0'){
input = i.toString();
if (firstNumber !== '' && currentOperator === ''){firstNumber = ''}
} else {
input = input + i.toString()
}
if (negative === true){input = input * -1 }
this.updateState({input: input, firstNumber: firstNumber})
}
handleDecimal() {
let input = this.state.input.toString();
if (input.match(/\./)){
return false
} else {
input = input + '.'
}
this.updateState({input: input})
}
handleOperator(operator) {
let op;
let input = this.state.input;
let firstNumber = this.state.firstNumber;
let prevOperator = this.state.currentOperator;
let negative = false;
if (firstNumber === '') {
firstNumber = input
} else {
if (prevOperator !== '' && input !== '0'){
firstNumber = this.handleEquals()
prevOperator = ''
}
}
switch (operator){
case 'add':
op = '+'
break;
case 'subtract':
if (prevOperator !== ''){
negative = true
op = prevOperator;
} else {
op = '-'
}
break;
case 'multiply':
op = '*'
break;
case 'divide':
op = '/'
break;
default:
break;
}
this.updateState({
currentOperator: op,
firstNumber: firstNumber,
input: '0',
negative: negative,
})
}
handleEquals(){
let firstNumber = Number(this.state.firstNumber)
let secondNumber = Number(this.state.input)
let operator = this.state.currentOperator
let result = 0
switch(operator){
case '+':
result = firstNumber + secondNumber
break;
case '-':
result = firstNumber - secondNumber
break;
case '*':
result = firstNumber * secondNumber
break;
case '/':
result = firstNumber / secondNumber
break;
default:
break;
}
this.updateState({
firstNumber: result.toString(),
currentOperator: '',
input: '0',
})
return result
}
render() {
let audio = new Audio(meow);
return (
<div className="App">
<div className={'Calculator'}>
<div id={'displayBox'}>
<div id={'display'}>{this.state.display}</div>
<div>{this.state.input}</div>
</div>
{numbers.map((name, i) => (
<div className={'number'} id={name} onClick={() => this.handleInput(i)}>{i}</div>
))}
<div id={'add'} className={'operator'} onClick={() => this.handleOperator('add')}>
<i className="fa-sharp fa-solid fa-plus" ></i>
</div>
<div id={'subtract'} className={'operator'} onClick={() => this.handleOperator('subtract')}>
<i className="fa-sharp fa-solid fa-minus"></i>
</div>
<div id={'multiply'} className={'operator'} onClick={() => this.handleOperator('multiply')}>
<i className="fa-sharp fa-solid fa-xmark"></i>
</div>
<div id={'divide'} className={'operator'} onClick={() => this.handleOperator('divide')}>
<i className="fa-sharp fa-solid fa-divide"></i>
</div>
<div id={'equals'} onClick={() => {this.handleEquals()}}>
=
</div>
<div id={'clear'} onClick={this.clear}>
C
</div>
<div id={'decimal'} onClick={() => {
this.handleDecimal()
}}>
.
</div>
<div id={'cat'} onClick={() => audio.play()}>
<i className="fa-solid fa-paw"></i>
</div>
</div>
</div>
);
}
}

View file

@ -0,0 +1,130 @@
body{
margin: 0
}
.App {
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
margin: 0;
background-color: darkgrey;
}
.Calculator {
height: 600px;
width: 400px;
display: grid;
grid-template-columns: repeat(4, 0.5fr);
grid-template-rows: repeat(6, 1fr);
grid-gap: 20px;
padding: 10px;
background-color: black;
border-radius: 5px;;
box-shadow: rgba(240, 46, 170, 0.4) 5px 5px, rgba(240, 46, 170, 0.3) 10px 10px, rgba(240, 46, 170, 0.2) 15px 15px, rgba(240, 46, 170, 0.1) 20px 20px, rgba(240, 46, 170, 0.05) 25px 25px;
div{
color: white;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
font-size: 24px;
box-shadow: rgba(0, 0, 0, 0.17) 0px -23px 25px 0px inset, rgba(0, 0, 0, 0.15) 0px -36px 30px 0px inset, rgba(0, 0, 0, 0.1) 0px -79px 40px 0px inset, rgba(0, 0, 0, 0.06) 0px 2px 1px, rgba(0, 0, 0, 0.09) 0px 4px 2px, rgba(0, 0, 0, 0.09) 0px 8px 4px, rgba(0, 0, 0, 0.09) 0px 16px 8px, rgba(0, 0, 0, 0.09) 0px 32px 16px;
}
#displayBox {
width: initial;
height: initial;
display: flex;
flex-direction: column;
justify-content: space-evenly;
align-items: flex-end;
}
.number, #decimal, #cat{
background-color: grey;
}
.operator, #equals{
background-color: orange;
}
#clear{
background-color: red;
}
#displayBox { grid-area: 1 / 1 / 2 / 5; }
#zero { grid-area: 6 / 1 / 7 / 2; }
#one { grid-area: 5 / 1 / 6 / 2; }
#two { grid-area: 5 / 2 / 6 / 3; }
#three { grid-area: 5 / 3 / 6 / 4; }
#four { grid-area: 4 / 1 / 5 / 2; }
#five { grid-area: 4 / 2 / 5 / 3; }
#six { grid-area: 4 / 3 / 5 / 4; }
#seven { grid-area: 3 / 1 / 4 / 2; }
#eight { grid-area: 3 / 2 / 4 / 3; }
#nine { grid-area: 3 / 3 / 4 / 4; }
#decimal { grid-area: 6 / 3 / 7 / 4; }
#clear { grid-area: 2 / 1 / 3 / 2; }
#add { grid-area: 5 / 4 / 6 / 5; }
#subtract { grid-area: 4 / 4 / 5 / 5; }
#multiply { grid-area: 3 / 4 / 4 / 5; }
#divide { grid-area: 2 / 4 / 3 / 5; }
#equals { grid-area: 6 / 4 / 7 / 5; }
#cat { grid-area: 6 / 2 / 7 / 3; }
}
/* Extra small devices (phones, 600px and down) */
@media only screen and (max-width: 600px) {
.Calculator {
height: 100%;
width: 100%;
div {
font-size: 12px
}
}
}
/* Small devices (portrait tablets and large phones, 600px and up) */
@media only screen and (min-width: 600px) {
.Calculator {
height: 200px;
width: 133px;
div {
font-size: 14px
}
}
}
/* Medium devices (landscape tablets, 768px and up) */
@media only screen and (min-width: 768px) {
.Calculator {
height: 300px;
width: 200px;
div {
font-size: 16px
}
}
}
/* Large devices (laptops/desktops, 992px and up) */
@media only screen and (min-width: 992px) {
.Calculator {
height: 400px;
width: 266px;
div {
font-size: 20px
}
}
}

View file

@ -0,0 +1,8 @@
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(<App />, document.getElementById("root"));

Binary file not shown.