Skip to content

Commit ae66023

Browse files
committed
first commit
0 parents  commit ae66023

15 files changed

+758
-0
lines changed

.gitignore

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Avoid accidental upload of the Sketch and Figma design files
2+
#####################################################
3+
## Please do not remove lines 5 and 6 - thanks! 🙂 ##
4+
#####################################################
5+
*.sketch
6+
*.fig
7+
8+
# Avoid accidental XD upload if you convert the design file
9+
###############################################
10+
## Please do not remove line 12 - thanks! 🙂 ##
11+
###############################################
12+
*.xd
13+
14+
# Avoid your project being littered with annoying .DS_Store files!
15+
.DS_Store
16+
.prettierignore

README.md

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Frontend Mentor - Tip calculator app solution
2+
3+
This is a solution to the [Tip calculator app challenge on Frontend Mentor](https://www.frontendmentor.io/challenges/tip-calculator-app-ugJNGbJUX). Frontend Mentor challenges help you improve your coding skills by building realistic projects.
4+
5+
### The challenge
6+
7+
Users should be able to:
8+
9+
- View the optimal layout for the app depending on their device's screen size
10+
- See hover states for all interactive elements on the page
11+
- Calculate the correct tip and total cost of the bill per person
12+
13+
### What I learned
14+
15+
I learned how to style placeholders and add images as backgrounds.
16+
17+
```css
18+
::placeholder {
19+
color: hsl(184, 14%, 56%);
20+
}
21+
22+
ol li #custom-tip::placeholder {
23+
color: hsl(186, 14%, 43%);
24+
font-size: 1.375rem;
25+
position: absolute;
26+
top: 0.3125rem;
27+
left: 0.625rem;
28+
}
29+
30+
#left-section input {
31+
background-image: url("images/icon-dollar.svg");
32+
}
33+
```
34+
35+

app.js

+150
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
const billInputField = document.getElementById("bill-amount");
2+
const billWarning = document.getElementById("bill-warning");
3+
4+
const tipAmountElements = document.querySelectorAll(".tip-percentage");
5+
const tipAmountCustom = document.querySelector("#tip-custom input");
6+
7+
const peopleInputField = document.getElementById("people-number");
8+
const peopleWarning = document.getElementById("people-warning");
9+
10+
const tipAmountResult = document.querySelector("#tip-amount p");
11+
const totalAmountResult = document.querySelector("#total-amount p");
12+
13+
const resetButton = document.querySelector("button");
14+
15+
let bill = 0;
16+
let people = 0;
17+
let tipPercent = 0;
18+
19+
let tipAmount = 0;
20+
let totalAmount = 0;
21+
22+
function getInput(event) {
23+
let inputValue = event.target.value;
24+
return inputValue;
25+
}
26+
27+
function getClickedButtonValue(event) {
28+
let buttonValue;
29+
let tipString = event.target.textContent;
30+
31+
event.target.classList.add("selected");
32+
33+
deselectButtons();
34+
resetCustomTipField();
35+
36+
buttonValue = +tipString.slice(0, tipString.indexOf("$"));
37+
return buttonValue;
38+
}
39+
40+
function deselectButtons() {
41+
for (const tipAmountElement of tipAmountElements) {
42+
if (tipAmountElement !== event.target) {
43+
tipAmountElement.classList.remove("selected");
44+
}
45+
}
46+
}
47+
48+
function resetCustomTipField() {
49+
tipAmountCustom.value = '';
50+
}
51+
52+
billInputField.addEventListener("keyup", getInput);
53+
54+
billInputField.addEventListener("focusout", updateBillValue);
55+
billInputField.addEventListener("keyup", updateBillValue);
56+
57+
function updateBillValue() {
58+
bill = getInput(event);
59+
60+
if (bill == 0 || bill === "") {
61+
billWarning.textContent = "Can't be zero";
62+
billInputField.classList.add("warning");
63+
} else {
64+
billWarning.textContent = "";
65+
billInputField.classList.remove("warning");
66+
}
67+
68+
calculateMoney();
69+
}
70+
71+
peopleInputField.addEventListener("click", getInput);
72+
73+
peopleInputField.addEventListener("focusout", updatePeopleNumber);
74+
peopleInputField.addEventListener("keyup", updatePeopleNumber);
75+
76+
function updatePeopleNumber() {
77+
people = getInput(event);
78+
79+
if (people == 0 || people === "") {
80+
peopleWarning.textContent = "Can't be zero";
81+
peopleInputField.classList.add("warning");
82+
} else {
83+
peopleWarning.textContent = "";
84+
peopleInputField.classList.remove("warning");
85+
}
86+
87+
calculateMoney();
88+
}
89+
90+
for (const tipAmountElement of tipAmountElements) {
91+
tipAmountElement.addEventListener("click", getClickedButtonValue);
92+
tipAmountElement.addEventListener("click", updateTipValue);
93+
}
94+
95+
function updateTipValue() {
96+
tipPercent = getClickedButtonValue(event) / 100;
97+
calculateMoney();
98+
}
99+
100+
tipAmountCustom.addEventListener("keyup", getInput);
101+
tipAmountCustom.addEventListener("keyup", updateCustomTipValue);
102+
tipAmountCustom.addEventListener("focus", deselectButtons);
103+
104+
function updateCustomTipValue() {
105+
tipPercent = getInput(event) / 100;
106+
calculateMoney();
107+
}
108+
109+
resetButton.addEventListener("click", resetValues);
110+
111+
function resetValues() {
112+
billInputField.value = "";
113+
tipAmountCustom.value = "";
114+
peopleInputField.value = "";
115+
116+
bill = 0;
117+
people = 0;
118+
tipPercent = 0;
119+
120+
tipAmount = 0;
121+
totalAmount = 0;
122+
123+
deselectButtons();
124+
125+
updateInterface();
126+
}
127+
128+
function calculateMoney() {
129+
tipAmount = (bill * tipPercent) / people;
130+
tipAmount = +tipAmount.toFixed(2);
131+
132+
totalAmount = (bill / people) + tipAmount;
133+
totalAmount = +totalAmount.toFixed(2);
134+
135+
updateInterface();
136+
}
137+
138+
function updateInterface() {
139+
if (isNaN(tipAmount) || !isFinite(tipAmount)) {
140+
return;
141+
} else {
142+
tipAmountResult.textContent = "$" + tipAmount;
143+
}
144+
145+
if (isNaN(totalAmount) || !isFinite(totalAmount)) {
146+
return;
147+
} else {
148+
totalAmountResult.textContent = "$" + totalAmount;
149+
}
150+
}

design/active-states.jpg

36.8 KB
Loading

design/desktop-design-completed.jpg

32.5 KB
Loading

design/desktop-design-empty.jpg

30.7 KB
Loading

design/desktop-preview.jpg

36.3 KB
Loading

design/mobile-design.jpg

21.9 KB
Loading

images/favicon-32x32.png

1.04 KB
Loading

images/icon-dollar.svg

+1
Loading

images/icon-person.svg

+1
Loading

images/logo.svg

+1
Loading

index.html

+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<link
7+
rel="icon"
8+
type="image/png"
9+
sizes="32x32"
10+
href="./images/favicon-32x32.png"
11+
/>
12+
<title>Frontend Mentor | Tip calculator app</title>
13+
<link rel="preconnect" href="https://fonts.googleapis.com" />
14+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
15+
<link
16+
href="https://fonts.googleapis.com/css2?family=Space+Mono:wght@700&display=swap"
17+
rel="stylesheet"
18+
/>
19+
<link rel="stylesheet" href="styles.css" />
20+
<script src="app.js" defer></script>
21+
</head>
22+
<body>
23+
<main>
24+
<img id="logo-image" src="images/logo.svg" alt="splitter logo" />
25+
<div id="calculator">
26+
<div id="left-section">
27+
<div id="bill-label">
28+
<label for="bill-amount">Bill</label>
29+
<p id="bill-warning"></p>
30+
</div>
31+
<input
32+
type="number"
33+
id="bill-amount"
34+
name="bill-amount"
35+
placeholder="0"
36+
/>
37+
<div id="tip-select">
38+
<p>Select Tip %</p>
39+
<ol>
40+
<li class="tip-percentage">5%</li>
41+
<li class="tip-percentage">10%</li>
42+
<li class="tip-percentage">15%</li>
43+
<li class="tip-percentage">25%</li>
44+
<li class="tip-percentage">50%</li>
45+
<li id="tip-custom">
46+
<input
47+
type="number"
48+
id="custom-tip"
49+
name="custom-tip"
50+
placeholder="Custom"
51+
/>
52+
</li>
53+
</ol>
54+
</div>
55+
56+
<div id="people-number-select">
57+
<div id="people-label">
58+
<label for="people-number">Number of People</label>
59+
<p id="people-warning"></p>
60+
</div>
61+
<input
62+
type="number"
63+
id="people-number"
64+
name="people-number"
65+
placeholder="0"
66+
/>
67+
</div>
68+
</div>
69+
70+
<div id="right-section">
71+
<div id="tip">
72+
<div id="tip-text">
73+
<p>Tip Amount</p>
74+
<p>/ person</p>
75+
</div>
76+
<div id="tip-amount">
77+
<p>$0.00</p>
78+
</div>
79+
</div>
80+
<div id="total">
81+
<div id="total-text">
82+
<p>Total</p>
83+
<p>/ person</p>
84+
</div>
85+
<div id="total-amount">
86+
<p>$0.00</p>
87+
</div>
88+
</div>
89+
<button>Reset</button>
90+
</div>
91+
</div>
92+
</main>
93+
94+
<div class="attribution">
95+
Challenge by
96+
<a href="https://www.frontendmentor.io?ref=challenge" target="_blank"
97+
>Frontend Mentor</a
98+
>. Coded by
99+
<a href="https://www.frontendmentor.io/profile/UrkeNzY">UrkeNzY</a>.
100+
</div>
101+
</body>
102+
</html>

style-guide.md

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Front-end Style Guide
2+
3+
## Layout
4+
5+
The designs were created to the following widths:
6+
7+
- Mobile: 375px
8+
- Desktop: 1440px
9+
10+
## Colors
11+
12+
### Primary
13+
14+
- Strong cyan: hsl(172, 67%, 45%)
15+
16+
### Neutral
17+
18+
- Very dark cyan: hsl(183, 100%, 15%)
19+
- Dark grayish cyan: hsl(186, 14%, 43%)
20+
- Grayish cyan: hsl(184, 14%, 56%)
21+
- Light grayish cyan: hsl(185, 41%, 84%)
22+
- Very light grayish cyan: hsl(189, 41%, 97%)
23+
- White: hsl(0, 0%, 100%)
24+
25+
## Typography
26+
27+
### Body Copy
28+
29+
- Font size (form inputs): 24px
30+
31+
### Font
32+
33+
- Family: [Space Mono](https://fonts.google.com/specimen/Space+Mono)
34+
- Weights: 700

0 commit comments

Comments
 (0)