Cloche
Beta Dashboard
Dashboard
Invite Codes
Feedback
Beta Users
Influencer
Timeline
Admin Access
Log in as an admin to view the beta dashboard.
Log In
Loading stats…
Feature Usage
last 30 days
30 days
7 days
#
Page
Views
Trend
Loading…
Feedback
—
All
Contextual Prompts
Manual
With Rating
Message
From
Prompt
Rating
Date
Loading…
Beta Users
—
All
Beta Invites
Active 7d
Account Frozen
User
Type
Signed Up
Last Active
Trial Ends
Loading…
function getCookie(n){for(var c=document.cookie.split(";"),i=0;i
(function(){var k="cloche_token",c=localStorage.getItem(k),d=document.getElementById("auth-gate"),f=document.getElementById("main-content"),o=null,g=!1;function b(e,a){return fetch(e,g?Object.assign({credentials:"include"},a||{}):Object.assign({headers:{Authorization:"Bearer "+c}},a||{}))}getCookie("polsia_session")?fetch("/api/admin/check-cookie",{credentials:"include"}).then(function(e){return e.ok?e.json():{success:!1}}).then(function(e){e.success?(g=!0,f.style.display="",m()):c?h():d.style.display=""}).catch(function(){c?h():d.style.display=""}):c?h():d.style.display="";function h(){fetch("/api/admin/is-admin",{headers:{Authorization:"Bearer "+c}}).then(function(e){return e.ok?e.json():{is_admin:!1}}).then(function(e){return e.is_admin?(f.style.display="",m()):(d.style.display="block",f.style.display="none",Promise.reject("not-admin"))}).catch(function(e){console.error("Admin check failed:",e)})}function m(){b("/api/admin/beta-stats"+(g?"-cookie":"")).then(function(e){if(e.status===401||e.status===403)throw d.style.display="block",f.style.display="none",new Error("Unauthorized");return e.json()}).then(function(e){if(!e.success)throw new Error(e.message||"Failed");o=e,x(e.stats),v(e.feature_usage,30),y(e.feedback,"all"),w(e.users,"all")}).catch(function(e){console.error("Dashboard load failed:",e.message)})}function x(e){if(e){var a=document.getElementById("stats-grid"),i=[{num:e.total_users,lbl:"Total Users",sub:""},{num:e.beta_users,lbl:"Beta Users",sub:"invite code"},{num:e.active_7d,lbl:"Active (7d)",sub:"had page views"},{num:e.new_this_week,lbl:"New This Week",sub:"last 7 days"},{num:e.total_feedback,lbl:"Total Feedback",sub:e.feedback_with_rating+" with rating"},{num:e.avg_rating?parseFloat(e.avg_rating).toFixed(1)+'
':"\u2014",lbl:"Avg Rating",sub:"from star prompts"}];a.innerHTML=i.map(function(r){return'
'+r.num+'
'+r.lbl+"
"+(r.sub?'
'+r.sub+"
":"")+"
"}).join("")}}function v(e,a){var i=(e||[]).filter(function(t){return a===30||t.period==="7d"}),r=document.getElementById("feature-usage-body"),n=a===7?o&&o.feature_usage_7d||[]:o&&o.feature_usage_30d||o&&o.feature_usage||[];if(!n||n.length===0){r.innerHTML='
No page views tracked yet \u2014 this feature rolls out now.
';return}var l=Math.max.apply(null,n.map(function(t){return parseInt(t.views,10)}));r.innerHTML=n.map(function(t,s){var p=Math.round(parseInt(t.views,10)/l*100);return'
'+(s+1)+"
"+u(t.page)+'
'+t.views+'
'}).join("")}document.querySelectorAll("[data-period]").forEach(function(e){e.addEventListener("click",function(){document.querySelectorAll("[data-period]").forEach(function(i){i.classList.remove("active")}),e.classList.add("active");var a=parseInt(e.dataset.period,10);document.getElementById("feature-period").textContent="last "+a+" days",v(null,a)})});function y(e,a){if(e){var i=e.filter(function(n){return a==="contextual"?n.prompt_type:a==="manual"?!n.prompt_type:a==="rated"?n.rating!==null:!0});document.getElementById("feedback-count").textContent=i.length;var r=document.getElementById("feedback-body");if(i.length===0){r.innerHTML='
No feedback '+(a!=="all"?"of this type ":"")+"yet.
";return}r.innerHTML=i.map(function(n){var l=n.prompt_type?'
'+(n.prompt_type||"").replace(/_/g," ")+"
":'
manual
',t="";n.rating!==null&&n.rating!==void 0?n.rating===1||n.rating===0?t=n.rating===1?'
':'
':t='
'+'
'.repeat(n.rating)+'
'.repeat(5-n.rating)+'
'+n.rating+"/5
":t='
\u2014
';var s=new Date(n.created_at).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"2-digit"}),p=(n.feedback_text||"").trim().substring(0,160)+((n.feedback_text||"").length>160?"\u2026":"");return'
'+u(p)+'
'+u(n.user_name||n.user_email||"\u2014")+"
"+l+'
'+t+'
'+s+"
"}).join("")}}document.getElementById("feedback-filters").addEventListener("click",function(e){var a=e.target.closest("[data-type]");a&&(document.querySelectorAll("#feedback-filters [data-type]").forEach(function(i){i.classList.remove("active")}),a.classList.add("active"),y(o&&o.feedback,a.dataset.type))});function w(e,a){if(e){var i=Date.now(),r=i-10080*60*1e3,n=e.filter(function(t){if(a==="beta")return t.trial_type==="beta";if(a==="active"){var s=t.last_active?new Date(t.last_active).getTime():0;return s>=r}return a==="frozen"?!!t.account_frozen_at:!0});document.getElementById("users-count").textContent=n.length;var l=document.getElementById("users-body");if(n.length===0){l.innerHTML='
No users match this filter.
';return}l.innerHTML=n.map(function(t){var s="";t.trial_type==="beta"?s='
beta
':t.trial_type==="influencer"&&(s='
influencer
'),t.account_frozen_at?s+='
frozen
':t.subscription_status==="active"&&t.subscription_tier==="pro"?s+='
pro
':t.subscription_status==="active"&&t.subscription_tier==="lite"?s+='
lite
':s+='
trial
';var p=t.created_at?new Date(t.created_at).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"2-digit"}):"\u2014",_=t.last_active?new Date(t.last_active).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"2-digit"}):"\u2014",L=t.trial_end_date?new Date(t.trial_end_date).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"2-digit"}):"\u2014",B=t.last_active&&new Date(t.last_active).getTime()>=r,E=B?'
'+_+'
':'
'+_+"
";return'
'+u(t.name||"(no name)")+'
'+u(t.email||"")+"
"+s+'
'+p+"
"+E+'
'+L+"
"}).join("")}}document.getElementById("user-filters").addEventListener("click",function(e){var a=e.target.closest("[data-type]");a&&(document.querySelectorAll("#user-filters [data-type]").forEach(function(i){i.classList.remove("active")}),a.classList.add("active"),w(o&&o.users,a.dataset.type))});function u(e){return String(e||"").replace(/&/g,"&").replace(//g,">").replace(/"/g,""")}})();