1import{r as a,j as e,a as k,x as _,L,J as x,ar as f,as as b,at as g,au as N,av as n,ax as $,l as C}from"./index-f--GfbGy.js";import{A as R}from"./arrow-left-CibCCW_O.js";import{R as B}from"./refresh-ccw-BOU2uH4i.js";const E=["all","detected_white","detected_dark","fallback","timeout","aborted","load_error","exception"];function O(t){const c=t.startsWith("detected")?"bg-emerald-100 text-emerald-800":t==="fallback"?"bg-amber-100 text-amber-800":t==="timeout"?"bg-orange-100 text-orange-800":t==="aborted"?"bg-slate-100 text-slate-700":"bg-rose-100 text-rose-800";return e.jsx($,{className:`${c} font-mono text-[10px]`,children:t})}function D(t){return t==null?"â":t<1024?`${t} B`:t<1024*1024?`${(t/1024).toFixed(1)} KB`:`${(t/(1024*1024)).toFixed(2)} MB`}function M(){const[t,c]=a.useState([]),[o,m]=a.useState(!1),[l,w]=a.useState("all"),[d,y]=a.useState("168"),[u,h]=a.useState(null),[i,v]=a.useState(null),p=async()=>{m(!0),h(null);try{const s=new URLSearchParams({since_hours:d});l!=="all"&&s.set("outcome",l);const{data:r,error:j}=await C.functions.invoke(`sticker-detection-list?${s.toString()}`,{method:"GET"});if(j)throw j;c(r?.rows??[])}catch(s){h(s?.message??"Failed to load diagnostics")}finally{m(!1)}};a.useEffect(()=>{p()},[l,d]);const S=a.useMemo(()=>{const s={};for(const r of t)s[r.outcome]=(s[r.outcome]??0)+1;return s},[t]);return e.jsxs("div",{className:"container mx-auto py-8 max-w-7xl",children:[e.jsxs("div",{className:"flex items-center justify-between mb-6",children:[e.jsxs("div",{children:[e.jsxs(k,{to:"/admin/sticker-help",className:"text-sm text-muted-foreground hover:underline inline-flex items-center gap-1 mb-2",children:[e.jsx(R,{className:"w-3 h-3"})," Back to Sticker help"]}),e.jsx("h1",{className:"text-2xl font-semibold",children:"QR Detection Diagnostics"}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:"Per-upload log of QR slot detection â duration, outcome, abort reason, and failure code."})]}),e.jsxs(_,{variant:"outline",size:"sm",onClick:()=>{p()},disabled:o,children:[o?e.jsx(L,{className:"w-4 h-4 me-2 animate-spin"}):e.jsx(B,{className:"w-4 h-4 me-2"}),"Refresh"]})]}),e.jsxs(x,{className:"p-4 mb-4 flex flex-wrap items-end gap-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"text-xs font-medium text-muted-foreground block mb-1",children:"Outcome"}),e.jsxs(f,{value:l,onValueChange:w,children:[e.jsx(b,{className:"w-48",children:e.jsx(g,{})}),e.jsx(N,{children:E.map(s=>e.jsx(n,{value:s,children:s},s))})]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"text-xs font-medium text-muted-foreground block mb-1",children:"Window"}),e.jsxs(f,{value:d,onValueChange:y,children:[e.jsx(b,{className:"w-48",children:e.jsx(g,{})}),e.jsxs(N,{children:[e.jsx(n,{value:"24",children:"Last 24 hours"}),e.jsx(n,{value:"168",children:"Last 7 days"}),e.jsx(n,{value:"720",children:"Last 30 days"})]})]})]}),e.jsxs("div",{className:"text-sm text-muted-foreground ms-auto",children:[t.length," rows · ",Object.entries(S).map(([s,r])=>`${s}:${r}`).join(" · ")]})]}),u&&e.jsx(x,{className:"p-4 mb-4 border-rose-200 bg-rose-50 text-rose-900 text-sm",children:u}),e.jsx(x,{className:"overflow-hidden",children:e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{className:"bg-surface-sunken",children:e.jsxs("tr",{className:"text-start text-xs uppercase text-muted-foreground",children:[e.jsx("th",{className:"px-3 py-2",children:"When"}),e.jsx("th",{className:"px-3 py-2",children:"Outcome"}),e.jsx("th",{className:"px-3 py-2",children:"Duration"}),e.jsx("th",{className:"px-3 py-2",children:"Image"}),e.jsx("th",{className:"px-3 py-2",children:"Filename"}),e.jsx("th",{className:"px-3 py-2",children:"Abort reason"}),e.jsx("th",{className:"px-3 py-2",children:"Failure code"}),e.jsx("th",{className:"px-3 py-2"})]})}),e.jsxs("tbody",{children:[t.map(s=>e.jsxs(e.Fragment,{children:[e.jsxs("tr",{className:"border-t border-border hover:bg-muted/30",children:[e.jsx("td",{className:"px-3 py-2 whitespace-nowrap font-mono text-xs",children:new Date(s.created_at).toLocaleStr
1ing()}),e.jsx("td",{className:"px-3 py-2",children:O(s.outcome)}),e.jsx("td",{className:"px-3 py-2 tabular-nums",children:s.duration_ms!=null?`${s.duration_ms} ms`:"â"}),e.jsxs("td",{className:"px-3 py-2 tabular-nums text-xs",children:[s.image_w&&s.image_h?`${s.image_w}Ã${s.image_h}`:"â",e.jsxs("span",{className:"text-muted-foreground",children:[" · ",D(s.artwork_bytes)]})]}),e.jsx("td",{className:"px-3 py-2 max-w-[220px] truncate text-xs",children:s.artwork_filename??"â"}),e.jsx("td",{className:"px-3 py-2 font-mono text-xs",children:s.abort_reason??"â"}),e.jsx("td",{className:"px-3 py-2 font-mono text-xs",children:s.failure_code??"â"}),e.jsx("td",{className:"px-3 py-2",children:e.jsx("button",{className:"text-xs underline text-muted-foreground",onClick:()=>v(i===s.id?null:s.id),children:i===s.id?"Hide":"Raw"})})]},s.id),i===s.id&&e.jsx("tr",{className:"bg-muted/20 border-t border-border",children:e.jsx("td",{colSpan:8,className:"px-3 py-3",children:e.jsx("pre",{className:"text-[11px] font-mono whitespace-pre-wrap break-all",children:JSON.stringify(s,null,2)})})})]})),t.length===0&&!o&&e.jsx("tr",{children:e.jsx("td",{colSpan:8,className:"px-3 py-12 text-center text-muted-foreground text-sm",children:"No detection diagnostics in this window."})})]})]})})})]})}export{M 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.