PageSourceSearch

https://adpilot-489907.web.app/assets/index-B-bfC41A.js

js adpilot-489907.web.app collected 2026-10-03 12:15:37 UTC 10,490 bytes, 3 lines download raw bytes

1import{r,a as m,j as e}from"./index-tNhE6V5Q.js";import{M as E}from"./MetaAdPreview-BBGVzfzq.js";function P(n){if(n==null)return"—";try{return`₹${Number(n).toLocaleString("en-IN",{maximumFractionDigits:0})}`}catch{return`₹${n}`}}function $(n){if(!n)return"—";try{const p=new Date(n).getTime(),a=Date.now()-p,c=a/36e5;return c<1?`${Math.round(a/6e4)}m ago`:c<48?`${Math.round(c)}h ago`:`${Math.round(c/24)}d ago`}catch{return n}}function O(){const[n,p]=r.useState([]),[a,c]=r.useState(null),[S,j]=r.useState(!0),[b,u]=r.useState(!1),[g,y]=r.useState(""),[v,o]=r.useState(null),[h,N]=r.useState(null),[k,w]=r.useState(null),[C,f]=r.useState(null),x=r.useCallback(async()=>{j(!0);try{const t=await m.get("/v1/campaign-approval/pending");p(t.drafts||[])}finally{j(!1)}},[]),_=r.useCallback(async()=>{try{await m.get("/v1/meta/probe"),N(!0)}catch{N(!1)}},[]),A=r.useCallback(async()=>{try{const t=await m.get("/v1/brand-kit");w(t)}catch{w(null)}},[]);r.useEffect(()=>{x(),_(),A()},[x,_,A]),r.useEffect(()=>{if(!a||!a.product_ids||a.product_ids.length===0){f(null);return}const t=a.product_ids[0];(async()=>{try{const l=((await m.get(`/v1/products/${t}`)).images||[])[0],i=typeof l=="string"?l:l?.src;f(i||null)}catch{f(null)}})()},[a]);const M=async t=>{if(window.confirm(`Approve this campaign and create it on Meta Ads (PAUSED)?
2
3You will need to activate it in Meta Ads Manager to start spending.`)){u(!0),o(null);try{const s=await m.post(`/v1/campaign-approval/approve/${t}`,{approved_by:"human"});s.published?o(`✓ Published to Meta (paused). Campaign ID: ${s.platform_campaign_id}`):o(`✗ Published failed: ${s.error||"unknown"}`),await x(),c(null)}catch(s){o(`Error: ${s instanceof Error?s.message:String(s)}`)}finally{u(!1)}}},R=async t=>{if(!g.trim()){alert("Please provide a rejection reason.");return}u(!0),o(null);try{await m.post(`/v1/campaign-approval/reject/${t}`,{rejected_by:"human",reason:g.trim()}),o("Draft rejected."),y(""),await x(),c(null)}catch(s){o(`Error: ${s instanceof Error?s.message:String(s)}`)}finally{u(!1)}};return e.jsxs("div",{className:"p-6 max-w-[1400px] mx-auto",children:[e.jsxs("header",{className:"mb-6",children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("h1",{className:"text-2xl font-semibold",children:"Pending Campaign Approvals"}),e.jsx("button",{onClick:x,className:"px-3 py-1.5 text-sm border border-gray-300 rounded hover:bg-gray-50",children:"Refresh"})]}),e.jsxs("p",{className:"text-sm text-gray-600 mb-3",children:["AdPilot generated these drafts. Each one publishes to Meta Ads as a ",e.jsx("strong",{children:"PAUSED"})," campaign on approval — you must activate it in Meta Ads Manager to start spending."]}),e.jsxs("div",{className:"text-xs",children:[e.jsx("span",{className:"text-gray-500",children:"Meta Ads connectivity: "}),h===null?e.jsx("span",{className:"text-gray-400",children:"checking…"}):h?e.jsx("span",{className:"text-green-600 font-medium",children:"✓ connected"}):e.jsx("span",{className:"text-red-600 font-medium",children:"✗ token / ad-account misconfigured — approvals will fail"})]})]}),v&&e.jsx("div",{className:"mb-4 px-4 py-2 bg-blue-50 border border-blue-200 rounded text-sm",children:v}),S?e.jsx("div",{className:"text-gray-400 text-sm",children:"Loading drafts…"}):n.length===0?e.jsx("div",{className:"text-gray-500 text-sm border border-dashed border-gray-300 rounded p-10 text-center",children:"No drafts awaiting approval. When AdPilot generates a campaign, it will appear here."}):e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-4",children:[e.jsx("div",{className:"space-y-2",children:n.map(t=>e.jsxs("button",{onClick:()=>c(t),className:`w-full text-left border rounded p-4 hover:border-blue-400 transition ${a?.id===t.id?"border-blue-500 bg-blue-50":"border-gray-200 bg-white"}`,children:[e.jsxs("div",{className:"flex items-start justify-between mb-1 gap-2",children:[e.jsx("div",{className:"font-medium text-sm truncate flex-1",children:t.name}),e.jsxs("div",{className:"flex items-center gap-1 flex-shrink-0",children:[(()=>{const s=t.platform_data?.claim_verification;if(!s)return null;const d=s.violations_high||0,l=s.violations_medium||0;return d>0?e.jsxs("span",{className:"text-xs px-2 py-0.5 bg-red-100 text-red-800 rounded",title:s.auditor_summary,children:["⚠ ",d," false claim",d>1?"s":""]}):l>0?e.jsxs("span",{className:"text-xs px-2 py-0.5 bg-amber-50 text-amber-700 rounded",title:s.auditor_summary,children:[l," warning",l>1?"s":""]}):e.jsx("span",{className:"text-xs px-2 py-0.5 bg-green-50 text-green-700 rounded",title:"All claims verified against product_intelligence",children:"✓ Verified"})})(),e.jsx("span",{className:"text-xs px-2 py-0.5 bg-amber-100 text-amber-800 rounded",children:"Pending"})]})]}),e.jsxs("div",{className:"text-xs text-gray-500 flex items-center gap-3",children:[e.jsx("span",{className:"capitalize",children:t.platform}),e.jsx("span",{children:"·"}),e.jsx("span",{children:t.campaign_type}),e.jsx("span",{children:"·"}),e.jsxs("span",{children:[P(t.daily_budget),"/day"]}),e.jsx("span",{children:"·"}),e.jsx("span",{children:$(t.created_at)})]})]},t.id))}),e.jsx("div",{children:a?e.jsxs("div",{className:"border border-gray-200 rounded p-5 bg-white",children:[e.jsx("div",{className:"flex items-start justify-between mb-3",children:e.jsxs("div",{children:[e.jsxs("div",{className:"text-xs text-gray-500 mb-1",children:["Draft ID: ",e.jsx("code",{className:"font-mono",children:a.id})]}),e.jsx("h2",{className:"text-lg font-semibold",children:a.name})]})}),e.jsxs("dl",{className:"grid grid-cols-2 gap-3 text-sm mb-4",children:[e.jsxs("div",{children:[e.jsx("dt",{className:"text-gray-500",children:"Platform"}),e.jsx("dd",{className:"capitalize",children:a.platform})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-gray-500",children:"Campaign type"}),e.jsx("dd",{children:a.campaign_type||"—"})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-gray-500",children:"Daily budget"}),e.jsx("dd",{className:"font-medium",children:P(a.daily_budget)})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-gray-500",children:"Action class"}),e.jsx("dd",{children:a.action_class||"—"})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-gray-500",children:"Products"}),e.jsx("dd",{children:(a.product_ids||[]).length})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-gray-500",children:"Created"}),e.jsx("dd",{children:$(a.created_at)})]})]}),(()=>{const t=a.platform_data?.claim_verification;if(!t)return e.jsx("div",{className:"mb-4 px-3 py-2 bg-gray-50 border border-gray-200 rounded text-xs text-gray-500",children:"ⓘ No claim verification ran on this draft (legacy or hand-crafted draft)."});const s=t.violations_high||0,d=t.violations_medium||0,l=s>0?"border-red-300 bg-red-50":d>0?"border-amber-300 bg-amber-50":"border-green-300 bg-green-50";return e.jsxs("div",{className:`mb-4 border ${l} rounded p-3`,children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("h3",{className:"text-sm font-semibold",children:s>0?`⚠ ${s} unsubstantiated claim${s>1?"s":""} caught`:d>0?`${d} warning${d>1?"s":""}`:"✓ All claims verified against product_intelligence"}),e.jsxs("span",{className:"text-xs text-gray-500",children:["audit method: ",t.method]})]}),t.auditor_summary&&e.jsx("p",{className:"text-xs text-gray-700 mb-2",children:t.auditor_summary}),(t.violations||[]).length>0&&e.jsx("div",{className:"space-y-2 mt-2",children:(t.violations||[]).slice(0,8).map((i,D)=>e.jsxs("div",{className:"text-xs bg-white border border-gray-200 rounded p-2",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[e.jsx("span",{className:`px-1.5 py-0.5 rounded text-[10px] font-medium ${i.severity==="high"?"bg-red-100 text-red-800":i.severity==="medium"?"bg-amber-100 text-amber-800":"bg-gray-100 text-gray-700"}`,children:(i.severity||"low").toUpperCase()}),e.jsx("span",{className:"text-gray-600",children:i.type})]}),e.jsxs("div",{children:[e.jsx("strong",{children:"Claimed:"})," ",e.jsx("code",{className:"text-red-700",children:i.claim})]}),i.fact&&e.jsxs("div",{className:"text-gray-600",children:[e.jsx("strong",{children:"Actual:"})," ",i.fact]}),i.reason&&e.jsx("div",{className:"text-gray-500 mt-1",children:i.reason}),i.suggested_fix&&e.jsxs("div",{className:"text-blue-700 mt-1",children:[e.jsx("strong",{children:"Fix:"})," ",i.suggested_fix]})]},D))})]})})(),e.jsxs("div",{className:"mb-4",children:[e.jsx("div",{className:"text-sm font-semibold mb-2",children:"What your customer will see"}
3),e.jsx(E,{draft:a.platform_data||{},brandKit:k,productImage:C})]}),a.platform_data&&e.jsxs("details",{className:"mb-4",children:[e.jsx("summary",{className:"text-xs text-gray-500 cursor-pointer hover:text-gray-700",children:"▸ View raw draft JSON (debug)"}),e.jsx("pre",{className:"mt-2 text-xs bg-gray-50 border border-gray-200 rounded p-3 overflow-auto max-h-64",children:JSON.stringify(a.platform_data,null,2)})]}),(()=>{const t=a.platform_data?.claim_verification,s=!!t&&(t.violations_high||0)>0;return e.jsxs("div",{className:"border-t border-gray-200 pt-4 space-y-3",children:[e.jsx("button",{onClick:()=>M(a.id),disabled:b||h===!1||s,className:"w-full px-4 py-2 bg-blue-600 text-white rounded font-medium disabled:opacity-50 disabled:cursor-not-allowed hover:bg-blue-700",children:b?"Publishing…":"✓ Approve & Publish to Meta (paused)"}),h===!1&&e.jsx("p",{className:"text-xs text-red-600",children:"Meta credentials not configured — fix /api/v1/meta/probe first."}),s&&e.jsx("p",{className:"text-xs text-red-600",children:"Blocked: this draft has unsubstantiated claims. Reject it with a reason, or wait for the next pipeline run to produce a corrected version."})]})})(),e.jsxs("div",{className:"border-t border-gray-100 pt-3 mt-3 space-y-2",children:[e.jsx("textarea",{value:g,onChange:t=>y(t.target.value),placeholder:"Rejection reason (required) — e.g. budget too high, wrong product, off-brand copy, false claims",rows:2,className:"w-full border border-gray-300 rounded px-3 py-2 text-sm"}),e.jsx("button",{onClick:()=>R(a.id),disabled:b||!g.trim(),className:"w-full px-4 py-2 border border-red-300 text-red-700 rounded text-sm disabled:opacity-50 hover:bg-red-50",children:"Reject draft"})]})]}):e.jsx("div",{className:"border border-dashed border-gray-300 rounded p-10 text-sm text-gray-400 text-center",children:"Select a draft to review"})})]})]})}export{O 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.