1import{e as C,a as L,r as l,s as n,j as e,B as x,m as d,A,L as y,S as I,ar as $}from"./index-Bpe3UPrl.js";import{P as E}from"./progress-CtjMNrnb.js";import{A as P}from"./AdminNav-BjH44lIk.js";import{A as q}from"./arrow-left-DtUzy-m0.js";import{C as k}from"./circle-check-big-DVy4B9CW.js";import{C as D}from"./circle-x-CvQMt4-D.js";import{I as R}from"./info-C9S8aj7I.js";import"./index-DT969Piu.js";import"./user-cog-4VgA4EMc.js";import"./trash-2-gJ8LxcYB.js";import"./book-open-B4EQwg6J.js";import"./receipt-CStKdnlA.js";import"./chevron-down-Gz4e3Y6q.js";const g="takeaway",V=()=>{const N=C(),{toast:m}=L(),[u,f]=l.useState(!0),[r,v]=l.useState({total:0,withTakeaways:0,withoutTakeaways:0}),[t,c]=l.useState(null),[j,w]=l.useState(!1),o=l.useCallback(async()=>{f(!0);const[{count:a},{count:i}]=await Promise.all([n.from("posts").select("*",{count:"exact",head:!0}),n.from("posts").select("*",{count:"exact",head:!0}).not("key_takeaways","is",null).neq("key_takeaways","")]),s=a||0,p=i||0;v({total:s,withTakeaways:p,withoutTakeaways:s-p}),f(!1)},[]),h=l.useCallback(async()=>{const{data:a}=await n.from("bulk_jobs").select("*").eq("job_type",g).in("status",["pending","processing"]).order("created_at",{ascending:!1}).limit(1);if(a&&a.length>0)c(a[0]);else{const{data:i}=await n.from("bulk_jobs").select("*").eq("job_type",g).eq("status","completed").order("created_at",{ascending:!1}).limit(1);if(i&&i.length>0){const s=i[0],p=new Date(s.completed_at||s.created_at);Date.now()-p.getTime()<36e5&&c(s)}}},[]);l.useEffect(()=>{o(),h()},[o,h]),l.useEffect(()=>{if(!t||t.status==="completed")return;const a=n.channel(`job-${t.id}`).on("postgres_changes",{event:"UPDATE",schema:"public",table:"bulk_jobs",filter:`id=eq.${t.id}`},i=>{const s=i.new;c(s),s.status==="completed"&&(m({title:"Generation complete",description:`${s.succeeded} succeeded, ${s.failed} failed.`}),o())}).subscribe();return()=>{n.removeChannel(a)}},[t==null?void 0:t.id,t==null?void 0:t.status,m,o]);const S=async()=>{t&&(await n.from("bulk_jobs").update({status:"completed",completed_at:new Date().toISOString(),updated_at:new Date().toISOString()}).eq("id",t.id),c(null),o(),m({title:"Job cancelled"}))},T=async()=>{w(!0);try{const{data:{user:a}}=await n.auth.getUser();if(!a)throw new Error("Not authenticated");const{data:i,error:s}=await n.from("bulk_jobs").insert({job_type:g,started_by:a.id,total:r.withoutTakeaways}).select().single();if(s)throw s;c(i),n.functions.invoke("bulk-generate-takeaways",{body:{jobId:i.id}}).catch(console.error),m({title:"Generation started",description:"Running in background. You can navigate away safely."})}catch(a){m({variant:"destructive",title:"Error",description:a.message})}finally{w(!1)}},_=t&&t.total>0?t.processed/t.total*100:0,b=(a,i)=>i>0?Math.round(a/i*100):0;return e.jsxs("div",{className:"min-h-screen bg-background",children:[e.jsx(P,{}),e.jsx("main",{className:"md:ml-52 p-6 md:p-8",children:e.jsxs("div",{className:"max-w-2xl mx-auto space-y-5",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(x,{variant:"ghost",size:"icon",onClick:()=>N("/admin/posts"),className:"shrink-0",children:e.jsx(q,{className:"h-4 w-4"})}),e.jsxs("div",{children:[e.jsx("h1",{className:"font-serif text-2xl font-bold tracking-tight",children:"Bulk Key Takeaways"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"AI-generate takeaways for posts missing them"})]})]}),e.jsx(d.div,{initial:{opacity:0,y:8},animate:{opacity:1,y:0},className:"grid grid-cols-3 gap-3",children:[{label:"Total",value:r.total,color:"text-foreground"},{label:"Done",value:r.withTakeaways,color:"text-green-600 dark:text-green-400"},{label:"Remaining",value:r.withoutTakeaways,color:"text-amber-600 dark:text-amber-400"}].map(a=>e.jsxs("div",{className:"rounded-xl border border-border bg-card p-3 text-center",children:[u?e.jsx("div",{className:"h-7 w-16 mx-auto rounded bg-muted animate-pulse"}):e.jsx("div",{className:`text-xl font-bold tabular-nums ${a.color}`,children:a.value.toLocaleString()}),e.jsx("div",{className:"text-[11px] text-muted-foreground mt-0.5",children:a.label})]},a.label))}),!u&&r.total>0&&e.jsxs("div",{className:"h-2 rounded-full bg-muted overflow-hidden flex",children:[e.jsx(d.div,{className:"bg-green-500 dark:bg-green-400",initial:{width:0},animate:{width:`${b(r.withTakeaways,r.total)}%`},transition:{duration:.8,ease:"easeOut"}}),e.jsx(d.div,{className:"bg-amber-400 dark:bg-amber-500",initial:{width:0},animate:{width:`${b(r.withoutTakeaways,r.total)}%`},transition:{duration:.8,ease:"easeOut",delay:.1}})]}),e.jsx(A,{mode:"wait",children:t&&t.status!=="completed"?e.jsxs(d.div,{initial:{opacity:0,scale:.98}
1,animate:{opacity:1,scale:1},exit:{opacity:0,scale:.98},className:"rounded-xl border border-border bg-card p-4 space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(y,{className:"h-4 w-4 animate-spin text-primary"}),e.jsx("span",{className:"text-sm font-medium",children:"Processingâ¦"})]}),e.jsxs("span",{className:"text-xs tabular-nums text-muted-foreground",children:[t.processed.toLocaleString()," / ",t.total.toLocaleString()]})]}),e.jsx(E,{value:_,className:"h-1.5"}),e.jsxs("div",{className:"flex gap-4 text-xs text-muted-foreground",children:[e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(k,{className:"h-3 w-3 text-green-500"}),t.succeeded.toLocaleString()," ok"]}),t.failed>0&&e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(D,{className:"h-3 w-3 text-red-500"}),t.failed.toLocaleString()," failed"]})]}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("p",{className:"text-[11px] text-muted-foreground/70",children:"Runs in background â you can navigate away safely."}),e.jsx(x,{variant:"ghost",size:"sm",className:"h-6 text-[11px] text-destructive",onClick:S,children:"Cancel"})]})]},"active"):t&&t.status==="completed"?e.jsxs(d.div,{initial:{opacity:0,scale:.98},animate:{opacity:1,scale:1},exit:{opacity:0,scale:.98},className:"rounded-xl border border-green-200 dark:border-green-800 bg-green-50 dark:bg-green-950/20 p-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(k,{className:"h-4 w-4 text-green-600"}),e.jsx("span",{className:"text-sm font-medium text-green-700 dark:text-green-400",children:"Last run completed"})]}),e.jsx(x,{variant:"ghost",size:"sm",className:"h-7 text-xs",onClick:()=>{c(null),o()},children:"Dismiss"})]}),e.jsxs("div",{className:"flex gap-4 mt-2 text-xs text-muted-foreground",children:[e.jsxs("span",{children:[t.succeeded.toLocaleString()," succeeded"]}),t.failed>0&&e.jsxs("span",{children:[t.failed.toLocaleString()," failed"]}),e.jsxs("span",{children:[t.total.toLocaleString()," total"]})]})]},"completed"):null}),(!t||t.status==="completed")&&e.jsx(d.div,{initial:{opacity:0}
1,animate:{opacity:1},transition:{delay:.2},children:e.jsxs(x,{onClick:T,className:"w-full h-11 gap-2",disabled:r.withoutTakeaways===0||j||u,children:[j?e.jsx(y,{className:"h-4 w-4 animate-spin"}):e.jsx(I,{className:"h-4 w-4"}),r.withoutTakeaways===0?"All posts have takeaways":`Generate for ${r.withoutTakeaways.toLocaleString()} posts`]})}),e.jsxs("div",{className:"flex gap-2 rounded-lg border border-border bg-muted/30 p-3 text-xs text-muted-foreground",children:[e.jsx(R,{className:"h-3.5 w-3.5 shrink-0 mt-0.5"}),e.jsxs("div",{className:"space-y-0.5",children:[e.jsx("p",{children:"Uses AI credits per post · Processes sequentially to avoid rate limits"}),e.jsx("p",{children:"Review & edit takeaways in the post editor"})]})]}),e.jsx("div",{className:"flex justify-center",children:e.jsxs(x,{variant:"ghost",size:"sm",className:"text-xs gap-1.5",onClick:()=>{o(),h()},disabled:u,children:[e.jsx($,{className:`h-3 w-3 ${u?"animate-spin":""}`}),"Refresh"]})})]})})]})};export{V 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.