1import{r,cY as O,cZ as z,ac as j,c_ as q,c$ as R,d0 as P,j as e,B as C,R as L,S as B}from"./index-CYggsFjq.js";const H="GTM-5K88JQH",K="AW-1067375204",F={ok:"bg-emerald-500",waiting:"bg-amber-500",off:"bg-muted-foreground/40",problem:"bg-destructive"},U={ok:"Working",waiting:"Waiting",off:"Not active",problem:"Problem"},$=o=>Array.from(document.querySelectorAll("script")).some(u=>u.src.includes(o)),V=()=>{const[o,u]=r.useState([]),[d,g]=r.useState(null),[i,p]=r.useState(null),[l,w]=r.useState(null),x=r.useCallback(async()=>{var M;const t=O(),m=window.dataLayer,s=Array.isArray(m)?m:[],a=s.filter(b=>z(b)&&b[0]==="consent").length,c=s.filter(b=>typeof b=="object"&&b!==null&&b.event==="lead_form_success").length,h=new Date(Date.now()-864e5).toISOString(),[{count:N},{data:y}]=await Promise.all([j.from("app_logs").select("id",{count:"exact",head:!0}).eq("event","pageview").gte("created_at",h),j.from("app_logs").select("created_at").eq("event","pageview").order("created_at",{ascending:!1}).limit(1)]),{data:G}=await j.from("app_logs").select("context").eq("event",q.CONSENT_CHOICE).gte("created_at",new Date(Date.now()-30*864e5).toISOString()).limit(1e4),k={all:0,none:0,custom:0};for(const b of G??[]){const _=b.context??{};_.analytics&&_.marketing?k.all++:!_.analytics&&!_.marketing?k.none++:k.custom++}w(k);const S=N??0,A=((M=y==null?void 0:y[0])==null?void 0:M.created_at)??null;g({h24:S,last:A});const T=$("googletagmanager.com/gtm.js")||!!s.length,D=$(`gtag/js?id=${R}`),I=$("snap.licdn.com");u([{name:`Tag Manager container (${H})`,status:T?"ok":"problem",detail:T?"Loaded in the page, so all tags inside it can run.":"Not detected in this page. Check the container snippet in the site head."},{name:`Google Analytics (${R})`,status:D?"ok":t!=null&&t.analytics?"problem":"waiting",detail:D?"Analytics tag loaded and measuring.":t!=null&&t.analytics?"Consent was given but the analytics tag did not load.":"Always loads, and runs cookieless until the visitor gives consent."},{name:"Cookie choice on this browser",status:t?"ok":"waiting",detail:t?`Analytics ${t.analytics?"accepted":"declined"}, marketing ${t.marketing?"accepted":"declined"}.`:"No choice made yet in this browser, so everything stays denied."},{name:"Consent signal sent to Google",status:a>0?"ok":"waiting",detail:a>0?`${a} consent instruction${a===1?"":"s"} passed to Google in this page.`:"Everything starts denied. A signal is sent once a choice is made."},{name:`Google Ads (${K})`,status:t!=null&&t.marketing?"ok":"off",detail:t!=null&&t.marketing?"Marketing accepted, so the Ads tag inside Tag Manager may fire. The conversion itself is counted when a visitor reaches the thank-you page.":"Runs only for visitors who accept marketing cookies. Managed inside Tag Manager, not in the site code."},{name:`LinkedIn Insight (${P})`,status:I?"ok":t!=null&&t.marketing?"problem":"off",detail:I?"Loaded for this visitor.":t!=null&&t.marketing?"Marketing accepted but the LinkedIn tag did not load.":"Loads only after marketing cookies are accepted."},{name:"Successful-form signal",status:c>0?"ok":"waiting",detail:c>0?`${c} confirmed submission signal${c===1?"":"s"} sent in this page.`:"Sent once per confirmed form submission, on the thank-you page only. Nothing to show on this page."},{name:"Own visit measurement (cookie-free)",status:S>0?"ok":"problem",detail:S>0?`${S.toLocaleString()} visits recorded in the last 24 hours${A?`, most recently ${new Date(A).toLocaleString()}`:""}.`:"No visits recorded in the last 24 hours. This is the measurement that does not depend on cookies."}]),p(new Date)},[]);r.useEffect(()=>{x()},[x]);const n=o.filter(t=>t.status==="problem").length;return e.jsxs("section",{className:"mb-8 rounded-lg border border-border bg-card p-5",children:[e.jsxs("div",{className:"mb-4 flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"font-heading text-base font-bold text-foreground",children:"Tracking heartbeat"}),e.jsxs("p",{className:"mt-1 font-body text-sm text-muted-foreground",children:["Everything that measures visitors, checked live in this browser."," ",n>0?`${n} item${n===1?"":"s"} need${n===1?"s":""} attention.`:"All active items are working.",i?` Checked ${i.toLocaleTimeString()}.`:""]})]}),e.jsxs(C,{variant:"outline",size:"sm",className:"rounded-md",onClick:()=>void x(),children:[e.jsx(L,{size:14,className:"mr-2"})," Check again"]})]}),e.jsx("ul",{className:"grid gap-3 md:grid-cols-2",children:o.map(t=>e.jsxs("li",{className:"rounded-md border border-border p-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:`h-2.5 w-2.5 shrink-0 rounded-full ${F[t.status]}`,"aria-hidden":"true"}),e.jsx("span",{className:"font-body text-sm font-semibold text-foreground",children:t.name}),e.jsx("span",{className:"ml-auto shrink-0 font-body text-xs text-muted-foreground",children:U[t.status]})]}),e.jsx("p",{className:"mt-1.5 font-body text-sm text-muted-foreground",children:t.detail})]},t.name))}),l&&e.jsxs("div",{className:"mt-4 rounded-md border border-border p-4",children:[e.jsx("p",{className:"font-body text-sm font-semibold text-foreground",children:"Cookie banner choices (last 30 days)"}),(()=>{const t=l.all+l.none+l.custom,m=s=>t?`${Math.round(s/t*100)}%`:"0%";return t===0?e.jsx("p",{className:"mt-1.5 font-body text-sm text-muted-foreground",children:"No choices recorded yet."}):e.jsxs("ul",{className:"mt-1.5 grid gap-1 font-body text-sm text-muted-foreground sm:grid-cols-3",children:[e.jsxs("li",{children:["Accepted all: ",l.all," (",m(l.all),")"]}),e.jsxs("li",{children:["Declined all: ",l.none," (",m(l.none),")"]}),e.jsxs("li",{children:["Custom: ",l.custom," (",m(l.custom),")"]})]})})()]}),d&&d.h24===0&&e.jsx("p",{className:"mt-4 font-body text-sm text-muted-foreground",children:"Note: admin pages and known bots are never counted, so browsing the backend does not add visits."})]})},W=[{value:"all",label:"Everything"},{value:"pageview",label:"Page views"},{value:"event",label:"Events"},{value:"consent",label:"Consent"}],J={pageview:"border-primary/30 bg-primary/10 text-primary",event:"border-emerald-500/30 bg-emerald-500/10 text-emerald-700",consent:"border-amber-500/30 bg-amber-500/10 text-amber-700"},Q={pageview:"page view",event:"event",consent:"consent"},Y=()=>{const[o,u]=r.useState([]),[d,g]=r.useState("all"),[i,p]=r.useState(!0),[l,w]=r.useState(!0),[x,n]=r.useState(null),t=r.useCallback(async()=>{const s=j.from("app_logs").select("id, created_at, outcome, source_page, session_id, context").eq("event","analytics.sent").not("context->data->>page_location","ilike","%lovable%").order("created_at",{ascending:!1}).limit(200),{data:a}=d==="all"?await s:await s.eq("outcome",d);u(a??[]),w(!1)},[d]);r.useEffect(()=>{t()},[t]),r.useEffect(()=>{if(!i)return;const s=window.setInterval(()=>void t(),1e4);return()=>window.clearInterval(s)},[i,t]);const m=r.useMemo(()=>{const s=new Map;return o.forEach(a=>{var h;const c=String(((h=a.context)==null?void 0:h.signal)??"unknown");s.set(c,(s.get(c)??0)+1)}),[...s.entries()].sort((a,c)=>c[1]-a[1]).slice(0,6)}
1,[o]);return e.jsxs("section",{className:"mb-8 rounded-lg border border-border bg-card p-5",children:[e.jsxs("div",{className:"mb-4 flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"font-heading text-base font-bold text-foreground",children:"Signals sent to Google"}),e.jsx("p",{className:"mt-1 max-w-2xl font-body text-sm text-muted-foreground",children:'Each line is one moment the site said "I just sent this to Google": the time it triggered, the page it happened on, the name of the signal and the exact data attached. Visitor addresses and names are never part of it. Activity in the Lovable preview is excluded. Refreshes by itself every 10 seconds.'})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("select",{value:d,onChange:s=>g(s.target.value),className:"h-9 rounded-md border border-input bg-background px-2 text-sm","aria-label":"Filter signals",children:W.map(s=>e.jsx("option",{value:s.value,children:s.label},s.value))}),e.jsxs(C,{variant:"outline",size:"sm",className:"rounded-md",onClick:()=>void t(),children:[e.jsx(L,{size:14,className:"mr-2"})," Refresh"]}),e.jsx(C,{variant:i?"default":"outline",size:"sm",className:"rounded-md",onClick:()=>p(s=>!s),children:i?"Live: on":"Live: off"})]})]}),m.length>0&&e.jsx("div",{className:"mb-4 flex flex-wrap gap-2",children:m.map(([s,a])=>e.jsxs("span",{className:"rounded-md border border-border bg-muted/50 px-2 py-1 font-body text-xs text-muted-foreground",children:[s," ",e.jsx("strong",{className:"text-foreground",children:a})]},s))}),l?e.jsx("p",{className:"font-body text-sm text-muted-foreground",children:"Loading recent signalsâ¦"}):o.length===0?e.jsx("p",{className:"font-body text-sm text-muted-foreground",children:"No signals recorded yet. They appear here as soon as visitors browse pages or submit a form."}):e.jsx("ul",{className:"max-h-[560px] divide-y divide-border overflow-y-auto rounded-md border border-border",children:o.map(s=>{const a=s.context??{},c=a.signal??"unknown",h=a.data??{},N=Object.keys(h),y=s.outcome??"event";return e.jsxs("li",{className:"px-4 py-3",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("span",{className:`rounded border px-2 py-0.5 text-xs ${J[y]??"border-border bg-muted text-muted-foreground"}`,children:Q[y]??y}),e.jsx("span",{className:"font-body text-sm font-semibold text-foreground",children:c}),e.jsx("span",{className:"font-body text-xs text-muted-foreground",children:new Date(s.created_at).toLocaleString()}),s.source_page&&e.jsxs("span",{className:"font-body text-xs text-muted-foreground",children:["on ",s.source_page]}),N.length>0&&e.jsx("button",{type:"button",className:"ml-auto font-body text-xs text-primary underline-offset-2 hover:underline",onClick:()=>n(x===s.id?null:s.id),children:x===s.id?"Hide data":`Show data (${N.length})`})]}),x===s.id&&e.jsx("pre",{className:"mt-2 max-h-56 overflow-auto whitespace-pre-wrap break-words rounded-md bg-muted/50 p-3 text-xs text-muted-foreground",children:JSON.stringify(h,null,2)})]},s.id)})})]})},Z=[{label:"24 hours",days:1},{label:"7 days",days:7},{label:"30 days",days:30},{label:"90 days",days:90}],X=o=>typeof o=="string"&&o.trim()?o.trim():null,f=(o,u)=>{const d=new Map;for(const g of o){const i=u(g)??"unknown";d.set(i,(d.get(i)??0)+1)}return[...d.entries()].sort((g,i)=>i[1]-g[1])},v=({title:o,data:u,total:d,limit:g=8})=>e.jsxs("section",{className:"rounded-lg border border-border bg-card p-5",children:[e.jsx("h2",{className:"mb-4 font-heading text-base font-bold text-foreground",children:o}),u.length===0?e.jsx("p",{className:"font-body text-sm text-muted-foreground",children:"No data yet."}):e.jsx("ul",{className:"space-y-2.5",children:u.slice(0,g).map(([i,p])=>{const l=d>0?Math.round(p/d*100):0;return e.jsxs("li",{children:[e.jsxs("div",{className:"flex items-baseline justify-between gap-3 font-body text-sm",children:[e.jsx("span",{className:"truncate text-foreground",title:i,children:i}),e.jsxs("span",{className:"shrink-0 tabular-nums text-muted-foreground",children:[p," · ",l,"%"]})]}),e.jsx("div",{className:"mt-1 h-1.5 w-full overflow-hidden rounded-full bg-muted",children:e.jsx("div",{className:"h-full rounded-full bg-primary",style:{width:`${l}%`}})})]},i)})})]}),E=({label:o,value:u})=>e.jsxs("div",{className:"rounded-lg border border-border bg-card p-5",children:[e.jsx("div",{className:"font-heading text-2xl font-bold text-foreground",children:u}),e.jsx("div",{className:"mt-1 font-body text-sm text-muted-foreground",children:o})]}),te=()=>{const[o,u]=r.useState([]),[d,g]=r.useState(!0),[i,p]=r.useState(7),[l,w]=r.useState(null),x=r.useCallback(async()=>{g(!0),w(null);const t=new Date(Date.now()-i*864e5).toISOString(),{data:m,error:s}=await j.from("app_logs").select("created_at, source_page, session_id, user_agent, context").eq("event","pageview").gte("created_at",t).order("created_at",{ascending:!1}).limit(2e4);s&&w(s.message),u(m??[]),g(!1)},[i]);r.useEffect(()=>{x()},[x]);const n=r.useMemo(()=>{const t=o.length,m=new Set(o.map(a=>
1a.session_id??"unknown")),s=(a,c)=>{var h;return X((h=a.context)==null?void 0:h[c])};return{total:t,sessions:m.size,perSession:m.size?(t/m.size).toFixed(1):"0",pages:f(o,a=>(a.source_page??"").split("?")[0]||"/"),devices:f(o,a=>s(a,"device")),browsers:f(o,a=>s(a,"browser")),os:f(o,a=>s(a,"os")),viewports:f(o,a=>s(a,"viewport_bucket")).sort((a,c)=>a[0].localeCompare(c[0],void 0,{numeric:!0})),languages:f(o,a=>s(a,"lang")),referrers:f(o,a=>s(a,"referrer_host")),hours:f(o,a=>`${String(new Date(a.created_at).getUTCHours()).padStart(2,"0")}:00 UTC`).sort((a,c)=>a[0].localeCompare(c[0]))}},[o]);return e.jsxs("div",{className:"container mx-auto px-4 py-10",children:[e.jsx(B,{title:"Audience | Backend",description:"Visitor devices, browsers and behaviour patterns.",noIndex:!0}),e.jsxs("div",{className:"mb-6 flex flex-wrap items-center gap-3",children:[e.jsxs("div",{className:"mr-auto",children:[e.jsx("h1",{className:"font-heading text-2xl font-bold text-foreground",children:"Audience"}),e.jsx("p",{className:"font-body text-sm text-muted-foreground",children:"Anonymous first-party pageview measurement. No cookies, no personal data. Admin pages and known bots are excluded."})]}),e.jsx("div",{className:"flex items-center gap-1 rounded-md border border-border bg-card p-1",children:Z.map(t=>e.jsx("button",{onClick:()=>p(t.days),className:`rounded px-3 py-1.5 font-body text-sm transition-colors ${i===t.days?"bg-primary text-primary-foreground":"text-muted-foreground hover:bg-muted"}`,children:t.label},t.days))}),e.jsxs(C,{variant:"outline",size:"sm",onClick:()=>void x(),disabled:d,children:[e.jsx(L,{size:16,className:`mr-2 ${d?"animate-spin":""}`})," Refresh"]})]}),l&&e.jsx("p",{className:"mb-6 rounded-md border border-destructive/30 bg-destructive/10 p-3 font-body text-sm text-destructive",children:l}),e.jsx(Y,{}),e.jsx(V,{}),e.jsxs("div",{className:"mb-6 grid gap-4 sm:grid-cols-3",children:[e.jsx(E,{label:"Pageviews",value:n.total}),e.jsx(E,{label:"Sessions",value:n.sessions}),e.jsx(E,{label:"Pages per session",value:n.perSession})]}),!d&&n.total===0&&e.jsx("p",{className:"mb-6 rounded-md border border-border bg-card p-4 font-body text-sm text-muted-foreground",children:"No pageviews recorded in this period yet. Tracking starts collecting from the moment this change is live, so give it some traffic before the breakdowns fill in."}),e.jsxs("div",{className:"grid gap-4 md:grid-cols-2 xl:grid-cols-3",children:[e.jsx(v,{title:"Screen size (viewport width)",data:n.viewports,total:n.total,limit:10}),e.jsx(v,{title:"Device type",data:n.devices,total:n.total}),e.jsx(v,{title:"Browser",data:n.browsers,total:n.total}),e.jsx(v,{title:"Operating system",data:n.os,total:n.total}),e.jsx(v,{title:"Language",data:n.languages,total:n.total}),e.jsx(v,{title:"Top pages",data:n.pages,total:n.total,limit:15}),e.jsx(v,{title:"Referrer",data:n.referrers,total:n.total}),e.jsx(v,{title:"Time of day",data:n.hours,total:n.total,limit:24})]})]})};export{te 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.