PageSourceSearch

https://app.snapto.ai/assets/ChargesHub-BFILnmLN.js

js snapto.ai collected 2026-10-05 15:08:49 UTC 17,376 bytes, 1 lines download raw bytes

1import{C as $e,q as de,r as s,fn as H,p as e,L as c,T as n,v as y,B as d,b7 as Le,af as Fe,a0 as oe,a1 as b,b1 as Ye,S as U,bl as v,bs as N,w as k,bj as Z,ag as _e,aZ as le}from"./index-C9IH3k-2.js";import{aW as Ge,I as A,g as ue,N as ce,W as M,T as l,a$ as Be,b0 as P,b1 as Ue,b2 as He,b3 as Ke,c as We,ac as Ve}from"./TemplateUtil-D1DzmWLm.js";import{g as Ze}from"./AuditConstant-C6syQHOu.js";import{a9 as he}from"./MainApp-BoiAvjMg.js";import{M as qe}from"./MarginRuleHelpDrawer-CnZWcG_6.js";import{u as Je}from"./useWalletReferenceData-CbOlkpTs.js";import{R as pe}from"./ReloadOutlined-0KdG7zYw.js";import{F as q}from"./Table-isZ0WXp4.js";import{D as Qe}from"./index-CmSVNJzc.js";import{P as Xe}from"./index-C0dhduHx.js";import{R as et}from"./GlobalOutlined-CzDL8eNz.js";import{A as tt}from"./Wrapper-ChjuDa3w.js";import{R as w}from"./InfoCircleOutlined-B7sKwm1k.js";import"./HelperMethods-C-ewwU_x.js";import"./CalendarOutlined-DyzsKNdO.js";import"./DollarOutlined-CHk-YVW_.js";import"./index-BOwvFOZJ.js";import"./Pagination-D1z-xPUv.js";import"./HolderOutlined-YOHjCGKZ.js";import"./index-Bv3SRNsl.js";import"./ClockCircleOutlined-Cym7vptW.js";const rt={MARKETING:"marketing",UTILITY:"utility",AUTHENTICATION:"authentication",AUTHENTICATION_INTERNATIONAL:"authenticationInternational",SERVICE:"service"},at=()=>{const C=$e(),T=de(t=>t?.jwtTokenDecodedData?.roleType)==="ADMIN",u=s.useMemo(()=>he(T),[T]),[z,O]=s.useState(!0),[K,S]=s.useState([]),[g,R]=s.useState(H),[$,L]=s.useState(!1),[f,F]=s.useState(!1),[h,p]=s.useState(null),[Y,a]=s.useState([]),[i,x]=s.useState([]),[m,Q]=s.useState(!1),[j,E]=s.useState({phoneNumberId:null,currency:null,countryCode:null}),[xe,W]=s.useState(!1),[ye,ge]=s.useState(null),[V,X]=s.useState(null),[me,ee]=s.useState(!1),[fe,je]=s.useState([]),[be,te]=s.useState(!1),[_,re]=s.useState(H),[G,Ce]=s.useState(!1),[Te,ae]=s.useState(!1),{countries:Se,currencies:Re}=Je(),Ie=s.useRef(null),D=async(t=g)=>{O(!0);try{const r=await u.listRules({pagination:{current:t.pagination?.current||1,pageSize:t.pagination?.pageSize||10},order:t.order||[],search:[{fieldName:"expired",value:["false"]},...t.search||[]]});r?.status===200&&(S(r.data?.results||[]),R({...t,pagination:{...t.pagination,total:r.data?.total||0}}))}catch(r){console.error("Error fetching rules:",r)}finally{O(!1)}};s.useEffect(()=>{D()},[]);const B=async(t=_)=>{te(!0);try{const r=await u.listRules({pagination:{current:t.pagination?.current||1,pageSize:t.pagination?.pageSize||10},order:t.order||[],search:[{fieldName:"expired",value:["true"]},...t.search||[]]});r?.status===200&&(je(r.data?.results||[]),re({...t,pagination:{...t.pagination,total:r.data?.total||0}}))}catch(r){console.error("Error fetching expired rules:",r)}finally{te(!1)}},ne=t=>Object.entries(t??{}).map(([r,o])=>({fieldName:r,value:o})).filter(r=>r.value?.length),we=(t,r)=>{const o={...g,pagination:{current:t.current||1,pageSize:t.pageSize||N},search:ne(r)};R(o),D(o)},ke=(t,r)=>{const o={..._,pagination:{current:t.current||1,pageSize:t.pageSize||N},search:ne(r)};re(o),B(o)},Pe=t=>{t.length>0&&!G&&(Ce(!0),B())},Ee=t=>{const r=[];return!t.phoneNumberId&&!t.countryCode&&!t.category?e.jsx(l,{color:"green",icon:e.jsx(et,{}),children:"Global Default"}):(t.phoneNumberId&&r.push(e.jsx(l,{color:"blue",icon:e.jsx(We,{}),children:"Phone Specific"},"phone")),t.countryCode&&r.push(e.jsx(l,{color:"purple",children:t.countryCode},"country")),t.category&&r.push(e.jsx(l,{color:"orange",icon:e.jsx(He,{}),children:Ue(t.category)},"cat")),e.jsx(y,{wrap:!0,children:r}))},De=async()=>{if(L(!0),p(null),E({phoneNumberId:null,currency:null,countryCode:null}),x([]),!Y.length)try{const t=await u.listCustomers();t?.status===200&&a(t.data||[])}catch(t){console.error("Error fetching customers:",t)}},ve=async t=>{if(E(r=>({...r,phoneNumberId:null})),x([]),p(null),!!t){Q(!0);try{const r=await u.listPhoneNumbers(t);r?.status===200&&x((r.data||[]).filter(o=>o.active))}catch(r){console.error("Error fetching phones:",r)}finally{Q(!1)}}},Me=async()=>{const{phoneNumberId:t,currency:r,countryCode:o}=j;if(!(!t||!r||!o)){F(!0),p(null);try{const I=await u.getPriceByParams({phoneNumberId:t,currency:r,countryCode:o,currentDate:Date.now()});I?.status===200&&p(I.data)}catch(I){console.error("Error fetching price:",I)}finally{F(!1)}}},Ne=()=>h?Ke.map(t=>({label:t.label,rate:h[rt[t.value]]}
1)):[],Ae=t=>{ge(t),X(null),W(!0)},ze=async()=>{ee(!0);try{const t={id:ye};V&&(t.endDate=V.format("YYYY-MM-DD")),await u.expireRule(t),W(!1),D(),G&&B()}catch(t){Z.error({message:"Error",description:t?.response?.data?.detail||"Failed to expire the rule. Please try again."})}finally{ee(!1)}},Oe=async t=>{try{await u.deleteRule(t),Z.success({message:"Deleted",description:"Margin rule has been deleted successfully."}),D(),G&&B()}catch(r){Z.error({message:"Error",description:r?.response?.data?.detail||"Failed to delete the rule. Please try again."})}},se=(t,r)=>({...Ze(t,r,Ie,(o,I)=>I()),onFilter:void 0}),ie=[{title:"Scope",key:"scope",render:(t,r)=>Ee(r)},{title:"Phone Number",dataIndex:"displayPhoneNumber",key:"displayPhoneNumber",...se("displayPhoneNumber","Phone Number"),render:(t,r)=>r.phoneNumberId?e.jsx(n.Text,{copyable:!0,title:r.phoneNumberId,children:t||r.phoneNumberId}):"-"},{title:"Customer",dataIndex:"username",key:"username",...se("username","Username"),render:t=>t?e.jsx(n.Text,{strong:!0,children:t}):"-"},{title:"Margin Type",key:"deltaType",render:(t,r)=>e.jsx(l,{color:r.pricingDelta?.deltaType==="PERCENTAGE"?"geekblue":"cyan",children:Be(r.pricingDelta?.deltaType)})},{title:"Margin Value",key:"priceDelta",render:(t,r)=>e.jsx(n.Text,{strong:!0,type:"success",children:r.pricingDelta?.deltaType==="PERCENTAGE"?`+${r.pricingDelta?.priceDelta}%`:`+${P(r.pricingDelta?.priceDelta)}`})},{title:"Effective Period",key:"period",render:(t,r)=>e.jsxs(n.Text,{style:{fontSize:12},children:[r.startDate?v(r.startDate).format("DD MMM YYYY"):"Start: Any"," → ",r.endDate?v(r.endDate).format("DD MMM YYYY"):"No End"]})},{title:"Last Updated",dataIndex:"lastUpdateTime",key:"lastUpdateTime",render:t=>ue(t)},{key:"action",title:"Actions",render:(t,r)=>{const o=!r.startDate||!v(r.startDate).isAfter(v(),"day");return e.jsxs(y,{children:[e.jsx(d,{variant:"dashed",color:"danger",onClick:()=>Ae(r.id),children:"Expire / Disable"}),e.jsx(Xe,{title:"Are you sure you want to delete this rule? It can not be recovered after deletion.",onConfirm:()=>Oe(r.id),okText:"Delete",okButtonProps:{danger:!0},cancelText:"Cancel",disabled:o,children:e.jsx(k,{title:o?"Rule can only be deleted before it becomes active (Starts after today's date)":"",children:e.jsx(d,{variant:"dashed",color:"danger",disabled:o,children:"Delete Rule"})})})]})}}];return e.jsxs(c,{vertical:!0,gap:"large",children:[e.jsxs(c,{justify:"space-between",align:"center",wrap:!0,children:[e.jsxs(c,{vertical:!0,children:[e.jsx(n.Title,{level:4,style:{margin:0},children:"Margin Configuration"}),e.jsx(n.Text,{type:"secondary",children:"Set your pricing margins on top of Meta rates"})]}),e.jsxs(y,{children:[e.jsx(d,{icon:e.jsx(Le,{}),onClick:()=>ae(!0),type:"dashed",children:"How it Works"}),e.jsx(d,{onClick:De,children:"Check Price"}),e.jsx(d,{icon:e.jsx(pe,{}),onClick:()=>D(),children:"Refresh"}),e.jsx(d,{type:"primary",icon:e.jsx(Fe,{}),onClick:()=>C(Ge.CREATE_MARGIN),children:"Add Margin Rule"})]})]}),e.jsx(A,{size:"small",title:"How Margin Rules Work",children:e.jsxs(oe,{gutter:[24,16],children:[e.jsx(b,{xs:24,md:8,children:e.jsxs(c,{vertical:!0,gap:"small",children:[e.jsx(n.Text,{strong:!0,type:"success",children:"1. Global Default"}),e.jsx(n.Text,{type:"secondary",children:"Set a base margin that applies to all messages when no specific rule matches."})]})}),e.jsx(b,{xs:24,md:8,children:e.jsxs(c,{vertical:!0,gap:"small",children:[e.jsx(n.Text,{strong:!0,children:"2. Category Override"}),e.jsx(n.Text,{type:"secondary",children:"Override for specific message types (Marketing, Utility, Authentication, Service)."})]})}),e.jsx(b,{xs:24,md:8,children:e.jsxs(c,{vertical:!0,gap:"small",children:[e.jsx(n.Text,{strong:!0,type:"warning",children:"3. Country/Phone Override"}),e.jsx(n.Text,{type:"secondary",children:"Most specific rules for particular countries or phone numbers take priority."})]})})]})}),e.jsx(A,{title:`Active Margin Rules (${g.pagination?.total||0})`,size:"small",children:e.jsx(q,{columns:ie,dataSource:K,rowKey:t=>t.id,loading:z,pagination:{...g.pagination,showSizeChanger:!0,showTotal:(t,r)=>`${r[0]}-${r[1]} of ${t} rules`},onChange:we,scroll:{x:1300},size:"small"})}),e.jsx(Ye,{onChange:Pe,items:[{key:"expired",label:e.jsxs(n.Text,{strong:!0,children:["Expired Margin Rules ",G?`(${_.pagination?.total||0})`:""]}),children:e.jsx(q,{columns:ie.filter(t=>t.key!=="action"),dataSource:fe,rowKey:t=>t.id,loading:be,pagination:{..._.pagination,showSizeChanger:!0,showTotal:(t,r)=>`${r[0]}-${r[1]} of ${t} rules`},onChange:ke,scroll:{x:1300},size:"small"})}]}),e.jsx(ce,{title:"Check Price",open:$,onCancel:()=>L(!1),footer:null,width:560,destroyOnHidden:!0,children:e.jsxs(c,{vertical:!0,gap:"middle",children:[e.jsxs(oe,{gutter:[12,12],children:[e.jsxs(b,{xs:24,md:12,children:[e.jsx(n.Text,{type:"secondary",style:{fontSize:12,display:"block",marginBottom:4},children:"Customer"}),e.jsx(U,{placeholder:"Select customer",style:{width:"100%"}
1,allowClear:!0,showSearch:!0,optionFilterProp:"label",onChange:ve,options:Y.map(t=>({label:t.username,value:t.id}))})]}),e.jsxs(b,{xs:24,md:12,children:[e.jsx(n.Text,{type:"secondary",style:{fontSize:12,display:"block",marginBottom:4},children:"Phone Number"}),e.jsx(U,{placeholder:"Select phone",style:{width:"100%"},allowClear:!0,showSearch:!0,optionFilterProp:"label",loading:m,value:j.phoneNumberId,onChange:t=>{E(r=>({...r,phoneNumberId:t})),p(null)},options:i.map(t=>({label:t.displayPhoneNumber,value:t.phoneNumberId,displayPhoneNumber:t.displayPhoneNumber})),optionRender:t=>e.jsxs("div",{children:[e.jsx(n.Text,{children:t.data?.displayPhoneNumber}),e.jsx("br",{}),e.jsx(n.Text,{type:"secondary",style:{fontSize:12},children:t.data?.value})]})})]}),e.jsxs(b,{xs:24,md:12,children:[e.jsx(n.Text,{type:"secondary",style:{fontSize:12,display:"block",marginBottom:4},children:"Currency"}),e.jsx(U,{placeholder:"Select currency",style:{width:"100%"},allowClear:!0,showSearch:!0,optionFilterProp:"label",value:j.currency,onChange:t=>{E(r=>({...r,currency:t})),p(null)},options:Re})]}),e.jsxs(b,{xs:24,md:12,children:[e.jsx(n.Text,{type:"secondary",style:{fontSize:12,display:"block",marginBottom:4},children:"Country"}),e.jsx(U,{placeholder:"Select country",style:{width:"100%"},allowClear:!0,showSearch:!0,optionFilterProp:"label",value:j.countryCode,onChange:t=>{E(r=>({...r,countryCode:t})),p(null)},options:Se})]})]}),e.jsx(d,{type:"primary",onClick:Me,loading:f,disabled:!j.phoneNumberId||!j.currency||!j.countryCode,children:"Check Price"}),h&&e.jsxs(e.Fragment,{children:[e.jsxs(M,{column:1,size:"small",bordered:!0,children:[e.jsxs(M.Item,{label:"Country",children:[h.country," (",h.countryCode,")"]}),e.jsx(M.Item,{label:"Currency",children:h.currency})]}),e.jsx(M,{column:1,size:"small",bordered:!0,title:"Charged Rates (margins applied)",children:Ne().map(({label:t,rate:r})=>e.jsx(M.Item,{label:t,children:e.jsx(n.Text,{code:!0,children:r!=null?Number(r):"-"})},t))}),e.jsx(n.Text,{type:"secondary",style:{fontSize:12},children:"These are the rates this phone number is billed at. Compare them with the Meta Rate Card tab to see the margin."})]})]})}),e.jsx(ce,{title:"Expire Margin Rule",open:xe,onCancel:()=>W(!1),onOk:ze,confirmLoading:me,okText:"Expire",okButtonProps:{danger:!0},destroyOnHidden:!0,children:e.jsxs(c,{vertical:!0,gap:"middle",children:[e.jsx(n.Text,{children:"Are you sure you want to expire this rule?"}),e.jsxs("div",{children:[e.jsx(n.Text,{type:"secondary",children:"End Date (optional)"}),e.jsx(Qe,{placeholder:"Leave empty to expire at midnight today",style:{width:"100%"},value:V,onChange:X,disabledDate:t=>t&&t.isBefore(v(),"day")}),e.jsx(n.Text,{type:"secondary",children:"If no date is selected, the rule will expire at midnight today."})]})]})}),e.jsx(qe,{open:Te,onClose:()=>ae(!1),section:"guide"})]})},nt=()=>{const C=de(a=>a?.jwtTokenDecodedData?.roleType)==="ADMIN",T=s.useMemo(()=>he(C),[C]),[u,z]=s.useState(!0),[O,K]=s.useState([]),[S,g]=s.useState(H),[R,$]=s.useState(""),L=s.useRef(null),f=async(a=S)=>{z(!0);try{const i=[];R&&i.push({fieldName:"currency",value:[R]});const x={pagination:{current:a.pagination?.current||1,pageSize:a.pagination?.pageSize||10},order:a.order||[],search:i},m=await T.listMetaRates(x);m?.status===200&&(K(m.data?.results||[]),g({...a,pagination:{...a.pagination,total:m.data?.total||0}}))}catch(i){console.error("Error fetching rates:",i)}finally{z(!1)}};s.useEffect(()=>{f()},[]);const F=(a,i,x)=>{const m={...S,pagination:{current:a.current||1,pageSize:a.pageSize||N},order:x.order?[{fieldName:x.columnKey,dir:x.order==="descend"?"desc":"asc"}]:[]};g(m),f(m)},h=()=>{const a={...S,pagination:{current:1,pageSize:N}};f(a)},p=()=>{$("");const a={...H,pagination:{current:1,pageSize:N}};g(a),f(a)},Y=[{title:"Country",dataIndex:"country",key:"country",render:(a,i)=>e.jsxs(c,{vertical:!0,gap:2,children:[e.jsx(n.Text,{strong:!0,children:a}),e.jsxs(n.Text,{type:"secondary",style:{fontSize:11},children:["Code: ",i.countryCode," | +",i.callingCode]})]})},{title:"Market",dataIndex:"market",key:"market",render:a=>a||"-"},{title:"Currency",dataIndex:"currency",key:"currency",render:a=>e.jsx(l,{color:"blue",children:a})},{title:e.jsxs(k,{title:"Rate for marketing/promotional messages",children:["Marketing ",e.jsx(w,{style:{fontSize:12}})]}),dataIndex:"marketing",key:"marketing",render:(a,i)=>e.jsx(l,{color:"blue",children:P(a,i.currency)})},{title:e.jsxs(k,{title:"Rate for utility/transactional messages",children:["Utility ",e.jsx(w,{style:{fontSize:12}})]}),dataIndex:"utility",key:"utility",render:(a,i)=>e.jsx(l,{color:"green",children:P(a,i.currency)})},{title:e.jsxs(k,{title:"Rate for authentication messages (OTP, etc.)",children:["Authentication ",e.jsx(w,{style:{fontSize:12}})]}),dataIndex:"authentication",key:"authentication",render:(a,i)=>e.jsx(l,{color:"purple",children:P(a,i.currency)})},{title:e.jsxs(k,{title:"Rate for international authentication messages",children:["Auth International ",e.jsx(w,{style:{fontSize:12}})]}),dataIndex:"authenticationInternational",key:"authenticationInternational",render:(a,i)=>e.jsx(l,{color:"orange",children:a!==null?P(a,i.currency):"-"})},{title:e.jsxs(k,{title:"Rate for non-template (free-form) messages sent in the 24h customer service window. Charged per message from 1 Oct 2026.",children:["Service ",e.jsx(w,{style:{fontSize:12}})]}),dataIndex:"service",key:"service",render:(a,i)=>e.jsx(l,{color:"cyan",children:a!=null?P(a,i.currency):"-"})},{title:"Effective From",dataIndex:"startDate",key:"startDate",render:a=>ue(a)}];return e.jsxs(c,{vertical:!0,gap:"large",children:[e.jsxs(c,{justify:"space-between",align:"center",wrap:!0,children:[e.jsxs(c,{vertical:!0,children:[e.jsx(n.Title,{level:4,style:{margin:0},children:"Meta WhatsApp Rate Card"}),e.jsx(n.Text,{type:"secondary",children:"Current messaging rates from Meta by country and category"})]}),e.jsx(d,{icon:e.jsx(pe,{}),onClick:()=>f(),children:"Refresh"})]}),e.jsx(tt,{type:"success",icon:e.jsx(w,{}),showIcon:!0,title:"These are the base rates from Meta. Your actual charges will include your configured margins on top of these rates. Rates are subject to change by Meta. Last sync from Meta's pricing API."}),e.jsx(A,{size:"small",children:e.jsxs(c,{gap:"middle",wrap:!0,children:[e.jsx(_e,{ref:L,placeholder:"Search by currency...",prefix:e.jsx(le,{}),value:R,onChange:a=>$(a.target.value),onPressEnter:h,style:{width:300},allowClear:!0}),e.jsxs(y,{children:[e.jsx(d,{type:"primary",icon:e.jsx(le,{}),onClick:h,children:"Search"}),e.jsx(d,{onClick:p,children:"Reset"})]})]})}),e.jsx(A,{title:"Rate Card",size:"small",children:e.jsx(q,{columns:Y,dataSource:O,rowKey:a=>a.id||`${a.countryCode}-${a.currency}`,loading:u,pagination:{...S.pagination,showSizeChanger:!0,showTotal:(a,i)=>`${i[0]}-${i[1]} of ${a} countries`},onChange:F,scroll:{x:1300},size:"small"})}),e.jsx(A,{size:"small",title:"Rate Categories",children:e.jsxs(c,{gap:"large",wrap:!0,children:[e.jsxs(y,{children:[e.jsx(l,{color:"blue",children:"Marketing"}),e.jsx(n.Text,{children:"Promotional messages, offers, updates"})]}),e.jsxs(y,{children:[e.jsx(l,{color:"green",children:"Utility"}),e.jsx(n.Text,{children:"Order confirmations, receipts, alerts"})]}),e.jsxs(y,{children:[e.jsx(l,{color:"purple",children:"Authentication"}),e.jsx(n.Text,{children:"OTP, verification codes"})]}),e.jsxs(y,{children:[e.jsx(l,{color:"orange",children:"Auth International"}),e.jsx(n.Text,{children:"Cross-border authentication"})]}),e.jsxs(y,{children:[e.jsx(l,{color:"cyan",children:"Service"}),e.jsx(n.Text,{children:"Free-form replies in the 24h window (billed from 1 Oct 2026)"})]})]})})]})},J={MARGINS:"margins",RATES:"rates"},st=[{key:J.MARGINS,label:"Margin Rules",children:e.jsx(at,{})},{key:J.RATES,label:"Meta Rate Card",children:e.jsx(nt,{})}],kt=()=>{const[C,T]=s.useState(J.MARGINS);return e.jsxs(c,{vertical:!0,gap:"middle",children:[e.jsx(n.Title,{level:4,style:{margin:0},children:"Charges Hub"}),e.jsx(Ve,{activeKey:C,onChange:T,items:st,destroyOnHidden:!0})]})};export{kt 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.