reworked site
This commit is contained in:
131
web/app.js
131
web/app.js
@@ -245,6 +245,7 @@ const DEFAULT_SORT_SETTINGS = { mode: 'created', direction: 'desc' };
|
|||||||
const BOOKMARKS_BASE_URL = 'https://www.facebook.com/search/top';
|
const BOOKMARKS_BASE_URL = 'https://www.facebook.com/search/top';
|
||||||
const BOOKMARK_WINDOW_DAYS = 28;
|
const BOOKMARK_WINDOW_DAYS = 28;
|
||||||
const BOOKMARK_SUFFIXES = ['Gewinnspiel', 'gewinnen', 'verlosen'];
|
const BOOKMARK_SUFFIXES = ['Gewinnspiel', 'gewinnen', 'verlosen'];
|
||||||
|
const BOOKMARK_PREFS_KEY = 'trackerBookmarkPreferences';
|
||||||
|
|
||||||
function initializeFocusParams() {
|
function initializeFocusParams() {
|
||||||
try {
|
try {
|
||||||
@@ -289,6 +290,45 @@ let bookmarkSearchTerm = '';
|
|||||||
let bookmarkSortMode = 'recent';
|
let bookmarkSortMode = 'recent';
|
||||||
let bookmarkSortDirection = 'desc';
|
let bookmarkSortDirection = 'desc';
|
||||||
|
|
||||||
|
function loadBookmarkPreferences() {
|
||||||
|
try {
|
||||||
|
const stored = localStorage.getItem(BOOKMARK_PREFS_KEY);
|
||||||
|
if (stored) {
|
||||||
|
const parsed = JSON.parse(stored);
|
||||||
|
if (parsed && typeof parsed === 'object') {
|
||||||
|
return parsed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('Konnte Bookmark-Einstellungen nicht laden:', error);
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
function persistBookmarkPreferences() {
|
||||||
|
try {
|
||||||
|
const payload = {
|
||||||
|
searchTerm: bookmarkSearchTerm,
|
||||||
|
sortMode: bookmarkSortMode,
|
||||||
|
sortDirection: bookmarkSortDirection
|
||||||
|
};
|
||||||
|
localStorage.setItem(BOOKMARK_PREFS_KEY, JSON.stringify(payload));
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('Konnte Bookmark-Einstellungen nicht speichern:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const storedBookmarkPrefs = loadBookmarkPreferences();
|
||||||
|
if (storedBookmarkPrefs.searchTerm && typeof storedBookmarkPrefs.searchTerm === 'string') {
|
||||||
|
bookmarkSearchTerm = storedBookmarkPrefs.searchTerm.trim();
|
||||||
|
}
|
||||||
|
if (storedBookmarkPrefs.sortMode === 'label' || storedBookmarkPrefs.sortMode === 'recent') {
|
||||||
|
bookmarkSortMode = storedBookmarkPrefs.sortMode;
|
||||||
|
}
|
||||||
|
if (storedBookmarkPrefs.sortDirection === 'asc' || storedBookmarkPrefs.sortDirection === 'desc') {
|
||||||
|
bookmarkSortDirection = storedBookmarkPrefs.sortDirection;
|
||||||
|
}
|
||||||
|
|
||||||
const INITIAL_POST_LIMIT = 10;
|
const INITIAL_POST_LIMIT = 10;
|
||||||
const POST_LOAD_INCREMENT = 10;
|
const POST_LOAD_INCREMENT = 10;
|
||||||
const tabVisibleCounts = {
|
const tabVisibleCounts = {
|
||||||
@@ -549,12 +589,6 @@ function filterBookmarksBySearch(list) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRecentBookmarks(list) {
|
|
||||||
const recent = sortBookmarksByRecency(list);
|
|
||||||
const RECENT_LIMIT = 5;
|
|
||||||
return recent.filter((bookmark) => bookmark.last_clicked_at).slice(0, RECENT_LIMIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateBookmarkSortDirectionUI() {
|
function updateBookmarkSortDirectionUI() {
|
||||||
if (!bookmarkSortDirectionToggle) {
|
if (!bookmarkSortDirectionToggle) {
|
||||||
return;
|
return;
|
||||||
@@ -1025,63 +1059,13 @@ function renderBookmarks() {
|
|||||||
|
|
||||||
const filteredBookmarks = filterBookmarksBySearch(dynamicBookmarks);
|
const filteredBookmarks = filterBookmarksBySearch(dynamicBookmarks);
|
||||||
const sortedForAll = sortBookmarksForDisplay(filteredBookmarks);
|
const sortedForAll = sortBookmarksForDisplay(filteredBookmarks);
|
||||||
const recent = bookmarkSearchTerm ? [] : getRecentBookmarks(filteredBookmarks);
|
|
||||||
|
|
||||||
const sections = [];
|
const displayList = bookmarkSearchTerm ? sortedForAll : [staticDefault, ...sortedForAll];
|
||||||
|
const titleText = bookmarkSearchTerm
|
||||||
if (recent.length) {
|
? (filteredBookmarks.length ? `Suchergebnisse (${filteredBookmarks.length})` : 'Keine Treffer')
|
||||||
sections.push({
|
|
||||||
id: 'recent',
|
|
||||||
title: 'Zuletzt verwendet',
|
|
||||||
items: recent
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const allItems = bookmarkSearchTerm ? sortedForAll : [staticDefault, ...sortedForAll];
|
|
||||||
const allTitle = bookmarkSearchTerm
|
|
||||||
? `Suchergebnisse${filteredBookmarks.length ? ` (${filteredBookmarks.length})` : ''}`
|
|
||||||
: 'Alle Bookmarks';
|
: 'Alle Bookmarks';
|
||||||
|
|
||||||
sections.push({
|
if (!displayList.length) {
|
||||||
id: bookmarkSearchTerm ? 'search' : 'all',
|
|
||||||
title: allTitle,
|
|
||||||
items: allItems
|
|
||||||
});
|
|
||||||
|
|
||||||
let renderedAnySection = false;
|
|
||||||
|
|
||||||
sections.forEach((section) => {
|
|
||||||
if (!section.items.length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
renderedAnySection = true;
|
|
||||||
const sectionElement = document.createElement('section');
|
|
||||||
sectionElement.className = 'bookmark-section';
|
|
||||||
sectionElement.dataset.section = section.id;
|
|
||||||
|
|
||||||
const header = document.createElement('header');
|
|
||||||
header.className = 'bookmark-section__header';
|
|
||||||
|
|
||||||
const title = document.createElement('h3');
|
|
||||||
title.className = 'bookmark-section__title';
|
|
||||||
title.textContent = section.title;
|
|
||||||
header.appendChild(title);
|
|
||||||
|
|
||||||
sectionElement.appendChild(header);
|
|
||||||
|
|
||||||
const list = document.createElement('div');
|
|
||||||
list.className = 'bookmark-section__list';
|
|
||||||
|
|
||||||
section.items.forEach((bookmark) => {
|
|
||||||
list.appendChild(createBookmarkRow(bookmark));
|
|
||||||
});
|
|
||||||
|
|
||||||
sectionElement.appendChild(list);
|
|
||||||
bookmarksList.appendChild(sectionElement);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!renderedAnySection) {
|
|
||||||
const empty = document.createElement('div');
|
const empty = document.createElement('div');
|
||||||
empty.className = 'bookmark-empty';
|
empty.className = 'bookmark-empty';
|
||||||
if (bookmarkSearchTerm) {
|
if (bookmarkSearchTerm) {
|
||||||
@@ -1090,7 +1074,29 @@ function renderBookmarks() {
|
|||||||
empty.textContent = 'Noch keine Bookmarks gespeichert.';
|
empty.textContent = 'Noch keine Bookmarks gespeichert.';
|
||||||
}
|
}
|
||||||
bookmarksList.appendChild(empty);
|
bookmarksList.appendChild(empty);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const sectionElement = document.createElement('section');
|
||||||
|
sectionElement.className = 'bookmark-section';
|
||||||
|
sectionElement.dataset.section = bookmarkSearchTerm ? 'search' : 'all';
|
||||||
|
|
||||||
|
const headerEl = document.createElement('header');
|
||||||
|
headerEl.className = 'bookmark-section__header';
|
||||||
|
const titleEl = document.createElement('h3');
|
||||||
|
titleEl.className = 'bookmark-section__title';
|
||||||
|
titleEl.textContent = titleText;
|
||||||
|
headerEl.appendChild(titleEl);
|
||||||
|
sectionElement.appendChild(headerEl);
|
||||||
|
|
||||||
|
const list = document.createElement('div');
|
||||||
|
list.className = 'bookmark-section__list';
|
||||||
|
displayList.forEach((bookmark) => {
|
||||||
|
list.appendChild(createBookmarkRow(bookmark));
|
||||||
|
});
|
||||||
|
|
||||||
|
sectionElement.appendChild(list);
|
||||||
|
bookmarksList.appendChild(sectionElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetBookmarkForm() {
|
function resetBookmarkForm() {
|
||||||
@@ -1278,19 +1284,23 @@ function initializeBookmarks() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (bookmarkSearchInput) {
|
if (bookmarkSearchInput) {
|
||||||
|
bookmarkSearchInput.value = bookmarkSearchTerm;
|
||||||
bookmarkSearchInput.addEventListener('input', () => {
|
bookmarkSearchInput.addEventListener('input', () => {
|
||||||
bookmarkSearchTerm = typeof bookmarkSearchInput.value === 'string'
|
bookmarkSearchTerm = typeof bookmarkSearchInput.value === 'string'
|
||||||
? bookmarkSearchInput.value.trim()
|
? bookmarkSearchInput.value.trim()
|
||||||
: '';
|
: '';
|
||||||
|
persistBookmarkPreferences();
|
||||||
renderBookmarks();
|
renderBookmarks();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bookmarkSortSelect) {
|
if (bookmarkSortSelect) {
|
||||||
|
bookmarkSortSelect.value = bookmarkSortMode;
|
||||||
bookmarkSortSelect.addEventListener('change', () => {
|
bookmarkSortSelect.addEventListener('change', () => {
|
||||||
const value = bookmarkSortSelect.value;
|
const value = bookmarkSortSelect.value;
|
||||||
if (value === 'label' || value === 'recent') {
|
if (value === 'label' || value === 'recent') {
|
||||||
bookmarkSortMode = value;
|
bookmarkSortMode = value;
|
||||||
|
persistBookmarkPreferences();
|
||||||
renderBookmarks();
|
renderBookmarks();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -1300,6 +1310,7 @@ function initializeBookmarks() {
|
|||||||
bookmarkSortDirectionToggle.addEventListener('click', () => {
|
bookmarkSortDirectionToggle.addEventListener('click', () => {
|
||||||
bookmarkSortDirection = bookmarkSortDirection === 'desc' ? 'asc' : 'desc';
|
bookmarkSortDirection = bookmarkSortDirection === 'desc' ? 'asc' : 'desc';
|
||||||
updateBookmarkSortDirectionUI();
|
updateBookmarkSortDirectionUI();
|
||||||
|
persistBookmarkPreferences();
|
||||||
renderBookmarks();
|
renderBookmarks();
|
||||||
});
|
});
|
||||||
updateBookmarkSortDirectionUI();
|
updateBookmarkSortDirectionUI();
|
||||||
|
|||||||
@@ -18,13 +18,12 @@
|
|||||||
<div class="header-main">
|
<div class="header-main">
|
||||||
<div>
|
<div>
|
||||||
<h1>📋 Post Tracker</h1>
|
<h1>📋 Post Tracker</h1>
|
||||||
<p class="site-header__subtitle">Alle Bereiche ohne Seitenwechsel erreichen</p>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="header-links site-nav">
|
<div class="site-nav">
|
||||||
<button type="button" class="btn btn-secondary" data-view-target="posts">Beiträge</button>
|
<button type="button" class="site-nav__btn" data-view-target="posts">Beiträge</button>
|
||||||
<button type="button" class="btn btn-secondary" data-view-target="dashboard">Dashboard</button>
|
<button type="button" class="site-nav__btn" data-view-target="dashboard">Dashboard</button>
|
||||||
<button type="button" class="btn btn-secondary" data-view-target="settings">⚙️ Einstellungen</button>
|
<button type="button" class="site-nav__btn" data-view-target="settings">⚙️ Einstellungen</button>
|
||||||
<button type="button" class="btn btn-secondary" data-view-target="bookmarks">🔖 Bookmarks</button>
|
<button type="button" class="site-nav__btn" data-view-target="bookmarks">🔖 Bookmarks</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -34,7 +33,7 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="page-toolbar">
|
<div class="page-toolbar">
|
||||||
<div class="page-toolbar__title">
|
<div class="page-toolbar__title">
|
||||||
<h1>📋 Post Tracker</h1>
|
<h2>Beiträge</h2>
|
||||||
<button type="button" class="btn btn-primary" id="openManualPostModalBtn">Beitrag hinzufügen</button>
|
<button type="button" class="btn btn-primary" id="openManualPostModalBtn">Beitrag hinzufügen</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="header-controls">
|
<div class="header-controls">
|
||||||
@@ -151,9 +150,6 @@
|
|||||||
<section id="view-dashboard" class="app-view" data-view="dashboard">
|
<section id="view-dashboard" class="app-view" data-view="dashboard">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="page-toolbar page-toolbar--dashboard">
|
<div class="page-toolbar page-toolbar--dashboard">
|
||||||
<div class="page-toolbar__title">
|
|
||||||
<h1>📊 Dashboard</h1>
|
|
||||||
</div>
|
|
||||||
<div class="header-controls">
|
<div class="header-controls">
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
<label for="timeFilter">Zeitraum:</label>
|
<label for="timeFilter">Zeitraum:</label>
|
||||||
@@ -593,7 +589,6 @@
|
|||||||
<section class="bookmark-page__panel">
|
<section class="bookmark-page__panel">
|
||||||
<div class="bookmark-panel__header">
|
<div class="bookmark-panel__header">
|
||||||
<h2 class="bookmark-panel__title">🔖 Bookmarks</h2>
|
<h2 class="bookmark-panel__title">🔖 Bookmarks</h2>
|
||||||
<a href="index.html" class="btn btn-secondary">Zurück zum Dashboard</a>
|
|
||||||
</div>
|
</div>
|
||||||
<p class="bookmark-page__lead">Über die Bookmarks kannst du auf einen Schlag mehrere relevante Suchanfragen öffnen.</p>
|
<p class="bookmark-page__lead">Über die Bookmarks kannst du auf einen Schlag mehrere relevante Suchanfragen öffnen.</p>
|
||||||
<div class="bookmark-panel__toolbar">
|
<div class="bookmark-panel__toolbar">
|
||||||
|
|||||||
@@ -77,17 +77,43 @@ header {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
background: #f3f4f6;
|
||||||
|
padding: 6px;
|
||||||
.site-nav .btn {
|
|
||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
padding-inline: 20px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.site-nav .btn.nav-active {
|
.site-nav {
|
||||||
background: #111827;
|
display: inline-flex;
|
||||||
color: #ffffff;
|
align-items: center;
|
||||||
border-color: #111827;
|
gap: 8px;
|
||||||
|
background: rgba(255, 255, 255, 0.6);
|
||||||
|
border-radius: 999px;
|
||||||
|
padding: 6px;
|
||||||
|
backdrop-filter: blur(8px);
|
||||||
|
border: 1px solid rgba(148, 163, 184, 0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-nav__btn {
|
||||||
|
border-radius: 999px;
|
||||||
|
padding: 10px 18px;
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #0f172a;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-nav__btn:hover {
|
||||||
|
background: rgba(15, 23, 42, 0.05);
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-nav__btn.nav-active {
|
||||||
|
background: linear-gradient(135deg, #2563eb, #7c3aed);
|
||||||
|
color: white;
|
||||||
|
box-shadow: 0 12px 30px rgba(37, 99, 235, 0.35);
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-controls {
|
.header-controls {
|
||||||
|
|||||||
Reference in New Issue
Block a user