goog modal

This commit is contained in:
Flatlogic Bot 2026-02-01 19:28:07 +00:00
parent ea0af5455b
commit 87c4c5dcc3
3 changed files with 239 additions and 29 deletions

View File

@ -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 */ /* Print Styles */
@media print { @media print {
body { background-color: white; } body { background-color: white; }

View File

@ -655,25 +655,102 @@ const app = {
const method = btn.dataset.method; const method = btn.dataset.method;
app.dom.addRecipeOptionsModal.hide(); app.dom.addRecipeOptionsModal.hide();
if (method === 'scratch' || method === 'photo') { if (method === 'scratch') {
app.ui.clearForm(); app.ui.clearForm();
app.dom.recipeFormModal.show(); app.dom.recipeFormModal.show();
if (method === 'photo') { } else if (method === 'photo') {
setTimeout(() => app.dom.recipeImage.click(), 500); app.dom.addRecipePhotoModal.show();
} } else if (method === 'link') {
} else if (method === 'web' || method === 'social') { app.dom.addRecipeLinkModal.show();
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 === 'ingredients') { } else if (method === 'ingredients') {
const ingredients = prompt('What ingredients do you have? (comma separated)'); app.dom.addRecipeIngredientsModal.show();
if (ingredients) {
alert('Generating a recipe from: ' + ingredients + '... (Feature integration in progress)');
// Here you would call an AI endpoint to generate a recipe
} }
});
// 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.addIngredientBtn.addEventListener('click', () => app.ui.addIngredientRow());
@ -1091,6 +1168,9 @@ const app = {
productCategoryWrapper: document.getElementById('product-category-wrapper'), productCategoryWrapper: document.getElementById('product-category-wrapper'),
productCategory: document.getElementById('productCategory'), productCategory: document.getElementById('productCategory'),
addRecipeOptionsModal: new bootstrap.Modal(document.getElementById('add-recipe-options-modal')), 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(); app.ui.loadCheckedItems();

View File

@ -27,7 +27,7 @@
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <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 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="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(); ?>_v19"> <link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>_v20">
</head> </head>
<body> <body>
@ -225,21 +225,14 @@
<i class="bi bi-camera fs-3 me-3"></i> <i class="bi bi-camera fs-3 me-3"></i>
<div> <div>
<div class="fw-bold">Create from a photo</div> <div class="fw-bold">Create from a photo</div>
<div class="small text-muted">Scan a physical recipe or a dish</div> <div class="small text-muted">AI turns a photo into a step-by-step recipe</div>
</div> </div>
</button> </button>
<button class="btn btn-outline-primary p-3 text-start d-flex align-items-center rounded-4 add-option-btn" data-method="web"> <button class="btn btn-outline-primary p-3 text-start d-flex align-items-center rounded-4 add-option-btn" data-method="link">
<i class="bi bi-globe fs-3 me-3"></i> <i class="bi bi-link-45deg fs-3 me-3"></i>
<div> <div>
<div class="fw-bold">Save from the web</div> <div class="fw-bold">Save from a link</div>
<div class="small text-muted">Paste a recipe URL</div> <div class="small text-muted">Add a recipe from any website or social media post</div>
</div>
</button>
<button class="btn btn-outline-primary p-3 text-start d-flex align-items-center rounded-4 add-option-btn" data-method="social">
<i class="bi bi-instagram fs-3 me-3"></i>
<div>
<div class="fw-bold">Save from social media</div>
<div class="small text-muted">Instagram, TikTok, Pinterest</div>
</div> </div>
</button> </button>
<button class="btn btn-outline-primary p-3 text-start d-flex align-items-center rounded-4 add-option-btn" data-method="ingredients"> <button class="btn btn-outline-primary p-3 text-start d-flex align-items-center rounded-4 add-option-btn" data-method="ingredients">
@ -262,6 +255,82 @@
</div> </div>
</div> </div>
<!-- Modal: Create from Photo -->
<div class="modal fade" id="add-recipe-photo-modal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content border-0 shadow-lg" style="border-radius: 20px;">
<div class="modal-header border-0 pb-0">
<h5 class="modal-title fw-bold">Create from a photo</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body p-4">
<div class="d-grid gap-3">
<button class="btn btn-primary p-4 rounded-4 d-flex flex-column align-items-center" id="take-photo-btn">
<i class="bi bi-camera-fill fs-1 mb-2"></i>
<span class="fw-bold">Take a photo</span>
</button>
<button class="btn btn-outline-primary p-4 rounded-4 d-flex flex-column align-items-center" id="upload-image-btn">
<i class="bi bi-image-fill fs-1 mb-2"></i>
<span class="fw-bold">Upload an image</span>
</button>
<input type="file" id="photo-camera-input" accept="image/*" capture="environment" class="d-none">
<input type="file" id="photo-upload-input" accept="image/*" class="d-none">
</div>
</div>
</div>
</div>
</div>
<!-- Modal: Save from Link -->
<div class="modal fade" id="add-recipe-link-modal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content border-0 shadow-lg" style="border-radius: 20px;">
<div class="modal-header border-0 pb-0">
<h5 class="modal-title fw-bold">Save from a link</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body p-4">
<div class="mb-4">
<label class="form-label text-muted">Paste a link to any website, Instagram, TikTok or Pinterest</label>
<input type="url" class="form-control form-control-lg rounded-3" id="link-recipe-url" placeholder="https://example.com/recipe or https://instagram.com/p/...">
</div>
<div class="d-grid">
<button class="btn btn-primary btn-lg rounded-3" id="save-from-link-confirm">Extract recipe</button>
</div>
</div>
</div>
</div>
</div>
<!-- Modal: Create from Ingredients -->
<div class="modal fade" id="add-recipe-ingredients-modal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content border-0 shadow-lg" style="border-radius: 20px;">
<div class="modal-header border-0 pb-0">
<h5 class="modal-title fw-bold">Create from ingredients</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body p-4">
<div class="d-grid gap-3">
<button class="btn btn-primary p-4 rounded-4 d-flex flex-column align-items-center" id="take-products-photo-btn">
<i class="bi bi-camera-fill fs-1 mb-2"></i>
<span class="fw-bold">Take a photo of the products</span>
</button>
<div class="text-center text-muted small my-1">OR</div>
<div class="mb-3">
<label class="form-label text-muted">Enter the list manually</label>
<textarea class="form-control rounded-3" id="manual-ingredients-list" rows="3" placeholder="Chicken, broccoli, rice..."></textarea>
</div>
<div class="d-grid">
<button class="btn btn-outline-primary btn-lg rounded-3" id="generate-from-ingredients-btn">Generate recipe</button>
</div>
<input type="file" id="products-camera-input" accept="image/*" capture="environment" class="d-none">
</div>
</div>
</div>
</div>
</div>
<!-- Modal Recipe Form --> <!-- Modal Recipe Form -->
<div class="modal fade" id="recipe-form-modal" tabindex="-1" aria-labelledby="recipe-form-modal-label" aria-hidden="true"> <div class="modal fade" id="recipe-form-modal" tabindex="-1" aria-labelledby="recipe-form-modal-label" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered"> <div class="modal-dialog modal-dialog-centered">
@ -434,7 +503,7 @@
<!-- Scripts --> <!-- Scripts -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<script src="assets/js/main.js?v=<?php echo time(); ?>_v10"></script> <script src="assets/js/main.js?v=<?php echo time(); ?>_v12"></script>
<!-- Confirmation Modal --> <!-- Confirmation Modal -->
<div class="modal fade" id="confirmRemoveModal" tabindex="-1" aria-labelledby="confirmRemoveModalLabel" aria-hidden="true"> <div class="modal fade" id="confirmRemoveModal" tabindex="-1" aria-labelledby="confirmRemoveModalLabel" aria-hidden="true">