PageSourceSearch

https://vagle.ai/assets/AdminPhoneNumbers-DSft-Kyb.js

js vagle.ai collected 2026-10-05 13:13:03 UTC 7,197 bytes, 1 lines download raw bytes

1import{b as x,j as e,e as d}from"./index-CbtKD9GF.js";import{b as i}from"./vendor-gmoby7Lc.js";import{A as M}from"./AdminTheme-CI_qYGsE.js";import"./icons-BYq1EogD.js";import"./sparkles--5vRErnb.js";import"./chart-column-DTz6hlN3.js";import"./users-B-7dCcKT.js";const q=()=>{const[p,w]=i.useState([]),[U,j]=i.useState(!0),[f,N]=i.useState(null),[o,A]=i.useState(""),[r,S]=i.useState({userId:"",assignedOnly:!1}),[l,m]=i.useState(1),[h,$]=i.useState(1),[v,C]=i.useState([]),[E,R]=i.useState([]),[P,y]=i.useState(new Set);i.useEffect(()=>{b(),I(),L()},[o,r,l]);const b=async()=>{try{j(!0),N(null);const s=localStorage.getItem("token"),a=new URLSearchParams;o&&a.append("search",o),r.userId&&a.append("userId",r.userId),r.assignedOnly&&a.append("assignedOnly","true"),a.append("page",l),a.append("limit",20);const n=await x.get(`/api/admin/phone-numbers?${a}`,{headers:{Authorization:`Bearer ${s}`}});n.data.success&&(w(n.data.phoneNumbers),$(n.data.totalPages))}catch(s){console.error("Error fetching phone numbers:",s),N(s.response?.data?.error||"Failed to load phone numbers")}finally{j(!1)}},I=async()=>{try{const s=localStorage.getItem("token"),a=await x.get("/api/admin/users?limit=100",{headers:{Authorization:`Bearer ${s}`}});a.data.success&&C(a.data.users)}catch(s){console.error("Error fetching users:",s)}},L=async()=>{try{const s=localStorage.getItem("token"),a=await x.get("/api/admin/assistants?limit=200",{headers:{Authorization:`Bearer ${s}`}});a.data.success&&R(a.data.assistants)}catch(s){console.error("Error fetching assistants:",s)}},k=(s,a)=>{S(n=>({...n,[s]:a})),m(1)},O=async(s,a,n,u)=>{if(n&&u&&n!==u){await d("Unassign this number before assigning it to a different assistant. This prevents accidental routing changes.");return}const g=`${a}-${s}`;y(t=>new Set([...t,g]));try{const t=localStorage.getItem("token"),c=await x.put(`/api/admin/phone-numbers/${a}/${s}/assign`,{assistantId:n||null},{headers:{Authorization:`Bearer ${t}`}});c.data.success?await b():d("❌ "+c.data.error)}catch(t){console.error("Error updating assignment:",t),d("❌ Error updating assignment: "+(t.response?.data?.error||t.message))}finally{y(t=>{const c=new Set(t);return c.delete(g),c})}},B=async s=>{if(!s.webhookUrl){await d(`No webhook URL is configured for ${s.phoneNumber}.`);return}try{await navigator.clipboard.writeText(s.webhookUrl),await d("Webhook URL copied.")}catch{await d("Could not copy the webhook URL. Copy it from the provider configuration instead.")}},z=s=>/^\+[1-9]\d{1,14}$/.test(s),F=s=>E.filter(a=>a.userEmail===v.find(n=>n.id===s)?.email);return e.jsxs(M,{children:[e.jsxs("div",{className:"admin-header",children:[e.jsx("h1",{children:"Phone Numbers"}),e.jsx("p",{children:"Manage phone number assignments and routing"})]}),e.jsxs("div",{className:"admin-card",children:[e.jsxs("div",{className:"admin-filters",children:[e.jsx("input",{type:"text",placeholder:"Search by phone number, user, or label...",value:o,onChange:s=>{A(s.target.value),m(1)},className:"admin-search-input"}),e.jsxs("select",{value:r.userId,onChange:s=>k("userId",s.target.value),className:"admin-filter-select",children:[e.jsx("option",{value:"",children:"All Users"}),v.map(s=>
1e.jsxs("option",{value:s.id,children:[s.fullName," (",s.email,")"]},s.id))]}),e.jsxs("label",{className:"admin-filter-checkbox",children:[e.jsx("input",{type:"checkbox",checked:r.assignedOnly,onChange:s=>k("assignedOnly",s.target.checked)}),"Assigned Only"]})]}),U?e.jsx("div",{className:"admin-loading",children:"Loading phone numbers..."}):f?e.jsxs("div",{className:"admin-error",children:[e.jsxs("p",{children:["❌ ",f]}),e.jsx("button",{onClick:b,className:"admin-btn-retry",children:"Retry"})]}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"admin-table-container",children:e.jsxs("table",{className:"admin-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Phone Number"}),e.jsx("th",{children:"User"}),e.jsx("th",{children:"Assigned Assistant"}),e.jsx("th",{children:"Status"}),e.jsx("th",{children:"Actions"})]})}),e.jsxs("tbody",{children:[!p.length&&e.jsx("tr",{children:e.jsx("td",{colSpan:"5",children:e.jsx("div",{className:"admin-empty",children:"No phone numbers match the current filters."})})}),p.map(s=>{const a=`${s.user.id}-${s.id}`,n=P.has(a),u=F(s.user.id),g=z(s.phoneNumber);return e.jsxs("tr",{children:[e.jsx("td",{children:e.jsxs("div",{className:"admin-phone-cell",children:[e.jsxs("div",{className:"admin-phone-number",children:[s.phoneNumber,!g&&e.jsx("span",{className:"admin-validation-error",title:"Invalid E.164 format",children:"⚠️"})]}),s.label&&e.jsx("div",{className:"admin-phone-label",children:s.label})]})}),e.jsx("td",{children:e.jsxs("div",{className:"admin-user-cell",children:[e.jsx("div",{className:"admin-user-name",children:s.user.fullName}),e.jsx("div",{className:"admin-user-email",children:s.user.email})]})}),e.jsx("td",{children:e.jsxs("div",{className:"admin-assignment-cell",children:[e.jsxs("select",{value:s.assignedAssistantId||"",onChange:t=>O(s.id,s.user.id,t.target.value,s.assignedAssistantId),disabled:n,className:"admin-assignment-select",children:[e.jsx("option",{value:"",children:"Unassigned"}),u.map(t=>e.jsx("option",{value:t.id,children:t.name},t.id))]}),n&&e.jsx("span",{className:"admin-updating-indicator",children:"Updating..."}),s.assignedAssistantName&&!n&&e.jsxs("div",{className:"admin-current-assignment",children:["Currently: ",s.assignedAssistantName]})]})}),e.jsx("td",{children:e.jsx("span",{className:`admin-badge ${s.assignedAssistantId?"admin-badge-success":"admin-badge-warning"}`,children:s.assignedAssistantId?"Active":"Inactive"})}),e.jsx("td",{children:e.jsx("div",{className:"admin-actions",children:e.jsx("button",{onClick:()=>B(s),className:"admin-btn-sm admin-btn-secondary",title:s.webhookUrl?"Copy configured webhook URL":"No webhook URL is configured",disabled:!s.webhookUrl,children:s.webhookUrl?"Copy webhook":"Not configured"})})})]},s.id)})]})]})}),h>1&&e.jsxs("div",{className:"admin-pagination",children:[e.jsx("button",{onClick:()=>m(s=>Math.max(1,s-1)),disabled:l===1,className:"admin-btn-pagination",children:"Previous"}),e.jsxs("span",{className:"admin-pagination-info",children:["Page ",l," of ",h]}),e.jsx("button",{onClick:()=>m(s=>Math.min(h,s+1)),disabled:l===h,className:"admin-btn-pagination",children:"Next"})]})]})]}),e.jsxs("div",{className:"admin-info-cards",children:[e.jsxs("div",{className:"admin-info-card",children:[e.jsx("h3",{children:"📋 Validation Rules"}),e.jsxs("ul",{children:[e.jsx("li",{children:"Phone numbers must be in E.164 format (+1234567890)"}),e.jsx("li",{children:"Each number can only be assigned to one assistant"}),e.jsx("li",{children:"Assistant must belong to the phone number owner"}),e.jsx("li",{children:"All changes are audited for security"})]})]}),e.jsxs("div",{className:"admin-info-card",children:[e.jsx("h3",{children:"🔗 Webhook URLs"}),e.jsxs("p",{children:["Inbound webhook format:",e.jsx("br",{}),e.jsxs("code",{children:["","/api/twilio/webhook/inbound/[PHONE_NUMBER]"]})]}),e.jsx("p",{children:'Use the "Copy URL" button to get the exact webhook URL for each number.'})]})]})]})};export{q 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.