Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions data/projects.json
Original file line number Diff line number Diff line change
Expand Up @@ -216,11 +216,22 @@
"difficulty": "easy"
},
{

"title": "Tip Calculator",
"slug": "Tip Calculator",
"description": "Calculate tips and divide bills accurately in seconds",
"category": "Productivity",
"categoryKey": "productivity",
"difficulty": "easy"
},
{

"title": "Hangman Game",
"slug": "hangman",
"description": "A two player word guessing game where one enters a secret word and the other tries to guess it.",
"category": "Small Games",
"categoryKey": "games",
"difficulty": "medium"

}
]
83 changes: 83 additions & 0 deletions projects/Tip Calculator/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Tip Calculator</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<button id="themeToggle" class="theme-toggle" aria-label="Toggle theme">
<svg
class="sun-icon"
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<circle cx="12" cy="12" r="5" />
<line x1="12" y1="1" x2="12" y2="3" />
<line x1="12" y1="21" x2="12" y2="23" />
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64" />
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78" />
<line x1="1" y1="12" x2="3" y2="12" />
<line x1="21" y1="12" x2="23" y2="12" />
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36" />
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22" />
</svg>
<svg
class="moon-icon"
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" />
</svg>
</button>
<h1>Tip Calculator</h1>

<div class="container">
<label for="bill">Enter total amount in ₹:</label>
<input
id="bill"
class="bill"
type="number"
placeholder="e.g. 50"
min="0"
/>

<h3>Select tip percentage:</h3>
<div class="tip-buttons">
<button type="button" class="tip-btn" data-tip="10">10%</button>
<button type="button" class="tip-btn" data-tip="15">15%</button>
<button type="button" class="tip-btn" data-tip="20">20%</button>
</div>

<label for="custom-tip">Or enter custom tip %:</label>
<input id="custom-tip" type="number" placeholder="e.g. 18" min="0" />

<label for="split">Number of people to split bill:</label>
<input
id="split"
class="split"
type="number"
placeholder="e.g. 2"
min="1"
value="1"
/>

<div class="results">
<h3>Tip Amount: <span id="tip-amount">Rs0.00</span></h3>
<h3>Total Bill: <span id="total-bill">Rs0.00</span></h3>
<h3>Total per Person: <span id="per-person">Rs0.00</span></h3>
</div>
</div>

<script src="main.js"></script>
</body>
</html>
67 changes: 67 additions & 0 deletions projects/Tip Calculator/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
const billInput = document.querySelector(".bill");
const splitInput = document.querySelector(".split");
const tipButtons = document.querySelectorAll(".tip-btn");
const customTipInput = document.getElementById("custom-tip");
const tipAmountDisplay = document.getElementById("tip-amount");
const totalBillDisplay = document.getElementById("total-bill");
const perPersonDisplay = document.getElementById("per-person");

let tipPercentage = 0;

tipButtons.forEach(btn => {
btn.addEventListener("click", () => {
tipPercentage = Number(btn.dataset.tip);
customTipInput.value = ""; // clear custom tip
tipButtons.forEach(b => b.classList.remove("active"));
btn.classList.add("active");
calculateTotals();
});
});


[billInput, splitInput, customTipInput].forEach(input => {
input.addEventListener("input", () => calculateTotals());
});


function calculateTotals() {
const bill = parseFloat(billInput.value);
const people = parseInt(splitInput.value) || 1;
const customTip = parseFloat(customTipInput.value);

// Use custom tip if entered
const tipPercent = customTip > 0 ? customTip : tipPercentage;

// Prevent calculation for empty bill
if (isNaN(bill) || bill <= 0) {
updateDisplay(0, 0, 0);
return;
}

const tipAmount = (bill * tipPercent) / 100;
const totalBill = bill + tipAmount;
const perPerson = totalBill / people;

updateDisplay(tipAmount, totalBill, perPerson);
}

function updateDisplay(tip, total, perPerson) {
tipAmountDisplay.textContent = `Rs${tip.toFixed(2)}`;
totalBillDisplay.textContent = `Rs${total.toFixed(2)}`;
perPersonDisplay.textContent = `Rs${perPerson.toFixed(2)}`;
}

const themeToggle = document.getElementById("themeToggle");
const body = document.body;

const currentTheme = localStorage.getItem("theme") || "light";
if (currentTheme === "dark") {
body.classList.add("dark-mode");
}

themeToggle.addEventListener("click", () => {
body.classList.toggle("dark-mode");

const theme = body.classList.contains("dark-mode") ? "dark" : "light";
localStorage.setItem("theme", theme);
});
Loading