Skip to content

Commit d52227f

Browse files
committed
added new project Tip calculator
1 parent 7dd44e1 commit d52227f

4 files changed

Lines changed: 389 additions & 2 deletions

File tree

data/projects.json

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,16 +196,24 @@
196196
"title": "Password Generator",
197197
"slug": "password-generator",
198198
"description": "Generate secure passwords with customizable options.",
199-
"category": "Productivity",
199+
"category": "Productivity",
200200
"categoryKey": "productivity",
201201
"difficulty": "easy"
202202
},
203203
{
204204
"title": "Simon Says",
205205
"slug": "simon-says",
206206
"description": "Play Simon Says",
207-
"category": "Small Games",
207+
"category": "Small Games",
208208
"categoryKey": "games",
209209
"difficulty": "easy"
210+
},
211+
{
212+
"title": "Tip Calculator",
213+
"slug": "Tip Calculator",
214+
"description": "Calculate tips and divide bills accurately in seconds",
215+
"category": "Productivity",
216+
"categoryKey": "productivity",
217+
"difficulty": "easy"
210218
}
211219
]

projects/Tip Calculator/index.html

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
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+
<title>Tip Calculator</title>
7+
<link rel="stylesheet" href="styles.css" />
8+
</head>
9+
<body>
10+
<button id="themeToggle" class="theme-toggle" aria-label="Toggle theme">
11+
<svg
12+
class="sun-icon"
13+
width="20"
14+
height="20"
15+
viewBox="0 0 24 24"
16+
fill="none"
17+
stroke="currentColor"
18+
stroke-width="2"
19+
>
20+
<circle cx="12" cy="12" r="5" />
21+
<line x1="12" y1="1" x2="12" y2="3" />
22+
<line x1="12" y1="21" x2="12" y2="23" />
23+
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64" />
24+
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78" />
25+
<line x1="1" y1="12" x2="3" y2="12" />
26+
<line x1="21" y1="12" x2="23" y2="12" />
27+
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36" />
28+
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22" />
29+
</svg>
30+
<svg
31+
class="moon-icon"
32+
width="20"
33+
height="20"
34+
viewBox="0 0 24 24"
35+
fill="none"
36+
stroke="currentColor"
37+
stroke-width="2"
38+
>
39+
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" />
40+
</svg>
41+
</button>
42+
<h1>Tip Calculator</h1>
43+
44+
<div class="container">
45+
<label for="bill">Enter total amount in ₹:</label>
46+
<input
47+
id="bill"
48+
class="bill"
49+
type="number"
50+
placeholder="e.g. 50"
51+
min="0"
52+
/>
53+
54+
<h3>Select tip percentage:</h3>
55+
<div class="tip-buttons">
56+
<button type="button" class="tip-btn" data-tip="10">10%</button>
57+
<button type="button" class="tip-btn" data-tip="15">15%</button>
58+
<button type="button" class="tip-btn" data-tip="20">20%</button>
59+
</div>
60+
61+
<label for="custom-tip">Or enter custom tip %:</label>
62+
<input id="custom-tip" type="number" placeholder="e.g. 18" min="0" />
63+
64+
<label for="split">Number of people to split bill:</label>
65+
<input
66+
id="split"
67+
class="split"
68+
type="number"
69+
placeholder="e.g. 2"
70+
min="1"
71+
value="1"
72+
/>
73+
74+
<div class="results">
75+
<h3>Tip Amount: <span id="tip-amount">Rs0.00</span></h3>
76+
<h3>Total Bill: <span id="total-bill">Rs0.00</span></h3>
77+
<h3>Total per Person: <span id="per-person">Rs0.00</span></h3>
78+
</div>
79+
</div>
80+
81+
<script src="main.js"></script>
82+
</body>
83+
</html>

projects/Tip Calculator/main.js

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
const billInput = document.querySelector(".bill");
2+
const splitInput = document.querySelector(".split");
3+
const tipButtons = document.querySelectorAll(".tip-btn");
4+
const customTipInput = document.getElementById("custom-tip");
5+
const tipAmountDisplay = document.getElementById("tip-amount");
6+
const totalBillDisplay = document.getElementById("total-bill");
7+
const perPersonDisplay = document.getElementById("per-person");
8+
9+
let tipPercentage = 0;
10+
11+
tipButtons.forEach(btn => {
12+
btn.addEventListener("click", () => {
13+
tipPercentage = Number(btn.dataset.tip);
14+
customTipInput.value = ""; // clear custom tip
15+
tipButtons.forEach(b => b.classList.remove("active"));
16+
btn.classList.add("active");
17+
calculateTotals();
18+
});
19+
});
20+
21+
22+
[billInput, splitInput, customTipInput].forEach(input => {
23+
input.addEventListener("input", () => calculateTotals());
24+
});
25+
26+
27+
function calculateTotals() {
28+
const bill = parseFloat(billInput.value);
29+
const people = parseInt(splitInput.value) || 1;
30+
const customTip = parseFloat(customTipInput.value);
31+
32+
// Use custom tip if entered
33+
const tipPercent = customTip > 0 ? customTip : tipPercentage;
34+
35+
// Prevent calculation for empty bill
36+
if (isNaN(bill) || bill <= 0) {
37+
updateDisplay(0, 0, 0);
38+
return;
39+
}
40+
41+
const tipAmount = (bill * tipPercent) / 100;
42+
const totalBill = bill + tipAmount;
43+
const perPerson = totalBill / people;
44+
45+
updateDisplay(tipAmount, totalBill, perPerson);
46+
}
47+
48+
function updateDisplay(tip, total, perPerson) {
49+
tipAmountDisplay.textContent = `Rs${tip.toFixed(2)}`;
50+
totalBillDisplay.textContent = `Rs${total.toFixed(2)}`;
51+
perPersonDisplay.textContent = `Rs${perPerson.toFixed(2)}`;
52+
}
53+
54+
const themeToggle = document.getElementById("themeToggle");
55+
const body = document.body;
56+
57+
const currentTheme = localStorage.getItem("theme") || "light";
58+
if (currentTheme === "dark") {
59+
body.classList.add("dark-mode");
60+
}
61+
62+
themeToggle.addEventListener("click", () => {
63+
body.classList.toggle("dark-mode");
64+
65+
const theme = body.classList.contains("dark-mode") ? "dark" : "light";
66+
localStorage.setItem("theme", theme);
67+
});

0 commit comments

Comments
 (0)