35900-vm/add_food.php
2025-11-21 12:22:08 +00:00

173 lines
6.8 KiB
PHP

<?php
require_once __DIR__ . '/db/config.php';
$success_message = "";
$error_message = "";
if ($_SERVER["REQUEST_METHOD"] == "POST") {
if (!empty($_POST['food_name']) && !empty($_POST['calories']) && is_numeric($_POST['calories'])) {
try {
$food_name = $_POST['food_name'];
$calories = (int)$_POST['calories'];
$pdo = db();
$stmt = $pdo->prepare("INSERT INTO food_log (food_name, calories) VALUES (?, ?)");
$stmt->execute([$food_name, $calories]);
$success_message = "Successfully added $food_name with $calories calories!";
} catch (PDOException $e) {
$error_message = "Error: Could not record the food. " . $e->getMessage();
}
} else {
$error_message = "Please fill out all fields correctly.";
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Add Food - Calorie Tracker</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
<?php if ($success_message): ?>
<meta http-equiv="refresh" content="2;url=index.php">
<?php endif; ?>
</head>
<body>
<div class="mobile-container">
<header class="app-header">
<h1>Add Food</h1>
</header>
<main class="main-content">
<?php if ($success_message): ?>
<div class="alert success">
<?php echo $success_message; ?>
<p>Redirecting you home...</p>
</div>
<?php else: ?>
<?php if ($error_message): ?>
<div class="alert error">
<?php echo $error_message; ?>
</div>
<?php endif; ?>
<div class="food-search-container">
<div class="form-group">
<label for="food_search">Search for a food</label>
<input type="text" id="food_search" placeholder="e.g., Apple">
</div>
<button type="button" id="search_btn" class="btn">Search</button>
<div id="search_results"></div>
</div>
<form action="add_food.php" method="POST" class="add-sale-form">
<div class="form-group">
<label for="food_name">Food Name</label>
<input type="text" id="food_name" name="food_name" required>
</div>
<div class="form-group">
<label for="calories">Calories</label>
<input type="number" id="calories" name="calories" min="0" required>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Log Food</button>
</div>
</form>
<?php endif; ?>
</main>
<nav class="bottom-nav">
<a href="index.php" class="nav-item">
<i class="bi bi-house-door-fill"></i>
<span>Home</span>
</a>
<a href="add_food.php" class="nav-item active">
<i class="bi bi-plus-circle-fill"></i>
<span>Add Food</span>
</a>
<a href="dashboard.php" class="nav-item">
<i class="bi bi-bar-chart-line-fill"></i>
<span>Dashboard</span>
</a>
</nav>
</div>
<script>
function debounce(func, wait) {
let timeout;
return function(...args) {
const context = this;
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(context, args), wait);
};
}
const searchInput = document.getElementById('food_search');
const searchBtn = document.getElementById('search_btn');
const resultsContainer = document.getElementById('search_results');
// Hide the original search button, as search will be triggered by typing
searchBtn.style.display = 'none';
const searchHandler = debounce(function() {
const searchTerm = searchInput.value;
if (searchTerm.trim() === '') {
resultsContainer.innerHTML = '';
return;
}
resultsContainer.innerHTML = '<p style="padding: 15px;">Searching...</p>';
fetch(`https://world.openfoodfacts.org/cgi/search.pl?search_terms=${encodeURIComponent(searchTerm)}&action=process&json=1&page_size=10`)
.then(response => response.json())
.then(data => {
resultsContainer.innerHTML = '';
if (data.products && data.products.length > 0) {
const list = document.createElement('ul');
list.className = 'search-results-list'; // Add a class for styling
data.products.forEach(product => {
const productName = product.product_name_en || product.product_name || 'Unknown Food';
const calories = product.nutriments['energy-kcal_100g'] || product.nutriments['energy-kcal'] || 0;
if (!productName.trim()) {
return;
}
const listItem = document.createElement('li');
listItem.innerHTML = `${productName} <span>(${calories} kcal/100g)</span>`;
listItem.addEventListener('click', function() {
document.getElementById('food_name').value = productName;
document.getElementById('calories').value = calories;
resultsContainer.innerHTML = '';
searchInput.value = '';
});
list.appendChild(listItem);
});
resultsContainer.appendChild(list);
} else {
resultsContainer.innerHTML = '<p style="padding: 15px;">No results found.</p>';
}
})
.catch(error => {
console.error('Error fetching data:', error);
resultsContainer.innerHTML = '<p style="padding: 15px;">An error occurred while searching.</p>';
});
}, 300); // 300ms debounce delay
searchInput.addEventListener('input', searchHandler);
</script>
</body>
</html>