148 lines
5.6 KiB
JavaScript
148 lines
5.6 KiB
JavaScript
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
|
|
// --- Snowflakes Effect ---
|
|
function createSnowflakes() {
|
|
const snowflakeContainer = document.body;
|
|
for (let i = 0; i < 50; i++) {
|
|
const snowflake = document.createElement('div');
|
|
snowflake.className = 'snowflake';
|
|
snowflake.textContent = '❄';
|
|
snowflake.style.left = Math.random() * 100 + 'vw';
|
|
snowflake.style.animationDuration = (Math.random() * 3 + 2) + 's'; // 2-5 seconds
|
|
snowflake.style.animationDelay = Math.random() * 2 + 's';
|
|
snowflake.style.opacity = Math.random();
|
|
snowflake.style.fontSize = Math.random() * 10 + 10 + 'px';
|
|
snowflakeContainer.appendChild(snowflake);
|
|
}
|
|
}
|
|
|
|
createSnowflakes();
|
|
|
|
// --- Calculator Logic ---
|
|
const ingredientsContainer = document.getElementById('ingredients-container');
|
|
const addIngredientBtn = document.getElementById('add-ingredient');
|
|
const calculateBtn = document.getElementById('calculate-btn');
|
|
const shoppingListContainer = document.getElementById('shopping-list-container');
|
|
|
|
let ingredientIndex = 1;
|
|
|
|
function addIngredientRow() {
|
|
ingredientIndex++;
|
|
const row = document.createElement('div');
|
|
row.className = 'ingredient-row mb-2';
|
|
row.innerHTML = `
|
|
<input type="text" class="form-control" placeholder="Ingredient Name" aria-label="Ingredient Name">
|
|
<input type="number" class="form-control" placeholder="Qty" aria-label="Quantity" min="0" step="any">
|
|
<input type="text" class="form-control" placeholder="Unit (e.g., grams, ml)" aria-label="Unit">
|
|
<button type="button" class="btn btn-danger btn-sm remove-ingredient">×</button>
|
|
`;
|
|
ingredientsContainer.appendChild(row);
|
|
}
|
|
|
|
if (addIngredientBtn) {
|
|
addIngredientBtn.addEventListener('click', addIngredientRow);
|
|
}
|
|
|
|
if (ingredientsContainer) {
|
|
ingredientsContainer.addEventListener('click', function(e) {
|
|
if (e.target.classList.contains('remove-ingredient')) {
|
|
e.target.closest('.ingredient-row').remove();
|
|
}
|
|
});
|
|
}
|
|
|
|
if (calculateBtn) {
|
|
calculateBtn.addEventListener('click', function() {
|
|
const recipeName = document.getElementById('recipeName').value || 'My Festive Recipe';
|
|
const guestCount = parseInt(document.getElementById('guestCount').value, 10);
|
|
|
|
if (isNaN(guestCount) || guestCount <= 0) {
|
|
alert('Please enter a valid number of guests.');
|
|
return;
|
|
}
|
|
|
|
const ingredients = [];
|
|
const rows = ingredientsContainer.querySelectorAll('.ingredient-row');
|
|
rows.forEach(row => {
|
|
const name = row.children[0].value;
|
|
const qty = parseFloat(row.children[1].value);
|
|
const unit = row.children[2].value;
|
|
|
|
if (name && !isNaN(qty) && qty > 0) {
|
|
ingredients.push({ name, qty, unit });
|
|
}
|
|
});
|
|
|
|
if (ingredients.length === 0) {
|
|
alert('Please add at least one ingredient.');
|
|
return;
|
|
}
|
|
|
|
// Calculate totals
|
|
const shoppingList = {};
|
|
ingredients.forEach(ing => {
|
|
const totalQty = ing.qty * guestCount;
|
|
const key = ing.name.toLowerCase().trim() + '_' + (ing.unit || '').toLowerCase().trim();
|
|
|
|
if (shoppingList[key]) {
|
|
shoppingList[key].qty += totalQty;
|
|
} else {
|
|
shoppingList[key] = {
|
|
name: ing.name,
|
|
qty: totalQty,
|
|
unit: ing.unit
|
|
};
|
|
}
|
|
});
|
|
|
|
// Render shopping list
|
|
renderShoppingList(recipeName, guestCount, Object.values(shoppingList));
|
|
});
|
|
}
|
|
|
|
function renderShoppingList(recipeName, guestCount, list) {
|
|
let html = `<h3>${recipeName} - Shopping List for ${guestCount} Guests</h3><hr>`;
|
|
|
|
if (list.length === 0) {
|
|
html += '<p>No ingredients to show. Please fill out the recipe form.</p>';
|
|
} else {
|
|
html += '<ul class="list-group list-group-flush">';
|
|
list.forEach(item => {
|
|
html += `<li class="list-group-item d-flex justify-content-between align-items-center">
|
|
<span>${item.name}</span>
|
|
<span class="badge bg-primary rounded-pill">${formatQuantity(item.qty)} ${item.unit}</span>
|
|
</li>`;
|
|
});
|
|
html += '</ul>';
|
|
}
|
|
|
|
shoppingListContainer.innerHTML = html;
|
|
}
|
|
|
|
function formatQuantity(qty) {
|
|
// Simple formatting, can be expanded for fractions
|
|
return parseFloat(qty.toFixed(2));
|
|
}
|
|
|
|
const newRecipeBtn = document.getElementById('new-recipe-btn');
|
|
|
|
if (newRecipeBtn) {
|
|
newRecipeBtn.addEventListener('click', function() {
|
|
document.getElementById('recipeName').value = '';
|
|
document.getElementById('guestCount').value = '';
|
|
ingredientsContainer.innerHTML = '';
|
|
addIngredientRow(); // Add a fresh row
|
|
shoppingListContainer.innerHTML = `
|
|
<div class="text-center text-muted p-5">
|
|
<h3 class="h4">Your Shopping List</h3>
|
|
<p>Your calculated list will appear here.</p>
|
|
</div>
|
|
`;
|
|
});
|
|
}
|
|
|
|
// Add one ingredient row by default
|
|
addIngredientRow();
|
|
});
|