diff --git a/src/App.svelte b/src/App.svelte index d05b326..23ef719 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -6,6 +6,7 @@ import Home from "./pages/Home.svelte"; import Preview from "./pages/Preview.svelte"; import NotFound from "./pages/NotFound.svelte"; + import Header from "./components/Header.svelte"; export const routes = { "/": Home, @@ -32,6 +33,7 @@ // --- Collection support --- let collection = localStorage.getItem("collection") || "logos"; function setCollection(val) { + console.log("setCollection called with", val, "current:", collection); if (val !== collection) { collection = val; localStorage.setItem("collection", val); @@ -40,12 +42,18 @@ } async function loadCollectionData() { + console.log("loadCollectionData: loading collection", collection); // Load the correct data file for the selected collection try { const timestamp = new Date().getTime(); const response = await fetch(`data/${collection}.json?t=${timestamp}`); + console.log("loadCollectionData: fetch status", response.status); if (response.ok) { logos = await response.json(); + console.log("loadCollectionData: loaded", logos.length, "items for", collection); + logos = [...logos]; // trigger reactivity + filteredLogos = logos; + displayLogos = logos; // Reset filters and state for new collection searchQuery = ""; selectedTags = []; @@ -55,9 +63,11 @@ compactMode = false; } else { logos = []; + console.log("loadCollectionData: failed to load data for", collection); } } catch (error) { logos = []; + console.error("loadCollectionData: error loading data for", collection, error); } } @@ -126,6 +136,7 @@ // Load logos from JSON file with cache busting onMount(async () => { console.log("App: onMount start - before loading logos"); + await loadCollectionData(); // Set initial empty app data if (typeof window !== "undefined") { @@ -164,93 +175,6 @@ }; } - try { - // Add timestamp as cache-busting query parameter - const timestamp = new Date().getTime(); - const response = await fetch(`data/logos.json?t=${timestamp}`, { - // Force reload from server, don't use cache - cache: "no-cache", - headers: { - "Cache-Control": "no-cache", - Pragma: "no-cache", - }, - }); - - if (response.ok) { - logos = await response.json(); - filteredLogos = logos; - displayLogos = logos; - console.log( - "Loaded logos:", - logos.length, - "at", - new Date().toLocaleTimeString(), - ); - - // Update app data immediately after logos are loaded - if (typeof window !== "undefined") { - window.appData = { - logos, - filteredLogos, - displayLogos, - theme, - effectiveTheme, - viewMode, - searchQuery, - allTags, - selectedTags, - selectedBrands, - selectedVariants, - tagDropdownOpen, - compactMode, - setSearchQuery, - setGridView, - setListView, - setCompactView, - setTheme, - toggleDropdown, - addTag, - removeTag, - toggleTag, - getTagObj, - closeDropdown, - setCompactMode, - onCopy: copyUrl, - onDownload: downloadLogo, - addBrand, - removeBrand, - addVariant, - removeVariant, - }; - console.log( - "App: Updated window.appData after loading with", - logos.length, - "logos", - ); - } - } else { - console.error("Failed to load logos data", response.status); - } - } catch (error) { - console.error("Error loading logos:", error); - } - - const stored = localStorage.getItem("theme"); - if (stored === "light" || stored === "dark" || stored === "system") { - theme = stored; - } - applyTheme(); - - // Listen for system theme changes if using system - mq = window.matchMedia("(prefers-color-scheme: dark)"); - mq.addEventListener("change", () => { - if (theme === "system") applyTheme(); - }); - - // Open preview if URL contains anchor - openLogoByAnchor(window.location.hash); - - // On mount, check for search param in URL and set searchQuery const params = new URLSearchParams(window.location.search); const searchParam = params.get("search"); if (searchParam) { @@ -836,7 +760,70 @@ } - + + + + +
diff --git a/src/components/CardFull.svelte b/src/components/CardFull.svelte index d8a5a33..2b3f9ac 100644 --- a/src/components/CardFull.svelte +++ b/src/components/CardFull.svelte @@ -170,7 +170,7 @@ /> {/if} {#if logo.brand} -

Brand: {logo.brand}

+

Owner: {logo.brand}

{/if}

Format: {logo.format}

Path: {logo.path}

diff --git a/src/components/CardMiddle.svelte b/src/components/CardMiddle.svelte index 1a0de85..266bfc7 100644 --- a/src/components/CardMiddle.svelte +++ b/src/components/CardMiddle.svelte @@ -10,7 +10,6 @@ export let onDownload; export let allLogos = []; export let addBrand = () => {}; - export const setTheme = () => {}; function openPreview(logo) { // Navigate to preview page using router diff --git a/src/components/Header.svelte b/src/components/Header.svelte index 0a1a90f..d760810 100644 --- a/src/components/Header.svelte +++ b/src/components/Header.svelte @@ -33,6 +33,19 @@ export let setCompactMode = () => {}; export let collection = "logos"; export let setCollection = () => {}; + + let dropdownOpen = false; + + function handleTitleClick() { + dropdownOpen = !dropdownOpen; + } + + function handleCollectionSelect(name) { + setCollection(name); + dropdownOpen = false; + } + + $: currentLabel = (collections.find(c => c.name === collection)?.label || "Logo Gallery").replace(/s$/, "");
@@ -41,12 +54,28 @@
Logo Gallery icon
- -

Logo Gallery

+ + {#if dropdownOpen} +
    + {#each collections as c} +
  • handleCollectionSelect(c.name)} + on:keydown={(e) => { + if (e.key === "Enter" || e.key === " ") { + e.preventDefault(); + handleCollectionSelect(c.name); + } + }} + >{c.label} Gallery
  • + {/each} +
+ {/if} {#if (searchQuery && searchQuery.trim() !== "") || selectedTags.length > 0 || selectedBrands.length > 0 || selectedVariants.length > 0 || compactMode} @@ -127,16 +156,59 @@ border-radius: 4px; } - .collection-chooser { - font-family: inherit; + .collection-title-btn { + background: none; + border: none; + font: inherit; + color: inherit; + font-size: 1.5rem; + font-weight: bold; + display: flex; + align-items: center; + gap: 0.3em; + cursor: pointer; + padding: 0; + margin: 0 1rem 0 0; + position: relative; + transition: color 0.15s; + } + .collection-title-btn:hover, + .collection-title-btn:focus { + color: var(--color-primary, #0070f3); + } + .triangle { font-size: 1rem; - color: var(--color-text); + margin-left: 0.2em; + transition: transform 0.2s; + } + .collection-title-btn[aria-expanded="true"] .triangle { + transform: rotate(180deg); + } + .collection-dropdown { + position: absolute; + top: 2.2em; + left: 0; background: var(--color-card); border: 1px solid var(--color-border); - border-radius: 4px; - padding: 0.25rem 0.5rem; - margin-right: 1rem; + border-radius: 6px; + box-shadow: 0 2px 8px rgba(0,0,0,0.08); + z-index: 10; + min-width: 180px; + padding: 0.3em 0; + margin: 0; + list-style: none; + } + .collection-dropdown li { + padding: 0.5em 1.2em; cursor: pointer; + font-size: 1.1rem; + color: var(--color-text); + transition: background 0.13s, color 0.13s; + } + .collection-dropdown li.active, + .collection-dropdown li:hover { + background: var(--color-primary, #0070f3); + color: #fff; } .header-controls { diff --git a/src/pages/Home.svelte b/src/pages/Home.svelte index 5495a14..3a917f6 100644 --- a/src/pages/Home.svelte +++ b/src/pages/Home.svelte @@ -20,6 +20,8 @@ let addVariant = () => {}; let removeVariant = () => {}; let setTheme = () => {}; + let collection = "logos"; // Default collection + let setCollection = () => {}; $: ({ @@ -30,6 +32,7 @@ effectiveTheme = "light", viewMode = "grid", searchQuery = "", + collection = "logos", allTags = [], selectedTags = [], selectedBrands = [], @@ -41,6 +44,7 @@ setListView = () => {}, setCompactView = () => {}, setTheme = () => {}, + setCollection = () => {}, toggleDropdown = () => {}, addTag = () => {}, removeTag = () => {}, @@ -62,6 +66,7 @@ allLogos = window.appData.logos || []; viewMode = window.appData.viewMode || "grid"; theme = window.appData.theme || "system"; + collection = window.appData.collection || "logos"; searchQuery = window.appData.searchQuery || ""; compactMode = window.appData.compactMode || false; tagDropdownOpen = window.appData.tagDropdownOpen || false; @@ -233,6 +238,8 @@ getTagObj={(tag) => (window.appData?.getTagObj ? window.appData.getTagObj(tag) : {text: tag})} {compactMode} {setCompactMode} + {collection} + {setCollection} />