ai recipes

This commit is contained in:
Flatlogic Bot 2026-01-30 22:49:40 +00:00
parent 70441c3380
commit 3830ef477f
6 changed files with 28 additions and 12 deletions

View File

@ -71,8 +71,8 @@ try {
$imageUrl = $existing['image_url']; $imageUrl = $existing['image_url'];
} }
$stmt = $pdo->prepare("UPDATE recipes SET name = ?, guests = ?, category = ?, image_url = ?, user_id = ? WHERE id = ?"); $stmt = $pdo->prepare("UPDATE recipes SET name = ?, guests = ?, category = ?, image_url = ?, instructions = ?, user_id = ? WHERE id = ?");
$stmt->execute([$data['name'], $data['guests'], $category, $imageUrl, $userId, $recipeId]); $stmt->execute([$data['name'], $data['guests'], $category, $imageUrl, $data['instructions'] ?? null, $userId, $recipeId]);
// Easiest way to handle ingredients is to delete old ones and insert new ones // Easiest way to handle ingredients is to delete old ones and insert new ones
$stmt = $pdo->prepare("DELETE FROM ingredients WHERE recipe_id = ?"); $stmt = $pdo->prepare("DELETE FROM ingredients WHERE recipe_id = ?");
@ -81,8 +81,8 @@ try {
} else { } else {
// Insert new recipe // Insert new recipe
$category = !empty($data['category']) ? $data['category'] : 'No category'; $category = !empty($data['category']) ? $data['category'] : 'No category';
$stmt = $pdo->prepare("INSERT INTO recipes (name, guests, category, image_url, user_id) VALUES (?, ?, ?, ?, ?)"); $stmt = $pdo->prepare("INSERT INTO recipes (name, guests, category, image_url, instructions, user_id) VALUES (?, ?, ?, ?, ?, ?)");
$stmt->execute([$data['name'], $data['guests'], $category, $imageUrl, $userId]); $stmt->execute([$data['name'], $data['guests'], $category, $imageUrl, $data['instructions'] ?? null, $userId]);
$recipeId = $pdo->lastInsertId(); $recipeId = $pdo->lastInsertId();
} }

View File

@ -28,6 +28,7 @@ Provide the information in JSON format IN ENGLISH:
- name: Ingredient name - name: Ingredient name
- quantity: Numeric quantity (float) - quantity: Numeric quantity (float)
- unit: Unit of measurement (e.g., 'g', 'kg', 'ml', 'l', 'pcs', 'pack') - unit: Unit of measurement (e.g., 'g', 'kg', 'ml', 'l', 'pcs', 'pack')
- instructions: A string containing clear, step-by-step cooking instructions. Use newlines (\n) between steps.
- guests: Default number of guests/portions (integer) - guests: Default number of guests/portions (integer)
Important: Important:
@ -71,6 +72,7 @@ Provide the information in JSON format IN ENGLISH:
- name: Ingredient name - name: Ingredient name
- quantity: Numeric quantity (float) - quantity: Numeric quantity (float)
- unit: Unit of measurement (e.g., 'g', 'kg', 'ml', 'l', 'pcs', 'pack') - unit: Unit of measurement (e.g., 'g', 'kg', 'ml', 'l', 'pcs', 'pack')
- instructions: A string containing clear, step-by-step cooking instructions. Use newlines (\n) between steps.
- guests: Default number of guests/portions (integer) - guests: Default number of guests/portions (integer)
Important: Important:

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

View File

