Filter popup improvement
This commit is contained in:
@@ -60,7 +60,7 @@ function getFilteredRecipes() {
|
||||
function renderRecipeCard(recipe) {
|
||||
const labels = slotLabelsFor(recipe);
|
||||
return `
|
||||
<div onclick="openRecipeDetail('${escapeHtml(recipe.id)}')" class="rounded-xl overflow-hidden flex flex-col bg-[#393937] cursor-pointer transition-shadow" style="background:#393937 !important; border:none !important; box-shadow:none !important;">
|
||||
<div data-recipe-id="${escapeHtml(recipe.id)}" onclick="openRecipeDetail('${escapeHtml(recipe.id)}')" class="recipe-card rounded-xl overflow-hidden flex flex-col bg-[#393937] cursor-pointer transition-shadow" style="background:#393937 !important; border:none !important; box-shadow:none !important;">
|
||||
<div class="h-32 bg-[#d4d4d4] relative overflow-hidden">
|
||||
${recipe.image
|
||||
? `<img src="${escapeHtml(recipe.image)}" alt="${escapeHtml(recipe.title)}" class="w-full h-full object-cover">`
|
||||
@@ -81,6 +81,17 @@ function renderRecipeCard(recipe) {
|
||||
</div>`;
|
||||
}
|
||||
|
||||
function getEmptyStateHTML() {
|
||||
return `
|
||||
<div id="recipe-empty-state" class="hidden flex flex-col items-center justify-center py-16 text-center">
|
||||
<div class="w-16 h-16 rounded-full bg-gray-100 flex items-center justify-center mb-4">
|
||||
<i class="fas fa-search text-2xl text-gray-300"></i>
|
||||
</div>
|
||||
<p class="text-sm font-semibold text-gray-700">Brak wyników</p>
|
||||
<p class="text-xs text-gray-500 mt-1 max-w-[220px] leading-relaxed">Zmień kryteria wyszukiwania lub filtry</p>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
function syncRecipeScrollShadow() {
|
||||
const scroll = document.getElementById('recipe-scroll');
|
||||
const searchShell = document.getElementById('recipe-search-shell');
|
||||
@@ -94,26 +105,41 @@ function syncRecipeScrollShadow() {
|
||||
searchShell.style.boxShadow = SEARCH_SHELL_BASE_SHADOW;
|
||||
}
|
||||
|
||||
function renderGrid() {
|
||||
function renderAllRecipeCards() {
|
||||
const grid = document.getElementById('recipe-grid');
|
||||
if (!grid) return;
|
||||
|
||||
const recipes = getFilteredRecipes();
|
||||
if (recipes.length === 0) {
|
||||
grid.innerHTML = `
|
||||
<div class="col-span-2 flex flex-col items-center justify-center py-16 text-center">
|
||||
<div class="w-16 h-16 rounded-full bg-gray-100 flex items-center justify-center mb-4">
|
||||
<i class="fas fa-search text-2xl text-gray-300"></i>
|
||||
</div>
|
||||
<p class="text-sm font-semibold text-gray-700">Brak wyników</p>
|
||||
<p class="text-xs text-gray-500 mt-1 max-w-[220px] leading-relaxed">Zmień kryteria wyszukiwania lub filtry</p>
|
||||
</div>`;
|
||||
requestAnimationFrame(syncRecipeScrollShadow);
|
||||
return;
|
||||
grid.innerHTML = Object.values(RECIPES).map(renderRecipeCard).join('');
|
||||
}
|
||||
|
||||
function syncVisibleRecipeCards() {
|
||||
const grid = document.getElementById('recipe-grid');
|
||||
const emptyState = document.getElementById('recipe-empty-state');
|
||||
if (!grid || !emptyState) return;
|
||||
|
||||
let visibleCount = 0;
|
||||
grid.querySelectorAll('[data-recipe-id]').forEach((card) => {
|
||||
const recipeId = card.getAttribute('data-recipe-id');
|
||||
const recipe = recipeId ? RECIPES[recipeId] : null;
|
||||
const isVisible = Boolean(recipe && matchesFilters(recipe));
|
||||
card.classList.toggle('hidden', !isVisible);
|
||||
if (isVisible) visibleCount += 1;
|
||||
});
|
||||
|
||||
grid.classList.toggle('hidden', visibleCount === 0);
|
||||
emptyState.classList.toggle('hidden', visibleCount !== 0);
|
||||
requestAnimationFrame(syncRecipeScrollShadow);
|
||||
}
|
||||
|
||||
function renderGrid({ rebuild = false } = {}) {
|
||||
const grid = document.getElementById('recipe-grid');
|
||||
if (!grid) return;
|
||||
|
||||
if (rebuild || !grid.querySelector('[data-recipe-id]')) {
|
||||
renderAllRecipeCards();
|
||||
}
|
||||
|
||||
grid.innerHTML = recipes.map(renderRecipeCard).join('');
|
||||
requestAnimationFrame(syncRecipeScrollShadow);
|
||||
syncVisibleRecipeCards();
|
||||
}
|
||||
|
||||
export function getRecipeListHTML() {
|
||||
@@ -130,6 +156,7 @@ export function getRecipeListHTML() {
|
||||
|
||||
<div id="recipe-scroll" class="relative flex-1 overflow-y-auto px-4 pt-20 pb-24 bg-[#2d2e2b]" style="background:#2d2e2b !important;">
|
||||
<div id="recipe-grid" class="grid grid-cols-2 gap-3 bg-[#2d2e2b]" style="background:#2d2e2b !important;"></div>
|
||||
${getEmptyStateHTML()}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -149,11 +176,11 @@ export function getFilteredCount() {
|
||||
}
|
||||
|
||||
export function refreshRecipeList() {
|
||||
renderGrid();
|
||||
renderGrid({ rebuild: true });
|
||||
}
|
||||
|
||||
export function setupRecipeList() {
|
||||
renderGrid();
|
||||
renderGrid({ rebuild: true });
|
||||
|
||||
document.getElementById('recipe-search-input')?.addEventListener('input', (e) => {
|
||||
filterState.query = e.target.value.trim();
|
||||
|
||||
Reference in New Issue
Block a user