Skip to content

Commit c406c87

Browse files
Merge branch 'main' into path_to_exit
2 parents fd390ac + 4297f15 commit c406c87

File tree

34 files changed

+6785
-517
lines changed

34 files changed

+6785
-517
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ vanillaverse/
4444
├── projects/ # Individual mini-project folders
4545
│ └── example/
4646
│ ├── index.html
47-
│ └── main.js # Each includes TODOs for contributors
47+
│ └── main.js # Each includes TODOs
4848
└── .github/ # Issue templates and deploy workflow
4949
```
5050

data/projects.json

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
11
[
2+
{
3+
"title": "Contributors Page",
4+
"slug": "contributor",
5+
"description": "See the contributions of people",
6+
"category": "contributor",
7+
"categoryKey": "contributor",
8+
"difficulty": "easy"
9+
},
210
{
311
"title": "Snake Game",
412
"slug": "snake",
@@ -231,14 +239,6 @@
231239
"categoryKey": "games",
232240
"difficulty": "easy"
233241
},
234-
{
235-
"title": "Contributors Page",
236-
"slug": "contributor",
237-
"description": "See the contributions of people",
238-
"category": "contributor",
239-
"categoryKey": "contributor",
240-
"difficulty": "easy"
241-
},
242242
{
243243
"title": "Rhythm Tap Garden",
244244
"slug": "rhythm-tap-garden",
@@ -310,5 +310,13 @@
310310
"category": "Fun UI / Visual",
311311
"categoryKey": "visual",
312312
"difficulty": "easy"
313+
},
314+
{
315+
"title": "Color Constellation",
316+
"slug": "color-constellation",
317+
"description": "Link stars to form constellations that match a given silhouette pattern. Lines cannot cross.",
318+
"category": "Small Games",
319+
"categoryKey": "games",
320+
"difficulty": "medium"
313321
}
314322
]
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 2.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)