1import{bR as A,r as i,cW as D,j as e,S as z,cX as M,V as j,B as N,R as w,ac as $}from"./index-CYggsFjq.js";const O=[{value:7,label:"Last 7 days"},{value:14,label:"Last 14 days"},{value:30,label:"Last 30 days"},{value:90,label:"Last 90 days"}],y=[{value:"desktop",label:"Desktop",width:1280},{value:"tablet",label:"Tablet",width:820},{value:"mobile",label:"Mobile",width:390}],W=()=>{var v;const{toast:k}=A(),[b,S]=i.useState([]),[E,p]=i.useState(!0),[c,_]=i.useState(14),[m,P]=i.useState(null),[u,L]=i.useState("desktop"),[C,g]=i.useState(0),f=async s=>{p(!0);const r=new Date(Date.now()-s*864e5).toISOString(),{data:a,error:n}=await $.from("app_logs").select("id, created_at, level, category, event, source_page, error, context").eq("level","error").gte("created_at",r).order("created_at",{ascending:!1}).limit(1e3);n?k({title:"Could not load errors",description:n.message,variant:"destructive"}):S(a||[]),p(!1)};i.useEffect(()=>{f(c)},[c]);const d=i.useMemo(()=>{const s=new Map;for(const r of b){if(D(r))continue;const a=(r.source_page||"").trim()||"(unknown page)",n=s.get(a);n?n.push(r):s.set(a,[r])}return Array.from(s.entries()).map(([r,a])=>{const n=new Map;for(const o of a){const l=(o.error||o.event||"Unknown error").slice(0,300),x=n.get(l);x?(x.count+=1,o.created_at>x.lastSeen&&(x.lastSeen=o.created_at)):n.set(l,{count:1,lastSeen:o.created_at})}return{page:r,count:a.length,lastSeen:a.reduce((o,l)=>l.created_at>o?l.created_at:o,a[0].created_at),errors:Array.from(n.entries()).map(([o,l])=>({message:o,...l})).sort((o,l)=>l.count-o.count)}}).sort((r,a)=>a.count-r.count||a.lastSeen.localeCompare(r.lastSeen))},[b]),t=m&&d.some(s=>s.page===m)?d.find(s=>s.page===m):d[0]??null,h=!!t&&t.page.startsWith("/"),R=y.find(s=>s.value===u).width;return e.jsxs(e.Fragment,{children:[e.jsx(z,{title:"Error Pages",description:"Pages that failed for visitors.",noIndex:!0}),e.jsxs("div",{className:"mx-auto max-w-[1400px] px-4 py-10",children:[e.jsxs("section",{className:"mb-10",children:[e.jsx("h1",{className:"font-heading text-2xl font-bold text-primary",children:"Error screens"}),e.jsx("p",{className:"mt-1 font-body text-sm text-muted-foreground",children:"Exactly what a visitor sees when something goes wrong. The buttons here are inactive on purpose."}),e.jsxs("div",{className:"mt-4 grid gap-6 lg:grid-cols-2",children:[e.jsxs("div",{className:"rounded-md border border-border bg-card",children:[e.jsxs("div",{className:"border-b border-border px-4 py-3",children:[e.jsx("div",{className:"font-body text-sm font-semibold text-foreground",children:"A page failed to load"}),e.jsx("div",{className:"font-body text-xs text-muted-foreground",children:"Shown when a page cannot be rendered, instead of a blank screen."})]}),e.jsx("div",{className:"bg-background",children:e.jsx(M,{preview:!0})})]}),e.jsxs("div",{className:"rounded-md border border-border bg-card",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3 border-b border-border px-4 py-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"font-body text-sm font-semibold text-foreground",children:"Page not found (404)"}),e.jsx("div",{className:"font-body text-xs text-muted-foreground",children:"Shown when a visitor opens an address that does not exist."})]}),e.jsxs("a",{href:"/this-address-does-not-exist",target:"_blank",rel:"noopener noreferrer",className:"inline-flex h-9 items-center gap-2 rounded-md border border-input px-3 font-body text-sm text-foreground no-underline transition-colors hover:bg-muted",children:[e.jsx(j,{size:14})," Open full page"]})]}),e.jsx("iframe",{src:"/this-address-does-not-exist",title:"Preview of the page not found screen",className:"block h-[420px] w-full bg-background"})]})]})]}),e.jsxs("div",{className:"mb-6 flex flex-wrap items-center justify-between gap-3 border-t border-border pt-8",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"font-heading text-xl font-bold text-primary",children:"Pages that failed for visitors"}),e.jsx("p",{className:"font-body text-sm text-muted-foreground",children:"Where these screens actually appeared, with a live preview of the page. Known browser and delivery noise is left out."})]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsx("select",{value:c,onChange:s=>_(Number(s.target.value)),className:"h-10 rounded-md border border-input bg-background px-3 text-sm","aria-label":"Time range",children:O.map(s=>e.jsx("option",{value:s.value,children:s.label},s.value))}),e.jsxs(N,{variant:"outline",className:"rounded-md",onClick:()=>void f(c),children:[e.jsx(w,{size:16,className:"mr-2"})," Refresh"]})]})]}),e.jsx("div",{className:"mb-6 grid grid-cols-2 gap-3 md:grid-cols-3",children:[{label:"Pages affected",value:d.length},{label:"Errors in range",value:d.reduce((s,r)=>s+r.count,0)},{label:"Most affected page",value:((v=d[0])==null?void 0:v.page)??"â",small:!0}].map(s=>e.jsxs("div",{className:"rounded-md border border-border bg-card p-4",children:[e.jsx("div",{className:s.small?"truncate font-body text-sm font-semibold text-primary":"font-heading text-2xl font-bold text-primary",children:s.value}),e.jsx("div",{className:"mt-1 font-body text-xs text-muted-foreground",children:s.label})]},s.label))}),E?e.jsx("p",{className:"text-muted-foreground",children:"Loadingâ¦"}):d.length===0?e.jsx("p",{className:"text-muted-foreground",children:"No page errors were recorded in this period. Nothing to fix."}):e.jsxs("div",{className:"grid gap-6 lg:grid-cols-[minmax(280px,380px)_minmax(0,1fr)]",children:[e.jsxs("div",{className:"rounded-md border border-border bg-card",children:[e.jsxs("div",{className:"border-b border-border px-4 py-3 font-body text-sm font-semibold text-foreground",children:["Affected pages (",d.length,")"]}),e.jsx("ul",{className:"max-h-[640px] divide-y divide-border overflow-y-auto",children:d.map(s=>{const r=(t==null?void 0:t.page)===s.page;return e.jsx("li",{children:e.jsxs("button",{type:"button",onClick:()=>{P(s.page),g(a=>a+1)},"aria-current":r,className:`flex w-full items-start justify-between gap-3 px-4 py-3 text-left transition-colors ${r?"bg-primary/10":"hover:bg-muted"}`,children:[e.jsxs("span",{className:"min-w-0",children:[e.jsx("span",{className:"block break-words font-body text-sm text-foreground",children:s.page}),e.jsxs("span",{className:"mt-0.5 block font-body text-xs text-muted-foreground",children:["last ",new Date(s.lastSeen).toLocaleStr
1ing()]})]}),e.jsx("span",{className:"shrink-0 rounded border border-destructive/30 bg-destructive/10 px-2 py-0.5 text-xs text-destructive",children:s.count})]})},s.page)})})]}),t&&e.jsxs("div",{className:"min-w-0 space-y-4",children:[e.jsxs("div",{className:"rounded-md border border-border bg-card",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3 border-b border-border px-4 py-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"break-words font-body text-sm font-semibold text-foreground",children:t.page}),e.jsxs("div",{className:"font-body text-xs text-muted-foreground",children:[t.count," error",t.count===1?"":"s"," in this period"]})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("select",{value:u,onChange:s=>L(s.target.value),className:"h-9 rounded-md border border-input bg-background px-2 text-sm","aria-label":"Preview size",children:y.map(s=>e.jsx("option",{value:s.value,children:s.label},s.value))}),e.jsxs(N,{variant:"outline",size:"sm",className:"rounded-md",onClick:()=>g(s=>s+1),children:[e.jsx(w,{size:14,className:"mr-2"})," Reload preview"]}),h&&e.jsxs("a",{href:t.page,target:"_blank",rel:"noopener noreferrer",className:"inline-flex h-9 items-center gap-2 rounded-md border border-input px-3 font-body text-sm text-foreground no-underline transition-colors hover:bg-muted",children:[e.jsx(j,{size:14})," Open page"]})]})]}),h?e.jsx("div",{className:"overflow-x-auto bg-muted/30 p-4",children:e.jsx("iframe",{src:t.page,title:`Preview of ${t.page}`,style:{width:R,height:620},className:"mx-auto block rounded-md border border-border bg-background",loading:"lazy"},`${t.page}-${u}-${C}`)}):e.jsx("p",{className:"px-4 py-6 font-body text-sm text-muted-foreground",children:"No page address was recorded for these errors, so there is nothing to preview."})]}),e.jsxs("div",{className:"rounded-md border border-border bg-card",children:[e.jsx("div",{className:"border-b border-border px-4 py-3 font-body text-sm font-semibold text-foreground",children:"Errors recorded on this page"}),e.jsx("ul",{className:"divide-y divide-border",children:t.errors.map(s=>e.jsxs("li",{className:"px-4 py-3",children:[e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsx("p",{className:"min-w-0 whitespace-pre-wrap break-words font-body text-sm text-destructive",children:s.message}),e.jsxs("span",{className:"shrink-0 rounded border border-border px-2 py-0.5 text-xs text-muted-foreground",children:[s.count,"x"]})]}),e.jsxs("p",{className:"mt-1 font-body text-xs text-muted-foreground",children:["last seen ",new Date(s.lastSeen).toLocaleString()]})]},s.message))})]})]})]})]})]})};export{W 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.