";
}).catch(function() {});
}
function toggleClientCard(i) { var body = document.getElementById("cc-body-" + i); var chev = document.getElementById("cc-chev-" + i); var isOpen = body.style.display !== "none"; body.style.display = isOpen ? "none" : "block"; chev.style.transform = isOpen ? "" : "rotate(90deg)"; if (!isOpen) loadClientStats(i);}
function loadClientStats(i) { var c = clientsCache[i]; if (!c) return; api("GET", "/api/client-stats/" + encodeURIComponent(c.name)).then(function(s) { var updateMini = function(id) { var el = document.getElementById(id); if (el) el.innerHTML = "
" + s.published + "
Published
" + "
" + s.approved + "
Approved
" + "
" + s.scheduled + "
Scheduled
"; }; updateMini("mini-stats-" + i); var aEl = document.getElementById("analytics-stats-" + i); if (aEl) aEl.innerHTML = "
" + s.published + "
Published
" + "
" + s.scheduled + "
Scheduled
" + "
" + s.failed + "
Failed
"; }).catch(function() {});}
function switchClientTab(i, tab, btn) { ["brand","suggestions","analytics","settings"].forEach(function(t) { var el = document.getElementById("cctab-" + t + "-" + i); if (el) el.classList.toggle("on", t === tab); }); btn.closest(".client-tabs").querySelectorAll(".ctab").forEach(function(b) { b.classList.remove("on"); }); btn.classList.add("on");}
function generateSuggestions(i, btn) { var c = clientsCache[i]; if (!c) return; var el = document.getElementById("sug-content-" + i); el.innerHTML = "
Blinkie AI is analyzing " + c.name + "...
"; spinBtn(btn, true); api("POST", "/api/ai/suggestions", { clientName: c.name, brandTone: c.brandTone, goals: c.goals, industry: c.industry, competitors: c.competitors }) .then(function(d) { var html = ""; if (d.audienceInsights) html += "
Audience Insights
" + d.audienceInsights + "
"; if (d.contentPillars && d.contentPillars.length) { html += "
Content Pillars
"; d.contentPillars.forEach(function(p) { html += "
Enable or disable autoposter for this client (credentials are preserved when OFF)
";html+="
";html+="
Facebook Page Access Token iHow to get: 1. Go to Facebook Business Manager 2. System Users -> Generate Token 3. Select your Page 4. Permissions: pages_manage_posts, pages_read_engagement, instagram_content_publish 5. Token expiry: Never 6. Copy token and paste below
";html+="";html+="
"+(fbConnected?"[OK] Connected - Page ID: "+config.facebook.pageId:"o Not connected")+"
";html+="
TikTok Access Token iHow to get: 1. Go to TikTok for Developers (developers.tiktok.com) 2. Create an App 3. Add Video Upload & Publish permissions 4. Generate Access Token 5. Note: Requires app review/approval
";html+="";html+="
"+( ttConnected?"[OK] TikTok Connected":"o TikTok not connected")+"
";html+="
";html+="
Instagram Business Account ID iAuto-filled when you add Facebook token. This is the Instagram Business Account linked to your Facebook Page. Cannot be edited manually.
";html+="";html+="
"+(igConnected?"[OK] Instagram Connected":"o No Instagram linked to Page")+"
";html+="
[GUIDE] Quick Setup Guide:* Facebook & Instagram share the same token * Page ID and IG User ID auto-fill from token * TikTok requires separate developer credentials * All tokens encrypted with AES-256-GCM * Turning autoposter OFF preserves credentials * Posts will fail if autoposter is disabled
";html+="
";html+="";container.innerHTML=html;}
function submitClient() { var name = document.getElementById("nc-name").value.trim(); var tok = document.getElementById("nc-tok").value.trim(); var rec = document.getElementById("nc-at").value; var err = document.getElementById("nc-err"); var btn = document.getElementById("btn-submit-client"); if (!name || !tok) { err.textContent = "Name and token are required"; return; } err.textContent = ""; spinBtn(btn, true); api("POST", "/api/clients", { name: name, pageAccessToken: tok, recordId: rec }) .then(function() { closeModal("m-addclient"); toast("Client connected and token encrypted", "ok"); document.getElementById("nc-name").value = ""; document.getElementById("nc-tok").value = ""; loadClients(); loadStats(); }) .catch(function(e) { err.textContent = e.message; }) .then(function() { spinBtn(btn, false); });}
function loadPosts() { var wrap = document.getElementById("posts-body"); wrap.innerHTML = "
Loading...
"; var st = document.getElementById("f-status").value; var cl = document.getElementById("f-client").value; var qs = new URLSearchParams(); if (st) qs.set("status", st); if (cl) qs.set("client", cl); api("GET", "/api/posts?" + qs).then(function(posts) { if (!posts.length) { wrap.innerHTML = "
No posts found
Try adjusting the filters
"; return; }
var sbadge = function(s) { var m = { "Approved":"b-green","Published":"b-blue","Failed":"b-red","Scheduled":"b-purple","In progress":"b-orange","Send for Approval":"b-orange","Revisions Requested":"b-red" }; return "" + s + ""; }; var rows = posts.map(function(p) { var d = p.date ? new Date(p.date).toLocaleString("el-GR", { day:"2-digit", month:"2-digit", year:"2-digit", hour:"2-digit", minute:"2-digit" }) : "-"; var pfB = p.platform === "Facebook" ? "FB" : p.platform === "Instagram" ? "IG" : "" + p.platform + ""; var flags = (!p.hasCaption ? "No caption " : "") + (!p.hasVisual ? "No visual" : ""); var acts = ""; if (p.status !== "Approved" && p.status !== "Published") acts += " "; if (p.status === "Approved") acts += " "; if (p.status === "Failed") acts += ""; return "