(function(){ var API = '/wp-json/wp/v2/posts'; var PER_PAGE = 12; var page = 1; var currentFilter = 'all'; var searchQuery = ''; var allPosts = []; var cardIndex = 0; var grid = document.getElementById('amb-grid'); var loadMore = document.getElementById('amb-load-more'); var loadBtn = document.getElementById('amb-load-btn'); var loading = document.getElementById('amb-loading'); var filters = document.getElementById('amb-filters'); var filtersWrap = document.getElementById('amb-filters-wrap'); var searchInput = document.getElementById('amb-search-input'); var featured = document.getElementById('amb-featured'); var backTop = document.getElementById('amb-back-top'); var searchTimer = null; function decode(s) { if (!s) return ''; var stripped = s.replace(/<[^>]*>/g, ''); try { var doc = new DOMParser().parseFromString(stripped, 'text/html'); return doc.body.textContent || ''; } catch(e) { return stripped; } } function formatDate(d) { var dt = new Date(d); var m = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']; return m[dt.getMonth()] + ' ' + dt.getDate() + ', ' + dt.getFullYear(); } function readTime(text) { var words = text.split(/\s+/).length; var min = Math.max(1, Math.round(words / 200)); return min + ' min read'; } var badgeColors = { 'coach':'gold', 'kate spade':'purple', 'michael kors':'blue', 'fossil':'green', 'marc jacobs':'purple', 'tory burch':'gold', 'gift guide':'red', 'fashion':'blue', 'style tips':'green', 'international':'purple', 'malaysia':'gold', 'singapore':'blue', 'philippines':'green', 'uae':'purple', 'brunei':'green', 'kuwait':'purple', 'budget':'blue', 'fake':'red', 'care':'green', 'bm':'gold', 'valentine':'red', 'mother':'gold', 'wedding':'purple', 'cny':'red', 'travel':'green', 'work':'blue', 'office':'blue', 'hari raya':'gold', 'preloved':'green', 'outlet':'gold', 'comparison':'blue' }; function getBadgeColor(allTerms) { var lc = allTerms.toLowerCase(); for (var k in badgeColors) { if (lc.indexOf(k) !== -1) return badgeColors[k]; } return ''; } function getAllCategories(post) { var names = []; if (post._embedded && post._embedded['wp:term']) { var cats = post._embedded['wp:term'][0]; if (cats) { for (var i = 0; i < cats.length; i++) names.push(cats[i].name); } var tags = post._embedded['wp:term'][1]; if (tags) { for (var j = 0; j < tags.length; j++) names.push(tags[j].name); } } return names.length > 0 ? names : ['Style Guide']; } function getCategoryName(post) { return getAllCategories(post)[0]; } function getImageUrl(post) { if (post._embedded && post._embedded['wp:featuredmedia'] && post._embedded['wp:featuredmedia'][0]) { var media = post._embedded['wp:featuredmedia'][0]; if (media.media_details && media.media_details.sizes) { if (media.media_details.sizes.medium_large) return media.media_details.sizes.medium_large.source_url; if (media.media_details.sizes.large) return media.media_details.sizes.large.source_url; if (media.media_details.sizes.medium) return media.media_details.sizes.medium.source_url; } if (media.source_url) return media.source_url; } return ''; } var brandKeywords = ['coach','kate spade','michael kors','fossil','marc jacobs','tory burch','longchamp','guess','furla']; var phThemes = ['warm','rose','sage','sky','gold']; var phIcons = ['\u2666','\u2726','\u25C7','\u2727','\u2662']; function extractBrand(title) { var lc = title.toLowerCase(); for (var i = 0; i < brandKeywords.length; i++) { if (lc.indexOf(brandKeywords[i]) !== -1) { return brandKeywords[i].split(' ').map(function(w){ return w.charAt(0).toUpperCase()+w.slice(1); }).join(' '); } } if (lc.indexOf('designer bag') !== -1) return 'Designer Bags'; if (lc.indexOf('beg branded') !== -1 || lc.indexOf('beg tangan') !== -1) return 'Beg Branded'; if (lc.indexOf('fake') !== -1 || lc.indexOf('authentication') !== -1) return 'Auth Guide'; if (lc.indexOf('care') !== -1 || lc.indexOf('jaga') !== -1 || lc.indexOf('store') !== -1) return 'Care Guide'; if (lc.indexOf('work') !== -1 || lc.indexOf('kerja') !== -1 || lc.indexOf('office') !== -1) return 'Work Style'; if (lc.indexOf('gift') !== -1 || lc.indexOf('hadiah') !== -1) return 'Gift Guide'; if (lc.indexOf('budget') !== -1 || lc.indexOf('murah') !== -1) return 'Budget Finds'; if (lc.indexOf('trend') !== -1) return 'Trends'; if (lc.indexOf('travel') !== -1) return 'Travel'; return 'Style Journal'; } function buildPlaceholder(title, idx) { var ph = document.createElement('div'); ph.className = 'amb-placeholder-img'; ph.setAttribute('data-theme', phThemes[idx % phThemes.length]); var icon = document.createElement('span'); icon.className = 'amb-ph-icon'; icon.textContent = phIcons[idx % phIcons.length]; var line = document.createElement('div'); line.className = 'amb-ph-line'; var brand = document.createElement('span'); brand.className = 'amb-ph-brand'; brand.textContent = extractBrand(title); ph.appendChild(icon); ph.appendChild(line); ph.appendChild(brand); return ph; } // ── Skeleton Loading ── function buildSkeletonCard() { var sk = document.createElement('div'); sk.className = 'amb-skeleton-card amb-blog-card amb-skeleton'; sk.setAttribute('data-skeleton', 'true'); sk.style.opacity = '1'; sk.style.animation = 'none'; return sk; } function showSkeletons(count) { for (var i = 0; i < count; i++) { grid.appendChild(buildSkeletonCard()); } } function removeSkeletons() { var sks = grid.querySelectorAll('[data-skeleton]'); for (var i = 0; i < sks.length; i++) sks[i].remove(); } // ── Build featured post ── function buildFeaturedPost(post) { var imgUrl = getImageUrl(post); var title = decode(post.title.rendered); var excerpt = decode(post.excerpt.rendered).substring(0, 200); var link = post.link; var date = formatDate(post.date); var time = readTime(decode(post.excerpt.rendered)); var card = document.createElement('div'); card.className = 'amb-featured-card'; var a = document.createElement('a'); a.href = link; var imgDiv = document.createElement('div'); imgDiv.className = 'amb-featured-img'; if (imgUrl) { var img = document.createElement('img'); img.src = imgUrl; img.alt = title; img.loading = 'eager'; imgDiv.appendChild(img); } else { imgDiv.appendChild(buildPlaceholder(title, 0)); } var body = document.createElement('div'); body.className = 'amb-featured-body'; var label = document.createElement('span'); label.className = 'amb-featured-label'; label.textContent = 'Featured Article'; var titleEl = document.createElement('h2'); titleEl.className = 'amb-featured-title'; titleEl.textContent = title; var excerptEl = document.createElement('p'); excerptEl.className = 'amb-featured-excerpt'; excerptEl.textContent = excerpt; var meta = document.createElement('div'); meta.className = 'amb-featured-meta'; meta.textContent = date + ' \u00B7 ' + time; var readEl = document.createElement('span'); readEl.className = 'amb-featured-read'; readEl.textContent = 'Read Article \u2192'; body.appendChild(label); body.appendChild(titleEl); body.appendChild(excerptEl); body.appendChild(meta); body.appendChild(readEl); a.appendChild(imgDiv); a.appendChild(body); card.appendChild(a); return card; } // ── Build blog card (overlay style) ── function buildCard(post) { var card = document.createElement('div'); card.className = 'amb-blog-card'; card.style.setProperty('--card-index', cardIndex++); var cat = getCategoryName(post); var imgUrl = getImageUrl(post); var title = decode(post.title.rendered); var excerpt = decode(post.excerpt.rendered).substring(0, 120); var date = formatDate(post.date); var time = readTime(decode(post.excerpt.rendered)); var link = post.link; var a = document.createElement('a'); a.href = link; a.setAttribute('aria-label', title); // Image layer (fills entire card) var imgWrap = document.createElement('div'); imgWrap.className = 'amb-card-img-wrap'; if (imgUrl) { var img = document.createElement('img'); img.src = imgUrl; img.alt = title; img.loading = 'lazy'; imgWrap.appendChild(img); } else { imgWrap.appendChild(buildPlaceholder(title, cardIndex)); } // Badge var badge = document.createElement('span'); badge.className = 'amb-card-badge'; badge.textContent = cat; var allTerms = getAllCategories(post).join(' '); var bc = getBadgeColor(allTerms); if (bc) badge.setAttribute('data-color', bc); imgWrap.appendChild(badge); // Body — overlaid at bottom of card var body = document.createElement('div'); body.className = 'amb-card-body'; var dateEl = document.createElement('span'); dateEl.className = 'amb-card-date'; dateEl.textContent = date; var titleEl = document.createElement('h3'); titleEl.className = 'amb-card-title'; titleEl.textContent = title; var excerptEl = document.createElement('p'); excerptEl.className = 'amb-card-excerpt'; excerptEl.textContent = excerpt; var footer = document.createElement('div'); footer.className = 'amb-card-footer'; var readEl = document.createElement('span'); readEl.className = 'amb-card-read'; readEl.textContent = 'Read More \u2192'; var timeEl = document.createElement('span'); timeEl.className = 'amb-card-time'; timeEl.textContent = time; footer.appendChild(readEl); footer.appendChild(timeEl); body.appendChild(dateEl); body.appendChild(titleEl); body.appendChild(excerptEl); body.appendChild(footer); a.appendChild(imgWrap); a.appendChild(body); card.appendChild(a); var allCats = getAllCategories(post).join(' '); card.setAttribute('data-categories', (allCats + ' ' + title + ' ' + decode(post.excerpt.rendered)).toLowerCase()); return card; } function renderPosts(posts) { posts.forEach(function(post) { grid.appendChild(buildCard(post)); }); } function insertAdZone() { if (allPosts.length >= 6) { var adZone = document.createElement('div'); adZone.className = 'amb-blog-ad-zone'; var children = grid.children; if (children.length >= 6) { grid.insertBefore(adZone, children[6]); } } } function updatePostCount() { var existing = document.querySelector('.amb-post-count'); if (existing) existing.remove(); var cards = grid.querySelectorAll('.amb-blog-card:not([data-skeleton])'); var visible = 0; for (var i = 0; i < cards.length; i++) { if (cards[i].style.display !== 'none') visible++; } if (visible > 0 && (currentFilter !== 'all' || searchQuery)) { var countDiv = document.createElement('div'); countDiv.className = 'amb-post-count'; countDiv.textContent = visible + ' article' + (visible !== 1 ? 's' : '') + ' found'; grid.parentNode.insertBefore(countDiv, grid); } } function filterPosts(keyword) { var cards = grid.querySelectorAll('.amb-blog-card:not([data-skeleton]), .amb-blog-ad-zone'); var visibleCount = 0; var query = searchQuery.toLowerCase(); for (var i = 0; i < cards.length; i++) { var card = cards[i]; if (card.classList.contains('amb-blog-ad-zone')) { card.style.display = (keyword === 'all' && !query) ? '' : 'none'; continue; } var data = (card.getAttribute('data-categories') || '').toLowerCase(); var matchFilter = keyword === 'all' || data.indexOf(keyword.toLowerCase()) !== -1; var matchSearch = !query || data.indexOf(query) !== -1; if (matchFilter && matchSearch) { card.style.display = ''; visibleCount++; } else { card.style.display = 'none'; } } var noRes = grid.querySelector('.amb-no-results'); if (visibleCount === 0) { if (!noRes) { var nr = document.createElement('div'); nr.className = 'amb-no-results'; nr.textContent = 'No articles found. Try a different search or filter.'; grid.appendChild(nr); } } else if (noRes) { noRes.remove(); } updatePostCount(); } function loadPosts() { if (page === 1) { showSkeletons(6); } else { loading.style.display = 'block'; } loadMore.style.display = 'none'; var url = API + '?per_page=' + PER_PAGE + '&page=' + page + '&_fields=id,title,excerpt,link,date,_links&_embed=wp:featuredmedia,wp:term&orderby=date&order=desc'; fetch(url).then(function(r) { var total = parseInt(r.headers.get('X-WP-TotalPages') || '1', 10); return r.json().then(function(posts) { return { posts: posts, totalPages: total }; }); }).then(function(data) { removeSkeletons(); loading.style.display = 'none'; if (!Array.isArray(data.posts) || data.posts.length === 0) { if (allPosts.length === 0) { grid.textContent = ''; var nr = document.createElement('div'); nr.className = 'amb-no-results'; nr.textContent = 'No articles yet. Check back soon!'; grid.appendChild(nr); } return; } if (page === 1 && data.posts.length > 0) { featured.textContent = ''; featured.appendChild(buildFeaturedPost(data.posts[0])); allPosts = allPosts.concat(data.posts); cardIndex = 0; renderPosts(data.posts.slice(1)); } else { cardIndex = 0; allPosts = allPosts.concat(data.posts); renderPosts(data.posts); } if (page === 1) insertAdZone(); if (page < data.totalPages) { loadMore.style.display = 'block'; } page++; if (currentFilter !== 'all') filterPosts(currentFilter); }).catch(function() { removeSkeletons(); loading.style.display = 'none'; if (allPosts.length === 0) { grid.textContent = ''; var nr = document.createElement('div'); nr.className = 'amb-no-results'; nr.textContent = 'Unable to load articles. Please refresh the page.'; grid.appendChild(nr); } }); } // ── Sticky filter bar ── if (filtersWrap) { var observer = new IntersectionObserver(function(entries) { entries.forEach(function(e) { filtersWrap.classList.toggle('amb-stuck', !e.isIntersecting); }); }, { threshold: [1], rootMargin: '-1px 0px 0px 0px' }); observer.observe(filtersWrap); } // ── Back to top ── if (backTop) { window.addEventListener('scroll', function() { if (window.scrollY > 600) { backTop.classList.add('amb-visible'); } else { backTop.classList.remove('amb-visible'); } }, { passive: true }); backTop.addEventListener('click', function() { window.scrollTo({ top: 0, behavior: 'smooth' }); }); } // ── Event listeners ── filters.addEventListener('click', function(e) { if (e.target.classList.contains('amb-filter-btn')) { var btns = filters.querySelectorAll('.amb-filter-btn'); for (var i = 0; i < btns.length; i++) btns[i].classList.remove('amb-active'); e.target.classList.add('amb-active'); currentFilter = e.target.getAttribute('data-filter'); filterPosts(currentFilter); } }); searchInput.addEventListener('input', function() { clearTimeout(searchTimer); searchTimer = setTimeout(function() { searchQuery = searchInput.value.trim(); filterPosts(currentFilter); }, 300); }); loadBtn.addEventListener('click', function() { loadPosts(); }); loadPosts(); })();