PageSourceSearch

https://budgetbro.app/_next/static/chunks/65112.275bdce6a5a14064.js

js budgetbro.app collected 2026-09-24 13:35:01 UTC 90,306 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[65112],{65112:(e,t,s)=>{s.r(t),s.d(t,{default:()=>eo});var a=s(95155),l=s(12115),n=s(70528),r=s(72040),i=s(66898),o=s(98987);let d=[{key:"all",label:"All",blurb:"Every search term we appeared for in the last 28 days."},{key:"wasted",label:"Wasted",blurb:"On page one, nobody clicks. The cheapest wins on the site: rewrite the title and description."},{key:"almost",label:"Almost there",blurb:"Positions 11 to 25. A push gets these onto page one."},{key:"winning",label:"Winning",blurb:"Page one and getting clicks. Protect these."},{key:"rising",label:"Rising",blurb:"Impressions up by half or more. Interest is growing."},{key:"falling",label:"Falling",blurb:"Impressions dropping. Something overtook us or the topic cooled."},{key:"lost",label:"Lost",blurb:"We appeared for these last period and not this one."},{key:"questions",label:"Questions",blurb:"Phrased as a question. Answer it in the first two lines and Google can feature it."}],c="rounded-[10px] border border-[#e2e8f0] bg-white p-4 drop-shadow-[0_1px_1.5px_rgba(15,23,42,0.04)] dark:border-slate-700 dark:bg-slate-900";function x(e){let{title:t,aside:s,children:l}=e;return(0,a.jsxs)("div",{children:[(0,a.jsxs)("div",{className:"flex items-center justify-between gap-3",children:[(0,a.jsx)("h3",{className:i.TB,children:t}),s&&(0,a.jsx)("span",{className:"text-[11px] text-[#94a3b8]",children:s})]}),(0,a.jsx)("div",{className:"mt-3",children:l})]})}let h=e=>e.replace(/^https?:\/\/[^/]+/,"")||"/",p=e=>`${(100*e).toFixed(1)}%`,u=e=>e?(0,o.r6)(new Date(e)):"never",g=e=>e>=70?i.XQ.good:e>=40?i.XQ.warning:i.XQ.critical;function m(e){let{score:t,label:s,hint:l,waiting:n,partial:r,size:o=112}=e,d=2*Math.PI*44,c=r?"#94a3b8":g(t);return(0,a.jsxs)("div",{className:"rounded-[10px] border border-[#e2e8f0] bg-white p-5 dark:border-slate-700 dark:bg-slate-900 flex h-full items-center gap-5",children:[(0,a.jsxs)("svg",{width:o,height:o,viewBox:"0 0 112 112",className:"shrink-0",children:[(0,a.jsx)("circle",{cx:"56",cy:"56",r:44,fill:"none",stroke:"currentColor",strokeWidth:"9",className:"text-[#f1f5f9] dark:text-slate-800"}),!n&&(0,a.jsx)("circle",{cx:"56",cy:"56",r:44,fill:"none",stroke:c,strokeWidth:"9",strokeLinecap:"round",strokeDasharray:`${t/100*d} ${d}`,transform:"rotate(-90 56 56)"}),n?(0,a.jsx)("text",{x:"56",y:"61",textAnchor:"middle",className:"fill-[#94a3b8] text-[12px] font-semibold",children:"Not ready"}):(0,a.jsx)("text",{x:"56",y:"62",textAnchor:"middle",className:`text-[26px] font-bold ${r?"fill-[#64748b] dark:fill-slate-400":"fill-[#111827] dark:fill-slate-100"}`,children:t})]}),(0,a.jsxs)("div",{className:"min-w-0",children:[(0,a.jsx)("p",{className:i.TB,children:s}),(0,a.jsx)("p",{className:"mt-1.5 text-[12px] leading-relaxed text-[#64748b] dark:text-slate-400",children:n??r??l})]})]})}function f(e){let{cur:t,prev:s,suffix:l="",lowerIsBetter:n=!1,asPct:r=!1}=e;if(!s)return null;let o=r?(t-s)/s*100:t-s;if(.05>Math.abs(o))return(0,a.jsx)("span",{className:"text-[#94a3b8]",children:"no change"});let d=n?o<0:o>0;return(0,a.jsxs)("span",{style:{color:d?i.XQ.good:i.XQ.critical},children:[o>0?"+":"",r?`${Math.round(o)}%`:o.toFixed(1),l]})}function b(e){let{action:t,state:s,onState:r,defaultOpen:o=!1}=e,[d,x]=(0,l.useState)(o),[h,p]=(0,l.useState)(!1),u="done"===s;return(0,a.jsxs)("div",{className:`${c} ${u?"opacity-55":""}`,children:[(0,a.jsxs)("div",{className:"flex items-start gap-3",children:[(0,a.jsx)("button",{onClick:()=>r(t.id,u?"open":"done"),"aria-label":u?"Mark as not done":"Mark as done",className:`mt-0.5 flex h-[18px] w-[18px] shrink-0 items-center justify-center rounded-[5px] border ${u?"border-transparent bg-[#14b8a6]":"border-[#cbd5e1] dark:border-slate-600"}`,children:u&&(0,a.jsx)("svg",{width:"11",height:"11",viewBox:"0 0 24 24",fill:"none",stroke:"#fff",strokeWidth:"3.5",strokeLinecap:"round",strokeLinejoin:"round",children:(0,a.jsx)("polyline",{points:"20 6 9 17 4 12"})})}),(0,a.jsxs)("button",{onClick:()=>x(!d),className:"min-w-0 flex-1 text-left",children:[(0,a.jsx)("p",{className:`text-[13px] font-bold text-[#111827] dark:text-slate-100 ${u?"line-through":""}`,children:t.title}),(0,a.jsxs)("div",{className:"mt-1.5 flex flex-wrap items-center gap-x-2.5 gap-y-1 text-[11px]",children:[(0,a.jsx)(i.vw,{tone:"live",children:t.gain}),(0,a.jsx)("span",{className:"text-[#94a3b8]",children:t.effort}),"snoozed"===s&&(0,a.jsx)("span",{className:"text-[#94a3b8]",children:"put off"})]})]})]}),d&&(0,a.jsxs)("div",{className:"mt-3 border-t border-[#f1f5f9] pt-3 dark:border-slate-800",children:[(0,a.jsx)("p",{className:"text-[12px] leading-relaxed text-[#374151] dark:text-slate-300",children:t.why}),(0,a.jsx)("ol",{className:"mt-3 flex flex-col gap-2",children:t.steps.map((e,t)=>(0,a.jsxs)("li",{className:"flex gap-2.5 text-[12px] leading-relaxed text-[#374151] dark:text-slate-300",children:[(0,a.jsx)("span",{className:"mt-[1px] flex h-[17px] w-[17px] shrink-0 items-center justify-center rounded-full bg-[#f1f5f9] text-[10px] font-bold text-[#64748b] dark:bg-slate-800 dark:text-slate-400",children:t+1}),(0,a.jsx)("span",{children:e})]},t))}),t.items.length>0&&(0,a.jsxs)("div",{className:"mt-3",children:[(0,a.jsx)("button",{onClick:()=>p(!h),className:"text-[11px] font-semibold text-[#94a3b8] hover:text-[#64748b] dark:hover:text-slate-300",children:h?"Hide":`Show the ${t.items.length} this is about`}),h&&(0,a.jsx)("div",{className:"mt-2 max-h-[240px] overflow-y-auto",children:t.items.map(e=>(0,a.jsx)("p",{className:"truncate border-t border-[#f1f5f9] py-1.5 text-[12px] text-[#111827] dark:border-slate-800 dark:text-slate-100",children:e},e))})]}),(0,a.jsxs)("div",{className:"mt-3 flex items-center gap-2",children:[(0,a.jsx)("button",{onClick:()=>r(t.id,u?"open":"done"),className:`${n.lJ} ${u?n.h0:n.rh}`,children:u?"Not done after all":"Mark done"}),!u&&(0,a.jsx)("button",{onClick:()=>r(t.id,"snoozed"===s?"open":"snoozed"),className:`${n.lJ} ${n.h0}`,children:"snoozed"===s?"Put back":"Not now"}),(0,a.jsx)("span",{className:"ml-auto text-[11px] text-[#94a3b8]",children:t.where})]})]})]})}function v(e){let{data:t,onState:s,filter:n,limit:r}=e,[i,o]=(0,l.useState)(!1),d=t.actions.filter(e=>!n||n(e)),c=d.filter(e=>!t.actionState[e.id]),x=d.filter(e=>t.actionState[e.id]),h=r?c.slice(0,r):c;return(0,a.jsxs)("div",{className:"flex flex-col gap-3",children:[(0,a.jsx)("div",{className:"grid items-start gap-3 lg:grid-cols-2",children:0===h.length?(0,a.jsx)("p",{className:"text-[12px] text-[#94a3b8]",children:d.length?"Everything here is ticked off. Refresh after the next crawl to see what is new.":"Nothing to do here yet."}):h.map(e=>{var l;return(0,a.jsx)(b,{action:e,state:null==(l=t.actionState[e.id])?void 0:l.state,onState:s},e.id)})}),x.length>0&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("button",{onClick:()=>o(!i),className:"self-start text-[11px] font-semibold text-[#94a3b8] hover:text-[#64748b] dark:hover:text-slate-300",children:i?"Hide":`${x.length} done or put off`}),i&&(0,a.jsx)("div",{className:"grid items-start gap-3 lg:grid-cols-2",children:x.map(e=>{var l;return(0,a.jsx)(b,{action:e,state:null==(l=t.actionState[e.id])?void 0:l.state,onState:s},e.id)})})]})]})}function j(e){let{data:t,dark:s,go:n,onState:r}=e,o=t.totals,d=(0,l.useMemo)(()=>
1{if(!o)return[];let e=[],t=null;return o.daily.forEach((s,a)=>{a%7==0&&(t={label:s.date.slice(5),value:0},e.push(t)),t.value+=s.clicks}),e},[o]),c=["Sites linking to us","Strength of those sites"],h=e=>t.domainStrength.parts.filter(t=>e.includes(t.label)).reduce((e,t)=>e+t.max,0),u=t.at.links?0:h(c),g=t.at.gsc?0:h(t.domainStrength.parts.map(e=>e.label).filter(e=>!c.includes(e))),f=u+g,b=t.actions.filter(e=>!t.actionState[e.id]).length;return(0,a.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,a.jsxs)("div",{className:i.PE,children:[(0,a.jsx)("p",{className:i.TB,children:"What is going on"}),(0,a.jsx)("div",{className:"mt-2 flex flex-col gap-2",children:t.verdicts.map((e,t)=>(0,a.jsx)("p",{className:"text-[13px] leading-relaxed text-[#374151] dark:text-slate-300",children:e},t))})]}),(0,a.jsxs)("div",{className:"grid gap-3 xl:grid-cols-2",children:[(0,a.jsx)("button",{onClick:()=>n("strength"),className:"text-left",children:(0,a.jsx)(m,{score:t.domainStrength.score,label:"Domain Strength",hint:"How much weight the site carries, 0 to 100. Mostly how many different sites link to us and how strong they are. Open it for the breakdown and what to do.",waiting:t.at.links||t.at.gsc?void 0:"Needs the link data from Bing and the search data from Search Console. Neither has loaded yet.",partial:f?`${t.domainStrength.score} of 100, but ${f} points cannot be measured yet: ${u&&g?"Bing has sent no link data and Search Console has not loaded":u?"Bing has not sent link data for the site yet":"Search Console has not loaded yet"}. Expect this to jump once it arrives.`:void 0})}),(0,a.jsx)("button",{onClick:()=>n("trust"),className:"text-left",children:(0,a.jsx)(m,{score:t.trust.score,label:"Trust Score",hint:`100 minus the things Google penalises, checked on ${t.trust.crawled} pages. Open it for what is costing points.`,waiting:t.at.crawl?void 0:"Needs a crawl of the site. Press Refresh now."})})]}),(0,a.jsx)(x,{title:"Do this next",aside:b?`${b} open`:void 0,children:(0,a.jsx)(v,{data:t,onState:r,limit:4})}),o&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("div",{className:"grid gap-3 sm:grid-cols-2 xl:grid-cols-4",children:[(0,a.jsx)(i.ro,{label:"Clicks",value:o.current.clicks,hint:`Visits from Google, ${o.range.start} to ${o.range.end}`,delta:o.previous.clicks?(o.current.clicks-o.previous.clicks)/o.previous.clicks*100:null,deltaSuffix:"%"}),(0,a.jsx)(i.ro,{label:"Impressions",value:o.current.impressions,hint:"Times we appeared in a search",delta:o.previous.impressions?(o.current.impressions-o.previous.impressions)/o.previous.impressions*100:null,deltaSuffix:"%"}),(0,a.jsx)(i.ro,{label:"Click rate",value:p(o.current.ctr),hint:"Good is 2 to 4%",delta:Math.round((o.current.ctr-o.previous.ctr)*1e3)/10,deltaSuffix:" pts"}),(0,a.jsx)(i.ro,{label:"Average position",value:o.current.position.toFixed(1),hint:"Where we sit in results. Under 10 is page one",delta:Math.round((o.current.position-o.previous.position)*10)/10,lowerIsBetter:!0})]}),(0,a.jsx)(i.wn,{title:"Clicks per week \xb7 last 13 weeks",children:(0,a.jsx)(i.e,{dark:s,data:d})})]}),(0,a.jsxs)("div",{className:"grid gap-3 xl:grid-cols-3",children:[(0,a.jsx)(i.wn,{title:"Quick wins",children:(0,a.jsx)(k,{items:t.keywords.filter(e=>e.buckets.includes("wasted")).slice(0,5).map(e=>({label:e.key,note:`pos ${e.position.toFixed(0)}, ${e.impressions} shown, ${e.clicks} clicks`})),empty:"No page-one terms without clicks. Good.",action:()=>n("keywords"),actionLabel:"All wasted terms"})}),(0,a.jsx)(i.wn,{title:"Almost page one",children:(0,a.jsx)(k,{items:t.keywords.filter(e=>e.buckets.includes("almost")).slice(0,5).map(e=>({label:e.key,note:`pos ${e.position.toFixed(0)}, ${e.impressions} shown`})),empty:"Nothing sitting just off page one.",action:()=>n("opportunities"),actionLabel:"All opportunities"})}),(0,a.jsx)(i.wn,{title:"Site problems",children:(0,a.jsx)(k,{items:t.trust.checks.filter(e=>e.penalty>0).slice(0,5).map(e=>({label:e.label,note:`${e.pages.length} page${1===e.pages.length?"":"s"}, costs ${e.penalty} pts`})),empty:"Nothing tripping the checks.",action:()=>n("trust"),actionLabel:"Trust Score"})})]})]})}function k(e){let{items:t,empty:s,action:l,actionLabel:n}=e;return(0,a.jsxs)("div",{className:"flex flex-col gap-1.5",children:[0===t.length?(0,a.jsx)("p",{className:"text-[12px] text-[#94a3b8]",children:s}):t.map(e=>(0,a.jsxs)("div",{className:"flex items-baseline justify-between gap-2 text-[12px]",children:[(0,a.jsx)("span",{className:"truncate text-[#111827] dark:text-slate-100",children:e.label}),(0,a.jsx)("span",{className:"shrink-0 text-[11px] text-[#94a3b8]",children:e.note})]},e.label)),(0,a.jsx)("button",{onClick:l,className:"mt-1 self-start text-[11px] font-semibold text-[#94a3b8] hover:text-[#64748b] dark:hover:text-slate-300",children:n})]})}let w={good:i.XQ.good,fair:i.XQ.warning,weak:i.XQ.critical};function y(e){let{data:t,onState:s}=e,l=["Sites linking to us","Strength of those sites"],n=e=>t.domainStrength.parts.filter(t=>e.includes(t.label)).reduce((e,t)=>
1e+t.max,0),r=t.at.links?0:n(l),o=r+(t.at.gsc?0:n(t.domainStrength.parts.map(e=>e.label).filter(e=>!l.includes(e)))),d=Object.fromEntries((t.strengthGuide??[]).map(e=>[e.label,e]));return(0,a.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,a.jsxs)("div",{className:"grid gap-3 xl:grid-cols-2",children:[(0,a.jsx)(m,{score:t.domainStrength.score,label:"Domain Strength",hint:"How much weight budgetbro.app carries with Google, 0 to 100. It decides how easily anything new you publish ranks at all. Five things add up to it.",partial:o?`${t.domainStrength.score} of 100, and ${o} points cannot be measured yet — ${r?"Bing has not sent link data":"Search Console has not loaded"}. Expect this to jump once it arrives.`:void 0}),(0,a.jsxs)("div",{className:"grid gap-3 sm:grid-cols-3",children:[(0,a.jsx)(i.ro,{label:"Sites linking to us",value:t.links?t.links.domains.length:"—",hint:"The biggest single lever"}),(0,a.jsx)(i.ro,{label:"Visits from Google",value:t.totals?t.totals.current.clicks:"—",hint:"Last 28 days"}),(0,a.jsx)(i.ro,{label:"Pages Google shows",value:(t.pages??[]).filter(e=>e.impressions>0).length,hint:"Pages earning impressions"})]})]}),o>0&&(0,a.jsx)(i.L7,{tone:"warn",children:"Until the missing data arrives this score reads lower than the site deserves. Nothing is broken; the parts below still show where you stand on everything that can be measured."}),(0,a.jsx)("div",{className:"grid items-start gap-3 lg:grid-cols-2",children:t.domainStrength.parts.map(e=>{let t=d[e.label],s=e.points/e.max*100;return(0,a.jsxs)("div",{className:c,children:[(0,a.jsxs)("div",{className:"flex items-baseline justify-between gap-3",children:[(0,a.jsxs)("p",{className:"flex items-center gap-2 text-[13px] font-bold text-[#111827] dark:text-slate-100",children:[t&&(0,a.jsx)("span",{className:"h-2 w-2 shrink-0 rounded-full",style:{background:w[t.state]}}),e.label]}),(0,a.jsxs)("p",{className:"shrink-0 text-[11px] tabular-nums text-[#94a3b8]",children:[(0,a.jsx)("span",{className:"font-bold text-[#111827] dark:text-slate-100",children:e.points})," of ",e.max," pts \xb7 ",e.value]})]}),(0,a.jsx)("div",{className:"mt-2 h-1.5 w-full overflow-hidden rounded-full bg-[#f1f5f9] dark:bg-slate-800/70",children:(0,a.jsx)("div",{className:"h-full rounded-full",style:{width:`${s}%`,background:t?w[t.state]:"#14b8a6"}})}),t?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("p",{className:"mt-3 text-[12px] leading-relaxed text-[#374151] dark:text-slate-300",children:t.standing}),(0,a.jsxs)("p",{className:"mt-1.5 text-[12px] leading-relaxed text-[#64748b] dark:text-slate-400",children:[(0,a.jsx)("span",{className:"font-semibold text-[#374151] dark:text-slate-300",children:"Aim for: "}),t.target]}),(0,a.jsx)("p",{className:`mt-3 ${i.TB}`,children:"How to move it"}),(0,a.jsx)("ul",{className:"mt-1.5 flex flex-col gap-1.5",children:t.moves.map((e,t)=>(0,a.jsxs)("li",{className:"flex gap-2 text-[12px] leading-relaxed text-[#64748b] dark:text-slate-400",children:[(0,a.jsx)("span",{className:"mt-[7px] h-[4px] w-[4px] shrink-0 rounded-full bg-[#cbd5e1] dark:bg-slate-600"}),(0,a.jsx)("span",{children:e})]},t))})]}):(0,a.jsx)("p",{className:"mt-3 text-[12px] leading-relaxed text-[#64748b] dark:text-slate-400",children:e.lever})]},e.label)})}),(0,a.jsx)(x,{title:"Jobs that move this score",children:(0,a.jsx)(v,{data:t,onState:s,filter:e=>"links"===e.area||"content"===e.area||"keywords"===e.area})}),(0,a.jsxs)("div",{className:i.PE,children:[(0,a.jsx)("p",{className:i.TB,children:"How the score is worked out"}),(0,a.jsx)("p",{className:"mt-2 text-[12px] leading-relaxed text-[#64748b] dark:text-slate-400",children:"Nobody outside Google knows its real numbers, so this is our own version of what Moz and Ahrefs sell: the five things that visibly track with how well a site ranks, weighted by how much each one matters, measured from Search Console and Bing. It is useful as a direction of travel, not as an absolute. What matters is that it goes up."})]})]})}function N(e){let{data:t,onState:s}=e,[r,o]=(0,l.useState)(null);if(!t.crawl)return(0,a.jsx)(i.Sv,{text:"No crawl of the site yet. Press Refresh n
1ow and it will check every page in the sitemap."});let d=t.trust.checks.filter(e=>e.penalty>=4),p=t.trust.checks.filter(e=>e.penalty>0&&e.penalty<4),u=t.trust.checks.filter(e=>!e.penalty),g=Math.round(10*t.trust.checks.reduce((e,t)=>e+t.penalty,0))/10;return(0,a.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,a.jsxs)("div",{className:"grid gap-3 xl:grid-cols-2",children:[(0,a.jsx)(m,{score:t.trust.score,label:"Trust Score",hint:"Starts at 100, and every check that fails takes points off. Under 70 is a site with real problems; over 85 is healthy."}),(0,a.jsxs)("div",{className:"grid gap-3 sm:grid-cols-3",children:[(0,a.jsx)(i.ro,{label:"Pages checked",value:t.trust.crawled,hint:"Everything in the sitemap"}),(0,a.jsx)(i.ro,{label:"Checks failing",value:d.length+p.length,hint:`of ${t.trust.checks.length}`,tone:d.length?"critical":p.length?"warning":"good"}),(0,a.jsx)(i.ro,{label:"Points lost",value:g,hint:"What the failures cost"})]})]}),t.spam&&(0,a.jsxs)(x,{title:`Spam risk ${t.spam.score} of 100`,children:[(0,a.jsx)("p",{className:"mb-2 text-[12px] leading-relaxed text-[#64748b] dark:text-slate-400",children:"Our own version of what Moz sells: the patterns that make a site look automated rather than written. Under 15 is clean, over 40 is worth acting on today."}),(0,a.jsx)("div",{className:"grid items-start gap-3 lg:grid-cols-2",children:t.spam.signals.map(e=>(0,a.jsxs)("div",{className:c,children:[(0,a.jsxs)("div",{className:"flex items-baseline justify-between gap-3",children:[(0,a.jsx)("p",{className:"text-[13px] font-bold text-[#111827] dark:text-slate-100",children:e.label}),(0,a.jsxs)("span",{className:"shrink-0 text-[11px] font-semibold tabular-nums",style:{color:e.points?e.points>=.5*e.max?i.XQ.critical:i.XQ.warning:i.XQ.good},children:[e.points," of ",e.max]})]}),(0,a.jsx)("div",{className:"mt-2 h-1.5 w-full overflow-hidden rounded-full bg-[#f1f5f9] dark:bg-slate-800/70",children:(0,a.jsx)("div",{className:"h-full rounded-full",style:{width:`${e.points/e.max*100}%`,background:e.points>=.5*e.max?i.XQ.critical:e.points?i.XQ.warning:i.XQ.good}})}),(0,a.jsx)("p",{className:"mt-2 text-[12px] leading-relaxed text-[#374151] dark:text-slate-300",children:e.detail}),(0,a.jsxs)("p",{className:"mt-1.5 text-[12px] leading-relaxed text-[#64748b] dark:text-slate-400",children:[(0,a.jsx)("span",{className:"font-semibold",children:"Fix: "}),e.fix]})]},e.label))})]}),(0,a.jsx)(x,{title:"Fix these, in this order",children:(0,a.jsx)(v,{data:t,onState:s,filter:e=>"trust"===e.area})}),d.length>0&&(0,a.jsx)(S,{title:"Costing you the most",checks:d,tone:i.XQ.critical,onOpen:o}),p.length>0&&(0,a.jsx)(S,{title:"Worth tidying",checks:p,tone:i.XQ.warning,onOpen:o}),u.length>0&&(0,a.jsx)(x,{title:`Passing \xb7 ${u.length} of ${t.trust.checks.length}`,children:(0,a.jsx)("div",{className:"flex flex-wrap gap-1.5",children:u.map(e=>(0,a.jsxs)("span",{className:"inline-flex items-center gap-1.5 rounded-[6px] border border-[#eee] px-2 py-0.5 text-[11px] text-[#64748b] dark:border-slate-700 dark:text-slate-400",children:[(0,a.jsx)("span",{className:"h-1.5 w-1.5 rounded-full",style:{background:i.XQ.good}}),e.label]},e.id))})}),(0,a.jsxs)("div",{className:i.PE,children:[(0,a.jsx)("p",{className:i.TB,children:"What this score is"}),(0,a.jsx)("p",{className:"mt-2 text-[12px] leading-relaxed text-[#64748b] dark:text-slate-400",children:"Every page in the sitemap is fetched and read the way Google reads it: title, description, headings, word count, links in and out, images, speed, and whether it loads at all. Each check takes points off in proportion to how much of the site fails it, so one bad page costs a little and four hundred costs a lot. It is the half of SEO you fully control — no competitor, no algorithm, just whether the site is built properly."})]}),r&&(0,a.jsxs)(n.zD,{onClose:()=>o(null),wide:!0,children:[(0,a.jsx)("p",{className:"text-[15px] font-bold text-[#111827] dark:text-slate-100",children:r.label}),(0,a.jsx)("p",{className:"text-[12px] leading-relaxed text-[#374151] dark:text-slate-300",children:r.what}),(0,a.jsxs)("p",{className:"text-[12px] leading-relaxed text-[#64748b] dark:text-slate-400",children:[(0,a.jsx)("span",{className:"font-semibold",children:"Fix: "}),r.fix]}),(0,a.jsxs)("p",{className:"text-[11px] text-[#94a3b8]",children:[r.pages.length+(r.more??0)," page",r.pages.length+(r.more??0)===1?"":"s"," \xb7 costing ",r.penalty," points"]}),(0,a.jsxs)("div",{className:"max-h-[50vh] overflow-y-auto",children:[r.pages.map(e=>(0,a.jsx)("a",{href:e,target:"_blank",rel:"noreferrer",className:"block truncate border-t border-[#f1f5f9] py-1.5 text-[12px] text-[#111827] hover:underline dark:border-slate-800 dark:text-slate-100",children:h(e)},e)),r.more?(0,a.jsxs)("p",{className:"border-t border-[#f1f5f9] py-1.5 text-[12px] text-[#94a3b8] dark:border-slate-800",children:["and ",r.more," more"]}):null]})]})]})}function S(e){let{title:t,checks:s,tone:l,onOpen:n}=e;return(0,a.jsx)(x,{title:t,children:(0,a.jsx)("div",{className:"grid items-start gap-3 lg:grid-cols-2",children:s.map(e=>(0,a.jsxs)("div",{className:`${c}
1 cursor-pointer transition hover:drop-shadow-[0_2px_8px_rgba(15,23,42,0.07)]`,onClick:()=>n(e),children:[(0,a.jsxs)("div",{className:"flex items-start justify-between gap-2",children:[(0,a.jsxs)("p",{className:"flex items-center gap-2 text-[13px] font-bold text-[#111827] dark:text-slate-100",children:[(0,a.jsx)("span",{className:"h-2 w-2 shrink-0 rounded-full",style:{background:l}}),e.label]}),(0,a.jsxs)("span",{className:"shrink-0 text-[11px] font-semibold tabular-nums text-[#94a3b8]",children:["-",e.penalty," pts"]})]}),(0,a.jsx)("p",{className:"mt-2 text-[12px] leading-relaxed text-[#374151] dark:text-slate-300",children:e.what}),(0,a.jsxs)("p",{className:"mt-1.5 text-[12px] leading-relaxed text-[#64748b] dark:text-slate-400",children:[(0,a.jsx)("span",{className:"font-semibold",children:"Fix: "}),e.fix]}),(0,a.jsxs)("p",{className:"mt-2 text-[11px] font-semibold text-[#94a3b8]",children:[e.pages.length+(e.more??0)," page",e.pages.length+(e.more??0)===1?"":"s"," \xb7 open the list"]})]},e.id))})})}function C(e){let{data:t,onWrite:s}=e,[r,o]=(0,l.useState)("all"),[c,x]=(0,l.useState)(""),[u,g]=(0,l.useState)(null),m=(0,l.useMemo)(()=>{let e=c.trim().toLowerCase();return t.keywords.filter(t=>("all"===r||t.buckets.includes(r))&&(!e||t.key.includes(e)))},[t.keywords,r,c]),b=d.find(e=>e.key===r),v=(0,l.useMemo)(()=>Object.fromEntries(d.map(e=>[e.key,"all"===e.key?t.keywords.length:t.keywords.filter(t=>t.buckets.includes(e.key)).length])),[t.keywords]);return t.configured.gsc||t.keywords.length?(0,a.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,a.jsxs)(i.M7,{children:[(0,a.jsx)("div",{className:"relative min-w-[220px] flex-1",children:(0,a.jsx)("input",{value:c,onChange:e=>x(e.target.value),placeholder:"Search terms…",className:n.bO})}),(0,a.jsx)("span",{className:i.XX}),(0,a.jsx)(i.C4,{value:r,options:d.map(e=>({key:e.key,label:`${e.label} ${v[e.key]??0}`})),onChange:o})]}),(0,a.jsx)("p",{className:"text-[12px] text-[#64748b] dark:text-slate-400",children:b.blurb}),(0,a.jsx)(i.XI,{rows:m,rowKey:e=>e.key,defaultSort:"impressions",onRow:g,perPage:25,empty:"Nothing in this group.",cols:[{key:"key",label:"Search term",cell:e=>(0,a.jsx)("span",{className:"font-semibold text-[#111827] dark:text-slate-100",children:e.key}),sort:e=>e.key},{key:"buckets",label:"",cell:e=>(0,a.jsx)("span",{className:"flex flex-wrap gap-1",children:e.buckets.map(e=>(0,a.jsx)(i.vw,{tone:"winning"===e?"live":"wasted"===e||"lost"===e||"falling"===e?"warn":void 0,children:e},e))})},{key:"impressions",label:"Shown",align:"right",sort:e=>e.impressions,cell:e=>(0,a.jsxs)(a.Fragment,{children:[(0,i.Sc)(e.impressions)," ",(0,a.jsx)("span",{className:"text-[10px]",children:(0,a.jsx)(f,{cur:e.impressions,prev:e.prevImpressions,asPct:!0})})]})},{key:"clicks",label:"Clicks",align:"right",sort:e=>e.clicks,cell:e=>(0,i.Sc)(e.clicks)},{key:"ctr",label:"Click rate",align:"right",sort:e=>e.ctr,cell:e=>p(e.ctr)},{key:"position",label:"Position",align:"right",sort:e=>-e.position,cell:e=>(0,a.jsxs)(a.Fragment,{children:[e.position?e.position.toFixed(1):"—"," ",(0,a.jsx)("span",{className:"text-[10px]",children:e.prevPosition?(0,a.jsx)(f,{cur:e.position,prev:e.prevPosition,lowerIsBetter:!0}):null})]})}]}),u&&(0,a.jsxs)(n.zD,{onClose:()=>g(null),wide:!0,children:[(0,a.jsx)("p",{className:"text-[15px] font-bold text-[#111827] dark:text-slate-100",children:u.key}),(0,a.jsxs)("div",{className:"grid gap-3 sm:grid-cols-4",children:[(0,a.jsx)(i.ro,{label:"Shown",value:u.impressions,hint:u.prevImpressions?`${u.prevImpressions} before`:void 0}),(0,a.jsx)(i.ro,{label:"Clicks",value:u.clicks,hint:`${u.prevClicks} before`}),(0,a.jsx)(i.ro,{label:"Click rate",value:p(u.ctr)}),(0,a.jsx)(i.ro,{label:"Position",value:u.position?u.position.toFixed(1):"—",hint:u.prevPosition?`${u.prevPosition.toFixed(1)} before`:void 0})]}),u.advice&&(0,a.jsxs)("div",{className:"rounded-[6px] border border-[#eee] px-3 py-2.5 text-[12px] leading-relaxed text-[#374151] dark:border-slate-700 dark:text-slate-300",children:[(0,a.jsx)("span",{className:"font-semibold",children:"What to do: "}),u.advice]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("p",{className:i.TB,children:"Our pages Google shows for it"}),(0,a.jsx)("div",{className:"mt-2 flex flex-col",children:0===(t.queryPages[u.key]??[]).length?(0,a.jsx)("p",{className:"text-[12px] text-[#94a3b8]",children:"No page recorded for this term in the peri
1od."}):t.queryPages[u.key].map(e=>(0,a.jsxs)("div",{className:"flex items-center justify-between gap-3 border-t border-[#f1f5f9] py-2 text-[12px] dark:border-slate-800",children:[(0,a.jsx)("a",{href:e.page,target:"_blank",rel:"noreferrer",className:"truncate text-[#111827] hover:underline dark:text-slate-100",children:h(e.page)}),(0,a.jsxs)("span",{className:"shrink-0 tabular-nums text-[#94a3b8]",children:["pos ",e.position.toFixed(1)," \xb7 ",e.impressions," shown \xb7 ",e.clicks," clicks"]})]},e.page))})]}),s&&(0===(t.queryPages[u.key]??[]).length?(0,a.jsx)("button",{onClick:()=>void s(u.key.replace(/\b\w/g,e=>e.toUpperCase()),u.key),className:`${n.lJ} ${n.rh} self-start`,children:"Write a page for this"}):(0,a.jsx)("p",{className:"text-[12px] text-[#94a3b8]",children:"We already have a page for this, so improve that one rather than writing another. Writing a second page about the same thing splits the ranking between them."}))]})]}):(0,a.jsx)(i.L7,{tone:"warn",children:"Search Console is not connected on this server. On the live site this fills in on its own."})}function $(e){let{data:t}=e,[s,r]=(0,l.useState)(""),[o,d]=(0,l.useState)("search"),c=(0,l.useMemo)(()=>{let e=s.trim().toLowerCase();return t.pages.filter(t=>!e||t.key.toLowerCase().includes(e))},[t.pages,s]),x=(0,l.useMemo)(()=>{let e=s.trim().toLowerCase();return t.strengths.filter(t=>!e||t.url.toLowerCase().includes(e)||t.title.toLowerCase().includes(e))},[t.strengths,s]);return(0,a.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,a.jsxs)(i.M7,{children:[(0,a.jsx)("div",{className:"relative min-w-[220px] flex-1",children:(0,a.jsx)("input",{value:s,onChange:e=>r(e.target.value),placeholder:"Search pages…",className:n.bO})}),(0,a.jsx)("span",{className:i.XX}),(0,a.jsx)(i.C4,{value:o,options:[{key:"search",label:"Search performance"},{key:"strength",label:"Page Strength"}],onChange:d})]}),"search"===o?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("p",{className:"text-[12px] text-[#64748b] dark:text-slate-400",children:"How each page did in Google over the last 28 days, against the 28 before. A page on page one with a click rate under 1% needs a better title."}),(0,a.jsx)(i.XI,{rows:c,rowKey:e=>e.key,defaultSort:"impressions",perPage:25,empty:"No pages recorded.",cols:[{key:"page",label:"Page",cell:e=>(0,a.jsx)("a",{href:e.key,target:"_blank",rel:"noreferrer",className:"font-semibold text-[#111827] hover:underline dark:text-slate-100",children:h(e.key)}),sort:e=>e.key},{key:"impressions",label:"Shown",align:"right",sort:e=>e.impressions,cell:e=>(0,a.jsxs)(a.Fragment,{children:[(0,i.Sc)(e.impressions)," ",(0,a.jsx)("span",{className:"text-[10px]",children:(0,a.jsx)(f,{cur:e.impressions,prev:e.prevImpressions,asPct:!0})})]})},{key:"clicks",label:"Clicks",align:"right",sort:e=>e.clicks,cell:e=>(0,a.jsxs)(a.Fragment,{children:[(0,i.Sc)(e.clicks)," ",(0,a.jsx)("span",{className:"text-[10px]",children:(0,a.jsx)(f,{cur:e.clicks,prev:e.prevClicks,asPct:!0})})]})},{key:"ctr",label:"Click rate",align:"right",sort:e=>e.ctr,cell:e=>p(e.ctr)},{key:"position",label:"Position",align:"right",sort:e=>-e.position,cell:e=>(0,a.jsxs)(a.Fragment,{children:[e.position?e.position.toFixed(1):"—"," ",(0,a.jsx)("span",{className:"text-[10px]",children:e.prevPosition?(0,a.jsx)(f,{cur:e.position,prev:e.prevPosition,lowerIsBetter:!0}):null})]})}]})]}):(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("p",{className:"text-[12px] text-[#64748b] dark:text-slate-400",children:"Page Strength, 0 to 100: how many of our own pages link to it, how many other sites link to it, and clicks. Pages with 0 internal links are orphans and need linking from a hub."}),(0,a.jsx)(i.XI,{rows:x,rowKey:e=>e.url,defaultSort:"score",perPage:25,empty:"Run a crawl first.",cols:[{key:"page",label:"Page",cell:e=>(0,a.jsxs)("span",{className:"block min-w-0",children:[(0,a.jsx)("a",{href:e.url,target:"_blank",rel:"noreferrer",className:"block truncate font-semibold text-[#111827] hover:underline dark:text-slate-100",children:h(e.url)}),e.title&&(0,a.jsx)("span",{className:"block truncate text-[11px] text-[#94a3b8]",children:e.title})]}),sort:e=>e.url},{key:"score",label:"Strength",align:"right",sort:e=>e.score,cell:e=>(0,a.jsx)("span",{className:"font-bold",style:{color:g(e.score)},children:e.score})},{key:"internalIn",label:"Our links in",align:"right",sort:e=>e.internalIn,cell:e=>0===e.internalIn?(0,a.jsx)("span",{style:{color:i.XQ.critical},children:"0"}):e.internalIn},{key:"externalIn",label:"Other sites' links",align:"right",sort:e=>e.externalIn,cell:e=>(0,i.Sc)(e.externalIn)},{key:"clicks",label:"Clicks",align:"right",sort:e=>e.clicks,cell:e=>(0,i.Sc)(e.clicks)},{key:"words",label:"Words",align:"right",sort:e=>e.words,cell:e=>e.words?(0,a.jsx)("span",{style:e.words<300?{color:i.XQ.warning}:void 0,children:(0,i.Sc)(e.words)}):"—"}]})]})]})}let M={"near-miss":{label:"Near miss",blurb:"We already rank at 11 to 30. A better page gets these onto page one."},"no-page":{label:"No real page",blurb:"Lots of impressions, ranking deep: the page Google shows is not about this. Write the page that is."},question:{label:"Question",blurb:"Answer it in the first two lines of a page."},"this-year":{label:"This year",blurb:"Fees, visas, dates, entry rules: the formula that ranks in weeks."}},P=e=>"no-page"===e.kind||!e.page;function T(e){let{data:t,onWrite:s}=e,[r,o]=(0,l.useState)("all"),d=t.opportunities.filter(e=>"all"===r||e.kind===r);return t.opportunities.length?(0,a.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,a.jsx)(i.C4,{value:r,options:[{key:"all",label:"All"},...Object.entries(M).map(e=>{let[t,s]=e;return{key:t,label:s.label}})],onChange:o}),(0,a.jsx)("p",{className:"text-[12px] text-[#64748b] dark:text-slate-400",children:"all"===r?"Search terms where a new or better page would pay off, biggest first.":M[r].blurb}),(0,a.jsx)("div",{className:"grid items-start gap-3 lg:grid-cols-2",children:d.map(e=>{var t;return(0,a.jsxs)("div",{className:i.PE,children:[(0,a.jsxs)("div",{className:"flex items-start justify-between gap-2",children:[(0,a.jsx)("p",{className:"text-[13px] font-bold text-[#111827] dark:text-slate-100",children:e.query}),(0,a.jsx)(i.vw,{children:(null==(t=M[e.kind])?void 0:t.label)??e.kind})]}),(0,a.jsx)("p",{className:"mt-2 text-[12px] leading-relaxed text-[#374151] dark:text-slate-300",children:e.why}),(0,a.jsxs)("div",{className:"mt-2 flex flex-wrap items-center gap-x-3 gap-y-1 text-[11px] text-[#94a3b8]",children:[(0,a.jsxs)("span",{children:[(0,i.Sc)(e.impressions)," shown"]}),(0,a.jsxs)("span",{children:["position ",e.position.toFixed(0)]}),e.page&&(0,a.jsxs)("a",{href:e.page,target:"_blank",rel:"noreferrer",className:"truncate hover:underline",children:["currently ",h(e.page)]})]}),(0,a.jsxs)("div",{className:"mt-3 flex items-center gap-2 border-t border-[#f1f5f9] pt-2.5 dark:border-slate-800",children:[(0,a.jsx)("span",{className:"min-w-0 flex-1 truncate text-[12px] text-[#64748b] dark:text-slate-400",title:e.title,children:P(e)?`Suggested: ${e.title}`:"Improve the page we already have"}),s&&P(e)&&(0,a.jsx)("button",{onClick:()=>void s(e.title,e.query),className:`${n.lJ} ${n.rh} shrink-0`,children:"Write it"}),e.page&&!P(e)&&(0,a.jsx)("a",{href:e.page,target:"_blank",rel:"noreferrer",className:`${n.lJ} ${n.h0} shrink-0`,children:"Open the page"})]})]},`${e.kind}-${e.query}`)})})]}):(0,a.jsx)(i.Sv,{text:t.configured.gsc?"No opportunities yet. They appear once Search Console has a month of data.":"Search Console is not connected on this server."})}function L(e){let{data:t}=e,[s,n]=(0,l.useState)("domains"),r=t.links;return r?(0,a.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,a.jsxs)("div",{className:"grid gap-3 sm:grid-cols-3",children:[(0,a.jsx)(i.ro,{label:"Sites linking to us",value:r.domains.length,hint:"Different websites. This is the number that moves Domain Strength."}),(0,a.jsx)(i.ro,{label:"Links in total",value:r.totalLinks,hint:"Counted by Bing across all our pages"}),(0,a.jsx)(i.ro,{label:"Pages with links",value:r.pages.filter(e=>e.count>0).length,hint:"Our pages that at least one other site points at"})]}),(0,a.jsx)(i.C4,{value:s,options:[{key:"domains",label:"Who links to us"},{key:"links",label:"Every link"},{key:"pages",label:"Our most linked pages"}],onChange:n}),r.sampled&&"pages"!==s&&(0,a.jsx)("p",{className:"text-[11px] text-[#94a3b8]",children:"Detail is gathered for our 40 most-linked pages; the totals cover everything."}),"domains"===s&&(0,a.jsx)(i.XI,{rows:r.domains,rowKey:e=>e.domain,defaultSort:"links",perPage:25,empty:"No linking sites found.",cols:[{key:"domain",label:"Site",cell:e=>(0,a.jsx)("a",{href:`https://${e.domain}`,target:"_blank",rel:"noreferrer",className:"font-semibold text-[#111827] hover:underline dark:text-slate-100",children:e.domain}),sort:e=>e.domain},{key:"links",label:"Links",align:"right",sort:e=>e.links,cell:e=>e.links},{key:"pages",label:"Our pages linked",align:"right",sort:e=>e.pages,cell:e=>e.pages}]}),"links"===s&&(0,a.jsx)(i.XI,{rows:r.links,rowKey:e=>`${e.source}>${e.target}`,perPage:25,empty:"No links recorded.",cols:[{key:"source",label:"From",cell:e=>(0,a.jsx)("a",{href:e.source,target:"_blank",rel:"noreferrer",className:"block max-w-[360px] truncate text-[#111827] hover:underline dark:text-slate-100",children:e.source})},{key:"anchor",label:"Link text",cell:e=>(0,a.jsx)("span",{className:"block max-w-[200px] truncate text-[#64748b] dark:text-slate-400",children:e.anchor||"—"})},{key:"target",label:"To",cell:e=>(0,a.jsx)("span",{className:"block max-w-[260px] truncate text-[#94a3b8]",children:h(e.target)})}]}),"pages"===s&&(0,a.jsx)(i.XI,{rows:r.pages.filter(e=>e.count>0),rowKey:e=>e.url,defaultSort:"count",perPage:25,empty:"No pages with links.",cols:[{key:"url",label:"Page",cell:e=>(0,a.jsx)("a",{href:e.url,target:"_blank",rel:"noreferrer",className:"font-semibold text-[#111827] hover:underline dark:text-slate-100",children:h(e.url)}),sort:e=>e.url},{key:"count",label:"Links in",align:"right",sort:e=>e.count,cell:e=>(0,i.Sc)(e.count)}]})]}):(0,a.jsx)(i.L7,{tone:"warn",children:t.configured.bing?"No link data yet. Press Refresh n
1ow.":"Bing Webmaster is not connected on this server."})}let A="text-[10px] font-bold uppercase tracking-wider text-[#94a3b8] dark:text-slate-500",E="cursor-default text-[#64748b] opacity-80 dark:text-slate-400";function I(e){let{adminHeaders:t,inspect:s}=e,[r,o]=(0,l.useState)([]),[d,h]=(0,l.useState)([]),[p,u]=(0,l.useState)(!0),[g,m]=(0,l.useState)(null),[f,b]=(0,l.useState)(!1),[v,j]=(0,l.useState)(null),[k,w]=(0,l.useState)(null),[y,N]=(0,l.useState)({}),[S,C]=(0,l.useState)(null),[$,M]=(0,l.useState)({}),P=(0,l.useCallback)(async()=>{if(t["x-secret-key"])try{let e=await fetch("/api/admin/workspace-v2/page-fixes",{headers:t}),s=await e.json();(null==s?void 0:s.success)&&(o(s.fixes??[]),h(s.applied??[]))}catch{}finally{u(!1)}},[t]);async function T(){b(!0),w(null),j(null);try{let e=await fetch("/api/admin/workspace-v2/page-fixes",{method:"POST",headers:{...t,"Content-Type":"application/json"},body:JSON.stringify({limit:25})}),s=await e.json();if(!e.ok||!(null==s?void 0:s.success))throw Error((null==s?void 0:s.error)??"That didn't work.");j(s.note??`${s.proposed} new suggestion${1===s.proposed?"":"s"} from ${s.candidates} page${1===s.candidates?"":"s"} worth a look.`),P()}catch(e){w(e instanceof Error?e.message:"That didn't work.")}finally{b(!1)}}async function L(e,s){m(e.id),w(null);let a=$[e.id]??{};try{let l=await fetch("/api/admin/workspace-v2/page-fixes",{method:"PATCH",headers:{...t,"Content-Type":"application/json"},body:JSON.stringify({id:e.id,action:s,metaTitle:a.proposedMetaTitle??e.proposedMetaTitle,metaDescription:a.proposedMetaDescription??e.proposedMetaDescription,keyTakeaway:a.proposedKeyTakeaway??e.proposedKeyTakeaway})}),n=await l.json();(null==n?void 0:n.success)?P():w((null==n?void 0:n.error)??"That didn't work.")}catch{w("That didn't work.")}finally{m(null)}}async function I(){let e=Object.entries(y).filter(e=>{let[,t]=e;return t}).map(e=>{let[t]=e;return t});if(!e.length)return;m("many"),w(null),C({ids:e,done:0,current:e[0]});let s=0,a=0;for(let l of e){let n=r.find(e=>e.id===l),i=$[l]??{};C({ids:e,done:s,current:l});try{let e=await fetch("/api/admin/workspace-v2/page-fixes",{method:"PATCH",headers:{...t,"Content-Type":"application/json"},body:JSON.stringify({id:l,action:"apply",metaTitle:i.proposedMetaTitle??(null==n?void 0:n.proposedMetaTitle),metaDescription:i.proposedMetaDescription??(null==n?void 0:n.proposedMetaDescription),keyTakeaway:i.proposedKeyTakeaway??(null==n?void 0:n.proposedKeyTakeaway)})}),r=await e.json();(null==r?void 0:r.success)?s++:a++}catch{a++}C({ids:e,done:s,current:null}),N(e=>({...e,[l]:!1}))}C(null),j(`${s} updated${a?`, ${a} failed`:""}. Google and Bing have been told to look again.`),m(null),P()}async function G(e){m(e.id);try{let s=await fetch("/api/admin/workspace-v2/page-fixes",{method:"PATCH",headers:{...t,"Content-Type":"application/json"},body:JSON.stringify({id:e.id,action:"undo"})}),a=await s.json();(null==a?void 0:a.success)?(j(`/blog/${e.slug} put back to what it said before.`),P()):w((null==a?void 0:a.error)??"That didn't work.")}catch{w("That didn't work.")}finally{m(null)}}(0,l.useEffect)(()=>{P()},[P]);let O=e=>{if(!(null==s?void 0:s.length)||!e.decidedAt)return"unknown";let t=s.find(t=>t.url.replace(/\/$/,"").endsWith(`/blog/${e.slug}`));return(null==t?void 0:t.lastCrawled)?new Date(t.lastCrawled)>new Date(e.decidedAt)?"yes":"no":"unknown"},B=(e,t,s)=>M(a=>({...a,[e]:{...a[e],[t]:s}})),U=Object.values(y).filter(Boolean).length,F=r.reduce((e,t)=>e+Math.max(0,Math.round(.025*t.stats.impressions-t.stats.clicks)),0);return(0,a.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,a.jsxs)("div",{className:"grid gap-3 sm:grid-cols-3",children:[(0,a.jsx)(i.ro,{label:"Pages waiting",value:r.length,hint:"Ranking well, nobody clicking"}),(0,a.jsx)(i.ro,{label:"Visits a month at stake",value:F,hint:"If these hit a normal click rate"}),(0,a.jsx)(i.ro,{label:"Changed so far",value:d.length,hint:"Applied and sent for re-crawl"})]}),(0,a.jsxs)("div",{className:"flex flex-wrap items-center gap-2",children:[(0,a.jsx)("button",{disabled:f,onClick:()=>void T(),className:`${n.lJ} ${n.h0} disabled:opacity-40`,children:f?"Looking… this takes a minute":"Look for more"}),r.length>0&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("button",{onClick:()=>N(Object.fromEntries(r.map(e=>[e.id,!0]))),className:`${n.lJ} ${n.h0}`,children:"Tick all"}),(0,a.jsx)("button",{disabled:!U||"many"===g,onClick:()=>void I(),className:`${n.lJ} ${n.rh} disabled:opacity-40`,children:"many"===g?"Applying…":`Apply ${U||""} ticked`.trim()})]}),v&&(0,a.jsx)("span",{className:"text-[11px] text-[#94a3b8]",children:v}),k&&(0,a.jsx)("span",{className:"text-[11px] font-semibold text-red-500",children:k})]}),S&&(0,a.jsxs)("div",{children:[(0,a.jsxs)("div",{className:"flex items-baseline justify-between gap-3",children:[(0,a.jsxs)("p",{className:"text-[12px] font-semibold text-[#111827] dark:text-slate-100",children:["Applying ",Math.min(S.done+1,S.ids.length)," of ",S.ids.length]}),(0,a.jsxs)("p",{className:"text-[11px] text-[#94a3b8]",children:["about ",Math.max(1,Math.round((S.ids.length-S.done)*12/60))," min left"]})]}),(0,a.jsx)("div",{className:"mt-1.5 h-1.5 w-full overflow-hidden rounded-full bg-[#f1f5f9] dark:bg-slate-800",children:(0,a.jsx)("div",{className:"h-full rounded-full transition-[width] duration-500",style:{width:`${S.done/S.ids.length*100}%`,background:"#14b8a6"}})})]}),p?(0,a.jsx)("p",{className:"text-[12px] text-[#94a3b8]",children:"Loading…"}):r.length?(0,a.jsx)("div",{className:"flex flex-col gap-3",children:r.map(e=>{let t=$[e.id]??{},s=t.proposedMetaTitle??e.proposedMetaTitle,l=t.proposedMetaDescription??e.proposedMetaDescription,r=t.proposedKeyTakeaway??e.proposedKeyTakeaway,o=!!(S&&S.ids.includes(e.id)),d=(null==S?void 0:S.current)===e.id;return(0,a.jsxs)("div",{className:`${c} ${d?"ring-1 ring-[#14b8a6]":""} ${o&&!d?"opacity-45":""} transition`,children:[(0,a.jsxs)("div",{className:"flex items-start gap-3",children:[(0,a.jsx)("button",{onClick:()=>N(t=>
1({...t,[e.id]:!t[e.id]})),"aria-label":"Tick to apply",className:`mt-0.5 flex h-[18px] w-[18px] shrink-0 items-center justify-center rounded-[5px] border ${y[e.id]?"border-transparent bg-[#14b8a6]":"border-[#cbd5e1] dark:border-slate-600"}`,children:y[e.id]&&(0,a.jsx)("svg",{width:"11",height:"11",viewBox:"0 0 24 24",fill:"none",stroke:"#fff",strokeWidth:"3.5",strokeLinecap:"round",strokeLinejoin:"round",children:(0,a.jsx)("polyline",{points:"20 6 9 17 4 12"})})}),(0,a.jsxs)("div",{className:"min-w-0 flex-1",children:[(0,a.jsxs)("span",{className:"flex items-center gap-2",children:[(0,a.jsxs)("a",{href:`https://budgetbro.app/blog/${e.slug}`,target:"_blank",rel:"noreferrer",className:"text-[13px] font-bold text-[#111827] hover:underline dark:text-slate-100",children:["/blog/",e.slug]}),d&&(0,a.jsx)("span",{className:"text-[11px] font-semibold text-[#14b8a6]",children:"writing…"}),o&&!d&&(0,a.jsx)("span",{className:"text-[11px] text-[#94a3b8]",children:"waiting"})]}),(0,a.jsxs)("div",{className:"mt-1.5 flex flex-wrap items-center gap-x-2.5 gap-y-1 text-[11px] text-[#94a3b8]",children:[(0,a.jsxs)(i.vw,{tone:"live",children:["+",Math.max(0,Math.round(.025*e.stats.impressions-e.stats.clicks))," visits a month"]}),(0,a.jsxs)("span",{children:[e.stats.impressions.toLocaleString()," shown"]}),(0,a.jsxs)("span",{children:[e.stats.clicks," clicks"]}),(0,a.jsxs)("span",{style:{color:i.XQ.critical},children:[(100*e.stats.ctr).toFixed(1),"%"]}),(0,a.jsxs)("span",{children:["position ",e.stats.position.toFixed(0)]})]})]})]}),e.stats.topQueries.length>0&&(0,a.jsxs)("p",{className:"mt-3 text-[12px] leading-relaxed text-[#64748b] dark:text-slate-400",children:[(0,a.jsx)("span",{className:"font-semibold text-[#374151] dark:text-slate-300",children:"People search: "}),e.stats.topQueries.join(" \xb7 ")]}),e.rationale&&(0,a.jsx)("p",{className:"mt-1.5 text-[12px] leading-relaxed text-[#64748b] dark:text-slate-400",children:e.rationale}),(0,a.jsxs)("div",{className:"mt-3 grid items-start gap-x-3 gap-y-2 lg:grid-cols-2",children:[(0,a.jsx)("p",{className:A,children:"Live now"}),(0,a.jsx)("p",{className:`${A} hidden lg:block`,children:"Suggested \xb7 edit anything before applying"}),(0,a.jsx)("input",{readOnly:!0,value:e.currentMetaTitle||e.currentTitle,placeholder:"— no title set —",className:`${n.bO} ${E}`}),(0,a.jsx)("p",{className:`${A} lg:hidden`,children:"Suggested"}),(0,a.jsx)("input",{value:s,onChange:t=>B(e.id,"proposedMetaTitle",t.target.value),className:n.bO}),(0,a.jsx)("textarea",{readOnly:!0,rows:3,value:e.currentMetaDescription,placeholder:"— no description set —",className:`${n.b4} ${E}`}),(0,a.jsx)("textarea",{value:l,onChange:t=>B(e.id,"proposedMetaDescription",t.target.value),rows:3,className:n.b4}),(0,a.jsx)("textarea",{readOnly:!0,rows:4,value:e.currentKeyTakeaway,placeholder:"— no quick answer set —",className:`${n.b4} ${E}`}),(0,a.jsx)("textarea",{value:r,onChange:t=>B(e.id,"proposedKeyTakeaway",t.target.value),rows:4,className:n.b4}),(0,a.jsx)("span",{}),(0,a.jsxs)("p",{className:"text-[10px] text-[#94a3b8]",children:["Title ",s.length,"/60 \xb7 description ",l.length,"/160"]})]}),(0,a.jsxs)("div",{className:"mt-3 flex items-center gap-2 border-t border-[#f1f5f9] pt-2.5 dark:border-slate-800",children:[(0,a.jsx)("button",{disabled:g===e.id,onClick:()=>void L(e,"apply"),className:`${n.lJ} ${n.rh} disabled:opacity-40`,children:g===e.id?"Applying…":"Apply"}),(0,a.jsx)("button",{disabled:g===e.id,onClick:()=>void L(e,"dismiss"),className:`${n.lJ} ${n.h0} disabled:opacity-40`,children:"Leave it"})]})]},e.id)})}):(0,a.jsx)(i.Sv,{text:"Nothing waiting. Press 'Look for more' to check Search Console for pages that rank but do not get clicked."}),d.length>0&&(0,a.jsx)(x,{title:"Changed recently",children:(0,a.jsx)("div",{className:"flex flex-col gap-2",children:d.map(e=>(0,a.jsxs)("div",{className:"flex items-center gap-3 border-t border-[#f1f5f9] py-2 text-[12px] dark:border-slate-800",children:[(0,a.jsxs)("a",{href:`https://budgetbro.app/blog/${e.slug}`,target:"_blank",rel:"noreferrer",className:"shrink-0 font-semibold text-[#111827] hover:underline dark:text-slate-100",children:["/blog/",e.slug]}),(0,a.jsx)("span",{className:"min-w-0 flex-1 truncate text-[#94a3b8]",children:e.proposedMetaTitle}),"yes"===O(e)?(0,a.jsx)("span",{className:"shrink-0 text-[11px] font-semibold text-[#0ca30c]",children:"Google has it"}):"no"===O(e)?(0,a.jsx)("span",{className:"shrink-0 text-[11px] text-[#94a3b8]",children:"waiting for Google"}):null,(0,a.jsx)("button",{disabled:g===e.id,onClick:()=>void G(e),className:`${n.lJ} ${n.h0} shrink-0 disabled:opacity-40`,children:"Put back"})]},e.id))})}),(0,a.jsx)("div",{className:i.PE,children:(0,a.jsx)(i.L7,{children:"Only the search result changes: the blue link, the grey line under it, and the sentence AI answer engines quote. The article itself is untouched. Every change bumps the page's updated date and tells Google and Bing to look again, and anything applied can be put back."})})]})}let G=e=>e?Math.floor((Date.now()-new Date(e).getTime())/864e5):null,O={"Submitted and indexed":"In Google, from your sitemap. Nothing to do.","Indexed, not submitted in sitemap":"In Google, but missing from your sitemap. Worth adding.","Crawled - currently not indexed":"Google read it and chose not to show it. Usually thin content or a page that duplicates another.","Discovered - currently not indexed":"Google knows it exists but has not read it yet. Often means the site has more pages than Google thinks are worth crawling.","Duplicate without user-selected canonical":"Google thinks another page says the same thing and is showing that one instead.","Duplicate, Google chose different canonical than user":"You pointed at one address, Google picked another.","Excluded by ‘noindex’ tag":"The page tells Google not to index it.","Page with redirect":"This address sends visitors somewhere else. A 301 is a permanent move and passes on what the old page had earned; a 302 is temporary and passes on nothing.","Not found (404)":"The page does not load.","Soft 404":"The page loads but looks empty to Google."},B=[{key:"all",label:"All"},{key:"new",label:"Just published"},{key:"indexed",label:"In Google"},{key:"not",label:"Not in Google"},{key:"stale",label:"Not crawled lately"},{key:"never",label:"Never crawled"}],U=e=>{let t=G(e.firstSeen??null);return null!==t&&t<=14};function F(e){let{data:t}=e,[s,r]=(0,l.useState)("all"),[o,d]=(0,l.useState)(""),[c,p]=(0,l.useState)(null),[u,g]=(0,l.useState)(!1),[m,f]=(0,l.useState)(null),b=t.inspect,v=(0,l.useMemo)(()=>
1{let e=(null==b?void 0:b.pages)??[],t=o.trim().toLowerCase();return e.filter(e=>{if(t&&!e.url.toLowerCase().includes(t)||m&&(e.coverage||"No reason given")!==m)return!1;let a=G(e.lastCrawled);return"new"===s?U(e):"indexed"===s?"PASS"===e.verdict:"not"===s?"PASS"!==e.verdict:"stale"===s?null!==a&&a>30:"never"!==s||null===a})},[b,s,o,m]);if(!b)return(0,a.jsx)(i.Sv,{text:"Google has not been asked yet. Press Refresh now — it checks your busiest 300 pages and takes a couple of minutes."});if(b.error)return(0,a.jsxs)(i.L7,{tone:"warn",children:["Google refused this: ",b.error,". The account we read Search Console with needs to be a full user on the property, not a restricted one. In Search Console go to Settings, then Users and permissions, find the budgetbro service account and set its permission to Full."]});let j=b.pages,k=j.filter(e=>"PASS"===e.verdict).length,w=j.filter(e=>!e.lastCrawled).length,y=j.filter(e=>(G(e.lastCrawled)??0)>30).length,N=j.filter(U),S=N.filter(e=>"PASS"!==e.verdict).length,C=j.map(e=>G(e.lastCrawled)).filter(e=>null!==e),$=C.length?C.sort((e,t)=>e-t)[Math.floor(C.length/2)]:null,M=Object.entries(j.filter(e=>"PASS"!==e.verdict).reduce((e,t)=>{let s=t.coverage||"No reason given";return e[s]=(e[s]??0)+1,e},{})).sort((e,t)=>t[1]-e[1]),P=e=>{f(null),r(t=>t===e?"all":e)};return(0,a.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,a.jsxs)("div",{className:"grid gap-3 sm:grid-cols-2 xl:grid-cols-5",children:[(0,a.jsx)("button",{onClick:()=>P("indexed"),className:"text-left",children:(0,a.jsx)(i.ro,{label:"In Google",value:`${k} of ${j.length}`,hint:"Of the pages we asked about",tone:k/Math.max(1,j.length)>.85?"good":"warning"})}),(0,a.jsx)(i.ro,{label:"Typical last crawl",value:null===$?"—":`${$} days ago`,hint:"Middle of the pack"}),(0,a.jsx)("button",{onClick:()=>P("stale"),className:"text-left",children:(0,a.jsx)(i.ro,{label:"Going stale",value:y,hint:"Not crawled in over a month",tone:y?"warning":"good"})}),(0,a.jsx)("button",{onClick:()=>P("never"),className:"text-left",children:(0,a.jsx)(i.ro,{label:"Never crawled",value:w,hint:"Google has not read these at all",tone:w?"critical":"good"})}),(0,a.jsx)("button",{onClick:()=>P("new"),className:"text-left",children:(0,a.jsx)(i.ro,{label:"Published lately",value:N.length,hint:S?`${S} not in Google yet`:"All picked up",tone:S?"warning":"good"})})]}),M.length>0&&(0,a.jsx)(x,{title:"Why pages are not being shown",children:(0,a.jsx)("div",{className:"grid items-start gap-3 lg:grid-cols-2",children:M.map(e=>{let[t,s]=e;return(0,a.jsxs)("button",{onClick:()=>{r("all"),f(e=>e===t?null:t)},className:`${i.PE} text-left transition hover:drop-shadow-[0_2px_8px_rgba(15,23,42,0.07)] ${m===t?"ring-1 ring-[#14b8a6]":""}`,children:[(0,a.jsxs)("div",{className:"flex items-baseline justify-between gap-3",children:[(0,a.jsx)("p",{className:"text-[13px] font-bold text-[#111827] dark:text-slate-100",children:t}),(0,a.jsxs)("span",{className:"shrink-0 text-[11px] font-semibold tabular-nums text-[#94a3b8]",children:[s," page",1===s?"":"s"]})]}),(0,a.jsx)("p",{className:"mt-2 text-[12px] leading-relaxed text-[#64748b] dark:text-slate-400",children:O[t]??"Google's own wording. Search it in Search Console help if it is not obvious."})]},t)})})}),(0,a.jsxs)(i.M7,{children:[(0,a.jsx)("div",{className:"relative min-w-[220px] flex-1",children:(0,a.jsx)("input",{value:o,onChange:e=>d(e.target.value),placeholder:"Search pages…",className:n.bO})}),(0,a.jsx)(i.C4,{value:s,options:[...B],onChange:e=>{f(null),r(e)}})]}),m&&(0,a.jsxs)("p",{className:"text-[11px] text-[#94a3b8]",children:["Showing the ",v.length," page",1===v.length?"":"s",' Google marked "',m,'".'," ",(0,a.jsx)("button",{onClick:()=>f(null),className:"font-semibold hover:text-[#64748b] dark:hover:text-slate-300",children:"Show everything"})]}),(0,a.jsx)(i.XI,{rows:v,rowKey:e=>e.url,defaultSort:"crawled",perPage:25,expandedKey:(null==c?void 0:c.url)??null,expanded:e=>(0,a.jsx)(D,{page:e,copied:u,onCopy:()=>g(!0)}),onRow:e=>{g(!1),p((null==c?void 0:c.url)===e.url?null:e)},empty:"Nothing in this group.",cols:[{key:"page",label:"Page",cell:e=>(0,a.jsx)("span",{className:"font-semibold text-[#111827] dark:text-slate-100",children:h(e.url)}),sort:e=>e.url},{key:"state",label:"In Google",cell:e=>(0,a.jsx)("span",{className:"text-[10px] font-bold uppercase tracking-wide",style:{color:"PASS"===e.verdict?i.XQ.good:i.XQ.warning},children:"PASS"===e.verdict?"yes":"no"}),sort:e=>+("PASS"===e.verdict)},{key:"reason",label:"Google's words",cell:e=>(0,a.jsxs)("span",{className:"block max-w-[340px] truncate text-[#64748b] dark:text-slate-400",children:[e.coverage||"—",e.redirectsTo?` → ${h(e.redirectsTo)}`:""]})},{key:"crawled",label:"Last crawled",align:"right",sort:e=>-(G(e.lastCrawled)??9999),cell:e=>{let t=G(e.lastCrawled);return null===t?(0,a.jsx)("span",{style:{color:i.XQ.critical},children:"never"}):(0,a.jsx)("span",{style:t>30?{color:i.XQ.warning}:void 0,children:0===t?"today":`${t}d ago`})}}]}),(0,a.jsx)("div",{className:i.PE,children:(0,a.jsxs)(i.L7,{children:["Checked ",b.asked," pages this run, and ",j.length,' are being tracked. New pages go to the front of the queue, then whatever was asked about longest ago; the list comes from your sitemap as well as Search Console, so a page published this morning is checked tonight rather than waiting to earn its first impression. It runs three times a day, about 100 pages each time. "Never crawled" on a page that matters is the one to act on: link to it from somewhere people go, and request indexing in Search Console.']})})]})}function D(e){let{page:t,copied:s,onCopy:l}=e;return(0,a.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,a.jsxs)("div",{className:"grid gap-x-6 gap-y-1 text-[12px] text-[#374151] sm:grid-cols-2 dark:text-slate-300",children:[(0,a.jsxs)("p",{children:[(0,a.jsx)("span",{className:"font-semibold",children:"Google says: "}),t.coverage||"—"]}),(0,a.jsxs)("p",{children:[(0,a.jsx)("span",{className:"font-semibold",children:"Last crawled: "}
1),t.lastCrawled?new Date(t.lastCrawled).toLocaleString("en-GB"):"never"]}),(0,a.jsxs)("p",{children:[(0,a.jsx)("span",{className:"font-semibold",children:"Can be indexed: "}),"INDEXING_ALLOWED"===t.indexingState?"yes":t.indexingState||"—"]}),t.firstSeen&&(0,a.jsxs)("p",{children:[(0,a.jsx)("span",{className:"font-semibold",children:"First seen here: "}),new Date(t.firstSeen).toLocaleDateString("en-GB")]})]}),t.redirectsTo&&(0,a.jsxs)("p",{className:"text-[12px] text-[#374151] dark:text-slate-300",children:[(0,a.jsxs)("span",{className:"font-semibold",children:["Sends visitors to",t.redirectStatus?` (${t.redirectStatus})`:"",": "]}),(0,a.jsx)("a",{href:t.redirectsTo,target:"_blank",rel:"noreferrer",onClick:e=>e.stopPropagation(),className:"hover:underline",children:h(t.redirectsTo)})]}),O[t.coverage]&&(0,a.jsx)("p",{className:"text-[12px] leading-relaxed text-[#64748b] dark:text-slate-400",children:O[t.coverage]}),t.googleCanonical&&t.userCanonical&&t.googleCanonical!==t.userCanonical&&(0,a.jsxs)("p",{className:"text-[12px]",style:{color:i.XQ.warning},children:["Google is showing ",h(t.googleCanonical)," instead of this page."]}),(0,a.jsxs)("div",{className:"mt-1 flex flex-wrap items-center gap-2",children:[(0,a.jsx)("a",{href:"https://search.google.com/search-console?resource_id=sc-domain%3Abudgetbro.app",target:"_blank",rel:"noreferrer",onClick:e=>{var s;e.stopPropagation(),null==(s=navigator.clipboard)||s.writeText(t.url),l()},className:`${n.lJ} ${n.h0}`,children:"Copy address and open Search Console"}),(0,a.jsx)("a",{href:t.url,target:"_blank",rel:"noreferrer",onClick:e=>e.stopPropagation(),className:`${n.lJ} ${n.h0}`,children:"View the page"}),(0,a.jsx)("span",{className:"text-[11px] text-[#94a3b8]",children:s?"Copied — paste it into the box at the top of Search Console.":"Paste it into the box at the top to inspect or request indexing."})]})]})}var R=s(4472);let _=[{days:7,label:"7 days"},{days:28,label:"28 days"},{days:90,label:"90 days"}],X=["Landing","About","How it works","Book a lesson"],z="rounded-2xl border border-[#f1f5f9] bg-[#fafafa] dark:border-slate-800 dark:bg-slate-900/40";function W(e,t){return t?(e-t)/t*100:e>0?null:0}function Q(e){let{value:t}=e;if(null===t)return(0,a.jsx)("span",{className:"text-[10px] font-semibold text-[#94a3b8]",children:"new"});let s=1>Math.abs(t),l=t>=1;return(0,a.jsxs)("span",{className:`text-[10px] font-bold tabular-nums ${s?"text-[#94a3b8]":l?"text-[#16a34a]":"text-[#dc2626]"}`,children:[s?"→":l?"↑":"↓"," ",Math.abs(t).toFixed(0),"%"]})}function J(e){let{name:t}=e,s={width:16,height:16,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};return"visitors"===t?(0,a.jsxs)("svg",{...s,children:[(0,a.jsx)("circle",{cx:"12",cy:"8",r:"4"}),(0,a.jsx)("path",{d:"M4 21a8 8 0 0116 0"})]}):"sessions"===t?(0,a.jsx)("svg",{...s,children:(0,a.jsx)("polyline",{points:"3 12 8 12 10 6 14 18 16 12 21 12"})}):"views"===t?(0,a.jsxs)("svg",{...s,children:[(0,a.jsx)("path",{d:"M14 3H6a2 2 0 00-2 2v14a2 2 0 002 2h12a2 2 0 002-2V8z"}),(0,a.jsx)("polyline",{points:"14 3 14 8 19 8"})]}):"time"===t?(0,a.jsxs)("svg",{...s,children:[(0,a.jsx)("circle",{cx:"12",cy:"12",r:"9"}),(0,a.jsx)("polyline",{points:"12 7 12 12 15.5 14"})]}):"click"===t?(0,a.jsx)("svg",{...s,children:(0,a.jsx)("path",{d:"M9 3l10 8-4.5 1.2L16 18l-2.3 1.2-1.7-4.6L8 17V3z"})}):(0,a.jsxs)("svg",{...s,children:[(0,a.jsx)("polygon",{points:"12 3 3 8 12 13 21 8 12 3"}),(0,a.jsx)("polyline",{points:"3 16 12 21 21 16"}),(0,a.jsx)("polyline",{points:"3 12 12 17 21 12"})]})}function K(e){let{adminHeaders:t}=e,[s,n]=(0,l.useState)(28),[r,i]=(0,l.useState)(null),[o,d]=(0,l.useState)(!0),[c,x]=(0,l.useState)(!1);(0,l.useEffect)(()=>{let e=document.documentElement,t=()=>x(e.classList.contains("dark"));t();let s=new MutationObserver(t);return s.observe(e,{attributes:!0,attributeFilter:["class"]}),()=>s.disconnect()},[]);let h=(0,l.useCallback)(async()=>{if(t["x-secret-key"]){d(!0);try{let e=await fetch(`/api/admin/workspace-v2/portuguese-analytics?days=${s}`,{headers:t}),a=await e.json();(null==a?void 0:a.success)&&i(a)}finally{d(!1)}}},[t,s]);if((0,l.useEffect)(()=>{h()}
1,[h]),o&&!r)return(0,a.jsx)(Y,{});if(!r)return(0,a.jsx)("p",{className:"text-[13px] text-[#94a3b8]",children:"Could not load analytics."});if(!r.configured)return(0,a.jsx)("div",{className:`${z} p-6 text-[13px] text-[#64748b] dark:text-slate-400`,children:"Analytics isn't connected yet — GA4 isn't configured for this site, so there's nothing to show."});let p=r.totals,u=r.previousTotals,g=R.tv[c?"dark":"light"],m=(null==p?void 0:p.activeUsers)?r.calClicks/p.activeUsers*100:0;return(0,a.jsxs)("div",{className:"flex flex-col gap-6",children:[(0,a.jsx)("div",{className:"flex items-center gap-1 rounded-full bg-[#f1f5f9] p-1 dark:bg-slate-800",children:_.map(e=>(0,a.jsx)("button",{onClick:()=>n(e.days),className:`rounded-full px-3.5 py-1 text-[12px] font-semibold transition ${s===e.days?"bg-white text-[#111827] shadow-[0_1px_2px_rgba(15,23,42,0.08)] dark:bg-slate-900 dark:text-slate-100":"text-[#64748b] hover:text-[#111827] dark:text-slate-400"}`,children:e.label},e.days))}),(0,a.jsxs)("div",{className:"flex flex-wrap items-center justify-between gap-6 rounded-2xl bg-gradient-to-br from-[#0d9488]/[0.08] to-transparent p-6 dark:from-[#0d9488]/[0.16]",children:[(0,a.jsxs)("div",{children:[(0,a.jsxs)("div",{className:"text-[12px] font-bold uppercase tracking-wider text-[#0d9488]",children:["Last ",s," days"]}),(0,a.jsxs)("div",{className:"mt-2 flex items-baseline gap-2",children:[(0,a.jsx)("span",{className:"text-[44px] font-bold leading-none tracking-[-0.02em] text-[#111827] dark:text-slate-100",children:((null==p?void 0:p.activeUsers)??0).toLocaleString()}),(0,a.jsx)("span",{className:"text-[15px] font-semibold text-[#94a3b8]",children:"visitors"}),(0,a.jsx)(Q,{value:W((null==p?void 0:p.activeUsers)??0,(null==u?void 0:u.activeUsers)??0)})]})]}),(0,a.jsxs)("div",{className:"flex flex-col items-end",children:[(0,a.jsxs)("div",{className:"flex items-baseline gap-2",children:[(0,a.jsxs)("span",{className:"text-[36px] font-bold leading-none tabular-nums text-[#d97757]",children:[m.toFixed(1),"%"]}),(0,a.jsx)(Q,{value:W(r.calClicks,r.previousCalClicks)})]}),(0,a.jsxs)("div",{className:"mt-1 text-[11px] font-semibold uppercase tracking-wider text-[#94a3b8]",children:["clicked Book Now (",r.calClicks,")"]})]})]}),(0,a.jsxs)("div",{className:"grid grid-cols-2 gap-3 sm:grid-cols-3 lg:grid-cols-5",children:[(0,a.jsx)(q,{icon:"sessions",accent:g[0],label:"Sessions",value:((null==p?void 0:p.sessions)??0).toLocaleString(),deltaValue:W((null==p?void 0:p.sessions)??0,(null==u?void 0:u.sessions)??0)}),(0,a.jsx)(q,{icon:"views",accent:g[3],label:"Page views",value:((null==p?void 0:p.screenPageViews)??0).toLocaleString(),deltaValue:W((null==p?void 0:p.screenPageViews)??0,(null==u?void 0:u.screenPageViews)??0)}),(0,a.jsx)(q,{icon:"time",accent:g[1],label:"Avg. time on site",value:function(e){if(!e||e<1)return"0s";let t=Math.floor(e/60),s=Math.round(e%60);return t>0?`${t}m ${s}s`:`${s}s`}((null==p?void 0:p.avgSessionSeconds)??0),deltaValue:W((null==p?void 0:p.avgSessionSeconds)??0,(null==u?void 0:u.avgSessionSeconds)??0)}),(0,a.jsx)(q,{icon:"depth",accent:g[2],label:"Pages / session",value:((null==p?void 0:p.pagesPerSession)??0).toFixed(1),deltaValue:W((null==p?void 0:p.pagesPerSession)??0,(null==u?void 0:u.pagesPerSession)??0)}),(0,a.jsx)(q,{icon:"click",accent:"#64748b",label:"Clicks, total",value:r.clicks.toLocaleString(),deltaValue:W(r.clicks,r.previousClicks)})]}),(0,a.jsxs)("div",{className:"grid gap-6 lg:grid-cols-2",children:[(0,a.jsxs)("div",{className:`${z} p-5`,children:[(0,a.jsx)("div",{className:"mb-4 text-[13px] font-bold text-[#111827] dark:text-slate-100",children:"Views by page"}),(0,a.jsx)(H,{data:r.byPage,palette:g})]}),r.daily.length>1&&(0,a.jsxs)("div",{className:`${z} p-5`,children:[(0,a.jsx)("div",{className:"mb-4 text-[13px] font-bold text-[#111827] dark:text-slate-100",children:"Page views, day by day"}),(0,a.jsx)(V,{data:r.daily,color:g[0]})]})]}),(0,a.jsx)("p",{className:"text-[11px] text-[#94a3b8]",children:'"Clicks, total" is every recorded click across these pages. Seeing exactly which button or link (other than Book Now) gets clicked needs one more GA4 setting — ask and I\'ll walk you through it.'})]})}function q(e){let{icon:t,accent:s,label:l,value:n,deltaValue:r}=e;return(0,a.jsxs)("div",{className:`${z} p-4`,children:[(0,a.jsxs)("div",{className:"flex items-center justify-between",children:[(0,a.jsx)("span",{className:"flex h-7 w-7 items-center justify-center rounded-full",style:{color:s,background:`${s}1a`},children:(0,a.jsx)(J,{name:t})}),(0,a.jsx)(Q,{value:r})]}),(0,a.jsx)("div",{className:"mt-3 text-[22px] font-bold leading-none tabular-nums tracking-[-0.02em] text-[#111827] dark:text-slate-100",children:n}),(0,a.jsx)("div",{className:"mt-1.5 text-[11px] text-[#94a3b8]",children:l})]})}function H(e){let{data:t,palette:s}=e;if(!t.length)return(0,a.jsx)("p",{className:"text-[12px] text-[#94a3b8]",children:"Nothing to show yet."});let l=Math.max(1,...t.map(e=>e.views));return(0,a.jsx)("div",{className:"flex flex-col gap-3",children:t.map(e=>{let t=X.indexOf(e.label),n=s[t>=0?t%s.length:s.length-1];return(0,a.jsxs)("div",{className:"flex items-center gap-3",children:[(0,a.jsx)("span",{className:"w-[104px] shrink-0 truncate text-[11px] font-medium text-[#64748b] dark:text-slate-400",children:e.label}),(0,a.jsx)("div",{className:"h-[10px] min-w-0 flex-1 overflow-hidden rounded-full bg-[#f1f5f9] dark:bg-slate-800",children:(0,a.jsx)("div",{className:"h-full rounded-full transition-[width]",style:{width:`${Math.max(3,e.views/l*100)}%`,background:n}})}),(0,a.jsx)("span",{className:"w-10 shrink-0 text-right text-[11px] font-bold tabular-nums text-[#111827] dark:text-slate-100",children:e.views})]},e.path)})})}function V(e){var t,s,l;let{data:n,color:r}=e,i=Math.max(1,...n.map(e=>e.views)),o=720/Math.max(1,n.length-1),d=n.map((e,t)=>[t*o,140-e.views/i*128-6]),c=d.map(e=>{let[t,s]=e;return`${t},${s}`}).join(" "),x=`0,140 ${c} ${(null==(t=d[d.length-1])?void 0:t[0])??0},140`;return(0,a.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,a.jsxs)("svg",{viewBox:"0 0 720 140",preserveAspectRatio:"none",style:{height:140},className:"w-full",children:[(0,a.jsx)("defs",{children:(0,a.jsxs)("linearGradient",{id:"lessons-trend-fill",x1:"0",y1:"0",x2:"0",y2:"1",children:[(0,a.jsx)("stop",{offset:"0%",stopColor:r,stopOpacity:"0.18"}),(0,a.jsx)("stop",{offset:"100%",stopColor:r,stopOpacity:"0"})]})}),(0,a.jsx)("polygon",{points:x,fill:"url(#lessons-trend-fill)"}),(0,a.jsx)("polyline",{points:c,fill:"none",stroke:r,strokeWidth:"2.5",vectorEffect:"non-scaling-stroke",strokeLinejoin:"round",strokeLinecap:"round"})]}),(0,a.jsxs)("div",{className:"flex items-center justify-between text-[10px] text-[#94a3b8]",children:[(0,a.jsx)("span",{children:null==(s=n[0])?void 0:s.day.slice(5)}),(0,a.jsx)("span",{children:null==(l=n[n.length-1])?void 0:l.day.slice(5)})]})]})}function Y(){return(0,a.jsxs)("div",{className:"flex flex-col gap-6",children:[(0,a.jsx)("span",{className:"bb-skeleton h-[30px] w-[220px] rounded-full"}),(0,a.jsx)("span",{className:"bb-skeleton h-[110px] w-full rounded-2xl"}),(0,a.jsx)("div",{className:"grid grid-cols-2 gap-3 sm:grid-cols-3 lg:grid-cols-5",children:[0,1,2,3,4].map(e=>(0,a.jsx)("span",{className:"bb-skeleton h-[86px] rounded-2xl"},e))}),(0,a.jsxs)("div",{className:"grid gap-6 lg:grid-cols-2",children:[(0,a.jsx)("span",{className:"bb-skeleton h-[180px] w-full rounded-2xl"}),(0,a.jsx)("span",{className:"bb-skeleton h-[180px] w-full rounded-2xl"})]})]})}var Z=s(67909);let ee={Afghanistan:[33.94,67.71],Albania:[41.15,20.17],Algeria:[28.03,1.66],Andorra:[42.55,1.6],Angola:[-11.2,17.87],Argentina:[-38.42,-63.62],Armenia:[40.07,45.04],Australia:[-25.27,133.78],Austria:[47.52,14.55],Azerbaijan:[40.14,47.58],Bahamas:[25.03,-77.4],Bahrain:[26.07,50.56],Bangladesh:[23.68,90.36],Belarus:[53.71,27.95],Belgium:[50.5,4.47],Belize:[17.19,-88.5],Benin:[9.31,2.32],Bhutan:[27.51,90.43],Bolivia:[-16.29,-63.59],"Bosnia and Herzegovina":[43.92,17.68],Botswana:[-22.33,24.68],Brazil:[-14.24,-51.93],Brunei:[4.54,114.73],Bulgaria:[42.73,25.49],"Burkina Faso":[12.24,-1.56],Burundi:[-3.37,29.92],C
1ambodia:[12.57,104.99],Cameroon:[7.37,12.35],Canada:[56.13,-106.35],Chad:[15.45,18.73],Chile:[-35.68,-71.54],China:[35.86,104.2],Colombia:[4.57,-74.3],"Costa Rica":[9.75,-83.75],Croatia:[45.1,15.2],Cuba:[21.52,-77.78],Cyprus:[35.13,33.43],Czechia:[49.82,15.47],Denmark:[56.26,9.5],"Dominican Republic":[18.74,-70.16],Ecuador:[-1.83,-78.18],Egypt:[26.82,30.8],"El Salvador":[13.79,-88.9],Estonia:[58.6,25.01],Ethiopia:[9.15,40.49],Fiji:[-17.71,178.07],Finland:[61.92,25.75],France:[46.23,2.21],Gabon:[-.8,11.61],Georgia:[42.32,43.36],Germany:[51.17,10.45],Ghana:[7.95,-1.02],Greece:[39.07,21.82],Guatemala:[15.78,-90.23],Honduras:[15.2,-86.24],"Hong Kong":[22.32,114.17],Hungary:[47.16,19.5],Iceland:[64.96,-19.02],India:[20.59,78.96],Indonesia:[-.79,113.92],Iran:[32.43,53.69],Iraq:[33.22,43.68],Ireland:[53.41,-8.24],Israel:[31.05,34.85],Italy:[41.87,12.57],"Ivory Coast":[7.54,-5.55],Jamaica:[18.11,-77.3],Japan:[36.2,138.25],Jordan:[30.59,36.24],Kazakhstan:[48.02,66.92],Kenya:[-.02,37.91],Kuwait:[29.31,47.48],Kyrgyzstan:[41.2,74.77],Laos:[19.86,102.5],Latvia:[56.88,24.6],Lebanon:[33.85,35.86],Libya:[26.34,17.23],Liechtenstein:[47.17,9.56],Lithuania:[55.17,23.88],Luxembourg:[49.82,6.13],Madagascar:[-18.77,46.87],Malawi:[-13.25,34.3],Malaysia:[4.21,101.98],Maldives:[3.2,73.22],Mali:[17.57,-3.99],Malta:[35.94,14.38],Mauritius:[-20.35,57.55],Mexico:[23.63,-102.55],Moldova:[47.41,28.37],Monaco:[43.74,7.42],Mongolia:[46.86,103.85],Montenegro:[42.71,19.37],Morocco:[31.79,-7.09],Mozambique:[-18.67,35.53],"Myanmar (Burma)":[21.91,95.96],Namibia:[-22.96,18.49],Nepal:[28.39,84.12],Netherlands:[52.13,5.29],"New Zealand":[-40.9,174.89],Nicaragua:[12.87,-85.21],Niger:[17.61,8.08],Nigeria:[9.08,8.68],"North Macedonia":[41.61,21.75],Norway:[60.47,8.47],Oman:[21.51,55.92],Pakistan:[30.38,69.35],Panama:[8.54,-80.78],"Papua New Guinea":[-6.31,143.96],Paraguay:[-23.44,-58.44],Peru:[-9.19,-75.02],Philippines:[12.88,121.77],Poland:[51.92,19.15],Portugal:[39.4,-8.22],"Puerto Rico":[18.22,-66.59],Qatar:[25.35,51.18],Romania:[45.94,24.97],Russia:[61.52,105.32],Rwanda:[-1.94,29.87],"Saudi Arabia":[23.89,45.08],Senegal:[14.5,-14.45],Serbia:[44.02,21.01],Singapore:[1.35,103.82],Slovakia:[48.67,19.7],Slovenia:[46.15,14.99],"South Africa":[-30.56,22.94],"South Korea":[35.91,127.77],Spain:[40.46,-3.75],"Sri Lanka":[7.87,80.77],Sudan:[12.86,30.22],Sweden:[60.13,18.64],Switzerland:[46.82,8.23],Syria:[34.8,38.997],Taiwan:[23.7,120.96],Tajikistan:[38.86,71.28],Tanzania:[-6.37,34.89],Thailand:[15.87,100.99],"Trinidad and Tobago":[10.69,-61.22],Tunisia:[33.89,9.54],Turkey:[38.96,35.24],Turkmenistan:[38.97,59.56],Uganda:[1.37,32.29],Ukraine:[48.38,31.17],"United Arab Emirates":[23.42,53.85],"United Kingdom":[55.38,-3.44],"United States":[37.09,-95.71],Uruguay:[-32.52,-55.77],Uzbekistan:[41.38,64.59],Venezuela:[6.42,-66.59],Vietnam:[14.06,108.28],Yemen:[15.55,48.52],Zambia:[-13.13,27.85],Zimbabwe:[-19.02,29.15]},et=(0,Z.default)(()=>Promise.all([s.e(50950),s.e(89367),s.e(61831),s.e(89804),s.e(20594),s.e(19767)]).then(s.bind(s,21099)),{loadableGenerated:{webpack:()=>[21099]},ssr:!1});function es(e){let{rows:t,cities:s=[]}=e,n=(0,l.useRef)(void 0),r=(0,l.useRef)(null),[i,o]=(0,l.useState)({w:900,h:600});(0,l.useEffect)(()=>{let e=r.current;if(!e)return;let t=t=>{let s=n.current;if(!s)return;let a=e.getBoundingClientRect(),l=s.camera(),r=l.position.length();if(r<=100)return;let i=(l.fov??50)*Math.PI/180,o=a.height/2*(Math.tan(Math.asin(100/r))/Math.tan(i/2));if(Math.hypot(t.clientX-(a.left+a.width/2),t.clientY-(a.top+a.height/2))>o)return void t.stopPropagation();t.preventDefault(),t.stopPropagation();let d=s.pointOfView(),c=Math.exp(.0015*t.deltaY),x=Math.min(5,Math.max(.12,(d.altitude??2.5)*c));s.pointOfView({altitude:x},0)};return e.addEventListener("wheel",t,{passive:!1,capture:!0}),()=>e.removeEventListener("wheel",t,{capture:!0})},[]),(0,l.useEffect)(()=>{let e=r.current;if(!e)return;let t=0,s=new ResizeObserver(e=>{let[s]=e;if(!s)return;let a=Math.round(s.contentRect.width),l=Math.round(s.contentRect.height);cancelAnimationFrame(t),t=requestAnimationFrame(()=>o(e=>e.w===a&&e.h===l?e:{w:a,h:l}))});return s.observe(e),()=>{cancelAnimationFrame(t),s.disconnect()}},[]);let d=s.filter(e=>"number"==typeof e.lat&&"number"==typeof e.lng).map(e=>({label:e.label,lat:e.lat,lng:e.lng,activeUsers:e.activeUsers})),c=new Set(s.filter(e=>"number"==typeof e.lat).map(e=>
1e.country??"").filter(Boolean)),x=[...d,...t.map(e=>{let t=ee[e.label]??null;return!t||c.has(e.label)?null:{label:e.label,lat:t[0],lng:t[1],activeUsers:e.activeUsers}}).filter(e=>null!==e)],h=Math.max(1,...x.map(e=>e.activeUsers));return(0,a.jsx)("div",{ref:r,className:"h-full w-full",children:(0,a.jsx)("div",{style:{width:i.w,height:i.h},children:(0,a.jsx)(et,{ref:n,width:i.w,height:i.h,rendererConfig:{antialias:!0,alpha:!0},globeImageUrl:"/globe/earth-blue-marble.jpg",bumpImageUrl:"/globe/earth-topology.png",backgroundColor:"rgba(0,0,0,0)",showAtmosphere:!0,atmosphereColor:"#4f9dff",atmosphereAltitude:.18,htmlElementsData:x,htmlLat:"lat",htmlLng:"lng",htmlAltitude:.01,htmlElement:e=>{let t=9+Math.round(e.activeUsers/h*9),s=document.createElement("div");return s.className="bb-globe-pin",s.style.setProperty("--pin",`${t}px`),s.title=`${e.label} \xb7 ${e.activeUsers}`,s.innerHTML='<span class="bb-globe-pin-ring"></span><span class="bb-globe-pin-dot"></span>',s},onGlobeReady:()=>{var e,t;let s=null==(e=n.current)?void 0:e.renderer();if(s){if(s.capabilities.maxTextureSize>=16384){let e=new Image;e.src="/globe/earth-blue-marble-16k.jpg",e.onload=()=>{let t=n.current;if("function"!=typeof(null==t?void 0:t.globeMaterial))return;let a=t.globeMaterial(),l=null==a?void 0:a.map;l&&(l.image=e,l.anisotropy=s.capabilities.getMaxAnisotropy(),l.needsUpdate=!0)}}s.setPixelRatio(Math.min(window.devicePixelRatio||1,2));let e=n.current,t="function"==typeof(null==e?void 0:e.globeMaterial)?e.globeMaterial():void 0,a=null==t?void 0:t.map;a&&(a.anisotropy=s.capabilities.getMaxAnisotropy(),a.needsUpdate=!0)}let a=null==(t=n.current)?void 0:t.controls();a&&(a.autoRotate=!0,a.autoRotateSpeed=.6,a.enableZoom=!1,a.minDistance=120,a.maxDistance=600,a.zoomSpeed=.7,a.enablePan=!1,a.addEventListener("start",()=>{a.autoRotate=!1}))}})})})}function ea(e){let{rows:t,empty:s}=e;if(!t.length)return(0,a.jsx)(i.Sv,{text:s});let l=Math.max(...t.map(e=>e.activeUsers),1);return(0,a.jsx)("div",{className:"flex flex-col gap-4",children:t.map(e=>(0,a.jsxs)("div",{children:[(0,a.jsxs)("div",{className:"mb-1.5 flex items-center justify-between gap-3 text-[13px]",children:[(0,a.jsx)("span",{className:"min-w-0 flex-1 truncate text-[#374151] dark:text-slate-300",children:e.label}),(0,a.jsx)("span",{className:"shrink-0 font-semibold tabular-nums text-[#111827] dark:text-slate-100",children:(0,i.Sc)(e.activeUsers)})]}),(0,a.jsx)("div",{className:"h-[3px] w-full overflow-hidden rounded-full bg-[#f1f5f9] dark:bg-slate-800",children:(0,a.jsx)("div",{className:"h-full rounded-full bb-accent-bg transition-[width]",style:{width:`${Math.max(e.activeUsers/l*100,4)}%`}})})]},e.label))})}function el(e){let{pages:t}=e,s=t.filter(e=>e.path.startsWith("/portuguese-lessons")),l=t.filter(e=>{let t;return t=e.path,/^\/blog\/lesson-/.test(t)}),n=[...s,...l].reduce((e,t)=>e+t.views,0);if(!n)return(0,a.jsx)(i.Sv,{text:"No Portuguese page views in the last 24 hours."});let r=(e,t)=>t.length?(0,a.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,a.jsxs)("div",{className:"flex items-baseline justify-between gap-3",children:[(0,a.jsx)("span",{className:"text-[11px] font-bold uppercase tracking-wide text-[#94a3b8]",children:e}),(0,a.jsx)("span",{className:"text-[12px] font-semibold tabular-nums text-[#64748b] dark:text-slate-400",children:(0,i.Sc)(t.reduce((e,t)=>e+t.views,0))})]}),(0,a.jsx)(ea,{rows:t.map(e=>({label:e.path,activeUsers:e.views})),empty:""})]}):null;return(0,a.jsxs)("div",{className:"flex flex-col gap-6",children:[(0,a.jsxs)("div",{className:"flex items-end gap-2",children:[(0,a.jsx)("span",{className:"text-[28px] font-bold leading-none tabular-nums text-[#111827] dark:text-slate-100",children:(0,i.Sc)(n)}),(0,a.jsx)("span",{className:"pb-0.5 text-[12px] font-semibold text-[#64748b] dark:text-slate-400",children:"views"})]}),r("Mini lessons",l),r("Lesson pages",s)]})}function en(e){let{countries:t,cities:s,empty:l}=e,n=new Map;for(let e of s){let t=e.country??"";t&&n.set(t,[...n.get(t)??[],e])}let r=new Set(t.map(e=>e.label)),o=s.filter(e=>!e.country||!r.has(e.country)),d=[...t.map(e=>({label:e.label,activeUsers:e.activeUsers,cities:(n.get(e.label)??[]).sort((e,t)=>
1t.activeUsers-e.activeUsers)})),...o.map(e=>({label:e.label,activeUsers:e.activeUsers,cities:[]}))];if(!d.length)return(0,a.jsx)(i.Sv,{text:l});let c=Math.max(...d.map(e=>e.activeUsers),1);return(0,a.jsx)("div",{className:"flex flex-col gap-4",children:d.map(e=>(0,a.jsxs)("div",{children:[(0,a.jsxs)("div",{className:"mb-1.5 flex items-center justify-between gap-3 text-[13px]",children:[(0,a.jsx)("span",{className:"min-w-0 flex-1 truncate text-[#374151] dark:text-slate-300",children:e.label}),(0,a.jsx)("span",{className:"shrink-0 font-semibold tabular-nums text-[#111827] dark:text-slate-100",children:(0,i.Sc)(e.activeUsers)})]}),(0,a.jsx)("div",{className:"h-[3px] w-full overflow-hidden rounded-full bg-[#f1f5f9] dark:bg-slate-800",children:(0,a.jsx)("div",{className:"h-full rounded-full bb-accent-bg transition-[width]",style:{width:`${Math.max(e.activeUsers/c*100,4)}%`}})}),e.cities.length>0&&(0,a.jsx)("p",{className:"mt-1.5 truncate text-[11px] text-[#94a3b8]",children:e.cities.map(e=>e.activeUsers>1?`${e.label} (${e.activeUsers})`:e.label).join(" \xb7 ")})]},e.label))})}function er(e){var t,s;let{points:n}=e,[r,o]=(0,l.useState)(null);if(n.length<2)return(0,a.jsx)("p",{className:"text-[12px] text-[#94a3b8]",children:"Nothing to show yet."});let d=Math.max(1,...n.map(e=>e.activeUsers)),c=720/n.length,x=.6*c,h=(c-x)/2,p=n.map((e,t)=>{let s=e.activeUsers/d*140,a=t*c+h,l=150-s,n=Math.min(4,x/2,s),r=s<=0?"":`M${a},${l+n} Q${a},${l} ${a+n},${l} L${a+x-n},${l} Q${a+x},${l} ${a+x},${l+n} L${a+x},150 L${a},150 Z`;return{x:a,y:l,barW:x,path:r}});return(0,a.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,a.jsxs)("div",{className:"relative",children:[(0,a.jsxs)("svg",{viewBox:"0 0 720 160",preserveAspectRatio:"none",style:{height:160},className:"w-full",onMouseLeave:()=>o(null),children:[p.map((e,t)=>(0,a.jsx)("path",{d:e.path,fill:"var(--bb-accent)"},t)),n.map((e,t)=>(0,a.jsx)("rect",{x:t*c,y:0,width:c,height:160,fill:"transparent",onMouseEnter:()=>o(t)},t))]}),null!==r&&(0,a.jsxs)("span",{className:"pointer-events-none absolute -translate-x-1/2 -translate-y-full whitespace-nowrap rounded-[4px] bg-[#111827] px-1.5 py-0.5 text-[10px] font-semibold text-white dark:bg-slate-100 dark:text-slate-900",style:{left:`${(p[r].x+p[r].barW/2)/720*100}%`,top:`${p[r].y/160*100}%`},children:[n[r].hour," \xb7 ",(0,i.Sc)(n[r].activeUsers)]})]}),(0,a.jsxs)("div",{className:"flex items-center justify-between text-[10px] text-[#94a3b8]",children:[(0,a.jsx)("span",{children:null==(t=n[0])?void 0:t.hour}),(0,a.jsx)("span",{children:null==(s=n[n.length-1])?void 0:s.hour})]})]})}function ei(e){let{adminHeaders:t}=e,[s,n]=(0,l.useState)(null),[r,o]=(0,l.useState)([]),[d,c]=(0,l.useState)([]),[x,h]=(0,l.useState)([]),[p,u]=(0,l.useState)("now"),g=(0,l.useRef)(null),[m,f]=(0,l.useState)({left:0,top:0});(0,l.useEffect)(()=>{let e=()=>{var e;let t=null==(e=g.current)?void 0:e.getBoundingClientRect();t&&f(e=>1>Math.abs(e.left-t.left)&&1>Math.abs(e.top-t.top)?e:{left:t.left,top:t.top})};return e(),window.addEventListener("resize",e),()=>window.removeEventListener("resize",e)});let[b,v]=(0,l.useState)(!0),[j,k]=(0,l.useState)(null),[w,y]=(0,l.useState)(!0),[N,S]=(0,l.useState)(null);if((0,l.useEffect)(()=>{let e=!0,s=async()=>{try{let s=await fetch("/api/admin/workspace-v2/seo/live",{headers:t,cache:"no-store"}),a=await s.json();if(!e)return;s.ok?a.rateLimited?k(a.message||"Google Analytics is rate limiting us."):(k(null),v(null!==a.live),n(a.live),S(new Date)):k((null==a?void 0:a.error)||"Could not load")}catch(t){e&&k(t instanceof Error?t.message:"Could not load")}finally{e&&y(!1)}};s();let a=setInterval(s,15e3);return()=>{e=!1,clearInterval(a)}},[]),(0,l.useEffect)(()=>{let e=!0,s=async()=>{try{let s=await fetch("/api/admin/workspace-v2/seo/live?hourly=1",{headers:t,cache:"no-store"}),a=await s.json();if(!e||!s.ok)return;o(a.hourly??[]),c(a.topPages??[]),h(a.cities24h??[])}catch{}};s();let a=setInterval(s,3e5);return()=>{e=!1,clearInterval(a)}},[]),w)return(0,a.jsx)("p",{className:"text-[12px] text-[#64748b] dark:text-slate-400",children:"Loading…"});if(!b)return(0,a.jsxs)("div",{children:[(0,a.jsx)("p",{className:"text-[13px] font-bold text-[#111827] dark:text-slate-100",children:"GA4 isn't connected on this server."}),(0,a.jsx)("p",{className:"mt-1.5 text-[12px] text-[#64748b] dark:text-slate-400",children:"Set GA4_PROPERTY_ID to see who's on the site right now."})]});let C="mb-4 text-[11px] font-bold uppercase tracking-wider text-[#64748b] dark:text-slate-500";return(0,a.jsxs)("div",{ref:g,className:"relative min-h-[calc(100vh-120px)]",children:[(0,a.jsx)("div",{className:"pointer-events-none absolute z-0",style:{left:0,top:0,width:`calc(100vw - ${m.left}px)`,height:"100vh"},children:(0,a.jsx)("div",{className:"pointer-events-auto h-full w-full",children:(0,a.jsx)(es,{rows:"now"===p?(null==s?void 0:s.byCountry)??[]:[],cities:"now"===p?(null==s?void 0:s.byCity)??[]:x})})}),(0,a.jsxs)("div",{className:"pointer-events-none relative z-10 mx-auto grid max-w-6xl grid-cols-1 items-start gap-x-12 gap-y-10 lg:grid-cols-[minmax(0,1fr)_minmax(320px,520px)_minmax(0,1fr)] lg:grid-rows-[auto_auto_auto_auto]",children:[(0,a.jsxs)("div",{className:"pointer-events-auto relative z-10 min-w-0 lg:col-start-1 lg:row-start-1 lg:self-start",children:[(0,a.jsxs)("div",{className:"flex items-center gap-2",children:[(0,a.jsxs)("span",{className:"relative flex h-2 w-2",children:[(0,a.jsx)("span",{className:"absolute inline-flex h-full w-full animate-ping rounded-full bb-accent-bg opacity-60"}),(0,a.jsx)("span",{className:"relative h-2 w-2 rounded-full bb-accent-bg"})]}),(0,a.jsx)("p",{className:"text-[11px] font-bold uppercase tracking-wider text-[#64748b] dark:text-slate-500",children:"On budgetbro.app right now"})]}),j?(0,a.jsx)("p",{className:"mt-2 text-[13px] text-red-600 dark:text-red-400",children:j}):(0,a.jsx)("p",{className:"mt-1 bg-gradient-to-br from-[#111827] to-[#111827]/70 bg-clip-text text-[80px] font-bold leading-none tracking-tight text-transparent dark:from-slate-100 dar
1k:to-slate-100/60",children:(0,i.Sc)((null==s?void 0:s.activeUsers)??0)}),(0,a.jsxs)("p",{className:"mt-3 text-[11px] text-[#94a3b8]",children:["Google Analytics realtime \xb7 updates every 15s",N?` \xb7 last ${N.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"})}`:""]}),(0,a.jsx)("p",{className:"mt-1 text-[11px] text-[#94a3b8]",children:"The headline count, the location list and the page list are three separate GA4 calls — GA4's own thresholding means they won't always add up to the same total. Not a bug."}),(0,a.jsx)("div",{className:"mt-6 flex items-center gap-1 rounded-full bg-[#f1f5f9] p-1 dark:bg-slate-800/80 w-fit",children:[{key:"now",label:"Now"},{key:"day",label:"Last 24h"}].map(e=>(0,a.jsx)("button",{onClick:()=>u(e.key),"aria-pressed":p===e.key,className:`rounded-full px-3 py-1 text-[11px] font-semibold transition ${p===e.key?"bb-accent-bg text-white":"text-[#64748b] hover:text-[#111827] dark:text-slate-400 dark:hover:text-slate-200"}`,children:e.label},e.key))}),"day"===p&&(0,a.jsx)("p",{className:"mt-2 text-[11px] text-[#94a3b8]",children:x.length?`${x.length} location${1===x.length?"":"s"} on the globe`:"No locations yet today."})]}),(0,a.jsx)("div",{className:"hidden lg:col-start-2 lg:row-start-1 lg:row-span-4 lg:block"}),(0,a.jsxs)("div",{className:"pointer-events-auto relative z-10 min-w-0 lg:col-start-3 lg:row-start-1 lg:self-start",children:[(0,a.jsx)("p",{className:C,children:"By location"}),(0,a.jsx)(en,{countries:(null==s?void 0:s.byCountry)??[],cities:(null==s?void 0:s.byCity)??[],empty:"No location data right now."})]}),(0,a.jsxs)("div",{className:"pointer-events-auto relative z-10 min-w-0 border-t border-[#eee] pt-8 dark:border-slate-800 lg:border-t-0 lg:col-start-1 lg:row-start-2 lg:self-start lg:pt-0",children:[(0,a.jsx)("p",{className:C,children:"By page"}),(0,a.jsx)(ea,{rows:(null==s?void 0:s.byPage)??[],empty:"No one's on a page right now."})]}),(0,a.jsxs)("div",{className:"pointer-events-auto relative z-10 min-w-0 border-t border-[#eee] pt-8 dark:border-slate-800 lg:border-t-0 lg:col-start-1 lg:row-start-3 lg:self-start lg:pt-0",children:[(0,a.jsx)("p",{className:C,children:"Most visited, last 24h"}),(0,a.jsx)(ea,{rows:d.slice(0,8).map(e=>({label:e.path,activeUsers:e.views})),empty:"No page views in the last 24 hours."})]}),(0,a.jsxs)("div",{className:"pointer-events-auto relative z-10 min-w-0 border-t border-[#eee] pt-8 dark:border-slate-800 lg:border-t-0 lg:col-start-1 lg:row-start-4 lg:self-start lg:pt-10",children:[(0,a.jsx)("p",{className:C,children:"Portuguese, last 24h"}),(0,a.jsx)(el,{pages:d})]}),(0,a.jsxs)("div",{className:"pointer-events-auto relative z-10 min-w-0 border-t border-[#eee] pt-8 dark:border-slate-800 lg:border-t-0 lg:col-start-3 lg:row-start-2 lg:self-start lg:pt-0",children:[(0,a.jsx)("p",{className:C,children:"Last 24 hours"}),(0,a.jsx)(er,{points:r})]})]})]})}function eo(e){var t;let{adminHeaders:s,view:o="dashboard",onOpenArticle:d,onGo:c}=e,x=(0,r.C6)(),{data:h,loading:p,error:g,reload:m}=(0,r.v_)("/api/admin/workspace-v2/seo",s),[f,b]=(0,l.useState)(null),[v,k]=(0,l.useState)(null),[w,S]=(0,l.useState)(null),[M,P]=(0,l.useState)(null);if("lessons"===o)return(0,a.jsx)(K,{adminHeaders:s});if("live"===o)return(0,a.jsx)(ei,{adminHeaders:s});async function A(e){b(e),k(null);try{let t=await fetch("/api/admin/workspace-v2/seo",{method:"POST",headers:{...s,"Content-Type":"application/json"},body:JSON.stringify({part:e})}),a=await t.json();k(t.ok?`Search Console: ${a.gsc}. Links: ${a.links}. Crawl: ${a.crawl}.`:(null==a?void 0:a.error)||"Refresh failed"),m()}catch(e){k(e instanceof Error?e.message:"Refresh failed")}finally{b(null)}}let E=(e,t)=>{let a={...w??(null==h?void 0:h.actionState)??{}};"open"===t?delete a[e]:a[e]={state:t,at:new Date().toISOString()},S(a),fetch("/api/admin/workspace-v2/seo",{method:"POST",headers:{...s,"Content-Type":"application/json"},body:JSON.stringify({action:e,state:t})})},G=h&&!h.at.gsc&&!h.at.links&&!h.at.crawl,O=h&&{...h,actions:h.actions??[],actionState:w??h.actionState??{}},B=async(e,t)=>{P({query:t,message:"Starting…",elapsed:0});let a=setInterval(()=>P(e=>!e||e.done||e.error?e:{...e,elapsed:e.elapsed+1}),1e3);try{let a=await fetch("/api/admin/workspace-v2/trends/write",{method:"POST",headers:{"Content-Type":"application/json",...s},body:JSON.stringify({query:t,title:e})});if(!a.body)throw Error("No response from the server");let l=a.body.getReader(),n=new TextDecoder,r="",i=null;for(;;){let{done:e,value:t}=await l.read();if(e)break;let s=(r+=n.decode(t,{stream:!0})).split("\n");for(let e of(r=s.pop()??"",s)){let t;if(e.trim()){try{t=JSON.parse(e)}catch{continue}if("failed"===t.step)throw Error(t.message);t.message&&P(e=>e&&{...e,message:t.message,elapsed:Number(t.elapsed??e.elapsed)}),"done"===t.step&&(i=t)}}}if(!(null==i?void 0:i.postId))throw Error("The draft was not created");let o=i.postId;P(t=>t&&{...t,done:`Draft ready: ${(null==i?void 0:i.title)??e}. It is in Articles as a draft.`}),d&&setTimeout(()=>d(o),1200)}catch(e){P(t=>t&&{...t,error:e instanceof Error?e.message:"Could not write that one"})}finally{clearInterval(a)}};return(0,a.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,a.jsxs)("div",{className:"flex items-center gap-3",children:[(0,a.jsx)("p",{className:"min-w-0 flex-1 truncate text-[11px] text-[#94a3b8]",children:g||v||(h?`Search Console ${u(h.at.gsc)} \xb7 links ${u(h.at.links)} \xb7 crawl ${u(h.at.crawl)} \xb7 Google index ${u(h.at.inspect??null)} \xb7 updates itself every night`:" ")}),(0,a.jsx)("button",{disabled:!!f,onClick:()=>void A("all"),className:`${n.lJ} ${n.h0} shrink-0 disabled:opacity-40`,children:f?"Refreshing… a minute or two":"Refresh n
1ow"})]}),h&&O?G?(0,a.jsxs)("div",{className:i.PE,children:[(0,a.jsx)("p",{className:"text-[13px] font-bold text-[#111827] dark:text-slate-100",children:"Nothing gathered yet."}),(0,a.jsxs)("p",{className:"mt-1.5 text-[12px] text-[#64748b] dark:text-slate-400",children:["Press Refresh now to pull Search Console, Bing links and a crawl of the site. After that it runs every night on its own.",!h.configured.gsc&&" Search Console is not connected on this server, so keywords will stay empty here."]})]}):"strength"===o?(0,a.jsx)(y,{data:O,onState:E}):"trust"===o?(0,a.jsx)(N,{data:O,onState:E}):"keywords"===o?(0,a.jsx)(C,{data:O,onWrite:B}):"pages"===o?(0,a.jsx)($,{data:O}):"opportunities"===o?(0,a.jsx)(T,{data:O,onWrite:B}):"links"===o?(0,a.jsx)(L,{data:O}):"indexing"===o?(0,a.jsx)(F,{data:O}):"results"===o?(0,a.jsx)(I,{adminHeaders:s,inspect:(null==(t=O.inspect)?void 0:t.pages)??null}):(0,a.jsx)(j,{data:O,dark:x,go:e=>null==c?void 0:c(e),onState:E}):p?(0,a.jsx)(i.mU,{n:4}):null,M&&(0,a.jsxs)(n.zD,{onClose:()=>(M.done||M.error)&&P(null),children:[(0,a.jsxs)("p",{className:"text-[15px] font-bold text-[#111827] dark:text-slate-100",children:['Writing a page for "',M.query,'"']}),M.error?(0,a.jsx)("p",{className:"text-[12px] text-red-600 dark:text-red-400",children:M.error}):M.done?(0,a.jsx)("p",{className:"text-[12px] text-[#374151] dark:text-slate-300",children:M.done}):(0,a.jsxs)("p",{className:"text-[12px] text-[#64748b] dark:text-slate-400",children:[M.message," ",(0,a.jsxs)("span",{className:"text-[#94a3b8]",children:[M.elapsed,"s"]})]}),(M.done||M.error)&&(0,a.jsx)("button",{onClick:()=>P(null),className:`${n.lJ} ${n.h0} self-start`,children:"Close"})]})]})}},72040:(e,t,s)=>{s.d(t,{C6:()=>n,HO:()=>r,v_:()=>l});var a=s(12115);function l(e,t){let s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e=>e,[l,n]=(0,a.useState)(null),[r,i]=(0,a.useState)(!!e),[o,d]=(0,a.useState)(null),c=(0,a.useCallback)(async()=>{if(e){i(!0),d(null);try{let a=await fetch(e,{headers:t,cache:"no-store"}),l=await a.json().catch(()=>null);if(!a.ok||l&&!1===l.success&&!1!==l.configured)throw Error((null==l?void 0:l.error)??`Request failed (${a.status})`);n(s(l))}catch(e){n(null),d(e instanceof Error?e.message:"Request failed")}finally{i(!1)}}},[e,t]);return(0,a.useEffect)(()=>{c()},[c]),{data:l,setData:n,loading:r,error:o,reload:c}}function n(){let[e,t]=(0,a.useState)(!1);return(0,a.useEffect)(()=>{let e=document.documentElement,s=()=>t(e.classList.contains("dark"));s();let a=new MutationObserver(s);return a.observe(e,{attributes:!0,attributeFilter:["class"]}),()=>a.disconnect()},[]),e}async function r(e,t,s,a){let l=await fetch(e,{method:s,headers:{...t,"Content-Type":"application/json"},body:void 0===a?void 0:JSON.stringify(a)}),n=await l.json().catch(()=>null);if(!l.ok||(null==n?void 0:n.success)===!1)throw Error((null==n?void 0:n.error)??`Request failed (${l.status})`);return n}}}]);

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.