ux: merge vacuum sealed question into move-after-use modal

Instead of a separate floating prompt after use, the vacuum sealed checkbox
is now shown directly inside the 'where to put the rest?' modal:
- Always shown for container-type units (conf/g/kg/ml/l) or if previously sealed
- Pre-checked when the item was already vacuum sealed (semi-automatic)
- Saving on 'rimani qui' button also persists the vacuum state
- Saves one step: user answers location + vacuum in a single interaction
This commit is contained in:
dadaloop82
2026-05-10 13:23:40 +00:00
parent 75ca49ac4e
commit 93684c5842
2 changed files with 29 additions and 21 deletions
+28 -20
View File
@@ -7798,16 +7798,19 @@ function startMoveModalCountdown(btnId, onExpire) {
}, duration); }, duration);
} }
function showMoveAfterUseModal(product, fromLoc, remaining, openedId) { function showMoveAfterUseModal(product, fromLoc, remaining, openedId, openedVacuumSealed, unit) {
const otherLocs = Object.entries(LOCATIONS).filter(([k]) => k !== fromLoc); const otherLocs = Object.entries(LOCATIONS).filter(([k]) => k !== fromLoc);
const locButtons = otherLocs.map(([k, v]) => const locButtons = otherLocs.map(([k, v]) =>
`<button type="button" class="loc-btn" onclick="clearMoveModalTimer();confirmMoveAfterUse(${product.id}, '${fromLoc}', '${k}', ${openedId || 0})">${v.icon} ${v.label}</button>` `<button type="button" class="loc-btn" onclick="clearMoveModalTimer();confirmMoveAfterUse(${product.id}, '${fromLoc}', '${k}', ${openedId || 0})">${v.icon} ${v.label}</button>`
).join(''); ).join('');
const wasVacuum = !!product.vacuum_sealed; // Show vacuum checkbox for any container-type unit or if the item was previously vacuum sealed.
const vacuumRow = wasVacuum ? ` // Pre-checked when it was already sealed (semi-automatic: if you sealed it last time, you likely will again).
const wasVacuum = !!(openedVacuumSealed ?? product.vacuum_sealed);
const isContainer = ['conf','g','kg','ml','l'].includes(unit || product.unit || '') || wasVacuum;
const vacuumRow = isContainer ? `
<label style="display:flex;align-items:center;gap:8px;margin-top:12px;cursor:pointer"> <label style="display:flex;align-items:center;gap:8px;margin-top:12px;cursor:pointer">
<input type="checkbox" id="move-vacuum-check" checked> <input type="checkbox" id="move-vacuum-check" ${wasVacuum ? 'checked' : ''}>
<span>${t('move.vacuum_restore')}</span> <span>🔒 Metti <b>sotto vuoto</b> il resto${wasVacuum ? ' (era già sigillato)' : ''}</span>
</label>` : ''; </label>` : '';
document.getElementById('modal-content').innerHTML = ` document.getElementById('modal-content').innerHTML = `
<div class="modal-header"> <div class="modal-header">
@@ -7818,11 +7821,24 @@ function showMoveAfterUseModal(product, fromLoc, remaining, openedId) {
<p style="margin-bottom:12px">${t('move.question').replace('{thing}', openedId ? t('move.thing_opened') : t('move.thing_rest')).replace('{name}', `<strong>${escapeHtml(product.name)}</strong>`)}</p> <p style="margin-bottom:12px">${t('move.question').replace('{thing}', openedId ? t('move.thing_opened') : t('move.thing_rest')).replace('{name}', `<strong>${escapeHtml(product.name)}</strong>`)}</p>
<div class="location-selector">${locButtons}</div> <div class="location-selector">${locButtons}</div>
${vacuumRow} ${vacuumRow}
<button type="button" id="btn-move-stay" class="btn btn-secondary full-width move-countdown-btn" style="margin-top:12px" onclick="clearMoveModalTimer();closeModal();showPage('dashboard')">${t('move.stay_btn').replace('{location}', LOCATIONS[fromLoc]?.label || fromLoc)}</button> <button type="button" id="btn-move-stay" class="btn btn-secondary full-width move-countdown-btn" style="margin-top:12px" onclick="clearMoveModalTimer();_saveVacuumAndStay(${openedId || 0});">${t('move.stay_btn').replace('{location}', LOCATIONS[fromLoc]?.label || fromLoc)}</button>
</div> </div>
`; `;
document.getElementById('modal-overlay').style.display = 'flex'; document.getElementById('modal-overlay').style.display = 'flex';
startMoveModalCountdown('btn-move-stay', () => { closeModal(); showPage('dashboard'); }); startMoveModalCountdown('btn-move-stay', () => { _saveVacuumAndStay(openedId || 0); });
}
/** Save vacuum state when user chooses to keep the item at the current location. */
async function _saveVacuumAndStay(openedId) {
closeModal();
if (openedId) {
const isVacuum = document.getElementById('move-vacuum-check')?.checked ? 1 : 0;
try {
await api('inventory_update', {}, 'POST', { id: openedId, vacuum_sealed: isVacuum });
if (isVacuum) showToast('🔒 Sotto vuoto registrato', 'success');
} catch (_) {}
}
showPage('dashboard');
} }
async function confirmMoveAfterUse(productId, fromLoc, toLoc, openedId) { async function confirmMoveAfterUse(productId, fromLoc, toLoc, openedId) {
@@ -8054,20 +8070,12 @@ async function submitUse(e) {
// If there's remaining quantity, offer to move to another location // If there's remaining quantity, offer to move to another location
const usedFrom = document.getElementById('use-location').value; const usedFrom = document.getElementById('use-location').value;
_recordUseLocationChoice(currentProduct.id, usedFrom); // track for preferred-location feature _recordUseLocationChoice(currentProduct.id, usedFrom); // track for preferred-location feature
const moveCallback = result.remaining > 0
? () => showMoveAfterUseModal(currentProduct, usedFrom, result.remaining, result.opened_id)
: () => showPage('dashboard');
// Check low stock → Bring! prompt, then vacuum seal prompt if product was opened
const afterLowStock = moveCallback;
showLowStockBringPrompt(result, afterLowStock);
// Show vacuum sealed prompt when some stock remains and it's a container type
// (conf/weighted units) or the item was previously vacuum sealed.
// Skip for pz "counting" items (e.g. 3 mele → 2 mele: no vacuum concept).
const _vacUnit = result.product_unit || currentProduct?.unit || ''; const _vacUnit = result.product_unit || currentProduct?.unit || '';
const _vacContainer = ['conf','g','kg','ml','l'].includes(_vacUnit) || !!(result.opened_vacuum_sealed); const moveCallback = result.remaining > 0
if (result.opened_id && result.remaining > 0 && _vacContainer) { ? () => showMoveAfterUseModal(currentProduct, usedFrom, result.remaining, result.opened_id, result.opened_vacuum_sealed ?? 0, _vacUnit)
setTimeout(() => _showVacuumPrompt(result.opened_id, result.opened_vacuum_sealed ?? 0), 600); : () => showPage('dashboard');
} // Check low stock → Bring! prompt, then move/vacuum modal
showLowStockBringPrompt(result, moveCallback);
} else if (result.duplicate) { } else if (result.duplicate) {
// Silently ignore: this was a scale double-trigger, not a real error // Silently ignore: this was a scale double-trigger, not a real error
} else { } else {
+1 -1
View File
@@ -1462,6 +1462,6 @@
</div> </div>
</div> </div>
<script src="assets/js/app.js?v=20260510d"></script> <script src="assets/js/app.js?v=20260510e"></script>
</body> </body>
</html> </html>