PageSourceSearch

https://mediasphere.ai/assets/EventBudgetBreakdown-D3RjRyfJ.js

js mediasphere.ai collected 2026-10-05 12:18:21 UTC 6,870 bytes, 1 lines download raw bytes

1import{w as k,r as h,b,j as s,d as t,ap as B,T as S,g as m,ac as $}from"./index-k0AW3ROl.js";import{c as z,f as i}from"./currency-sRdnheTW.js";import{T as U}from"./trending-up-DtDoxeGp.js";import{T as K}from"./trending-down-Dt1nONO-.js";import{C as L}from"./chart-pie-DxzlOqN2.js";import{R as _,E as V,T as E,X as I,Y as X,B as Y}from"./generateCategoricalChart-DzoLWs_K.js";import{P as q,a as G}from"./PieChart-BRtuozq7.js";import{B as H}from"./BarChart-B-nCoHlg.js";import"./tiny-invariant-BaFNuDhB.js";const A=["#0026cf","#0E00AE","#3B82F6","#22C55E","#F97316","#8B5CF6","#EC4899","#14B8A6","#FBBF24","#b20817"];function re({project:a,spendData:r}){const{organizationId:u}=k(),o=(r==null?void 0:r.reportingCurrency)||"USD",O=z(o),[j,P]=h.useState([]),[F,R]=h.useState([]),[J,T]=h.useState([]);h.useEffect(()=>{!(a!=null&&a.id)||!u||Promise.all([b.entities.Expense.filter({project_id:a.id}).catch(()=>[]),b.entities.PurchaseOrder.filter({project_id:a.id}).catch(()=>[]),b.entities.Agency.filter({organization_id:u}).catch(()=>[])]).then(([e,l,C])=>{P(Array.isArray(e)?e:[]),R(Array.isArray(l)?l:[]),T(Array.isArray(C)?C:[])})},[a==null?void 0:a.id,u]);const c=(a==null?void 0:a.vendors)||[],x=(r==null?void 0:r.projected)??((a==null?void 0:a.budget)||0),N=(r==null?void 0:r.committed)??0,y=(r==null?void 0:r.actual)??0,M=Math.max(0,N-y),g=x-y,n={};c.forEach(e=>{const l=e.category||"Other";n[l]=(n[l]||0)+(e.agreed_amount||e.quoted_amount||0)}),j.forEach(e=>{const l=e.category||"Miscellaneous";n[l]=(n[l]||0)+(e.amount||0)});const f=Object.entries(n).map(([e,l])=>({name:e,value:l})).sort((e,l)=>l.value-e.value),p={};[...c.flatMap(e=>(e.payment_history||[]).map(l=>({...l,source:"Vendor"}))),...j.filter(e=>e.paid_date).map(e=>({date:e.paid_date,amount:e.amount,source:"Expense"})),...F.flatMap(e=>(e.payment_history||[]).map(l=>({...l,source:"PO"})))].forEach(e=>{if(!e.date)return;const l=new Date(e.date).toLocaleDateString("en-US",{month:"short",year:"2-digit"});p[l]=(p[l]||0)+(e.amount||0)});const v=Object.entries(p).map(([e,l])=>({month:e,amount:l})),d=x>0?y/x*100:0,w=d>100?t.colors.accent:d>80?t.colors.yellow:t.colors.green;return s.jsxs("div",{className:"space-y-5",children:[s.jsx("div",{className:"grid grid-cols-2 md:grid-cols-5 gap-3",children:[{label:"Total Budget",value:x,icon:B,color:t.text.primary},{label:"Committed",value:N,icon:U,color:t.colors.blue},{label:"Spent",value:y,icon:K,color:t.colors.green},{label:"Outstanding",value:M,icon:S,color:t.colors.orange},{label:"Remaining",value:g,icon:B,color:g<0?t.colors.accent:t.colors.green}].map((e,l)=>s.jsxs("div",{className:"p-3",style:m,children:[s.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[s.jsx("div",{className:"w-8 h-8 rounded-lg flex items-center justify-center",style:$(e.color),children:s.jsx(e.icon,{className:"w-4 h-4",style:{color:e.color}})}),s.jsx("span",{className:"text-[10px] font-semibold uppercase",style:{color:t.text.tertiary},children:e.label})]}),s.jsxs("div",{className:"text-xl font-bold",style:{color:e.color},children:[e.value<0?"-":"",i(Math.abs(e.value),o)]})]},l))}),s.jsxs("div",{className:"p-4",style:m,children:[s.jsxs("div",{className:"flex items-center justify-between mb-2",children:[s.jsx("span",{className:"text-sm font-bold",style:{color:t.text.primary},children:"Budget Utilization"}),s.jsxs("span",{className:"text-sm font-bold",style:{color:w},children:[d.toFixed(0),"%"]})]}),s.jsx("div",{className:"w-full h-3 overflow-hidden",style:{background:"rgba(0,0,0,0.06)",borderRadius:t.radius.full},children:s.jsx("div",{className:"h-full transition-all",style:{width:`${Math.min(d,100)}%`,background:w,borderRadius:t.radius.full}})}),d>100&&s.jsxs("div",{className:"mt-2 text-xs font-semibold flex items-center gap-1",style:{color:t.colors.accent},children:[s.jsx(S,{className:"w-3.5 h-3.5"})," Over budget by ",i(Math.abs(g),o)]})]}),s.jsxs("div",{className:"grid md:grid-cols-2 gap-5",children:[f.length>0&&s.jsxs("div",{className:"p-5",style:m,children:[s.jsxs("h3",{className:"text-sm font-bold mb-4 flex items-center gap-2",style:{color:t.text.primary},children:[s.jsx(L,{className:"w-4 h-4",style:{color:t.colors.primary}})," Spend by Category"]}),s.jsx("div",{className:"h-48",children:s.jsx(_,{width:"100%",height:"100%",children:s.jsxs(q,{children:[s.jsx(G,{data:f,dataKey:"value",nameKey:"name",cx:"50%",cy:"50%",outerRadius:70,label:({name:e,percent:l})=>`${e} ${(l*100).toFixed(0)}
1%`,labelLine:!1,fontSize:10,children:f.map((e,l)=>s.jsx(V,{fill:A[l%A.length]},l))}),s.jsx(E,{formatter:e=>i(e,o)})]})})})]}),v.length>0&&s.jsxs("div",{className:"p-5",style:m,children:[s.jsx("h3",{className:"text-sm font-bold mb-4",style:{color:t.text.primary},children:"Payment Timeline"}),s.jsx("div",{className:"h-48",children:s.jsx(_,{width:"100%",height:"100%",children:s.jsxs(H,{data:v,children:[s.jsx(I,{dataKey:"month",tick:{fontSize:10,fill:t.text.tertiary}}),s.jsx(X,{tick:{fontSize:10,fill:t.text.tertiary},tickFormatter:e=>`${O}${(e/1e3).toFixed(0)}k`}),s.jsx(E,{formatter:e=>i(e,o)}),s.jsx(Y,{dataKey:"amount",fill:t.colors.primary,radius:[4,4,0,0]})]})})})]})]}),c.length>0&&s.jsxs("div",{style:m,children:[s.jsxs("div",{className:"px-4 py-3 flex items-center justify-between",style:{borderBottom:"1px solid rgba(0,0,0,0.06)"},children:[s.jsx("h3",{className:"text-sm font-bold",style:{color:t.text.primary},children:"Vendor Cost Summary"}),s.jsxs("span",{className:"text-xs",style:{color:t.text.tertiary},children:[c.length," vendors"]})]}),s.jsx("div",{className:"overflow-x-auto",children:s.jsxs("table",{className:"w-full text-sm",children:[s.jsx("thead",{children:s.jsx("tr",{style:{borderBottom:"1px solid rgba(0,0,0,0.08)"},children:["Vendor","Category","Agreed","Paid","Outstanding","Status"].map(e=>s.jsx("th",{className:"px-4 py-2 text-left text-[10px] font-semibold uppercase",style:{color:t.text.tertiary},children:e},e))})}),s.jsx("tbody",{children:c.map(e=>s.jsxs("tr",{style:{borderBottom:"1px solid rgba(0,0,0,0.04)"},children:[s.jsx("td",{className:"px-4 py-2 font-semibold",style:{color:t.text.primary},children:e.name}),s.jsx("td",{className:"px-4 py-2",style:{color:t.text.secondary},children:e.category}),s.jsx("td",{className:"px-4 py-2 font-semibold",style:{color:t.text.primary},children:i(e.agreed_amount||0,o)}),s.jsx("td",{className:"px-4 py-2",style:{color:t.colors.green},children:i(e.paid_amount||0,o)}),s.jsx("td",{className:"px-4 py-2",style:{color:t.colors.orange},children:i((e.agreed_amount||0)-(e.paid_amount||0),o)}),s.jsx("td",{className:"px-4 py-2",children:s.jsx("span",{className:"px-2 py-0.5 text-[10px] font-semibold",style:{background:e.payment_status==="Fully Paid"?`${t.colors.green}15`:`${t.colors.yellow}15`,color:e.payment_status==="Fully Paid"?t.colors.green:t.colors.yellow,borderRadius:t.radius.sm},children:e.payment_status})})]},e.id))})]})})]})]})}export{re 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.