Spaces:
Running
Running
Here's a detailed breakdown of the food logging components in a calorie tracker app:
f121505
verified
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Calorie Tracker</title> | |
| <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css"> | |
| <style> | |
| body { | |
| padding: 20px; | |
| background-color: #f8f9fa; | |
| } | |
| .calorie-card { | |
| background: white; | |
| border-radius: 10px; | |
| padding: 20px; | |
| box-shadow: 0 2px 10px rgba(0,0,0,0.1); | |
| margin-bottom: 20px; | |
| } | |
| .meal-entry { | |
| margin-bottom: 15px; | |
| padding: 10px; | |
| border: 1px solid #dee2e6; | |
| border-radius: 5px; | |
| background: #f8f9fa; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <div class="calorie-card"> | |
| <h1 class="text-center mb-4">Calorie Tracker</h1> | |
| <div class="row mb-4"> | |
| <div class="col-md-6"> | |
| <h3>Add New Meal</h3> | |
| <form id="mealForm"> | |
| <div class="mb-3"> | |
| <label for="mealType" class="form-label">Meal Type</label> | |
| <select class="form-select" id="mealType"> | |
| <option value="breakfast">Breakfast</option> | |
| <option value="lunch">Lunch</option> | |
| <option value="dinner">Dinner</option> | |
| <option value="snack">Snack</option> | |
| </select> | |
| </div> | |
| <div class="mb-3"> | |
| <label for="mealName" class="form-label">Food Item</label> | |
| <input type="text" class="form-control" id="mealName" required> | |
| </div> | |
| <div class="mb-3"> | |
| <label for="quantity" class="form-label">Quantity</label> | |
| <div class="input-group"> | |
| <input type="number" class="form-control" id="quantity" value="1" min="0.1" step="0.1"> | |
| <select class="form-select" id="unit"> | |
| <option value="g">g</option> | |
| <option value="oz">oz</option> | |
| <option value="cup">cup</option> | |
| <option value="tbsp">tbsp</option> | |
| <option value="serving">serving</option> | |
| </select> | |
| </div> | |
| </div> | |
| <div class="mb-3"> | |
| <label for="calories" class="form-label">Calories</label> | |
| <input type="number" class="form-control" id="calories" required> | |
| </div> | |
| <div class="d-flex gap-2"> | |
| <button type="submit" class="btn btn-primary">Add Meal</button> | |
| <button type="button" class="btn btn-outline-secondary" data-bs-toggle="modal" data-bs-target="#barcodeModal"> | |
| <i data-feather="maximize"></i> Scan Barcode | |
| </button> | |
| </div> | |
| </form> | |
| </div> | |
| <div class="col-md-6"> | |
| <h3>Daily Summary</h3> | |
| <div class="card"> | |
| <div class="card-body"> | |
| <h5 class="card-title">Total Calories</h5> | |
| <h2 id="totalCalories">0</h2> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div id="mealList"> | |
| <div class="d-flex justify-content-between align-items-center mb-3"> | |
| <h3>Today's Meals</h3> | |
| <div> | |
| <button id="sortByName" class="btn btn-sm btn-outline-secondary me-2">Sort by Name</button> | |
| <button id="sortByCalories" class="btn btn-sm btn-outline-secondary">Sort by Calories</button> | |
| </div> | |
| </div> | |
| <div class="accordion" id="mealsAccordion"> | |
| <div class="accordion-item"> | |
| <h2 class="accordion-header"> | |
| <button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#breakfastCollapse"> | |
| Breakfast (0 cal) | |
| </button> | |
| </h2> | |
| <div id="breakfastCollapse" class="accordion-collapse collapse show" data-bs-parent="#mealsAccordion"> | |
| <div class="accordion-body p-0" id="breakfastContainer"></div> | |
| </div> | |
| </div> | |
| <div class="accordion-item"> | |
| <h2 class="accordion-header"> | |
| <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#lunchCollapse"> | |
| Lunch (0 cal) | |
| </button> | |
| </h2> | |
| <div id="lunchCollapse" class="accordion-collapse collapse" data-bs-parent="#mealsAccordion"> | |
| <div class="accordion-body p-0" id="lunchContainer"></div> | |
| </div> | |
| </div> | |
| <div class="accordion-item"> | |
| <h2 class="accordion-header"> | |
| <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#dinnerCollapse"> | |
| Dinner (0 cal) | |
| </button> | |
| </h2> | |
| <div id="dinnerCollapse" class="accordion-collapse collapse" data-bs-parent="#mealsAccordion"> | |
| <div class="accordion-body p-0" id="dinnerContainer"></div> | |
| </div> | |
| </div> | |
| <div class="accordion-item"> | |
| <h2 class="accordion-header"> | |
| <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#snacksCollapse"> | |
| Snacks (0 cal) | |
| </button> | |
| </h2> | |
| <div id="snacksCollapse" class="accordion-collapse collapse" data-bs-parent="#mealsAccordion"> | |
| <div class="accordion-body p-0" id="snacksContainer"></div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Barcode Modal --> | |
| <div class="modal fade" id="barcodeModal" tabindex="-1" aria-hidden="true"> | |
| <div class="modal-dialog"> | |
| <div class="modal-content"> | |
| <div class="modal-header"> | |
| <h5 class="modal-title">Scan Barcode</h5> | |
| <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> | |
| </div> | |
| <div class="modal-body text-center"> | |
| <div id="barcodeScanner" style="width: 100%; height: 300px; background: #eee; margin-bottom: 15px;"></div> | |
| <p>Or enter barcode manually:</p> | |
| <input type="text" class="form-control mb-3" id="manualBarcode" placeholder="Enter barcode number"> | |
| <button id="lookupBarcode" class="btn btn-primary">Lookup</button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script> | |
| <script> | |
| document.addEventListener('DOMContentLoaded', function() { | |
| feather.replace(); | |
| document.getElementById('mealForm').addEventListener('submit', function(e) { | |
| e.preventDefault(); | |
| const mealName = document.getElementById('mealName').value; | |
| const calories = parseInt(document.getElementById('calories').value); | |
| if (!mealName || isNaN(calories)) return; | |
| addMeal(mealName, calories); | |
| updateTotal(); | |
| // Reset form | |
| document.getElementById('mealName').value = ''; | |
| document.getElementById('calories').value = ''; | |
| }); | |
| function addMeal(name, calories) { | |
| const mealsContainer = document.getElementById('mealsContainer'); | |
| const mealDiv = document.createElement('div'); | |
| mealDiv.className = 'meal-entry'; | |
| mealDiv.innerHTML = ` | |
| <div class="d-flex justify-content-between"> | |
| <strong>${name}</strong> | |
| <span>${calories} cal</span> | |
| </div> | |
| `; | |
| mealsContainer.appendChild(mealDiv); | |
| } | |
| function updateTotal() { | |
| const entries = document.querySelectorAll('.meal-entry span'); | |
| let total = 0; | |
| entries.forEach(entry => { | |
| const calories = parseInt(entry.textContent); | |
| total += calories; | |
| }); | |
| document.getElementById('totalCalories').textContent = total; | |
| } | |
| </script> | |
| </body> | |
| </html> |