goog modal
This commit is contained in:
parent
ea0af5455b
commit
87c4c5dcc3
@ -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; }
|
||||
|
||||
@ -655,25 +655,102 @@ 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());
|
||||
@ -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();
|
||||
|
||||
97
index.php
97
index.php
@ -27,7 +27,7 @@
|
||||
<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(); ?>_v19">
|
||||
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>_v20">
|
||||
|
||||
</head>
|
||||
<body>
|
||||
@ -225,21 +225,14 @@
|
||||
<i class="bi bi-camera fs-3 me-3"></i>
|
||||
<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>
|
||||
</button>
|
||||
<button class="btn btn-outline-primary p-3 text-start d-flex align-items-center rounded-4 add-option-btn" data-method="web">
|
||||
<i class="bi bi-globe fs-3 me-3"></i>
|
||||
<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-link-45deg fs-3 me-3"></i>
|
||||
<div>
|
||||
<div class="fw-bold">Save from the web</div>
|
||||
<div class="small text-muted">Paste a recipe URL</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 class="fw-bold">Save from a link</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="ingredients">
|
||||
@ -262,6 +255,82 @@
|
||||
</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 -->
|
||||
<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">
|
||||
@ -434,7 +503,7 @@
|
||||
|
||||
<!-- Scripts -->
|
||||
<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 -->
|
||||
<div class="modal fade" id="confirmRemoveModal" tabindex="-1" aria-labelledby="confirmRemoveModalLabel" aria-hidden="true">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user