Use SVGs in pantry list
Some checks failed
Build and Deploy / build-and-push (push) Failing after 1m17s
Some checks failed
Build and Deploy / build-and-push (push) Failing after 1m17s
This commit is contained in:
@@ -624,7 +624,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const APP_ASSET_VERSION = '20260417-svg2';
|
const APP_ASSET_VERSION = '20260417-svg6';
|
||||||
const APP_VERSION_STORAGE_KEY = 'recipe-app-asset-version';
|
const APP_VERSION_STORAGE_KEY = 'recipe-app-asset-version';
|
||||||
const APP_VERSION_QUERY_KEY = 'appv';
|
const APP_VERSION_QUERY_KEY = 'appv';
|
||||||
|
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ export function getIngredientCardHTML({
|
|||||||
<div id="${idBase}" class="${cardClass}" style="${cardStyle}">
|
<div id="${idBase}" class="${cardClass}" style="${cardStyle}">
|
||||||
<div class="relative px-4 pt-4 pb-2">
|
<div class="relative px-4 pt-4 pb-2">
|
||||||
<div class="flex items-start gap-3 pr-10">
|
<div class="flex items-start gap-3 pr-10">
|
||||||
<div id="${idBase}-hero" class="relative w-16 h-16 rounded-2xl flex items-center justify-center shrink-0 overflow-hidden" style="background:#393937;">
|
<div id="${idBase}-hero" class="relative w-20 h-20 rounded-2xl flex items-center justify-center shrink-0 overflow-hidden" style="background:#393937;">
|
||||||
<img id="${idBase}-img" class="w-full h-full hidden" alt="" />
|
<img id="${idBase}-img" class="w-full h-full hidden" alt="" />
|
||||||
<div id="${idBase}-fallback" class="absolute inset-0 flex items-center justify-center">
|
<div id="${idBase}-fallback" class="absolute inset-0 flex items-center justify-center">
|
||||||
<i id="${idBase}-fallback-icon" class="fas fa-box-open text-2xl" style="color:#6d6c67;"></i>
|
<i id="${idBase}-fallback-icon" class="fas fa-box-open text-2xl" style="color:#6d6c67;"></i>
|
||||||
@@ -254,7 +254,7 @@ export function createIngredientCardController({ idBase, defaultSourceNote = 'Ze
|
|||||||
const isSvg = image.endsWith('.svg');
|
const isSvg = image.endsWith('.svg');
|
||||||
img.classList.toggle('object-contain', isSvg);
|
img.classList.toggle('object-contain', isSvg);
|
||||||
img.classList.toggle('object-cover', !isSvg);
|
img.classList.toggle('object-cover', !isSvg);
|
||||||
img.style.padding = isSvg ? '6px' : '';
|
img.style.padding = isSvg ? '4px' : '';
|
||||||
img.classList.remove('hidden');
|
img.classList.remove('hidden');
|
||||||
fallback.classList.add('hidden');
|
fallback.classList.add('hidden');
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import {
|
|||||||
renderCalendarGrid,
|
renderCalendarGrid,
|
||||||
syncCalendarTodayButton,
|
syncCalendarTodayButton,
|
||||||
} from './mealCalendar.js?v=11';
|
} from './mealCalendar.js?v=11';
|
||||||
import { createIngredientCardController, getIngredientCardHTML } from './ingredientCard.js?v=20260417-115';
|
import { createIngredientCardController, getIngredientCardHTML } from './ingredientCard.js?v=20260417-116';
|
||||||
|
|
||||||
function esc(s) {
|
function esc(s) {
|
||||||
return String(s).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
return String(s).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import {
|
|||||||
renderCalendarGrid,
|
renderCalendarGrid,
|
||||||
syncCalendarTodayButton,
|
syncCalendarTodayButton,
|
||||||
} from '../ui/mealCalendar.js?v=11';
|
} from '../ui/mealCalendar.js?v=11';
|
||||||
import { createIngredientCardController, getIngredientCardHTML } from '../ui/ingredientCard.js?v=20260417-115';
|
import { createIngredientCardController, getIngredientCardHTML } from '../ui/ingredientCard.js?v=20260417-116';
|
||||||
|
|
||||||
/* ── helpers ── */
|
/* ── helpers ── */
|
||||||
|
|
||||||
@@ -550,6 +550,7 @@ function classifyIngredients(searchQuery) {
|
|||||||
name: def.name,
|
name: def.name,
|
||||||
qty: getPantryTotal(id, pantry),
|
qty: getPantryTotal(id, pantry),
|
||||||
unit: def.pantryUnit,
|
unit: def.pantryUnit,
|
||||||
|
image: def.image || null,
|
||||||
icon: CATEGORY_ICONS[def.category] || 'fa-jar',
|
icon: CATEGORY_ICONS[def.category] || 'fa-jar',
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
@@ -560,14 +561,19 @@ function classifyIngredients(searchQuery) {
|
|||||||
|
|
||||||
/* ══════════════════════ TILE RENDERING ══════════════════════ */
|
/* ══════════════════════ TILE RENDERING ══════════════════════ */
|
||||||
|
|
||||||
|
function tileIconHtml(item) {
|
||||||
|
if (item.image) {
|
||||||
|
return `<div class="w-6 h-6 rounded-md shrink-0 overflow-hidden" style="background:#2f2f2d;"><img src="${esc(item.image)}" alt="" class="w-full h-full object-contain" style="padding:1px;"></div>`;
|
||||||
|
}
|
||||||
|
return `<div class="w-6 h-6 rounded-md flex items-center justify-center shrink-0" style="background:#2f2f2d;"><i class="fas ${item.icon} text-[11px]" style="color:#7d7a74;"></i></div>`;
|
||||||
|
}
|
||||||
|
|
||||||
function shortfallTileHtml(item) {
|
function shortfallTileHtml(item) {
|
||||||
const clamp = item.name.length > 25 ? ' min-w-0' : '';
|
const clamp = item.name.length > 25 ? ' min-w-0' : '';
|
||||||
return `
|
return `
|
||||||
<button type="button" class="pv2-tile text-left rounded-2xl flex flex-col gap-2 px-2.5 py-2${clamp} transition-all active:scale-[0.98]" style="flex:1 0 6rem; background:#393937; border:none; box-shadow:0 2px 8px rgba(0,0,0,0.28);" data-id="${esc(item.ingredientId)}">
|
<button type="button" class="pv2-tile text-left rounded-2xl flex flex-col gap-2 px-2.5 py-2${clamp} transition-all active:scale-[0.98]" style="flex:1 0 auto; min-width:6rem; max-width:100%; background:#393937; border:none; box-shadow:0 2px 8px rgba(0,0,0,0.28);" data-id="${esc(item.ingredientId)}">
|
||||||
<div class="flex items-center gap-1.5 min-w-0">
|
<div class="flex items-center gap-1.5 min-w-0">
|
||||||
<div class="w-6 h-6 rounded-md flex items-center justify-center shrink-0" style="background:#2f2f2d;">
|
${tileIconHtml(item)}
|
||||||
<i class="fas ${item.icon} text-[11px]" style="color:${SHORTFALL_ACCENT};"></i>
|
|
||||||
</div>
|
|
||||||
<p class="text-[11px] font-normal leading-tight truncate min-w-0" style="color:#ddd6ca;">${esc(item.name)}</p>
|
<p class="text-[11px] font-normal leading-tight truncate min-w-0" style="color:#ddd6ca;">${esc(item.name)}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-full flex items-center gap-2">
|
<div class="w-full flex items-center gap-2">
|
||||||
@@ -582,11 +588,9 @@ function shortfallTileHtml(item) {
|
|||||||
function sufficientTileHtml(item) {
|
function sufficientTileHtml(item) {
|
||||||
const clamp = item.name.length > 25 ? ' min-w-0' : '';
|
const clamp = item.name.length > 25 ? ' min-w-0' : '';
|
||||||
return `
|
return `
|
||||||
<button type="button" class="pv2-tile text-left rounded-2xl flex flex-col gap-2 px-2.5 py-2${clamp} transition-all active:scale-[0.98]" style="flex:1 0 6rem; background:#393937; border:none; box-shadow:0 2px 8px rgba(0,0,0,0.28);" data-id="${esc(item.ingredientId)}">
|
<button type="button" class="pv2-tile text-left rounded-2xl flex flex-col gap-2 px-2.5 py-2${clamp} transition-all active:scale-[0.98]" style="flex:1 0 auto; min-width:6rem; max-width:100%; background:#393937; border:none; box-shadow:0 2px 8px rgba(0,0,0,0.28);" data-id="${esc(item.ingredientId)}">
|
||||||
<div class="flex items-center gap-1.5 min-w-0">
|
<div class="flex items-center gap-1.5 min-w-0">
|
||||||
<div class="w-6 h-6 rounded-md flex items-center justify-center shrink-0" style="background:#2f2f2d;">
|
${tileIconHtml(item)}
|
||||||
<i class="fas ${item.icon} text-[11px]" style="color:#6ee7b7;"></i>
|
|
||||||
</div>
|
|
||||||
<p class="text-[11px] font-normal leading-tight truncate min-w-0" style="color:#ddd6ca;">${esc(item.name)}</p>
|
<p class="text-[11px] font-normal leading-tight truncate min-w-0" style="color:#ddd6ca;">${esc(item.name)}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-full flex items-center gap-2">
|
<div class="w-full flex items-center gap-2">
|
||||||
@@ -602,10 +606,8 @@ function notPlannedChipHtml(item) {
|
|||||||
const hasStock = item.qty > 0;
|
const hasStock = item.qty > 0;
|
||||||
const clamp = item.name.length > 25 ? ' min-w-0' : '';
|
const clamp = item.name.length > 25 ? ' min-w-0' : '';
|
||||||
return `
|
return `
|
||||||
<button type="button" class="pv2-tile text-left rounded-2xl flex items-center gap-1.5 px-2.5 py-2${clamp} transition-all active:scale-[0.98]" style="flex:1 0 6rem; background:#393937; border:none; box-shadow:0 2px 8px rgba(0,0,0,0.28);" data-id="${esc(item.ingredientId)}">
|
<button type="button" class="pv2-tile text-left rounded-2xl flex items-center gap-1.5 px-2.5 py-2${clamp} transition-all active:scale-[0.98]" style="flex:1 0 auto; min-width:6rem; max-width:100%; background:#393937; border:none; box-shadow:0 2px 8px rgba(0,0,0,0.28);" data-id="${esc(item.ingredientId)}">
|
||||||
<div class="w-6 h-6 rounded-md flex items-center justify-center shrink-0" style="background:#2f2f2d;">
|
${tileIconHtml(item)}
|
||||||
<i class="fas ${item.icon} text-[11px]" style="color:#7d7a74;"></i>
|
|
||||||
</div>
|
|
||||||
<p class="text-[11px] font-normal leading-tight truncate min-w-0" style="color:${hasStock ? '#b7ada1' : '#9b978f'};">${esc(item.name)}</p>
|
<p class="text-[11px] font-normal leading-tight truncate min-w-0" style="color:${hasStock ? '#b7ada1' : '#9b978f'};">${esc(item.name)}</p>
|
||||||
<span class="text-[10px] font-semibold tabular-nums shrink-0 ml-auto" style="color:${hasStock ? '#9b978f' : '#6d6c67'};">${esc(formatQty(item.qty))} ${esc(unitLabel(item.unit))}</span>
|
<span class="text-[10px] font-semibold tabular-nums shrink-0 ml-auto" style="color:${hasStock ? '#9b978f' : '#6d6c67'};">${esc(formatQty(item.qty))} ${esc(unitLabel(item.unit))}</span>
|
||||||
</button>`;
|
</button>`;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { RECIPES, INGREDIENTS, PRODUCTS } from '../data/catalog.js?v=9';
|
import { RECIPES, INGREDIENTS, PRODUCTS } from '../data/catalog.js?v=9';
|
||||||
import { createIngredientCardController, getIngredientCardHTML } from '../ui/ingredientCard.js?v=20260417-115';
|
import { createIngredientCardController, getIngredientCardHTML } from '../ui/ingredientCard.js?v=20260417-116';
|
||||||
|
|
||||||
function escapeHtml(s) {
|
function escapeHtml(s) {
|
||||||
return String(s)
|
return String(s)
|
||||||
|
|||||||
Reference in New Issue
Block a user