
            //
            //
            // region POSTS FILTER & LOADING
            //
            //

            var allPosts = [];
            let postsPage = 1;
            const postsLimit = 100;

            let postsFilterState = {
                sortBy: 'newest',
                searchTerm: '',
                filters: {
                    date_range: { from: 1, to: 1825 },
                    upvotes: { from: 0, to: 9999 },
                    comments: { from: 0, to: 9999 },
                    author_name: ''
                }
            };

            let setPostsSort = (value) => {
                postsFilterState.sortBy = value;
            };

            // Slider steps for date range
            const postsDaysSliderSteps = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,30,60,90,120,150,180,365,730,1095,1460,1825];

            let postsDaysToStepIndex = (days) => {
                let best = 0;
                for (let i = 0; i < postsDaysSliderSteps.length; i++) {
                    if (Math.abs(postsDaysSliderSteps[i] - days) <= Math.abs(postsDaysSliderSteps[best] - days)) best = i;
                }
                return best;
            };

            // Convert days-ago value to a Date object (days=1 means today)
            let postsDaysAgoToDate = (days) => {
                let d = new Date();
                d.setHours(0, 0, 0, 0);
                d.setDate(d.getDate() - (days - 1));
                return d;
            };

            // Format Date as YYYY-MM-DD (for <input type="date"> value)
            let postsDateToISOString = (date) => {
                let yyyy = date.getFullYear();
                let mm = String(date.getMonth() + 1).padStart(2, '0');
                let dd = String(date.getDate()).padStart(2, '0');
                return `${yyyy}-${mm}-${dd}`;
            };

            // Convert YYYY-MM-DD string back to days-ago value
            let postsIsoStringToDays = (isoStr) => {
                let parts = isoStr.split('-');
                let date = new Date(parseInt(parts[0]), parseInt(parts[1]) - 1, parseInt(parts[2]));
                let now = new Date();
                now.setHours(0, 0, 0, 0);
                date.setHours(0, 0, 0, 0);
                let diffDays = Math.round((now - date) / (1000 * 60 * 60 * 24));
                return Math.max(1, diffDays + 1);
            };

            let postsTodayISO = postsDateToISOString(new Date());
            let postsOldestISO = postsDateToISOString(postsDaysAgoToDate(1825));

            let postsFormatDaysDisplay = (days) => postsDateToISOString(postsDaysAgoToDate(days));

            let postsHandleDualSliderInput = (key, side, stepIdx) => {
                const days = postsDaysSliderSteps[stepIdx];
                const elem = document.getElementById(`posts_input_${key}_${side}`);
                if (elem) elem.value = postsFormatDaysDisplay(days);
            };

            // Handle date input change (from <input type="date">)
            let postsHandleDateInput = (key, side, isoValue) => {
                if (!isoValue) return;
                const days = postsIsoStringToDays(isoValue);
                if (days < 1) return;
                postsSetRangeFilterValue(key, side, Math.min(1825, days));
                postsSyncRangeUI(key);
            };

            let postsHandleDualSliderChange = (key, side, stepIdx) => {
                const days = postsDaysSliderSteps[stepIdx];
                postsSetRangeFilterValue(key, side, days);
                postsSyncRangeUI(key);
            };

            let postsSetRangeFilterValue = (key, side, days) => {
                if (!postsFilterState.filters[key]) return;
                days = Math.max(1, Math.min(1825, days));
                if (side === 'from') {
                    postsFilterState.filters[key].from = days;
                    if (postsFilterState.filters[key].to < days) postsFilterState.filters[key].to = days;
                } else {
                    postsFilterState.filters[key].to = days;
                    if (postsFilterState.filters[key].from > days) postsFilterState.filters[key].from = days;
                }
            };

            let postsSyncRangeUI = (key) => {
                const f = postsFilterState.filters[key];
                if (!f) return;
                const fromSlider = document.getElementById(`posts_slider_${key}_from`);
                const toSlider = document.getElementById(`posts_slider_${key}_to`);
                if (fromSlider) fromSlider.value = postsDaysToStepIndex(f.from);
                if (toSlider) toSlider.value = postsDaysToStepIndex(f.to);
                const fromDisplay = document.getElementById(`posts_input_${key}_from`);
                const toDisplay = document.getElementById(`posts_input_${key}_to`);
                if (fromDisplay) fromDisplay.value = postsFormatDaysDisplay(f.from);
                if (toDisplay) toDisplay.value = postsFormatDaysDisplay(f.to);
            };

            let postsBuildDualRangeSlider = (key) => {
                const f = postsFilterState.filters[key];
                if (!f) return '';
                const fromIdx = postsDaysToStepIndex(f.from);
                const toIdx = postsDaysToStepIndex(f.to);
                const maxIdx = postsDaysSliderSteps.length - 1;
                const fromDisplay = postsFormatDaysDisplay(f.from);
                const toDisplay = postsFormatDaysDisplay(f.to);
                return `
                    <div class="dual-range-wrap">
                        <div class="dual-range-labels">
                            <input type="date" class="dual-range-date-input" id="posts_input_${key}_from"
                                value="${fromDisplay}" min="${postsOldestISO}" max="${postsTodayISO}"
                                onchange="postsHandleDateInput('${key}','from',this.value); this.blur();">
                            <span class="dual-range-unit">&mdash;</span>
                            <input type="date" class="dual-range-date-input" id="posts_input_${key}_to"
                                value="${toDisplay}" min="${postsOldestISO}" max="${postsTodayISO}"
                                onchange="postsHandleDateInput('${key}','to',this.value); this.blur();">
                        </div>
                        <div class="dual-range-track">
                            <input type="range" id="posts_slider_${key}_from"
                                min="0" max="${maxIdx}" value="${fromIdx}"
                                oninput="postsHandleDualSliderInput('${key}','from',this.value)"
                                onchange="postsHandleDualSliderChange('${key}','from',this.value)">
                            <input type="range" id="posts_slider_${key}_to"
                                min="0" max="${maxIdx}" value="${toIdx}"
                                oninput="postsHandleDualSliderInput('${key}','to',this.value)"
                                onchange="postsHandleDualSliderChange('${key}','to',this.value)">
                        </div>
                    </div>`;
            };

            let postsBuildFilterRow = (key, label, controlsHtml) => {
                return `<div class="filter-row filter-row-enabled">
                    <div class="filter-row-header">
                        <span class="filter-row-label">${label}</span>
                    </div>
                    <div class="filter-row-controls">${controlsHtml}</div>
                </div>`;
            };

            let renderPostsFilterPanel = () => {
                const f = postsFilterState.filters;
                let html = '';

                // Date range
                html += postsBuildFilterRow('date_range', 'Date Range',
                    postsBuildDualRangeSlider('date_range'));

                // Upvotes range
                html += postsBuildFilterRow('upvotes', 'Upvotes',
                    `<div class="numeric-range-wrap">
                        <input type="number" min="0" value="${f.upvotes.from}" onchange="postsFilterState.filters.upvotes.from = parseInt(this.value) || 0">
                        <span class="numeric-range-sep">to</span>
                        <input type="number" min="0" value="${f.upvotes.to}" onchange="postsFilterState.filters.upvotes.to = parseInt(this.value) || 0">
                    </div>`);

                // Comments range
                html += postsBuildFilterRow('comments', 'Comments',
                    `<div class="numeric-range-wrap">
                        <input type="number" min="0" value="${f.comments.from}" onchange="postsFilterState.filters.comments.from = parseInt(this.value) || 0">
                        <span class="numeric-range-sep">to</span>
                        <input type="number" min="0" value="${f.comments.to}" onchange="postsFilterState.filters.comments.to = parseInt(this.value) || 0">
                    </div>`);

                // Author name
                html += postsBuildFilterRow('author_name', 'Author',
                    `<input type="text" placeholder="Author name..." value="${f.author_name || ''}"
                        onchange="postsFilterState.filters.author_name = this.value" style="width: 100%;">`);

                // Apply button
                html += '<div style="margin-top: 12px;"><button onclick="applyPostsFilter()" style="width: 100%; padding: 8px; font-weight: bold; background: var(--theme-color, #4a90d9); color: white !important; border: none; border-radius: 4px; cursor: pointer;">Apply</button></div>';

                // Clear button
                html += '<div style="margin-top: 8px;"><button onclick="clearPostsFilter()" style="width: 100%; padding: 8px; font-weight: bold; background: #d9534f; color: white !important; border: none; border-radius: 4px; cursor: pointer;">Clear</button></div>';

                document.getElementById('filter-panel-body').innerHTML = html;
            };

            let applyPostsFilter = () => {
                loadPosts();
            };

            let clearPostsFilter = () => {
                postsFilterState = {
                    sortBy: 'newest',
                    searchTerm: '',
                    filters: {
                        date_range: { from: 1, to: 1825 },
                        upvotes: { from: 0, to: 9999 },
                        comments: { from: 0, to: 9999 },
                        author_name: ''
                    }
                };
                document.getElementById('posts-search-input').value = '';
                document.getElementById('posts-sort-select').value = 'newest';
                renderPostsFilterPanel();
                loadPosts();
            };

            var loadPosts = async (skipAnimation = false) => {
                if (!skipAnimation) lib.showLoading();
                const res = await post('/api/post/filter', postsFilterState);
                if (!skipAnimation) lib.hideLoading();
                if (res.ok) {
                    allPosts = res.data.posts;
                    postsPage = 1;
                    document.getElementById("postAmount").innerText = allPosts.length.toString();
                    renderPostsView();
                    if (!postsInitialLoading) renderPostsSecondaryView();
                }
            };

            let setPostsPage = (page) => {
                postsPage = page;
                renderPostsView();
                document.getElementById("posts-view").scrollIntoView({behavior: 'smooth'});
            };

            let renderPostsPagination = () => {
                const total = allPosts.length;
                const pages = Math.ceil(total / postsLimit);
                if (pages <= 1) return '';
                const start = (postsPage - 1) * postsLimit + 1;
                const end = Math.min(postsPage * postsLimit, total);
                let html = `<div style="margin:10px 0;display:flex;gap:5px;align-items:center;flex-wrap:wrap;">`;
                html += `<span>${start}-${end} of ${total} | Page ${postsPage}/${pages}</span>`;
                html += `<button onclick="setPostsPage(1)" ${postsPage===1?'disabled':''}>&#171;</button>`;
                html += `<button onclick="setPostsPage(${postsPage-1})" ${postsPage===1?'disabled':''}>&#8249;</button>`;
                const pStart = Math.max(1, postsPage - 2);
                const pEnd = Math.min(pages, postsPage + 2);
                for (let i = pStart; i <= pEnd; i++) {
                    html += `<button onclick="setPostsPage(${i})" ${i===postsPage?'style="font-weight:bold"':''}>${i}</button>`;
                }
                html += `<button onclick="setPostsPage(${postsPage+1})" ${postsPage===pages?'disabled':''}>&#8250;</button>`;
                html += `<button onclick="setPostsPage(${pages})" ${postsPage===pages?'disabled':''}>&#187;</button>`;
                html += `</div>`;
                return html;
            };

            const renderPostCard = (p) => {
                const meta = p.metadata ? JSON.parse(p.metadata) : {};
                const title = meta.title || p.name || '(Untitled)';
                const content = meta.content || '';
                const preview = content.length > 200 ? content.substring(0, 200) + '...' : content;
                const createdAt = p.skool_created_at ? new Date(p.skool_created_at).toLocaleDateString() : '-';
                const commentCount = p.comments || 0;
                const label = meta.label || p.label_id || '';
                const labelHtml = label ? `<span style="background: var(--theme-color, #4a90d9); color: #fff; padding: 1px 6px; border-radius: 3px; font-size: 0.8em;">${label}</span>` : '';

                return `
                    <article style="margin: 4px 0; padding: 10px; border: 1px solid #444; border-radius: 6px; cursor: pointer"
                        onclick="togglePostComments(this, '${p.skool_id}')">
                        <div style="display: flex; justify-content: space-between; align-items: flex-start;">
                            <b>${title}</b>
                            ${labelHtml}
                        </div>
                        <small style="color: #888; display: block; margin: 4px 0;">${preview}</small>
                        <small>
                            by <b>${p.user_name || '-'}</b> |
                            ${p.upvotes || 0} upvotes | ${commentCount} comments |
                            ${createdAt}
                        </small>
                        <div class="post-comments" style="display:none"></div>
                    </article>
                `;
            };

            const renderPostsView = () => {
                const postsView = document.getElementById("posts-list");
                if (!postsView) return;

                const offset = (postsPage - 1) * postsLimit;
                const pagePosts = allPosts.slice(offset, offset + postsLimit);

                let html = '';
                for (const p of pagePosts) {
                    html += renderPostCard(p);
                }
                html += renderPostsPagination();
                postsView.innerHTML = html;
            };

            let togglePostComments = async (articleEl, postSkoolId) => {
                const commentsDiv = articleEl.querySelector('.post-comments');
                if (!commentsDiv) return;

                if (commentsDiv.style.display !== 'none') {
                    commentsDiv.style.display = 'none';
                    return;
                }

                commentsDiv.style.display = 'block';
                if (commentsDiv.dataset.loaded) return;

                commentsDiv.innerHTML = '<small>Loading comments...</small>';
                const res = await get(`/api/post/${postSkoolId}/comments`);
                const comments = res.ok ? res.data : [];
                commentsDiv.dataset.loaded = '1';

                if (comments.length === 0) {
                    commentsDiv.innerHTML = '<small style="color:#999">No comments</small>';
                    return;
                }

                let html = '';
                for (const c of comments) {
                    const meta = c.metadata ? JSON.parse(c.metadata) : {};
                    const content = meta.content || '';
                    const createdAt = c.skool_created_at ? new Date(c.skool_created_at).toLocaleDateString() : '-';
                    html += `<div style="margin: 4px 0 0 12px; padding: 4px 8px; border-left: 2px solid #aaa">
                        <small><b>${c.user_name || '-'}</b> | ${createdAt}</small><br>
                        <small>${content}</small>
                    </div>`;
                }
                commentsDiv.innerHTML = html;
            };
