PageSourceSearch

https://knuckl.com/assets/AdminPushDeliveryLog-q1acm-V6.js

js knuckl.com collected 2026-10-02 01:36:58 UTC 7,455 bytes, 1 lines download raw bytes

1import{a,e as W,j as t}from"./vendor-query-CRhh6spR.js";import{I as d,B as C,A as z,ah as H,h as x,s as I}from"./index-BkVb42KZ.js";import{A as K}from"./AdminPage-BhQW-9r_.js";import{A as m}from"./AdminCard-FaakhOlA.js";import{A as Q,a as G}from"./AdminLoading-CBBcaphO.js";import{B as J}from"./badge-DfIFDYyU.js";import{S as f,a as v,b as j,c as g,d as y}from"./select-B5KGv1Do.js";import{S as X}from"./send-5x2Iukow.js";import{B as Y}from"./bell-CGtP-THa.js";import"./vendor-react-BAmwgVqg.js";import"./vendor-charts-BVeOEGzI.js";import"./vendor-stripe-2y4Jo9_W.js";import"./vendor-supabase-Csx7YFID.js";import"./index-D17hSi50.js";import"./index-Bmtd1gWP.js";import"./index-fVqgy0Om.js";import"./chevron-down-CXoJibNt.js";import"./check-BtcgJ1Z4.js";import"./chevron-up-DcqJwcAx.js";const Z=["all","sent","skipped","error","pruned","suppressed"],$=[{value:"1h",label:"Last hour",hours:1},{value:"24h",label:"Last 24h",hours:24},{value:"7d",label:"Last 7 days",hours:24*7},{value:"30d",label:"Last 30 days",hours:24*30}];function ee(n){return n==="sent"?"default":n==="error"?"destructive":"outline"}function ye(){const[n,B]=a.useState("all"),[c,F]=a.useState("24h"),[u,O]=a.useState("all"),[p,E]=a.useState(""),L=a.useMemo(()=>{var r;const e=((r=$.find(s=>s.value===c))==null?void 0:r.hours)??24;return new Date(Date.now()-e*3600*1e3).toISOString()},[c]),{data:i,isLoading:q,refetch:N,isFetching:S}=W({queryKey:["admin-push-log",n,c,u,p],refetchInterval:3e4,queryFn:async()=>{let e=I.from("push_delivery_log").select("id, user_id, notification_type, title, body_preview, platform, token_preview, status, reason, error, created_at").gte("created_at",L).order("created_at",{ascending:!1}).limit(500);if(n!=="all"&&(e=e.eq("status",n)),u!=="all"&&(e=e.eq("notification_type",u)),p.trim()){const o=p.trim();e=e.or(`title.ilike.%${o}%,body_preview.ilike.%${o}%,user_id.ilike.%${o}%,error.ilike.%${o}%`)}const{data:r,error:s}=await e;if(s)throw s;return r??[]}}),l=a.useMemo(()=>{var r;const e={total:0,sent:0,error:0,skipped:0,pruned:0,suppressed:0,retried:0};for(const s of i??[])e.total++,s.status==="sent"?e.sent++:s.status==="error"?e.error++:s.status==="skipped"?e.skipped++:s.status==="pruned"?e.pruned++:s.status==="suppressed"&&e.suppressed++,(r=s.reason)!=null&&r.startsWith("retried_")&&e.retried++;return e},[i]),D=a.useMemo(()=>{const e=new Set;for(const r of i??[])r.notification_type&&e.add(r.notification_type);return["all",...Array.from(e).sort()]},[i]),w=l.total>0?Math.round(l.sent/l.total*100):null,[h,P]=a.useState(""),[b,R]=a.useState("profile_tip"),[_,U]=a.useState("Test notification"),[T,M]=a.useState("Hello from the admin push tester."),[k,A]=a.useState(!1),V=async()=>{if(!h.trim()){x.error("Enter a user_id (uuid)");return}A(!0);try{const{data:e,error:r}=await I.functions.invoke("send-push",{body:{user_id:h.trim(),notification_type:b.trim()||void 0,title:_,body:T,data:{admin_test:!0}}});if(r)throw r;const s=(e==null?void 0:e.sent)??0,o=e==null?void 0:e.reason;x.success(s>0?`Delivered to ${s} device${s===1?"":"s"}`:`No push sent${o?` — ${o}`:""}`),N()}catch(e){x.error(e.message||"send-push failed")}finally{A(!1)}};return t.jsxs(K,{title:"Push delivery log",subtitle:"Every OneSignal / Median push attempt in the selected window.",actions:t.jsxs(C,{variant:"outline",size:"sm",onClick:()=>N(),disabled:S,children:[t.jsx(H,{className:`w-4 h-4 mr-1 ${S?"animate-spin":""}`}),"Refresh"]}),children:[t.jsxs(m,{className:"p-3",children:[t.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[t.jsx(X,{className:"w-4 h-4 text-muted-foreground"}),t.jsx("span",{className:"text-sm font-medium",children:"Send a test push"})]}),t.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-5 gap-2",children:[t.jsx(d,{placeholder:"User ID (uuid)",value:h,onChange:e=>P(e.target.value),className:"md:col-span-2 font-mono text-xs"}),t.jsx(d,{placeholder:"notification_type",value:b,onChange:e=>R(e.target.value)}),t.jsx(d,{placeholder:"Title",value:_,onChange:e=>U(e.target.value)}),t.jsxs("div",{className:"flex gap-2",children:[t.jsx(d,{placeholder:"Body",value:T,onChange:e=>M(e.target.value)}),t.jsx(C,{size:"sm",onClick:V,disabled:k,children:k?"Sending…":"Send"})]})]}),t.jsx("p",{className:"text-caption text-muted-foreground mt-2",children:"Uses the recipient's real preferences and quiet hours. Result is written to the delivery log below."})]}),t.jsx("div",{className:"grid grid-cols-2 md:grid-cols-6 gap-2",children:[{label:"Total",value:l.total},{label:"Sent",value:l.sent},{label:"Errors",value:l.error},{label:"Skipped",value:l.skipped},{label:"Pruned",value:l.pruned},{label:"Success",value:w==null?"—":`${w}%`}].map(e=>t.jsxs(m,{className:"p-3",children:[t.jsx("div",{className:"text-micro uppercase tracking-wider text-muted-foreground",children:e.label}),t.jsx("div",{className:"text-lg font-semibold text-foreground mt-0.5",children:e.value})]},e.label))}),l.retried>0&&t.jsxs("div",{className:"text-xs text-muted-foreground",children:[l.retried," delivery",l.retried===1?"":"s"," succeeded after a retry."]}),t.jsx(m,{className:"p-3",children:t.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-4 gap-2",children:[t.jsxs(f,{value:c,onValueChange:e=>F(e),children:[t.jsx(v,{children:t.jsx(j,{})}),t.jsx(g,{children:$.map(e=>t.jsx(y,{value:e.value,children:e.label},e.value))})]}),t.jsxs(f,{value:n,onValueChange:e=>B(e),children:[t.jsx(v,{children:t.jsx(j,{})}),t.jsx(g,{children:Z.map(e=>t.jsx(y,{value:e,children:e==="all"?"All statuses":e},e))})]}),t.jsxs(f,{value:u,onValueChange:O,children:[t.jsx(v,{children:t.jsx(j,{placeholder:"Notification type"})}),t.jsx(g,{children:D.map(e=>t.jsx(y,{value:e,children:e==="all"?"All types":e},e))})]}),t.jsx(d,{placeholder:"Search title, body, user, error…",value:p,onChange:e=>E(e.target.value)})]})}),q?t.jsx(Q,{rows:6}):i!=null&&i.length?t.jsx(m,{className:"overflow-hidden",children:t.jsx("div",{className:"overflow-x-auto",children:t.jsxs("table",{className:"w-full text-sm",children:[t.jsx("thead",{className:"bg-muted/40 text-xs uppercase text-muted-foreground",children:t.jsxs("tr",{children:[t.jsx("th",{className:"text-left px-3 py-2",children:"When"}),t.jsx("th",{className:"text-left px-3 py-2",children:"Status"}),t.jsx("th",{className:"text-left px-3 py-2",children:"Type"}),t.jsx("th",{className:"text-left px-3 py-2",children:"Title"}),t.jsx("th",{className:"text-left px-3 py-2",children:"User"}),t.jsx("th",{className:"text-left px-3 py-2",children:"Reason / Error"})]})}),t.jsx("tbody",{className:"divide-y divide-border",children:i.map(e=>t.jsxs("tr",{className:"text-xs align-top",children:[t.jsx("td",{className:"px-3 py-2 whitespace-nowrap text-muted-foreground",children:z(e.created_at)}),t.jsx("td",{className:"px-3 py-2",children:t.jsx(J,{variant:ee(e.status),children:e.status})}),t.jsx("td",{className:"px-3 py-2 whitespace-nowrap",children:e.notification_type??"—"}),t.jsxs("td",{className:"px-3 py-2 max-w-[260px]",children:[t.jsx("div",{className:"truncate font-medium",children:e.title??"—"}),e.body_preview&&t.jsx("div",{className:"truncate text-muted-foreground",children:e.body_preview})]}),t.jsx("td",{className:"px-3 py-2 font-mono text-micro text-muted-foreground",children:e.user_id.slice(0,8)}),t.jsx("td",{className:"px-3 py-2 text-muted-foreground max-w-[320px] truncate",children:e.error??e.reason??"—"})]},e.id))})]})})}):t.jsx(G,{Icon:Y,title:"No push deliveries in this window"})]})}
1export{ye 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.