PageSourceSearch

https://whassan-mkmedicalcentre.hf.space/assets/AdminCommunicationsPage-wLCd_pdx.js

js whassan-mkmedicalcentre.hf.space collected 2026-10-03 17:30:54 UTC 12,985 bytes, 1 lines download raw bytes

1import{b as W,r as t,j as e,L as c}from"./vendor-react-C1xWfpXO.js";import{u as L,n as A,s as m}from"./index-D7bujhxm.js";import{R as E}from"./RecordingAudioPlayer-LTWBMyFU.js";import"./twilio-voice-B2G-s7Fn.js";const V=()=>{const{hasPermission:p}=L(),[C]=W(),i=C.get("conversationId")||"",S=i.startsWith("voice:")?"calls":i?"messages":"overview",[l,d]=t.useState(S),[a,N]=t.useState(null),[o,w]=t.useState(null),[u,I]=t.useState([]),[v,B]=t.useState([]),[x,T]=t.useState("all"),[n,h]=t.useState(i),[D,g]=t.useState(!0),[y,f]=t.useState(null);t.useEffect(()=>{i&&(h(i),i.startsWith("voice:")?d("calls"):d("messages"))},[i]),t.useEffect(()=>{async function r(){g(!0),f(null);try{if(p("TWILIO_CONFIG_READ")){const[s,R,k,z]=await Promise.all([m.twilioStatus(),m.twilioWebhooks().catch(()=>null),m.listCommunicationsMessages({limit:50}).catch(()=>[]),m.listCommunicationsCalls({limit:50}).catch(()=>[])]);N(s),w(R),I(k),B(z)}}catch(s){f(s.message||"Failed to load communications status")}finally{g(!1)}}r()},[p]);const j=u.filter(r=>{if(x!=="all"&&r.channel!==x)return!1;if(n){const s=n.toLowerCase();return r.body.toLowerCase().includes(s)||r.from.toLowerCase().includes(s)||r.to.toLowerCase().includes(s)||r.conversationId.toLowerCase().includes(s)}return!0}),b=v.filter(r=>{if(n){const s=n.toLowerCase();return r.caller.toLowerCase().includes(s)||r.conversationId.toLowerCase().includes(s)||r.transcript&&r.transcript.toLowerCase().includes(s)||r.aiSummary&&r.aiSummary.toLowerCase().includes(s)}return!0});return e.jsxs("div",{children:[e.jsxs("div",{style:{marginBottom:"1.5rem"},children:[e.jsx(c,{to:"/staff/admin",style:{fontSize:"0.875rem",color:"var(--color-primary)"},children:"← Back to Administration"}),e.jsx("h1",{style:{fontSize:"1.75rem",marginTop:"0.5rem",marginBottom:"0.375rem"},children:"Communications Center"}),e.jsx("p",{style:{color:"var(--color-text-muted)"},children:"Live channel health, unified conversation transcripts, SMS, WhatsApp, and voice recording lifecycle."})]}),y&&e.jsx("div",{className:"notice-banner",style:{borderLeftColor:"var(--color-danger)",background:"var(--color-danger-subtle)",color:"var(--color-danger-text)",marginBottom:"1.5rem"},children:y}),e.jsxs("div",{style:{display:"flex",gap:"0.5rem",borderBottom:"1px solid var(--color-border)",marginBottom:"1.5rem"},children:[e.jsx("button",{onClick:()=>d("overview"),className:`btn ${l==="overview"?"btn-primary":"btn-secondary"}`,style:{borderRadius:"4px 4px 0 0"},children:"📊 Channels & Ingress"}),e.jsxs("button",{onClick:()=>d("messages"),className:`btn ${l==="messages"?"btn-primary":"btn-secondary"}`,style:{borderRadius:"4px 4px 0 0"},children:["💬 Message History (",u.length,")"]}),e.jsxs("button",{onClick:()=>d("calls"),className:`btn ${l==="calls"?"btn-primary":"btn-secondary"}`,style:{borderRadius:"4px 4px 0 0"},children:["📞 Voice Calls & Transcripts (",v.length,")"]})]}),D?e.jsx("div",{className:"card",children:e.jsx("p",{style:{color:"var(--color-text-muted)"},children:"Loading communications..."})}):l==="overview"?e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"1.5rem"},children:[e.jsx(A,{}),e.jsxs("div",{style:{display:"grid",gridTemplateColumns:"repeat(auto-fit, minmax(240px, 1fr))",gap:"1rem"},children:[e.jsxs("div",{className:"card",children:[e.jsx("h3",{className:"card-title",style:{fontSize:"1rem",marginBottom:"0.5rem"},children:"📱 SMS"}),e.jsx("p",{style:{fontSize:"0.875rem",color:"var(--color-text-muted)",marginBottom:"0.75rem"},children:"Patient reminder and booking messages."}),e.jsx("span",{className:"badge",style:{background:"var(--color-surface-hover)"},children:(a==null?void 0:a.status)??"UNKNOWN"})]}),e.jsxs("div",{className:"card",children:[e.jsx("h3",{className:"card-title",style:{fontSize:"1rem",marginBottom:"0.5rem"},children:"💬 WhatsApp"}),e.jsx("p",{style:{fontSize:"0.875rem",color:"var(--color-text-muted)",marginBottom:"0.75rem"},children:"Interactive conversational channel."}),e.jsx("span",{className:"badge",style:{background:"var(--color-surface-hover)"},children:(a==null?void 0:a.status)??"UNKNOWN"})]}),e.jsxs("div",{className:"card",children:[e.jsx("h3",{className:"card-title",style:{fontSize:"1rem",marginBottom:"0.5rem"},children:"📞 Voice (Media Streams)"}),e.jsx("p",{style:{fontSize:"0.875rem",color:"var(--color-text-muted)",marginBottom:"0.75rem"},children:"8kHz μ-law WebSocket audio stream."}),e.jsx("span",{className:"badge",style:{background:"var(--color-surface-hover)"},children:o?o.voiceWebhookConfigured?"ACTIVE":"NOT CONFIGURED":"UNKNOWN"})]}),e.jsxs("div",{className:"card",children:[e.jsx("h3",{className:"card-title",style:{fontSize:"1rem",marginBottom:"0.5rem"},children:"🔒 Twilio Verify"}),e.jsx("p",{style:{fontSize:"0.875rem",color:"var(--color-text-muted)",marginBottom:"0.75rem"},children:"Identity verification & OTP delivery."}),e.jsx("span",{className:"badge",style:{background:"var(--color-surface-hover)"},children:"ACTIVE"})]})]}),e.jsxs("div",{className:"card",children:[e.jsx("h2",{className:"card-title",style:{marginBottom:"1rem"},children:"Webhook Ingress Posture"}),e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"0.75rem",fontSize:"0.875rem"},children:[e.jsxs("div",{style:{display:"flex",justifyContent:"space-between",paddingBottom:"0.5rem",borderBottom:"1px solid var(--color-border)"},children:[e.jsx("span",{children:"Messaging Webhook (`/api/webhooks/messaging`)"}),e.jsx("strong",{children:o!=null&&o.messagingWebhookConfigured?"Mounted":"Not mounted"})]}),e.jsxs("div",{style:{display:"flex",justifyContent:"space-between",paddingBottom:"0.5rem",borderBottom:"1px solid var(--color-border)"},children:[e.jsx("span",{children:"Voice Webhook (`/api/voice/incoming`)"}),e.jsx("strong",{children:o!=null&&o.voiceWebhookConfigured?"Mounted":"Not mounted"})]}),e.jsxs("div",{style:{display:"flex",justifyContent:"space-between"},children:[e.jsx("span",{children:"Twilio HMAC Signature Verification"}),e.jsx("strong",{children:o!=null&&o.signatureValidationEnabled?"Enforced (Strict)":"Development (Permissive)"})]})]})]}),e.jsx("div",{style:{display:"flex",gap:"1rem"},children:e.jsx(c,{to:"/staff/admin/twilio",className:"btn btn-primary",children:"Configure Twilio Credentials & Test SMS"})})]}):l==="messages"?e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"1rem"},children:[e.jsxs("div",{className:"card",style:{display:"flex",gap:"1rem",flexWrap:"wrap",alignItems:"center"},children:[e.jsxs("div",{style:{display:"flex",gap:"0.5rem",alignItems:"center"},children:[e.jsx("label",{style:{fontSize:"0.875rem",fontWeight:600},children:"Channel:"}),e.jsxs("select",{value:x,onChange:r=>T(r.target.value),style:{padding:"0.375rem 0.75rem",borderRadius:"4px",border:"1px solid var(--color-border)"},children:[e.jsx("option",{value:"all",children:"All Channels"}),e.jsx("option",{value:"sms",children:"SMS"}),e.jsx("option",{value:"whatsapp",children:"WhatsApp"}),e.jsx("option",{value:"web",children:"Web Chat"}),e.jsx("option",{value:"voice",children:"Voice"})]})]}),e.jsx("div",{style:{flex:1,minWidth:"200px"},children:e.jsx("input",{type:"text",placeholder:"Search by text, phone, or conversation ID...",value:n,onChange:r=>h(r.target.value),style:{width:"100%",padding:"0.375rem 0.75rem",borderRadius:"4px",border:"1px solid var(--color-border)"}}
1)})]}),j.length===0?e.jsx("div",{className:"card",children:e.jsx("p",{style:{color:"var(--color-text-muted)"},children:"No messages match your criteria."})}):e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:"0.75rem"},children:j.map(r=>e.jsxs("div",{className:"card",style:{padding:"1rem"},children:[e.jsxs("div",{style:{display:"flex",justifyContent:"space-between",marginBottom:"0.5rem"},children:[e.jsxs("div",{children:[e.jsx("span",{className:"badge",style:{marginRight:"0.5rem",textTransform:"uppercase"},children:r.channel}),e.jsx("span",{className:"badge",style:{background:r.direction==="INBOUND"?"var(--color-primary-subtle, #e0f2fe)":"var(--color-surface-hover)"},children:r.direction}),e.jsx("span",{style:{marginLeft:"0.5rem",fontSize:"0.8125rem",color:"var(--color-text-muted)"},children:new Date(r.timestamp).toLocaleString()})]}),e.jsxs("span",{style:{fontSize:"0.75rem",color:"var(--color-text-muted)"},children:["Status: ",e.jsx("strong",{children:r.deliveryStatus})]})]}),e.jsxs("div",{style:{fontSize:"0.9375rem",marginBottom:"0.5rem"},children:[e.jsx("strong",{children:r.direction==="INBOUND"?"Patient: ":"Lina AI: "}),r.body]}),r.aiResponse&&r.direction==="INBOUND"&&e.jsxs("div",{style:{background:"var(--color-surface-hover)",padding:"0.5rem 0.75rem",borderRadius:"4px",fontSize:"0.875rem",marginTop:"0.5rem"},children:[e.jsx("strong",{children:"AI Response:"})," ",r.aiResponse]}),e.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",fontSize:"0.75rem",color:"var(--color-text-muted)",marginTop:"0.5rem",paddingTop:"0.375rem",borderTop:"1px dashed var(--color-border)"},children:[e.jsxs("div",{children:["Conv Ref: ",e.jsx("code",{children:r.conversationId})," | From: ",e.jsx("code",{children:r.from})," → To: ",e.jsx("code",{children:r.to}),r.relatedAppointmentId&&` | Appt: ${r.relatedAppointmentId}`]}),e.jsxs("div",{style:{display:"flex",gap:"0.75rem"},children:[e.jsx(c,{to:`/staff/messages?caller=${encodeURIComponent(r.direction==="INBOUND"?r.from:r.to)}`,style:{color:"var(--color-primary)",textDecoration:"underline"},children:"Caller Dossier →"}),r.twilioConsoleUrl&&e.jsx("a",{href:r.twilioConsoleUrl,target:"_blank",rel:"noopener noreferrer",style:{color:"var(--color-primary)",textDecoration:"underline"},children:"Twilio Console ↗"})]})]})]},r.id))})]}):e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"1rem"},children:[e.jsx("div",{className:"card",children:e.jsx("input",{type:"text",placeholder:"Search calls by caller phone, transcript, or summary...",value:n,onChange:r=>h(r.target.value),style:{width:"100%",padding:"0.375rem 0.75rem",borderRadius:"4px",border:"1px solid var(--color-border)"}})}),b.length===0?e.jsx("div",{className:"card",children:e.jsx("p",{style:{color:"var(--color-text-muted)"},children:"No voice calls match your criteria."})}):e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:"0.75rem"},children:b.map(r=>e.jsxs("div",{className:"card",style:{padding:"1rem"},children:[e.jsxs("div",{style:{display:"flex",justifyContent:"space-between",marginBottom:"0.5rem"},children:[e.jsxs("div",{children:[e.jsx("span",{className:"badge",style:{marginRight:"0.5rem"},children:"📞 VOICE"}),e.jsxs("span",{style:{fontSize:"0.8125rem",color:"var(--color-text-muted)"},children:[new Date(r.startTime).toLocaleString(),r.durationSeconds?` (${r.durationSeconds}s)`:""]})]}),e.jsxs("div",{children:[e.jsxs("span",{className:"badge",style:{marginRight:"0.5rem"},children:["Rec: ",r.recordingStatus]}),e.jsxs("span",{className:"badge",style:{background:r.escalationStatus==="PENDING"?"var(--color-danger-subtle)":"var(--color-surface-hover)"},children:["Escalation: ",r.escalationStatus]})]})]}),e.jsxs("div",{style:{fontSize:"0.875rem",marginBottom:"0.5rem"},children:["Caller: ",e.jsx("strong",{children:r.caller})," → Clinic: ",e.jsx("strong",{children:r.clinicNumber})]}),r.aiSummary&&e.jsxs("div",{style:{background:"var(--color-surface-hover)",padding:"0.5rem 0.75rem",borderRadius:"4px",fontSize:"0.875rem",marginBottom:"0.5rem"},children:[e.jsx("strong",{children:"AI Summary:"})," ",r.aiSummary]}),r.transcript&&e.jsx("div",{style:{fontSize:"0.875rem",color:"var(--color-text)",borderLeft:"3px solid var(--color-primary)",paddingLeft:"0.75rem",margin:"0.5rem 0"},children:e.jsxs("em",{children:['"',r.transcript,'"']})}),r.recordingSid&&e.jsxs("div",{style:{background:"var(--color-surface-hover)",padding:"0.625rem 0.75rem",borderRadius:"4px",margin:"0.5rem 0"},children:[e.jsxs("div",{style:{fontSize:"0.75rem",marginBottom:"0.25rem",fontWeight:600},children:["🎙️ Voicemail Audio (",r.recordingSid,")"]}),e.jsx(E,{recordingSid:r.recordingSid,showDownload:!0,downloadFilename:`voicemail_${r.recordingSid}.mp3`})]}),e.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",fontSize:"0.75rem",color:"var(--color-text-muted)",marginTop:"0.5rem",paddingTop:"0.375rem",borderTop:"1px dashed var(--color-border)"},children:[e.jsxs("div",{children:["Call SID: ",e.jsx("code",{children:r.id})," | Conv Ref: ",e.jsx("code",{children:r.conversationId})]}),e.jsxs("div",{style:{display:"flex",gap:"0.75rem"},children:[e.jsx(c,{to:`/staff/messages?caller=${encodeURIComponent(r.caller)}`,style:{color:"var(--color-primary)",textDecoration:"underline"},children:"Caller Dossier →"}),e.jsx("a",{href:r.twilioConsoleUrl||`https://console.twilio.com/us1/develop/voice/manage/call-logs/${r.id}`,target:"_blank",rel:"noopener noreferrer",style:{color:"var(--color-primary)",textDecoration:"underline"},children:"Twilio Console ↗"})]})]})]},r.id))})]})]})};export{V as AdminCommunicationsPage};

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.