diff --git a/shopping_app/static/css/style.css b/shopping_app/static/css/style.css index 918ee55..19adb1a 100644 --- a/shopping_app/static/css/style.css +++ b/shopping_app/static/css/style.css @@ -3619,6 +3619,28 @@ input[type="checkbox"].form-check-input, flex: 0 0 auto; } +.endpoint-list .shopping-product-input-group > .shopping-compact-submit, +.endpoint-list_share .shopping-product-input-group > .shopping-compact-submit, +.endpoint-shared_list .shopping-product-input-group > .shopping-compact-submit, +.endpoint-list .shopping-expense-input-group > .shopping-compact-submit, +.endpoint-list_share .shopping-expense-input-group > .shopping-compact-submit, +.endpoint-shared_list .shopping-expense-input-group > .shopping-compact-submit { + border-top-left-radius: 0 !important; + border-bottom-left-radius: 0 !important; + border-top-right-radius: .9rem !important; + border-bottom-right-radius: .9rem !important; + margin-left: 0; +} + +.endpoint-list .shopping-product-input-group, +.endpoint-list_share .shopping-product-input-group, +.endpoint-shared_list .shopping-product-input-group, +.endpoint-list .shopping-expense-input-group, +.endpoint-list_share .shopping-expense-input-group, +.endpoint-shared_list .shopping-expense-input-group { + flex-wrap: nowrap; +} + @media (max-width: 991.98px) { .navbar-collapse .app-navbar__actions { padding-top: .6rem; @@ -3658,17 +3680,26 @@ input[type="checkbox"].form-check-input, .shopping-product-input-group > .shopping-product-name-input, .shopping-expense-input-group > .shopping-expense-amount-input { - flex: 1 1 auto; + flex: 0 0 60%; min-width: 0; } .shopping-product-input-group > .shopping-qty-input { - flex: 0 0 3.8rem; - max-width: 3.8rem; + flex: 0 0 15%; + max-width: 15%; + min-width: 0; } - .shopping-expense-input-group > .shopping-compact-submit, .shopping-product-input-group > .shopping-compact-submit { + flex: 0 0 25%; + width: 25%; + min-width: 0; + padding-left: .55rem; + padding-right: .55rem; + font-size: .95rem; + } + + .shopping-expense-input-group > .shopping-compact-submit { padding-left: .7rem; padding-right: .7rem; } @@ -3712,3 +3743,272 @@ input[type="checkbox"].form-check-input, display: inline !important; } } + + +/* form input/button unification fix 2026-03-15 */ +.endpoint-list .shopping-product-input-group, +.endpoint-list_share .shopping-product-input-group, +.endpoint-shared_list .shopping-product-input-group, +.endpoint-list .shopping-expense-input-group, +.endpoint-list_share .shopping-expense-input-group, +.endpoint-shared_list .shopping-expense-input-group { + display: flex; + flex-wrap: nowrap !important; + align-items: stretch; + gap: 0 !important; +} + +.endpoint-list .shopping-product-input-group > .form-control, +.endpoint-list_share .shopping-product-input-group > .form-control, +.endpoint-shared_list .shopping-product-input-group > .form-control, +.endpoint-list .shopping-expense-input-group > .form-control, +.endpoint-list_share .shopping-expense-input-group > .form-control, +.endpoint-shared_list .shopping-expense-input-group > .form-control, +.endpoint-list .shopping-product-input-group > .btn, +.endpoint-list_share .shopping-product-input-group > .btn, +.endpoint-shared_list .shopping-product-input-group > .btn, +.endpoint-list .shopping-expense-input-group > .btn, +.endpoint-list_share .shopping-expense-input-group > .btn, +.endpoint-shared_list .shopping-expense-input-group > .btn { + position: relative; + min-height: 46px; + box-shadow: none; +} + +.endpoint-list .shopping-product-input-group > .shopping-product-name-input, +.endpoint-list_share .shopping-product-input-group > .shopping-product-name-input, +.endpoint-shared_list .shopping-product-input-group > .shopping-product-name-input, +.endpoint-list .shopping-expense-input-group > .shopping-expense-amount-input, +.endpoint-list_share .shopping-expense-input-group > .shopping-expense-amount-input, +.endpoint-shared_list .shopping-expense-input-group > .shopping-expense-amount-input { + border-top-right-radius: 0 !important; + border-bottom-right-radius: 0 !important; +} + +.endpoint-list .shopping-product-input-group > .shopping-qty-input, +.endpoint-list_share .shopping-product-input-group > .shopping-qty-input, +.endpoint-shared_list .shopping-product-input-group > .shopping-qty-input { + border-radius: 0 !important; + border-left-width: 0 !important; +} + +.endpoint-list .shopping-product-input-group > .shopping-compact-submit, +.endpoint-list_share .shopping-product-input-group > .shopping-compact-submit, +.endpoint-shared_list .shopping-product-input-group > .shopping-compact-submit, +.endpoint-list .shopping-expense-input-group > .shopping-compact-submit, +.endpoint-list_share .shopping-expense-input-group > .shopping-compact-submit, +.endpoint-shared_list .shopping-expense-input-group > .shopping-compact-submit { + display: inline-flex; + align-items: center; + justify-content: center; + gap: .35rem; + margin-left: 0 !important; + border-top-left-radius: 0 !important; + border-bottom-left-radius: 0 !important; + border-top-right-radius: .9rem !important; + border-bottom-right-radius: .9rem !important; + border-left-width: 0 !important; +} + +.endpoint-list .shopping-product-input-group > .shopping-compact-submit, +.endpoint-list .shopping-expense-input-group > .shopping-compact-submit, +.endpoint-list_share .shopping-product-input-group > .shopping-compact-submit, +.endpoint-list_share .shopping-expense-input-group > .shopping-compact-submit, +.endpoint-shared_list .shopping-product-input-group > .shopping-compact-submit, +.endpoint-shared_list .shopping-expense-input-group > .shopping-compact-submit, +.endpoint-list .share-submit-btn, +.endpoint-list_share .share-submit-btn, +.endpoint-shared_list .share-submit-btn { + min-width: 7.25rem; +} + +.shopping-btn-icon { + line-height: 1; +} + +.shopping-btn-label { + line-height: 1; +} + +@media (max-width: 767.98px) { + .endpoint-list .shopping-product-input-group, + .endpoint-list_share .shopping-product-input-group, + .endpoint-shared_list .shopping-product-input-group, + .endpoint-list .shopping-expense-input-group, + .endpoint-list_share .shopping-expense-input-group, + .endpoint-shared_list .shopping-expense-input-group { + width: 100%; + } + + .endpoint-list .shopping-product-input-group > .shopping-product-name-input, + .endpoint-list_share .shopping-product-input-group > .shopping-product-name-input, + .endpoint-shared_list .shopping-product-input-group > .shopping-product-name-input { + flex: 0 0 60% !important; + max-width: 60% !important; + min-width: 0; + } + + .endpoint-list .shopping-product-input-group > .shopping-qty-input, + .endpoint-list_share .shopping-product-input-group > .shopping-qty-input, + .endpoint-shared_list .shopping-product-input-group > .shopping-qty-input { + flex: 0 0 15% !important; + max-width: 15% !important; + min-width: 0; + padding-left: .35rem; + padding-right: .35rem; + } + + .endpoint-list .shopping-product-input-group > .shopping-compact-submit, + .endpoint-list_share .shopping-product-input-group > .shopping-compact-submit, + .endpoint-shared_list .shopping-product-input-group > .shopping-compact-submit { + flex: 0 0 25% !important; + width: 25% !important; + min-width: 0 !important; + padding-left: .4rem; + padding-right: .4rem; + } + + .endpoint-list .shopping-expense-input-group > .shopping-expense-amount-input, + .endpoint-list_share .shopping-expense-input-group > .shopping-expense-amount-input, + .endpoint-shared_list .shopping-expense-input-group > .shopping-expense-amount-input { + flex: 1 1 auto !important; + min-width: 0; + } + + .endpoint-list .shopping-expense-input-group > .shopping-compact-submit, + .endpoint-list_share .shopping-expense-input-group > .shopping-compact-submit, + .endpoint-shared_list .shopping-expense-input-group > .shopping-compact-submit { + flex: 0 0 5rem !important; + width: 5rem !important; + min-width: 5rem !important; + padding-left: .35rem; + padding-right: .35rem; + } + + .endpoint-list .shopping-product-input-group > .shopping-compact-submit .shopping-btn-label, + .endpoint-list_share .shopping-product-input-group > .shopping-compact-submit .shopping-btn-label, + .endpoint-shared_list .shopping-product-input-group > .shopping-compact-submit .shopping-btn-label, + .endpoint-list .shopping-expense-input-group > .shopping-compact-submit .shopping-btn-label, + .endpoint-list_share .shopping-expense-input-group > .shopping-compact-submit .shopping-btn-label, + .endpoint-shared_list .shopping-expense-input-group > .shopping-compact-submit .shopping-btn-label { + display: none; + } + + .endpoint-list .shopping-product-input-group > .shopping-compact-submit .shopping-btn-icon, + .endpoint-list_share .shopping-product-input-group > .shopping-compact-submit .shopping-btn-icon, + .endpoint-shared_list .shopping-product-input-group > .shopping-compact-submit .shopping-btn-icon, + .endpoint-list .shopping-expense-input-group > .shopping-compact-submit .shopping-btn-icon, + .endpoint-list_share .shopping-expense-input-group > .shopping-compact-submit .shopping-btn-icon, + .endpoint-shared_list .shopping-expense-input-group > .shopping-compact-submit .shopping-btn-icon { + margin: 0; + font-size: 1rem; + } +} + + +/* endpoint fix for /list route */ +.endpoint-view_list .shopping-product-input-group, +.endpoint-view_list .shopping-expense-input-group { + display: flex; + flex-wrap: nowrap !important; + align-items: stretch; + gap: 0 !important; + width: 100%; +} + +.endpoint-view_list .shopping-product-input-group > .form-control, +.endpoint-view_list .shopping-expense-input-group > .form-control, +.endpoint-view_list .shopping-product-input-group > .btn, +.endpoint-view_list .shopping-expense-input-group > .btn { + position: relative; + min-height: 46px; + box-shadow: none; +} + +.endpoint-view_list .shopping-product-input-group > .shopping-product-name-input, +.endpoint-view_list .shopping-expense-input-group > .shopping-expense-amount-input { + border-top-right-radius: 0 !important; + border-bottom-right-radius: 0 !important; +} + +.endpoint-view_list .shopping-product-input-group > .shopping-qty-input { + border-radius: 0 !important; + border-left-width: 0 !important; +} + +.endpoint-view_list .shopping-product-input-group > .shopping-compact-submit, +.endpoint-view_list .shopping-expense-input-group > .shopping-compact-submit, +.endpoint-view_list .share-submit-btn { + display: inline-flex; + align-items: center; + justify-content: center; + gap: .35rem; + margin-left: 0 !important; + min-width: 7.25rem; + border-top-left-radius: 0 !important; + border-bottom-left-radius: 0 !important; + border-top-right-radius: .9rem !important; + border-bottom-right-radius: .9rem !important; + border-left-width: 0 !important; +} + +@media (max-width: 767.98px) { + .endpoint-view_list .shopping-product-input-group > .shopping-product-name-input { + flex: 0 0 60% !important; + max-width: 60% !important; + min-width: 0; + } + + .endpoint-view_list .shopping-product-input-group > .shopping-qty-input { + flex: 0 0 15% !important; + max-width: 15% !important; + min-width: 0; + padding-left: .35rem; + padding-right: .35rem; + } + + .endpoint-view_list .shopping-product-input-group > .shopping-compact-submit { + flex: 0 0 25% !important; + width: 25% !important; + min-width: 0 !important; + padding-left: .4rem; + padding-right: .4rem; + } + + .endpoint-view_list .shopping-expense-input-group > .shopping-expense-amount-input { + flex: 1 1 auto !important; + min-width: 0; + } + + .endpoint-view_list .shopping-expense-input-group > .shopping-compact-submit { + flex: 0 0 5rem !important; + width: 5rem !important; + min-width: 5rem !important; + padding-left: .35rem; + padding-right: .35rem; + } + + .endpoint-view_list .shopping-product-input-group > .shopping-compact-submit .shopping-btn-label, + .endpoint-view_list .shopping-expense-input-group > .shopping-compact-submit .shopping-btn-label { + display: none; + } + + .endpoint-view_list .shopping-product-input-group > .shopping-compact-submit .shopping-btn-icon, + .endpoint-view_list .shopping-expense-input-group > .shopping-compact-submit .shopping-btn-icon { + margin: 0; + font-size: 1rem; + } +} + +/* --- JS render + progress bar consistency patch --- */ +#progress-bar-purchased { + background: linear-gradient(135deg, rgba(39,208,125,0.96), rgba(22,150,91,0.98)) !important; +} + +#progress-bar-not-purchased { + background: linear-gradient(135deg, rgba(246,196,83,0.96), rgba(224,164,26,0.98)) !important; +} + +#progress-bar-remaining { + background: rgba(255,255,255,0.08) !important; +} diff --git a/shopping_app/static/js/functions.js b/shopping_app/static/js/functions.js index ef89d4b..2c2c886 100644 --- a/shopping_app/static/js/functions.js +++ b/shopping_app/static/js/functions.js @@ -257,6 +257,17 @@ function showToast(message, type = 'primary') { setTimeout(() => { toast.remove(); }, 1750); } + +function escapeHtml(value) { + return String(value ?? '') + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); +} + + function isListDifferent(oldItems, newItems) { if (oldItems.length !== newItems.length) return true; @@ -271,96 +282,85 @@ function isListDifferent(oldItems, newItems) { return false; } + function renderItem(item, isShare = window.IS_SHARE, showEditOnly = false) { const li = document.createElement('li'); li.id = `item-${item.id}`; - li.dataset.name = item.name.toLowerCase(); - li.className = `list-group-item d-flex justify-content-between align-items-center flex-wrap clickable-item ${item.purchased ? 'bg-success text-white' + li.dataset.name = String(item.name || '').toLowerCase(); + li.dataset.isShare = isShare ? 'true' : 'false'; + li.className = `list-group-item shopping-item-row clickable-item ${item.purchased ? 'bg-success text-white' : item.not_purchased ? 'bg-warning text-dark' : 'item-not-checked' }`; const isOwner = window.IS_OWNER === true || window.IS_OWNER === 'true'; const allowEdit = !isShare || showEditOnly || isOwner; + const safeName = escapeHtml(item.name || ''); + const nameForEdit = JSON.stringify(String(item.name || '')); + const quantity = Number.isInteger(item.quantity) ? item.quantity : parseInt(item.quantity, 10) || 1; + const quantityBadge = quantity > 1 + ? `x${quantity}` + : ''; - let quantityBadge = ''; - if (item.quantity && item.quantity > 1) { - quantityBadge = `x${item.quantity}`; + const checkboxHtml = ``; + + const infoParts = []; + if (item.note) { + infoParts.push(`[ ${escapeHtml(item.note)} ]`); } + if (item.not_purchased_reason) { + infoParts.push(`[ Powód: ${escapeHtml(item.not_purchased_reason)} ]`); + } + const addedByDisplay = item.added_by_display || item.added_by; + if (addedByDisplay && item.owner_id && item.added_by_id && item.added_by_id !== item.owner_id) { + infoParts.push(`[ Dodał/a: ${escapeHtml(addedByDisplay)} ]`); + } + const infoHtml = infoParts.length + ? `
💸 Łącznie wydano: {{ '%.2f'|format(total_expense) }} PLN
@@ -216,7 +216,7 @@