1import{u as p,c as a,a as u,b as r,h as at,w as tt,d as t,l as lt,f as it,t as o,o as l,i as d,F as x,r as m}from"./app-CwJyEnkI.js";import{A as ct}from"./AppLayout-D9Iyjoll.js";/* empty css */import"./FeedbackIdeaWidget-CGfZ10N4.js";const dt={class:"border-b border-slate-200 pb-6"},rt={class:"flex flex-wrap items-start justify-between gap-4"},xt={class:"panel mt-7 p-5"},pt={class:"flex flex-wrap items-start justify-between gap-4"},ut={class:"mt-1 text-sm text-slate-600"},mt={class:"mt-1 text-xs text-slate-500"},bt={class:"flex flex-wrap gap-2"},yt=["disabled"],ft=["disabled"],gt=["disabled"],ht={key:0,class:"mt-5 rounded border border-amber-200 bg-amber-50 p-4 text-sm text-amber-900"},kt={class:"mt-1"},vt={key:1,class:"mt-5 grid gap-3 rounded border border-slate-200 bg-slate-50 p-4 text-sm md:grid-cols-4"},At={class:"font-semibold text-ink"},_t={class:"font-semibold text-ink"},Gt={class:"font-semibold text-ink"},wt={class:"font-semibold text-ink"},Ct={key:2,class:"mt-5 rounded border border-rose-200 bg-rose-50 p-4 text-sm text-rose-800"},Pt={class:"mt-1"},Dt={class:"mt-7 grid gap-4 md:grid-cols-2 xl:grid-cols-5"},St={class:"panel p-5"},It={class:"mt-2 text-3xl font-black text-ink"},Lt={class:"panel p-5"},Tt={class:"mt-2 text-3xl font-black text-ink"},Ut={class:"panel p-5"},Nt={class:"mt-2 text-3xl font-black text-ink"},Ft={class:"panel p-5"},Rt={class:"mt-2 text-3xl font-black text-ink"},Vt={class:"panel p-5"},jt={class:"mt-2 text-3xl font-black text-ink"},Bt={class:"mt-7 grid gap-5 xl:grid-cols-2"},Mt={class:"panel overflow-hidden"},Ot={class:"overflow-x-auto"},Et={class:"min-w-full text-left text-sm"},Qt={class:"divide-y divide-slate-100"},$t={class:"px-5 py-3"},qt={class:"font-semibold text-ink"},zt={class:"text-xs text-slate-500"},Ht={class:"px-5 py-3 font-semibold text-ink"},Jt={class:"px-5 py-3 text-slate-600"},Kt={key:0},Wt={class:"panel overflow-hidden"},Xt={class:"overflow-x-auto"},Yt={class:"min-w-full text-left text-sm"},Zt={class:"divide-y divide-slate-100"},ts={class:"px-5 py-3 font-semibold text-ink"},ss={class:"px-5 py-3 text-slate-600"},es={class:"px-5 py-3 text-slate-600"},os={key:0},ns={class:"panel overflow-hidden xl:col-span-2"},as={class:"grid gap-3 p-5 md:grid-cols-2 xl:grid-cols-5"},ls={class:"text-sm font-bold text-ink"},is={class:"mt-2 text-2xl font-black text-ocean"},cs={class:"text-xs text-slate-500"},ds={key:0,class:"text-sm text-slate-500"},ms={__name:"GoogleAnalytics",props:{analytics:Object},setup(e){const b=p({}),y=p({}),f=p({});function i(c){return new Intl.NumberFormat().format(Number(c||0))}function g(c){return c?new Date(c).toLocaleString():"-"}function st(c){return c.pageTitle||c.pagePathPlusQueryString||"-"}function h(c){return c.pagePathPlusQueryString||""}function et(){b.post("/platform/google-analytics/connect")}function ot(){y.post("/platform/google-analytics/refresh",{preserveScroll:!0})}function nt(){confirm("Disconnect Google Analytics from Logivo? Stored OAuth tokens will be deleted.")&&f.delete("/platform/google-analytics")}return(c,s)=>(l(),a(x,null,[u(r(at),{title:"Google Analytics"}),u(ct,null,{default:tt(()=>{var k,v,A,_,G,w,C,P,D,S,I,L,T,U,N,F,R,V,j,B,M,O,E,Q,$,q,z,H,J,K,W,X,Y,Z;return[t("section",dt,[t("div",rt,[s[1]||(s[1]=t("div",null,[t("p",{class:"text-sm font-bold uppercase text-ocean"},"Platform analytics"),t("h1",{class:"mt-2 text-3xl font-black text-ink"},"Google Analytics dashboard"),t("p",{class:"mt-2 max-w-3xl text-sm text-slate-600"}," Connect a Google account with access to the Logivo.ai GA4 property. This dashboard reads reporting data through the Google Analytics Data API; it does not use the Measurement Protocol secret shown in Google Analytics. ")],-1)),u(r(lt),{href:"/platform",class:"rounded border border-slate-300 px-4 py-2 text-sm font-bold text-ink hover:bg-slate-50"},{default:tt(()=>[...s[0]||(s[0]=[it("Back to platform",-1)])]),_:1})])]),t("section",xt,[t("div",pt,[t("div",null,[s[2]||(s[2]=t("p",{class:"text-sm font-bold uppercase text-ocean"},"Connection",-1)),s[3]||(s[3]=t("h2",{class:"mt-2 text-xl font-black text-ink"},"GA4 property access",-1)),t("p",ut,"Measurement ID: "+o(((v=(k=e.analytics)==null?void 0:k.config)==null?void 0:v.measurement_id)||"not configured")+" · Property ID: "+o(((_=(A=e.analytics)==null?void 0:A.config)==null?void 0:_.property_id)||"not configured"),1),t("p",mt,"OAuth redirect URI: "+o(((w=(G=e.anal
1ytics)==null?void 0:G.config)==null?void 0:w.redirect_uri)||"-"),1)]),t("div",bt,[(P=(C=e.analytics)==null?void 0:C.config)!=null&&P.configured?(l(),a("button",{key:0,type:"button",class:"rounded bg-ocean px-4 py-2 text-sm font-bold text-white hover:bg-ocean-dark disabled:opacity-60",disabled:r(b).processing,onClick:et},o((D=e.analytics)!=null&&D.connection?"Reconnect Google":"Connect Google"),9,yt)):d("",!0),(S=e.analytics)!=null&&S.connection?(l(),a("button",{key:1,type:"button",class:"rounded border border-slate-300 px-4 py-2 text-sm font-bold text-ink hover:bg-slate-50 disabled:opacity-60",disabled:r(y).processing,onClick:ot},"Refresh",8,ft)):d("",!0),(I=e.analytics)!=null&&I.connection?(l(),a("button",{key:2,type:"button",class:"rounded border border-rose-200 px-4 py-2 text-sm font-bold text-rose-700 hover:bg-rose-50 disabled:opacity-60",disabled:r(f).processing,onClick:nt},"Disconnect",8,gt)):d("",!0)])]),(T=(L=e.analytics)==null?void 0:L.config)!=null&&T.configured?d("",!0):(l(),a("div",ht,[s[4]||(s[4]=t("p",{class:"font-bold"},"Server configuration still needed before Google login can work.",-1)),t("p",kt,"Missing: "+o(((F=(N=(U=e.analytics)==null?void 0:U.config)==null?void 0:N.missing)==null?void 0:F.join(", "))||"unknown"),1),s[5]||(s[5]=t("p",{class:"mt-2 text-xs"},"Create a Google OAuth web client, enable Google Analytics Data API, add the redirect URI above, then place the values in shared .env. Do not paste secrets into source.",-1))])),(R=e.analytics)!=null&&R.connection?(l(),a("div",vt,[t("p",null,[s[6]||(s[6]=t("span",{class:"block text-xs font-bold uppercase text-slate-500"},"Status",-1)),t("span",At,o(e.analytics.connection.status),1)]),t("p",null,[s[7]||(s[7]=t("span",{class:"block text-xs font-bold uppercase text-slate-500"},"Connected email",-1)),t("span",_t,o(e.analytics.connection.connected_email||"-"),1)]),t("p",null,[s[8]||(s[8]=t("span",{class:"block text-xs font-bold uppercase text-slate-500"},"Last synced",-1)),t("span",Gt,o(g(e.analytics.connection.last_synced_at)),1)]),t("p",null,[s[9]||(s[9]=t("span",{class:"block text-xs font-bold uppercase text-slate-500"},"Token expires",-1)),t("span",wt,o(g(e.analytics.connection.token_expires_at)),1)])])):d("",!0),(V=e.analytics)!=null&&V.error?(l(),a("div",Ct,[s[10]||(s[10]=t("p",{class:"font-bold"},"Google Analytics Data API returned an error.",-1)),t("p",Pt,o(e.analytics.error),1)])):d("",!0)]),t("section",Dt,[t("article",St,[s[11]||(s[11]=t("p",{class:"text-sm font-semibold text-slate-500"},"Active users",-1)),t("p",It,o(i((B=(j=e.analytics)==null?void 0:j.summary)==null?void 0:B.active_users)),1),s[12]||(s[12]=t("p",{class:"mt-1 text-xs text-slate-500"},"Last 28 days",-1))]),t("article",Lt,[s[13]||(s[13]=t("p",{class:"text-sm font-semibold text-slate-500"},"Sessions",-1)),t("p",Tt,o(i((O=(M=e.analytics)==null?void 0:M.summary)==null?void 0:O.sessions)),1),s[14]||(s[14]=t("p",{class:"mt-1 text-xs text-slate-500"},"Last 28 days",-1))]),t("article",Ut,[s[15]||(s[15]=t("p",{class:"text-sm font-semibold text-slate-500"},"Page views",-1)),t("p",Nt,o(i((Q=(E=e.analytics)==null?void 0:E.summary)==null?void 0:Q.views)),1),s[16]||(s[16]=t("p",{class:"mt-1 text-xs text-slate-500"},"Last 28 days",-1))]),t("article",Ft,[s[17]||(s[17]=t("p",{class:"text-sm font-semibold text-slate-500"},"Events",-1)),t("p",Rt,o(i((q=($=e.analytics)==null?void 0:$.summary)==null?void 0:q.events)),1),s[18]||(s[18]=t("p",{class:"mt-1 text-xs text-slate-500"},"Last 28 days",-1))]),t("article",Vt,[s[19]||(s[19]=t("p",{class:"text-sm font-semibold text-slate-500"},"Right now",-1)),t("p",jt,o(i((H=(z=e.analytics)==null?void 0:z.realtime)==null?void 0:H.active_users)),1),s[20]||(s[20]=t("p",{class:"mt-1 text-xs text-slate-500"},"Realtime active users",-1))])]),t("section",Bt,[t("article",Mt,[s[23]||(s[23]=t("div",{class:"border-b border-slate-200 p-5"},[t("p",{class:"text-sm font-bold uppercase text-ocean"},"Content"),t("h2",{class:"mt-1 text-xl font-black text-ink"},"Top pages")],-1)),t("div",Ot,[t("table",Et,[s[22]||(s[22]=t("thead",{class:"bg-slate-50 text-xs uppercase text-slate-500"},[t("tr",null,[t("th",{class:"px-5 py-3"},"Page"),t("th",{class:"px-5 py-3"},"Views"),t("th",{class:"px-5 py-3"},"Users")])],-1)),t("tbody",Qt,[(l(!0),a(x,null,m(((J=e.analytics)==null?void 0:J.top_pages)||[],n=>(l(),a("tr",{key:`${h(n)}-${n.pageTitle}`},[t("td",$t,[t("p",qt,o(st(n)),1),t("p",zt,o(h(n)),1)]),t("td",Ht,o(i(n.screenPageViews)),1),t("td",Jt,o(i(n.activeUsers)),1)]))),128)),(((K=e.analytics)==null?void 0:K.top_pages)||[]).length?d("",!0):(l(),a("tr",Kt,[...s[21]||(s[21]=[t("td",{colspan:"3",class:"px-5 py-6 text-center text-slate-500"},"Connect Google Analytics to load page data.",-1)])]))])])])]),t("article",Wt,[s[26]||(s[26]=t("div",{class:"border-b border-slate-200 p-5"},[t("p",{class:"text-sm font-bold uppercase text-ocean"},"Acquisition"),t("h2",{class:"mt-1 text-xl font-black text-ink"},"Channels")],-1)),t("div",Xt,[t("table",Yt,[s[25]||(s[25]=t("thead",{class:"bg-slate-50 text-xs uppercase text-slate-500"},[t("tr",null,[t("th",{class:"px-5 py-3"},"Channel"),t("th",{class:"px-5 py-3"},"Sessions"),t("th",{class:"px-5 py-3"}
1,"Users")])],-1)),t("tbody",Zt,[(l(!0),a(x,null,m(((W=e.analytics)==null?void 0:W.channels)||[],n=>(l(),a("tr",{key:n.sessionDefaultChannelGroup},[t("td",ts,o(n.sessionDefaultChannelGroup||"Unassigned"),1),t("td",ss,o(i(n.sessions)),1),t("td",es,o(i(n.activeUsers)),1)]))),128)),(((X=e.analytics)==null?void 0:X.channels)||[]).length?d("",!0):(l(),a("tr",os,[...s[24]||(s[24]=[t("td",{colspan:"3",class:"px-5 py-6 text-center text-slate-500"},"No channel data loaded yet.",-1)])]))])])])]),t("article",ns,[s[27]||(s[27]=t("div",{class:"border-b border-slate-200 p-5"},[t("p",{class:"text-sm font-bold uppercase text-ocean"},"Audience"),t("h2",{class:"mt-1 text-xl font-black text-ink"},"Countries")],-1)),t("div",as,[(l(!0),a(x,null,m(((Y=e.analytics)==null?void 0:Y.countries)||[],n=>(l(),a("article",{key:n.country,class:"rounded border border-slate-200 p-4"},[t("p",ls,o(n.country||"Unknown"),1),t("p",is,o(i(n.activeUsers)),1),t("p",cs,o(i(n.sessions))+" sessions",1)]))),128)),(((Z=e.analytics)==null?void 0:Z.countries)||[]).length?d("",!0):(l(),a("p",ds,"No country data loaded yet."))])])]),s[28]||(s[28]=t("section",{class:"mt-7 rounded border border-amber-200 bg-amber-50 p-4 text-sm text-amber-900"},[t("p",{class:"font-bold"},"Security note"),t("p",{class:"mt-1"},"The Measurement Protocol API secret is for sending events to GA4, not for reading dashboard data. If a secret has been shown in screenshots or chat, rotate it in Google Analytics and keep it out of source and logs.")],-1))]}),_:1})],64))}};export{ms as default};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.