@ -394,6 +394,7 @@ const app = {
clearForm() { clearForm() {
app.dom.recipeIdInput.value = ''; app.dom.recipeIdInput.value = '';
app.dom.recipeNameInput.value = ''; app.dom.recipeNameInput.value = '';
app.dom.recipeInstructionsInput.value = '';
app.dom.recipeCategoryInput.value = ''; app.dom.recipeCategoryInput.value = '';
app.dom.recipeImage.value = ''; app.dom.recipeImage.value = '';
app.dom.guestCountInput.value = '1'; app.dom.guestCountInput.value = '1';
@ -409,6 +410,7 @@ const app = {
app.dom.recipeIdInput.value = recipe.id; app.dom.recipeIdInput.value = recipe.id;
app.dom.recipeNameInput.value = recipe.name; app.dom.recipeNameInput.value = recipe.name;
app.dom.recipeInstructionsInput.value = recipe.instructions || '';
app.dom.recipeCategoryInput.value = recipe.category || ''; app.dom.recipeCategoryInput.value = recipe.category || '';
app.dom.guestCountInput.value = recipe.guests; app.dom.guestCountInput.value = recipe.guests;
@ -450,6 +452,7 @@ const app = {
recipe.category === 'Dinner' ? 'Lunch/Dinner' : recipe.category === 'Dinner' ? 'Lunch/Dinner' :
recipe.category === 'Appetizers' ? 'Appetizers' : 'No category'; recipe.category === 'Appetizers' ? 'Appetizers' : 'No category';
document.getElementById('view-recipe-guests').textContent = recipe.guests; document.getElementById('view-recipe-guests').textContent = recipe.guests;
document.getElementById('view-recipe-instructions').textContent = recipe.instructions || 'No instructions provided.';
const ingredientsList = document.getElementById('view-recipe-ingredients'); const ingredientsList = document.getElementById('view-recipe-ingredients');
ingredientsList.innerHTML = ''; ingredientsList.innerHTML = '';
@ -467,6 +470,7 @@ const app = {
}, },
getRecipeDataFromForm() { getRecipeDataFromForm() {
const recipeName = app.dom.recipeNameInput.value.trim(); const recipeName = app.dom.recipeNameInput.value.trim();
const instructions = app.dom.recipeInstructionsInput.value.trim();
const guests = parseInt(app.dom.guestCountInput.value, 10) || 0; const guests = parseInt(app.dom.guestCountInput.value, 10) || 0;
const category = app.dom.recipeCategoryInput.value; const category = app.dom.recipeCategoryInput.value;
@ -486,7 +490,7 @@ const app = {
}); });
if (recipeName && guests > 0 && ingredients.length > 0) { if (recipeName && guests > 0 && ingredients.length > 0) {
return { name: recipeName, guests, ingredients, category }; return { name: recipeName, instructions, guests, ingredients, category };
} }
return null; return null;
}, },
@ -607,6 +611,7 @@ const app = {
if (result.success) { if (result.success) {
const data = result.data; const data = result.data;
if (data.name) app.dom.recipeNameInput.value = data.name; if (data.name) app.dom.recipeNameInput.value = data.name;
if (data.instructions) app.dom.recipeInstructionsInput.value = data.instructions;
if (data.category) app.dom.recipeCategoryInput.value = data.category; if (data.category) app.dom.recipeCategoryInput.value = data.category;
if (data.guests) app.dom.guestCountInput.value = data.guests; if (data.guests) app.dom.guestCountInput.value = data.guests;
@ -657,6 +662,7 @@ const app = {
const formData = new FormData(); const formData = new FormData();
formData.append('name', recipeData.name); formData.append('name', recipeData.name);
formData.append('instructions', recipeData.instructions);
formData.append('guests', recipeData.guests); formData.append('guests', recipeData.guests);
formData.append('category', recipeData.category); formData.append('category', recipeData.category);
formData.append('ingredients', JSON.stringify(recipeData.ingredients)); formData.append('ingredients', JSON.stringify(recipeData.ingredients));
@ -943,6 +949,7 @@ const app = {
init() { init() {
app.dom = { app.dom = {
recipeNameInput: document.getElementById('recipeName'), recipeNameInput: document.getElementById('recipeName'),
recipeInstructionsInput: document.getElementById('recipeInstructions'),
guestCountInput: document.getElementById('guestCount'), guestCountInput: document.getElementById('guestCount'),
portionsPerGuestInput: document.getElementById('portionsPerGuest'), portionsPerGuestInput: document.getElementById('portionsPerGuest'),
ingredientsContainer: document.getElementById('ingredients-container'), ingredientsContainer: document.getElementById('ingredients-container'),

View File

@ -0,0 +1,2 @@
-- Add instructions column to recipes table
ALTER TABLE `recipes` ADD COLUMN `instructions` TEXT DEFAULT NULL;

View File

@ -76,15 +76,11 @@
<div class="feature-list mt-4 text-start position-relative"> <div class="feature-list mt-4 text-start position-relative">
<div class="d-flex mb-3 align-items-center transition-all feature-item"> <div class="d-flex mb-3 align-items-center transition-all feature-item">
<span class="checkmark"></span> <span class="checkmark"></span>
<h5 class="mb-0">AI Recipes from Photos</h5> <h5 class="mb-0">AI Recipes from Images & Prompts</h5>
</div> </div>
<div class="d-flex mb-3 align-items-center transition-all feature-item"> <div class="d-flex mb-3 align-items-center transition-all feature-item">
<span class="checkmark"></span> <span class="checkmark"></span>
<h5 class="mb-0">Smart Shopping Lists</h5> <h5 class="mb-0">Auto-Generated Shopping Lists</h5>
</div>
<div class="d-flex mb-3 align-items-center transition-all feature-item">
<span class="checkmark"></span>
<h5 class="mb-0">AI Recipe Flow on Laptop</h5>
</div> </div>
<div class="d-flex mb-3 align-items-center transition-all feature-item"> <div class="d-flex mb-3 align-items-center transition-all feature-item">
<span class="checkmark"></span> <span class="checkmark"></span>
@ -262,6 +258,11 @@
<hr class="my-4 border-secondary"> <hr class="my-4 border-secondary">
<div class="mb-3">
<label for="recipeInstructions" class="form-label">Cooking instructions</label>
<textarea class="form-control" id="recipeInstructions" rows="5" placeholder="Step 1. Prep... \nStep 2. Cook..."></textarea>
</div>
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<div class="mb-3"> <div class="mb-3">
@ -356,8 +357,12 @@
<p><strong>Guest count:</strong> <span id="view-recipe-guests"></span></p> <p><strong>Guest count:</strong> <span id="view-recipe-guests"></span></p>
<hr> <hr>
<h3>Ingredients</h3> <h3>Ingredients</h3>
<ul id="view-recipe-ingredients" class="list-group"> <ul id="view-recipe-ingredients" class="list-group mb-4">
</ul> </ul>
<hr>
<h3>Cooking instructions</h3>
<div id="view-recipe-instructions" class="p-3 bg-light rounded" style="white-space: pre-line;">
</div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>