1import{r as x,j as e,N as H}from"./vendor-react-DgEia5Y0.js";import{d as z}from"./index-LTTGZaNt.js";import"./vendor-icons-J4_e8JZg.js";const O=()=>localStorage.getItem("auth_token"),_="",a=o=>`$${o.toFixed(2)}`,$=o=>`${o.toFixed(0)}%`,N=({label:o,value:m,sub:d,color:j})=>e.jsxs("div",{className:"bg-white rounded-xl shadow-sm border border-gray-100 p-5",children:[e.jsx("p",{className:"text-sm text-gray-500 mb-1",children:o}),e.jsx("p",{className:`text-2xl font-bold ${j||"text-gray-900"}`,children:m}),d&&e.jsx("p",{className:"text-xs text-gray-400 mt-1",children:d})]}),B=({label:o,value:m,max:d,color:j,detail:u})=>e.jsxs("div",{className:"mb-3",children:[e.jsxs("div",{className:"flex justify-between text-sm mb-1",children:[e.jsx("span",{className:"font-medium text-gray-700 truncate max-w-[60%]",children:o}),e.jsx("span",{className:"text-gray-500",children:u})]}),e.jsx("div",{className:"w-full bg-gray-100 rounded-full h-3",children:e.jsx("div",{className:`h-3 rounded-full ${j}`,style:{width:`${Math.max(2,m/d*100)}%`}})})]});function V(){var R,M,P,F,S,I;const{currentApiUser:o}=z(),m=O(),[d,j]=x.useState(7),[u,C]=x.useState(!0),[t,E]=x.useState(null),[l,U]=x.useState(null),[f,A]=x.useState(""),[i,J]=x.useState(null),v=x.useCallback(async()=>{if(m){C(!0),A("");try{const s={Authorization:`Bearer ${m}`,"Content-Type":"application/json"},[r,T,L]=await Promise.all([fetch(`${_}/api/v1/admin/api-costs/summary?days=${d}`,{headers:s}),fetch(`${_}/api/v1/admin/api-costs/arkroute?days=${d}`,{headers:s}),fetch(`${_}/api/v1/admin/keypool/status`,{headers:s})]);if(r.ok){const b=await r.json();E(b.data||b)}if(T.ok){const b=await T.json();U(b.data||b)}if(L.ok){const b=await L.json();J(b)}}catch(s){A(s.message||"Failed to load")}finally{C(!1)}}},[m,d]);if(x.useEffect(()=>{v()},[v]),!o||!o.is_admin)return e.jsx(H,{to:"/"});const c=((t==null?void 0:t.total_cost_usd)||0)+((l==null?void 0:l.total_cost_usd)||0),n=((t==null?void 0:t.total_revenue_usd)||0)+((l==null?void 0:l.total_revenue_usd)||0),h=((t==null?void 0:t.total_calls)||0)+((l==null?void 0:l.total_calls)||0),g=n>0?(n-c)/n*100:0,y=[...((l==null?void 0:l.by_model)||[]).map(s=>({...s,provider:s.provider||"ark"})),...((t==null?void 0:t.by_model)||[]).map(s=>({...s,provider:s.provider||"ff"}))].sort((s,r)=>r.cost-s.cost).slice(0,15),K=Math.max(...y.map(s=>s.cost),1),p={};for(const s of[...(l==null?void 0:l.daily_trend)||[],...(t==null?void 0:t.daily_trend)||[]]){const r=s.date||s.day||"";p[r]||(p[r]={cost:0,revenue:0,calls:0}),p[r].cost+=s.cost,p[r].revenue+=s.revenue,p[r].calls+=s.calls}const w=Object.entries(p).sort(([s],[r])=>s.localeCompare(r)),k=Math.max(...w.map(([,s])=>s.cost),1);return e.jsx("div",{className:"min-h-screen bg-gray-50 p-6",children:e.jsxs("div",{className:"max-w-7xl mx-auto",children:[e.jsxs("div",{className:"flex items-center justify-between mb-8",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-3xl font-bold text-gray-900",children:"ð API Cost Dashboard"}),e.jsx("p",{className:"text-gray-500 mt-1",children:"Real-time cost tracking across FashionFlow & ArkRoute"})]}),e.jsxs("div",{className:"flex gap-2",children:[[1,7,30].map(s=>e.jsx("button",{onClick:()=>j(s),className:`px-4 py-2 rounded-lg text-sm font-medium transition ${d===s?"bg-indigo-600 text-white shadow-md":"bg-white text-gray-600 hover:bg-gray-100 border"}`,children:s===1?"Today":s===7?"7 Days":"30 Days"},s)),e.jsx("button",{onClick:v,className:"px-4 py-2 rounded-lg text-sm font-medium bg-white text-gray-600 hover:bg-gray-100 border",children:"ð"})]})]}),f&&e.jsx("div",{className:"mb-6 p-4 bg-red-50 border border-red-200 rounded-lg text-red-700",children:f}),u?e.jsx("div",{className:"text-center py-20 text-gray-400",children:"Loading cost data..."}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-4 mb-8",children:[e.jsx(N,{label:"Total Cost",value:a(c),sub:`${d===1?"Today":`Last ${d} days`}`,color:c>10?"text-red-600":"text-gray-900"}),e.jsx(N,{label:"Total Revenue",value:a(n),sub:`${h} API calls`,color:"text-green-600"}),e.jsx(N,{label:"Margin",value:$(g),color:g>50?"text-green-600":g>0?"text-yellow-600":"text-red-600"}),e.jsx(N,{label:"Avg Cost/Call",value:h>0?a(c/h):"$0.00"})]}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-6 mb-8",children:[e.jsxs("div",{className:"bg-white rounded-xl shadow-sm border border-gray-100 p-6",children:[e.jsx("h3",{className:"text-lg font-semibold text-blue-600 mb-4",children:"ð· ArkRoute"}),e.jsxs("div",{className:"grid grid-cols-3 gap-3 mb-4",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-xs text-gray-400",children:"Cost"}),e.jsx("p",{className:"font-bold",children:a((l==null?void 0:l.total_cost_usd)||0)})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-xs text-gray-400",children:"Revenue"}),e.jsx("p",{className:"font-bold text-green-600",children:a((l==null?void 0:l.total_revenue_usd)||0)})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-xs text-gray-400",children:"Calls"}),e.jsx("p",{className:"font-bold",children:(l==null?void 0:l.total_calls)||0})]})]}),((l==null?void 0:l.by_provider)||[]).map(s=>e.jsxs("div",{className:"flex justify-between text-sm py-1 border-t",children:[e.jsx("span",{className:"text-gray-600",children:s.provider}),e.jsxs("span",{children:[s.calls," calls · ",a(s.cost)," · margin ",$(s.avg_margin||0)]})]},s.provider))]}),e.jsxs("div",{className:"bg-white rounded-xl shadow-sm border border-gray-100 p-6",children:[e.jsx("h3",{className:"text-lg font-semibold text-purple-600 mb-4",children:"ð£ FashionFlow"}),e.jsxs("div",{className:"grid grid-cols-3 gap-3 mb-4",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-xs text-gray-400",children:"Cost"}),e.jsx("p",{className:"font-bold",children:a((t==null?void 0:t.total_cost_usd)||0)})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-xs text-gray-400",children:"Revenue"}),e.jsx("p",{className:"font-bold text-green-600",children:a((t==null?void 0:t.total_revenue_usd)||0)})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-xs text-gray-400",children:"Calls"}),e.jsx("p",{className:"font-bold",children:(t==null?void 0:t.total_calls)||0})]})]}),(t==null?void 0:t.total_calls)===0&&e.jsx("p",{className:"text-sm text-gray-400 italic",children:"Cost tracking just enabled â data will appear as new API calls are made."}),((t==null?void 0:t.by_provider)||[]).map(s=>e.jsxs("div",{className:"flex justify-between text-sm py-1 border-t",children:[e.jsx("span",{className:"text-gray-600",children:s.provider}),e.jsxs("span",{children:[s.calls," calls · ",a(s.cost)]})]},s.provider))]})]}),e.jsxs("div",{className:"bg-white rounded-xl shadow-sm border border-gray-100 p-6 mb-8",children:[e.jsx("h3",{className:"text-lg font-semibold text-gray-900 mb-4",children:"ð° Cost by Model"}),y.length===0?e.jsx("p",{className:"text-gray-400 text-sm",children:"No data yet"}):y.map(s=>e.jsx(B,{label:s.model,value:s.cost,max:K,color:s.cost>5?"bg-red-500":s.cost>
11?"bg-yellow-500":"bg-blue-500",detail:`${s.calls} calls · ${a(s.cost)} · rev ${a(s.revenue)}`},`${s.model}-${s.provider}`))]}),e.jsxs("div",{className:"bg-white rounded-xl shadow-sm border border-gray-100 p-6 mb-8",children:[e.jsx("h3",{className:"text-lg font-semibold text-gray-900 mb-4",children:"ð Daily Trend"}),w.length===0?e.jsx("p",{className:"text-gray-400 text-sm",children:"No data yet"}):w.map(([s,r])=>e.jsx(B,{label:s,value:r.cost,max:k,color:r.cost>5?"bg-red-400":"bg-indigo-400",detail:`${r.calls} calls · cost ${a(r.cost)} · rev ${a(r.revenue)}`},s))]}),((t==null?void 0:t.top_users)||[]).length>0&&e.jsxs("div",{className:"bg-white rounded-xl shadow-sm border border-gray-100 p-6 mb-8",children:[e.jsx("h3",{className:"text-lg font-semibold text-gray-900 mb-4",children:"ð¤ Top Cost Users (FashionFlow)"}),e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"text-left text-gray-400 border-b",children:[e.jsx("th",{className:"pb-2",children:"User"}),e.jsx("th",{className:"pb-2",children:"Calls"}),e.jsx("th",{className:"pb-2",children:"Cost"}),e.jsx("th",{className:"pb-2",children:"Credits Used"})]})}),e.jsx("tbody",{children:((t==null?void 0:t.top_users)||[]).map(s=>e.jsxs("tr",{className:"border-b last:border-0",children:[e.jsx("td",{className:"py-2 font-medium",children:s.email||"Unknown"}),e.jsx("td",{className:"py-2",children:s.calls}),e.jsx("td",{className:"py-2",children:a(s.cost)}),e.jsx("td",{className:"py-2",children:s.credits})]},s.email))})]})]}),i&&e.jsxs("div",{className:"bg-white rounded-xl shadow-sm border border-gray-100 p-6 mb-8",children:[e.jsx("h3",{className:"text-lg font-semibold text-gray-900 mb-4",children:"ð Provider API Keys"}),e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-3 mb-4",children:[e.jsxs("div",{className:"bg-gray-50 rounded-lg p-3",children:[e.jsx("p",{className:"text-xs text-gray-400",children:"Active Keys"}),e.jsxs("p",{className:"text-xl font-bold",children:[(R=i.pool)==null?void 0:R.active_keys,"/",(M=i.pool)==null?void 0:M.total_keys]})]}),e.jsxs("div",{className:"bg-gray-50 rounded-lg p-3",children:[e.jsx("p",{className:"text-xs text-gray-400",children:"Credits Left"}),e.jsx("p",{className:"text-xl font-bold text-green-600",children:a(((P=i.pool)==null?void 0:P.credits_remaining)||0)})]}),e.jsxs("div",{className:"bg-gray-50 rounded-lg p-3",children:[e.jsx("p",{className:"text-xs text-gray-400",children:"24h Calls"}),e.jsx("p",{className:"text-xl font-bold",children:((F=i.pool)==null?void 0:F.daily_calls)||0})]}),e.jsxs("div",{className:"bg-gray-50 rounded-lg p-3",children:[e.jsx("p",{className:"text-xs text-gray-400",children:"Runway"}),e.jsx("p",{className:"text-xl font-bold",children:(S=i.pool)!=null&&S.runway_days?`${i.pool.runway_days}d`:"â"})]})]}),e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"text-left text-gray-400 border-b text-xs",children:[e.jsx("th",{className:"pb-2",children:"Provider"}),e.jsx("th",{className:"pb-2",children:"Label"}),e.jsx("th",{className:"pb-2",children:"Status"}),e.jsx("th",{className:"pb-2",children:"Credits"}),e.jsx("th",{className:"pb-2",children:"Calls"})]})}),e.jsx("tbody",{children:(i.keys||[]).map(s=>e.jsxs("tr",{className:"border-b last:border-0",children:[e.jsx("td",{className:"py-2 font-medium",children:s.provider}),e.jsx("td",{className:"py-2 text-gray-600 text-xs",children:s.label}),e.jsx("td",{className:"py-2",children:e.jsx("span",{className:`text-xs px-2 py-0.5 rounded-full ${s.status==="active"?"bg-green-100 text-green-700":"bg-red-100 text-red-700"}`,children:s.status})}),e.jsx("td",{className:"py-2",children:s.credits_remaining!=null?`${a(s.credits_remaining)}/${a(s.credits_total)}`:"N/A"}),e.jsx("td",{className:"py-2",children:s.total_calls})]},s.id))})]})]}),e.jsxs("div",{className:"bg-white rounded-xl shadow-sm border border-gray-100 p-6 mb-8",children:[e.jsx("h3",{className:"text-lg font-semibold text-gray-900 mb-4",children:"ð¼ Business Health"}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-4",children:[e.jsxs("div",{className:"bg-gray-50 rounded-lg p-4",children:[e.jsx("p",{className:"text-xs text-gray-400 mb-1",children:"Daily Burn Rate"}),e.jsxs("p",{className:"text-xl font-bold text-red-600",children:[d>0?a(c/d):"$0","/day"]}),e.jsxs("p",{className:"text-xs text-gray-400 mt-1",children:["Monthly projection: ",a(c/Math.max(d,1)*30)]})]}),e.jsxs("div",{className:"bg-gray-50 rounded-lg p-4",children:[e.jsx("p",{className:"text-xs text-gray-400 mb-1",children:"Revenue per API Call"}),e.jsx("p",{className:"text-xl font-bold text-green-600",children:h>0?a(n/h):"$0"}),e.jsxs("p",{className:"text-xs text-gray-400 mt-1",children:["Cost per call: ",h>0?a(c/h):"$0"]})]}),e.jsxs("div",{className:"bg-gray-50 rounded-lg p-4",children:[e.jsxs("p",{className:"text-xs text-gray-400 mb-1",children:["Net Profit (",d,"d)"]}),e.jsx("p",{className:`text-xl font-bold ${n-c>0?"text-green-600":"text-red-600"}`,children:a(n-c)}),e.jsxs("p",{className:"text-xs text-gray-400 mt-1",children:["Monthly projection: ",a((n-c)/Math.max(d,1)*30)]})]})]})]}),c>5&&e.jsxs("div",{className:"bg-red-50 border border-red-200 rounded-xl p-6",children:[e.jsx("h3",{className:"text-lg font-semibold text-red-700 mb-2",children:"â ï¸ Cost Alerts"}),e.jsxs("ul",{className:"text-sm text-red-600 space-y-1",children:[c>10&&e.jsxs("li",{children:["ð´ Combined cost ",a(c)," exceeds $10 threshold"]}),c>5&&c<=10&&e.jsxs("li",{children:["ð¡ Combined cost ",a(c)," exceeds $5 threshold"]}),g<0&&e.jsx("li",{children:"ð´ Negative margin! Losing money on API calls"}),g>0&&g<30&&e.jsxs("li",{children:["ð¡ Low margin (",$(g),") â consider raising prices"]}),y.some(s=>s.cost>5)&&e.jsxs("li",{children:["ð´ High-cost model detected: ",(I=y.find(s=>s.cost>5))==null?void 0:I.model]})]})]})]})]})})}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.