Add dark mode
All checks were successful
Build and Deploy / build-and-push (push) Successful in 1m12s
All checks were successful
Build and Deploy / build-and-push (push) Successful in 1m12s
This commit is contained in:
40
js/app.js
40
js/app.js
@@ -3,7 +3,6 @@ import { getFilterHTML, setupFilter } from './views/Filter.js?v=2';
|
||||
import { getRecipeDetailHTML, setupRecipeDetail } from './views/RecipeDetailV2.js?v=2';
|
||||
import { getMealPlannerHTML, setupMealPlanner } from './views/MealPlanner.js?v=2';
|
||||
import { getPantryHTML, refreshPantry, setupPantry } from './views/Pantry.js?v=2';
|
||||
import { getShoppingHTML, refreshShopping, setupShopping } from './views/Shopping.js?v=2';
|
||||
|
||||
function getAppToastHTML() {
|
||||
return `
|
||||
@@ -14,6 +13,7 @@ function getAppToastHTML() {
|
||||
}
|
||||
|
||||
function getBottomNavHTML() {
|
||||
const isDark = document.documentElement.classList.contains('dark');
|
||||
return `
|
||||
<nav id="app-bottom-nav" class="absolute bottom-0 left-0 right-0 w-full bg-white border-t border-gray-200 flex justify-between px-1 py-2.5 pb-6 z-20 gap-0" aria-label="Główna nawigacja">
|
||||
<button type="button" data-tab="recipes" id="nav-recipes" class="nav-tab flex flex-col items-center gap-0.5 text-black flex-1 min-w-0 max-w-[5.5rem]">
|
||||
@@ -28,21 +28,39 @@ function getBottomNavHTML() {
|
||||
<i class="fas fa-warehouse text-base" aria-hidden="true"></i>
|
||||
<span class="text-[9px] font-medium leading-tight text-center">Spiżarnia</span>
|
||||
</button>
|
||||
<button type="button" data-tab="shopping" id="nav-shopping" class="nav-tab flex flex-col items-center gap-0.5 text-gray-500 hover:text-gray-700 flex-1 min-w-0 max-w-[5.5rem]">
|
||||
<i class="fas fa-cart-shopping text-base" aria-hidden="true"></i>
|
||||
<span class="text-[9px] font-medium leading-tight text-center">Zakupy</span>
|
||||
<button type="button" id="nav-theme-toggle" class="flex flex-col items-center gap-0.5 text-gray-500 hover:text-gray-700 flex-1 min-w-0 max-w-[5.5rem]" aria-label="Przełącz tryb ciemny/jasny">
|
||||
<i class="${isDark ? 'fas fa-sun' : 'fas fa-moon'} text-base" aria-hidden="true"></i>
|
||||
<span class="text-[9px] font-medium leading-tight text-center">${isDark ? 'Jasny' : 'Ciemny'}</span>
|
||||
</button>
|
||||
</nav>
|
||||
`;
|
||||
}
|
||||
|
||||
function setupThemeToggle() {
|
||||
const btn = document.getElementById('nav-theme-toggle');
|
||||
if (!btn) return;
|
||||
|
||||
btn.addEventListener('click', () => {
|
||||
const html = document.documentElement;
|
||||
const isDark = html.classList.toggle('dark');
|
||||
localStorage.setItem('theme', isDark ? 'dark' : 'light');
|
||||
|
||||
const icon = btn.querySelector('i');
|
||||
const label = btn.querySelector('span');
|
||||
if (icon) icon.className = isDark ? 'fas fa-sun text-base' : 'fas fa-moon text-base';
|
||||
if (label) label.textContent = isDark ? 'Jasny' : 'Ciemny';
|
||||
|
||||
const meta = document.querySelector('meta[name="theme-color"]');
|
||||
if (meta) meta.setAttribute('content', isDark ? '#0d0d0d' : '#ffffff');
|
||||
});
|
||||
}
|
||||
|
||||
function setupTabs() {
|
||||
const main = document.getElementById('main-view');
|
||||
const planner = document.getElementById('planner-view');
|
||||
const pantry = document.getElementById('pantry-view');
|
||||
const shopping = document.getElementById('shopping-view');
|
||||
const nav = document.getElementById('app-bottom-nav');
|
||||
if (!main || !planner || !pantry || !shopping || !nav) return;
|
||||
if (!main || !planner || !pantry || !nav) return;
|
||||
|
||||
const activeTab = 'nav-tab flex flex-col items-center gap-0.5 text-black flex-1 min-w-0 max-w-[5.5rem]';
|
||||
const idleTab = 'nav-tab flex flex-col items-center gap-0.5 text-gray-500 hover:text-gray-700 flex-1 min-w-0 max-w-[5.5rem]';
|
||||
@@ -51,15 +69,13 @@ function setupTabs() {
|
||||
main.classList.toggle('hidden', tab !== 'recipes');
|
||||
planner.classList.toggle('hidden', tab !== 'planner');
|
||||
pantry.classList.toggle('hidden', tab !== 'pantry');
|
||||
shopping.classList.toggle('hidden', tab !== 'shopping');
|
||||
|
||||
if (tab === 'pantry') refreshPantry();
|
||||
if (tab === 'shopping') refreshShopping();
|
||||
|
||||
nav.querySelectorAll('.nav-tab[data-tab]').forEach((btn) => {
|
||||
const id = btn.getAttribute('data-tab');
|
||||
if (btn.hasAttribute('disabled')) return;
|
||||
if (id === 'recipes' || id === 'planner' || id === 'pantry' || id === 'shopping') {
|
||||
if (id === 'recipes' || id === 'planner' || id === 'pantry') {
|
||||
btn.className = id === tab ? activeTab : idleTab;
|
||||
}
|
||||
});
|
||||
@@ -69,14 +85,13 @@ function setupTabs() {
|
||||
const btn = e.target.closest('.nav-tab[data-tab]');
|
||||
if (!btn || btn.hasAttribute('disabled')) return;
|
||||
const tab = btn.getAttribute('data-tab');
|
||||
if (tab === 'recipes' || tab === 'planner' || tab === 'pantry' || tab === 'shopping') apply(tab);
|
||||
if (tab === 'recipes' || tab === 'planner' || tab === 'pantry') apply(tab);
|
||||
});
|
||||
|
||||
apply('recipes');
|
||||
|
||||
window.refreshStockViews = () => {
|
||||
refreshPantry();
|
||||
refreshShopping();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -87,7 +102,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
${getRecipeListHTML()}
|
||||
${getMealPlannerHTML()}
|
||||
${getPantryHTML()}
|
||||
${getShoppingHTML()}
|
||||
${getBottomNavHTML()}
|
||||
${getRecipeDetailHTML()}
|
||||
${getFilterHTML()}
|
||||
@@ -95,10 +109,10 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
`;
|
||||
|
||||
setupTabs();
|
||||
setupThemeToggle();
|
||||
setupRecipeList();
|
||||
setupMealPlanner();
|
||||
setupPantry();
|
||||
setupShopping();
|
||||
setupFilter();
|
||||
setupRecipeDetail();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user