From 87c4c5dcc3aedfb6d5cf2f068c59e0a9aac7ac73 Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Sun, 1 Feb 2026 19:28:07 +0000 Subject: [PATCH] goog modal --- assets/css/custom.css | 61 +++++++++++++++++++++++ assets/js/main.js | 110 ++++++++++++++++++++++++++++++++++++------ index.php | 97 +++++++++++++++++++++++++++++++------ 3 files changed, 239 insertions(+), 29 deletions(-) diff --git a/assets/css/custom.css b/assets/css/custom.css index 56e16e1..37058a3 100644 --- a/assets/css/custom.css +++ b/assets/css/custom.css @@ -620,6 +620,67 @@ body:has(#guest-view:not(.d-none)) footer { } } +/* Modal Custom Styles */ +.modal-content { + border-radius: 28px !important; +} + +.add-option-btn { + border: 2px solid #F0F0F0 !important; + transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) !important; +} + +.add-option-btn:hover { + border-color: var(--brand-primary) !important; + background-color: #F7FAF9 !important; + transform: scale(1.02); +} + +.add-option-btn i { + color: var(--brand-primary); + background: #E9F5EF; + width: 60px; + height: 60px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 18px; + transition: all 0.3s ease; +} + +.add-option-btn:hover i { + background: var(--brand-primary); + color: #ffffff; +} + +#take-photo-btn, #take-products-photo-btn { + background: linear-gradient(135deg, var(--brand-primary) 0%, var(--brand-primary-hover) 100%) !important; + border: none !important; + box-shadow: 0 10px 20px rgba(45, 106, 79, 0.2); +} + +#take-photo-btn:hover, #take-products-photo-btn:hover { + transform: translateY(-5px); + box-shadow: 0 15px 30px rgba(45, 106, 79, 0.3); +} + +#upload-image-btn { + border: 2px dashed var(--brand-primary) !important; + background: #F7FAF9 !important; + color: var(--brand-primary) !important; +} + +#upload-image-btn:hover { + background: #E9F5EF !important; + transform: translateY(-5px); +} + +#manual-ingredients-list { + border-radius: 18px; + padding: 15px; + background-color: #F9F9F9; +} + /* Print Styles */ @media print { body { background-color: white; } diff --git a/assets/js/main.js b/assets/js/main.js index ab5437f..750e80b 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -655,27 +655,104 @@ const app = { const method = btn.dataset.method; app.dom.addRecipeOptionsModal.hide(); - if (method === 'scratch' || method === 'photo') { + if (method === 'scratch') { app.ui.clearForm(); app.dom.recipeFormModal.show(); - if (method === 'photo') { - setTimeout(() => app.dom.recipeImage.click(), 500); - } - } else if (method === 'web' || method === 'social') { - const url = prompt('Please enter the URL of the recipe:'); - if (url) { - alert('Analyzing recipe from URL... (Feature integration in progress)'); - // Here you would typically call an AI endpoint to scrape/analyze the URL - } + } else if (method === 'photo') { + app.dom.addRecipePhotoModal.show(); + } else if (method === 'link') { + app.dom.addRecipeLinkModal.show(); } else if (method === 'ingredients') { - const ingredients = prompt('What ingredients do you have? (comma separated)'); - if (ingredients) { - alert('Generating a recipe from: ' + ingredients + '... (Feature integration in progress)'); - // Here you would call an AI endpoint to generate a recipe - } + app.dom.addRecipeIngredientsModal.show(); } }); + // Specific Modal Handlers + document.getElementById('take-photo-btn').addEventListener('click', () => { + document.getElementById('photo-camera-input').click(); + }); + document.getElementById('upload-image-btn').addEventListener('click', () => { + document.getElementById('photo-upload-input').click(); + }); + + const handlePhotoInput = async (e) => { + const file = e.target.files[0]; + if (!file) return; + + app.dom.addRecipePhotoModal.hide(); + app.ui.clearForm(); + app.dom.recipeFormModal.show(); + + // Trigger AI Scan logic + app.dom.aiScanBtn.disabled = true; + app.dom.aiScanLoading.classList.remove('d-none'); + + const formData = new FormData(); + formData.append('image', file); + + try { + const response = await fetch('api/scan_recipe.php', { + method: 'POST', + body: formData + }); + const result = await response.json(); + + if (result.success) { + const data = result.data; + 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.guests) app.dom.guestCountInput.value = data.guests; + + if (data.ingredients && Array.isArray(data.ingredients)) { + app.dom.ingredientsContainer.innerHTML = ''; + data.ingredients.forEach(ing => { + app.ui.addIngredientRow({ + name: ing.name || '', + quantity: ing.quantity || '', + unit: ing.unit || 'g' + }); + }); + } + } else { + alert('AI scan error: ' + result.error); + } + } catch (error) { + console.error('Error during AI scan:', error); + } finally { + app.dom.aiScanBtn.disabled = false; + app.dom.aiScanLoading.classList.add('d-none'); + } + }; + + document.getElementById('photo-camera-input').addEventListener('change', handlePhotoInput); + document.getElementById('photo-upload-input').addEventListener('change', handlePhotoInput); + + document.getElementById('save-from-link-confirm').addEventListener('click', () => { + const url = document.getElementById('link-recipe-url').value; + if (!url) { alert('Please enter a link'); return; } + alert('Extracting recipe from: ' + url + '... (Integration in progress)'); + app.dom.addRecipeLinkModal.hide(); + }); + + document.getElementById('take-products-photo-btn').addEventListener('click', () => { + document.getElementById('products-camera-input').click(); + }); + + document.getElementById('products-camera-input').addEventListener('change', (e) => { + const file = e.target.files[0]; + if (!file) return; + alert('AI is analyzing your products... (Integration in progress)'); + app.dom.addRecipeIngredientsModal.hide(); + }); + + document.getElementById('generate-from-ingredients-btn').addEventListener('click', () => { + const list = document.getElementById('manual-ingredients-list').value; + if (!list) { alert('Please enter some ingredients'); return; } + alert('Generating recipe from: ' + list + '... (Integration in progress)'); + app.dom.addRecipeIngredientsModal.hide(); + }); + app.dom.addIngredientBtn.addEventListener('click', () => app.ui.addIngredientRow()); app.dom.aiScanBtn.addEventListener('click', async function() { @@ -1091,6 +1168,9 @@ const app = { productCategoryWrapper: document.getElementById('product-category-wrapper'), productCategory: document.getElementById('productCategory'), addRecipeOptionsModal: new bootstrap.Modal(document.getElementById('add-recipe-options-modal')), + addRecipePhotoModal: new bootstrap.Modal(document.getElementById('add-recipe-photo-modal')), + addRecipeLinkModal: new bootstrap.Modal(document.getElementById('add-recipe-link-modal')), + addRecipeIngredientsModal: new bootstrap.Modal(document.getElementById('add-recipe-ingredients-modal')), }; app.ui.loadCheckedItems(); diff --git a/index.php b/index.php index 8ac5a78..6ae046a 100644 --- a/index.php +++ b/index.php @@ -27,7 +27,7 @@ - + @@ -225,21 +225,14 @@
Create from a photo
-
Scan a physical recipe or a dish
+
AI turns a photo into a step-by-step recipe
- - + + + + + + + + + + + +