PageSourceSearch

https://joylo.ai/assets/AdminCosts-Dxs1zY_P.js

js joylo.ai collected 2026-10-05 13:54:20 UTC 18,317 bytes, 2 lines download raw bytes

1import{r as a,R as A,j as e}from"./react-vendor-CqG5yQ2C.js";import{u as Q,y as X}from"./Landing-CdN20u6i.js";import{R as B,L as E,bG as O,a7 as C,bB as U,aY as W,bl as M,h as Z,ax as ee,b0 as te,W as se,bW as re,ae}from"./icons-vendor-DhLe6X_T.js";import"./radix-vendor-BhO3ERRl.js";import"./query-vendor-D5nP-1jG.js";const d=(s,p=4)=>s==null?"—":`$${s.toFixed(p)}`,b=s=>s?new Date(s).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"}):"—",z=()=>{const s=new Date;return s.setDate(s.getDate()-1),s.toISOString().split("T")[0]},xe=()=>{const s=X(),{toast:p}=Q(),[N,G]=a.useState("daily"),[H,S]=a.useState(!0),[D,P]=a.useState(!1),[j,I]=a.useState(30),[l,K]=a.useState(null),[V,F]=a.useState(!0),[L,T]=a.useState(!1),[y,Y]=a.useState(20),[f,R]=a.useState(z()),[g,$]=a.useState(z()),[o,q]=a.useState(null),v=a.useCallback(async(t=!1)=>{if(s){t?P(!0):S(!0);try{const r=await fetch(`https://api.joylo.ai/admin/costs/daily?days=${j}`,{headers:{Authorization:`Bearer ${s}`}});if(!r.ok)throw new Error("Failed to fetch daily costs");K(await r.json())}catch{p({variant:"destructive",title:"Error",description:"Failed to fetch daily costs"})}finally{S(!1),P(!1)}}},[s,j,p]),w=a.useCallback(async(t=!1)=>{if(s){t?T(!0):F(!0);try{const r=new URLSearchParams({limit:String(y)});f&&r.set("date_from",f),g&&r.set("date_to",g);const c=await fetch(`https://api.joylo.ai/admin/costs/projects?${r}`,{headers:{Authorization:`Bearer ${s}`}});if(!c.ok)throw new Error("Failed to fetch project costs");q(await c.json())}catch{p({variant:"destructive",title:"Error",description:"Failed to fetch project costs"})}finally{F(!1),T(!1)}}},[s,y,f,g,p]);a.useEffect(()=>{s&&v()},[v]),a.useEffect(()=>{s&&w()},[w]);const n=A.useMemo(()=>{const t=o==null?void 0:o.projects;if(!(t!=null&&t.length))return null;const r=t.reduce((m,u)=>m+u.total_cost_usd,0),c=t.reduce((m,u)=>m+u.active_days,0),_=c>0?r/c:0,k=t.slice(0,3).reduce((m,u)=>m+u.total_cost_usd,0),x=r>0?k/r*100:0,i=[...t].sort((m,u)=>u.total_cost_usd/u.active_days-m.total_cost_usd/m.active_days)[0];return{total:r,avgBurnRate:_,top3Pct:x,highestBurn:i}},[o]),h=A.useMemo(()=>{if(!(l!=null&&l.records.length))return null;const t=l.records,r=t.reduce((x,i)=>x+(i.total_cost??0),0),c=r/t.length,_=t.reduce((x,i)=>(i.total_cost??0)>(x.total_cost??0)?i:x),k=t.reduce((x,i)=>x+(i.active_projects_count??0),0)/t.length;return{totalCost:r,avgDaily:c,peak:_,avgProjects:Math.round(k)}},[l]),J=[{id:"daily",label:"Daily Breakdown",icon:e.jsx(M,{className:"w-4 h-4"})},{id:"projects",label:"Project Costs",icon:e.jsx(ae,{className:"w-4 h-4"})}];return e.jsxs("div",{className:"space-y-4 sm:space-y-6",children:[e.jsx("p",{className:"text-[13px] text-muted-foreground",children:"Daily AWS cost breakdown and per-project cost allocation"}),e.jsx("div",{className:"border-b border-line",children:e.jsx("div",{className:"flex space-x-1 overflow-x-auto",children:J.map(t=>e.jsxs("button",{onClick:()=>G(t.id),className:`flex items-center space-x-2 px-4 py-3 text-sm font-medium border-b-2 transition-colors whitespace-nowrap ${N===t.id?"border-plum text-plum":"border-transparent text-muted-foreground hover:text-foreground hover:border-plum/40"}`,children:[t.icon,e.jsx("span",{children:t.label})]},t.id))})}),N==="daily"&&e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsxs("select",{value:j,onChange:t=>I(Number(t.target.value)),className:"px-3 py-2 bg-surface border border-input rounded-[9px] text-foreground focus:border-plum/40 focus:outline-none text-sm",children:[e.jsx("option",{value:7,children:"Last 7 days"}),e.jsx("option",{value:30,children:"Last 30 days"}),e.jsx("option",{value:90,children:"Last 90 days"}),e.jsx("option",{value:180,children:"Last 180 days"}),e.jsx("option",{value:365,children:"Last 365 days"})]}),e.jsxs("button",{onClick:()=>v(!0),disabled:D,className:"flex items-center space-x-2 px-3 py-2 bg-soft hover:bg-selected border border-input rounded-lg text-foreground text-sm transition-colors disabled:opacity-50",children:[e.jsx(B,{className:`w-4 h-4 ${D?"animate-spin":""}`}),e.jsx("span",{children:"Refresh"})]})]}),H?e.jsx("div",{className:"flex items-center justify-center p-12",children:e.jsx(E,{className:"w-8 h-8 animate-spin text-plum"})}):e.jsxs(e.Fragment,{children:[h&&e.jsxs("div",{className:"grid grid-cols-2 lg:grid-cols-4 gap-4",children:[e.jsxs("div",{className:"bg-surface rounded-xl p-4 border border-line",children:[e.jsxs("div",{className:"flex items-center space-x-2 mb-2",children:[e.jsx(O,{className:"w-4 h-4 text-plum"}),e.jsx("span",{className:"text-muted-foreground text-xs",children:"Period Total"})]}),e.jsx("p",{className:"text-foreground text-xl font-bold",children:d(h.totalCost,2)}),e.jsxs("p",{className:"text-muted-foreground text-xs mt-1",children:[j," days"]})]}),e.jsxs("div",{className:"bg-surface rounded-xl p-4 border border-line",children:[e.jsxs("div",{className:"flex items-center space-x-2 mb-2",children:[e.jsx(C,{className:"w-4 h-4 text-plum"}),e.jsx("span",{className:"text-muted-foreground text-xs",children:"Avg Daily Cost"})]}),e.jsx("p",{className:"text-foreground text-xl font-bold",children:d(h.avgDaily,2)}),e.jsx("p",{className:"text-muted-foreground text-xs mt-1",children:"per day"})]}),e.jsxs("div",{className:"bg-surface rounded-xl p-4 border border-line",children:[e.jsxs("div",{className:"flex items-center space-x-2 mb-2",children:[e.jsx(U,{className:"w-4 h-4 text-warning"}),e.jsx("span",{className:"text-muted-foreground text-xs",children:"Peak Day"})]}),e.jsx("p",{className:"text-foreground text-xl font-bold",children:d(h.peak.total_cost,2)}),e.jsx("p",{className:"text-muted-foreground text-xs mt-1",children:b(h.peak.date)})]}),e.jsxs("div",{className:"bg-surface rounded-xl p-4 border border-line",children:[e.jsxs("div",{className:"flex items-center space-x-2 mb-2",children:[e.jsx(W,{className:"w-4 h-4 text-plum"}),e.jsx("span",{className:"text-muted-foreground text-xs",children:"Avg Active Projects"})]}),e.jsx("p",{className:"text-foreground text-xl font-bold",children:h.avgProjects}),e.jsx("p",{className:"text-muted-foreground text-xs mt-1",children:"per day"})]})]}),e.jsxs("div",{className:"bg-surface rounded-xl border border-line overflow-hidden",children:[e.jsxs("div",{className:"px-4 py-3 border-b border-line flex items-center space-x-2",children:[e.jsx(M,{className:"w-4 h-4 text-plum"}),e.jsx("span",{className:"text-foreground font-medium text-sm",children:"Daily Cost Records"}),l&&e.jsxs("span",{className:"ml-auto text-muted-foreground text-xs",children:[l.records.length," days"]})]}),e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{className:"bg-soft text-muted-foreground text-xs uppercase",children:e.jsxs("tr",{children:[e.jsx("th",{className:"px-4 py-3 text-left text-[11px] font-semibold uppercase tracking-[0.08em] text-muted-foreground",children:"Date"}),e.jsx("th",{className:"px-4 py-3 text-right hidden sm:table-cell text-[11px] font-semibold uppercase tracking-[0.08em] text-muted-foreground",children:e.jsxs("span",{className:"flex items-center justify-end gap-1",children:[e.jsx(Z,{className:"w-3 h-3"}),"EC2"]})}),e.jsx("th",{className:"px-4 py-3 text-right hidden md:table-cell text-[11px] font-semibold uppercase tracking-[0.08em] text-muted-foreground",children:e.jsxs("span",{className:"flex items-center justify-end gap-1",children:[e.jsx(ee,{className:"w-3 h-3"}),"RDS"]})}),e.jsx("th",{className:"px-4 py-3 text-right hidden lg:table-cell text-[11px] font-semibold uppercase tracking-[0.08em] text-muted-foreground",children:e.jsxs("span",{className:"flex items-center justify-end gap-1",children:[e.jsx(te,{className:"w-3 h-3"}),"EKS"]})}),e.jsx("th",{className:"px-4 py-3 text-right hidden lg:table-cell text-[11px] font-semibold uppercase tracking-[0.08em] text-muted-foreground",children:e.jsxs("span",{className:"flex items-center justify-end gap-1",children:[e.jsx(se,{className:"w-3 h-3"}),"ELB"]})}),e.jsx("th",{className:"px-4 py-3 text-right hidden xl:table-cell text-[11px] font-semibold uppercase tracking-[0.08em] text-muted-foreground",children:"CloudWatch"}),e.jsx("th",{className:"px-4 py-3 text-right hidden xl:table-cell text-[11px] font-semibold uppercase tracking-[0.08em] text-muted-foreground",children:"VPC"}),e.jsx("th",{className:"px-4 py-3 text-right hidden xl:table-cell text-[11px] font-semibold uppercase tracking-[0.08em] text-muted-foreground",children:"EC2 Other"}),e.jsx("th",{className:"px-4 py-3 text-right text-[11px] font-semibold uppercase tracking-[0.08em] text-muted-foreground",children:"Total"}),e.jsx("th",{className:"px-4 py-3 text-right hidden sm:table-cell text-[11px] font-semibold uppercase tracking-[0.08em] text-muted-foreground",children:"Projects"})]})}),e.jsxs("tbody",{className:"divide-y divide-line",children:[(l==null?void 0:l.records.length)===0&&e.jsx("tr",{children:e.jsx("td",{colSpan:10,className:"px-4 py-8 text-center text-muted-foreground",children:"No cost records foun
1d"})}),l==null?void 0:l.records.map(t=>e.jsxs("tr",{className:"hover:bg-soft transition-colors",children:[e.jsx("td",{className:"px-4 py-3 text-foreground font-medium whitespace-nowrap",children:b(t.date)}),e.jsx("td",{className:"px-4 py-3 text-right text-foreground hidden sm:table-cell font-mono text-xs",children:d(t.ec2_cost)}),e.jsx("td",{className:"px-4 py-3 text-right text-foreground hidden md:table-cell font-mono text-xs",children:d(t.rds_cost)}),e.jsx("td",{className:"px-4 py-3 text-right text-foreground hidden lg:table-cell font-mono text-xs",children:d(t.eks_cost)}),e.jsx("td",{className:"px-4 py-3 text-right text-foreground hidden lg:table-cell font-mono text-xs",children:d(t.elb_cost)}),e.jsx("td",{className:"px-4 py-3 text-right text-foreground hidden xl:table-cell font-mono text-xs",children:d(t.cloudwatch_cost)}),e.jsx("td",{className:"px-4 py-3 text-right text-foreground hidden xl:table-cell font-mono text-xs",children:d(t.vpc_cost)}),e.jsx("td",{className:"px-4 py-3 text-right text-foreground hidden xl:table-cell font-mono text-xs",children:d(t.ec2_other_cost)}),e.jsx("td",{className:"px-4 py-3 text-right font-mono text-xs",children:e.jsx("span",{className:"text-plum font-semibold",children:d(t.total_cost,2)})}),e.jsx("td",{className:"px-4 py-3 text-right text-muted-foreground hidden sm:table-cell text-xs",children:t.active_projects_count??"—"})]},t.date))]})]})})]})]})]}),N==="projects"&&e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"bg-surface rounded-xl border border-line p-4",children:[e.jsxs("div",{className:"flex items-center space-x-2 mb-3",children:[e.jsx(re,{className:"w-4 h-4 text-plum"}),e.jsx("span",{className:"text-foreground text-sm font-medium",children:"Filters"})]}),e.jsxs("div",{className:"flex flex-wrap items-end gap-3",children:[e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx("label",{className:"text-muted-foreground text-xs",children:"Limit"}),e.jsxs("select",{value:y,onChange:t=>Y(Number(t.target.value)),className:"px-3 py-2 bg-surface border border-input rounded-[9px] text-foreground focus:border-plum/40 focus:outline-none text-sm",children:[e.jsx("option",{value:10,children:"Top 10"}),e.jsx("option",{value:20,children:"Top 20"}),e.jsx("option",{value:50,children:"Top 50"}),e.jsx("option",{value:100,children:"Top 100"})]})]}),e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx("label",{className:"text-muted-foreground text-xs",children:"From date"}),e.jsx("input",{type:"date",value:f,onChange:t=>R(t.target.value),className:"px-3 py-2 bg-surface border border-input rounded-[9px] text-foreground focus:border-plum/40 focus:outline-none text-sm"})]}),e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx("label",{className:"text-muted-foreground text-xs",children:"To date"}),e.jsx("input",{type:"date",value:g,onChange:t=>$(t.target.value),className:"px-3 py-2 bg-surface border border-input rounded-[9px] text-foreground focus:border-plum/40 focus:outline-none text-sm"})]}),e.jsxs("button",{onClick:()=>w(!0),disabled:L,className:"flex items-center space-x-2 px-4 py-2 bg-gradient-sunset hover:opacity-90 rounded-lg text-white text-sm transition-colors disabled:opacity-50",children:[e.jsx(B,{className:`w-4 h-4 ${L?"animate-spin":""}`}),e.jsx("span",{children:"Apply"})]}),(f||g)&&e.jsx("button",{onClick:()=>{R(""),$("")},className:"px-3 py-2 bg-soft hover:bg-selected border border-input rounded-lg text-muted-foreground hover:text-foreground text-sm transition-colors",children:"Clear"})]})]}),V?e.jsx("div",{className:"flex items-center justify-center p-12",children:e.jsx(E,{className:"w-8 h-8 animate-spin text-plum"})}):e.jsxs(e.Fragment,{children:[n&&e.jsxs("div",{className:"grid grid-cols-2 lg:grid-cols-4 gap-4",children:[e.jsxs("div",{className:"bg-surface rounded-xl p-4 border border-line",children:[e.jsxs("div",{className:"flex items-center space-x-2 mb-2",children:[e.jsx(O,{className:"w-4 h-4 text-plum"}),e.jsx("span",{className:"text-muted-foreground text-xs",children:"Total Shown"})]}),e.jsxs("p",{className:"text-foreground text-xl font-bold",children:["$",n.total.toFixed(2)]}),e.jsxs("p",{className:"text-muted-foreground text-xs mt-1",children:[o.projects.length," projects"]})]}),e.jsxs("div",{className:"bg-surface rounded-xl p-4 border border-line",children:[e.jsxs("div",{className:"flex items-center space-x-2 mb-2",children:[e.jsx(C,{className:"w-4 h-4 text-plum"}),e.jsx("span",{className:"text-muted-foreground text-xs",children:"Avg Burn Rate"})]}),e.jsxs("p",{className:"text-foreground text-xl font-bold",children:["$",n.avgBurnRate.toFixed(4)]}),e.jsx("p",{className:"text-muted-foreground text-xs mt-1",children:"per active day"})]}),e.jsxs("div",{className:"bg-surface rounded-xl p-4 border border-line",children:[e.jsxs("div",{className:"flex items-center space-x-2 mb-2",children:[e.jsx(W,{className:"w-4 h-4 text-warning"}),e.jsx("span",{className:"text-muted-foreground text-xs",children:"Top 3 Concentration"})]}),e.jsxs("p",{className:"text-foreground text-xl font-bold",children:[n.top3Pct.toFixed(1),"%"]}),e.jsx("p",{className:"text-muted-foreground text-xs mt-1",children:"of total cost"})]}),e.jsxs("div",{className:"bg-surface rounded-xl p-4 border border-line",children:[e.jsxs("div",{className:"flex items-center space-x-2 mb-2",children:[e.jsx(U,{className:"w-4 h-4 text-danger"}),e.jsx("span",{className:"text-muted-foreground text-xs",children:"Highe
1st Burn Rate"})]}),e.jsxs("p",{className:"text-foreground text-xl font-bold",children:["$",(n.highestBurn.total_cost_usd/n.highestBurn.active_days).toFixed(4)]}),e.jsxs("p",{className:"text-muted-foreground text-xs mt-1 truncate",children:[n.highestBurn.project_name??n.highestBurn.project_id.slice(0,12)+"…","/day"]})]})]}),e.jsxs("div",{className:"bg-surface rounded-xl border border-line overflow-hidden",children:[e.jsxs("div",{className:"px-4 py-3 border-b border-line flex items-center space-x-2",children:[e.jsx(C,{className:"w-4 h-4 text-plum"}),e.jsx("span",{className:"text-foreground font-medium text-sm",children:"Project Cost Breakdown"}),o&&e.jsxs("span",{className:"ml-auto text-muted-foreground text-xs",children:[o.projects.length," projects"]})]}),e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{className:"bg-soft text-muted-foreground text-xs uppercase",children:e.jsxs("tr",{children:[e.jsx("th",{className:"px-4 py-3 text-left w-8 text-[11px] font-semibold uppercase tracking-[0.08em] text-muted-foreground",children:"#"}),e.jsx("th",{className:"px-4 py-3 text-left text-[11px] font-semibold uppercase tracking-[0.08em] text-muted-foreground",children:"Project"}),e.jsx("th",{className:"px-4 py-3 text-left hidden sm:table-cell text-[11px] font-semibold uppercase tracking-[0.08em] text-muted-foreground",children:"Owner"}),e.jsx("th",{className:"px-4 py-3 text-right text-[11px] font-semibold uppercase tracking-[0.08em] text-muted-foreground",children:"Total Cost"}),e.jsx("th",{className:"px-4 py-3 text-right hidden md:table-cell text-[11px] font-semibold uppercase tracking-[0.08em] text-muted-foreground",children:"$/day"}),e.jsx("th",{className:"px-4 py-3 text-right hidden md:table-cell text-[11px] font-semibold uppercase tracking-[0.08em] text-muted-foreground",children:"Active Days"}),e.jsx("th",{className:"px-4 py-3 text-left hidden lg:table-cell text-[11px] font-semibold uppercase tracking-[0.08em] text-muted-foreground",children:"Active Period"})]})}),e.jsxs("tbody",{className:"divide-y divide-line",children:[(o==null?void 0:o.projects.length)===0&&e.jsx("tr",{children:e.jsx("td",{colSpan:7,className:"px-4 py-8 text-center text-muted-foreground",children:"No projects found"})}),o==null?void 0:o.projects.map((t,r)=>{const c=t.total_cost_usd/t.active_days;return e.jsxs("tr",{className:"hover:bg-soft transition-colors",children:[e.jsx("td",{className:"px-4 py-3 text-muted-foreground text-xs font-mono",children:r+1}),e.jsxs("td",{className:"px-4 py-3",children:[e.jsx("div",{className:"text-foreground font-medium truncate max-w-[180px]",children:t.project_name??e.jsx("span",{className:"text-muted-foreground italic",children:"Unnamed"})}),e.jsx("div",{className:"text-muted-foreground text-xs font-mono truncate max-w-[180px]",children:t.project_id})]}),e.jsx("td",{className:"px-4 py-3 text-foreground text-xs hidden sm:table-cell",children:t.user_email??e.jsx("span",{className:"text-muted-foreground",children:"—"})}),e.jsx("td",{className:"px-4 py-3 text-right",children:e.jsxs("span",{className:"text-plum font-semibold font-mono text-sm",children:["$",t.total_cost_usd.toFixed(4)]})}),e.jsx("td",{className:"px-4 py-3 text-right hidden md:table-cell",children:e.jsxs("span",{className:"text-warning font-mono text-xs font-medium",children:["$",c.toFixed(4)]})}),e.jsxs("td",{className:"px-4 py-3 text-right text-muted-foreground text-xs hidden md:table-cell",children:[t.active_days,"d"]}),e.jsxs("td",{className:"px-4 py-3 text-muted-foreground text-xs hidden lg:table-cell whitespace-nowrap",children:[b(t.first_active_date)," → ",b(t.last_active_date)]})]},t.project_id)})]})]})})]})]})]})]})};export{xe as AdminCosts};
2//# sourceMappingURL=AdminCosts-Dxs1zY_P.js.map

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.