@realtek/core-theme 0.0.368 → 0.0.369
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-lib/{FacebookCourseMappingsSection-C7qyexlU.cjs → FacebookCourseMappingsSection-AYu5JiEt.cjs} +3 -3
- package/dist-lib/FacebookCourseMappingsSection-AYu5JiEt.cjs.map +1 -0
- package/dist-lib/{FacebookCourseMappingsSection-C49voxq7.js → FacebookCourseMappingsSection-kmMbflwV.js} +347 -256
- package/dist-lib/FacebookCourseMappingsSection-kmMbflwV.js.map +1 -0
- package/dist-lib/index.cjs +19 -19
- package/dist-lib/index.cjs.map +1 -1
- package/dist-lib/index.js +4290 -4299
- package/dist-lib/index.js.map +1 -1
- package/package.json +1 -1
- package/dist-lib/FacebookCourseMappingsSection-C49voxq7.js.map +0 -1
- package/dist-lib/FacebookCourseMappingsSection-C7qyexlU.cjs.map +0 -1
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
const e=require("./rolldown-runtime-Chgba0Kb.cjs"),t=require("./authApi-D0LZjLV6.cjs");let n=require("react"),r=require("antd"),i=require("@ant-design/icons"),a=require("react/jsx-runtime"),o=require("dayjs");o=e.n(o,1);function s({className:e=``,variant:t=`default`,showIcon:n=!0,...i}){return(0,a.jsx)(r.Alert,{className:`app-alert app-alert--${t} ${e}`.trim(),showIcon:n,...i})}var c=new Intl.NumberFormat;function l(e){return e==null||e===``?`–`:typeof e==`number`&&Number.isFinite(e)?c.format(e):String(e)}function u({items:e=[],loading:t=!1,className:n=``,ariaLabel:i=`Summary`}){return t&&e.length===0?(0,a.jsx)(`div`,{className:`cc-stat-strip ${n}`.trim(),"aria-busy":`true`,"aria-label":i,children:[0,1,2,3].map(e=>(0,a.jsx)(`div`,{className:`cc-stat`,children:(0,a.jsx)(r.Skeleton.Button,{active:!0,size:`small`,style:{width:56}})},e))}):e.length===0?null:(0,a.jsx)(`div`,{className:`cc-stat-strip ${n}`.trim(),role:`group`,"aria-label":i,"aria-busy":t||void 0,children:e.map(e=>{let t=(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(`span`,{className:`cc-stat__value`,children:l(e.value)}),(0,a.jsx)(`span`,{className:`cc-stat__label`,children:e.label})]});return typeof e.onClick==`function`?(0,a.jsx)(`button`,{type:`button`,className:`cc-stat cc-stat--button${e.active?` is-active`:``}`,onClick:e.onClick,"aria-pressed":e.active?!0:void 0,children:t},e.key):(0,a.jsx)(`div`,{className:`cc-stat`,children:t},e.key)})})}var d=`${t.y}/admin/facebook`;async function f(e,n={}){let r=t.u(),i=await fetch(`${d}${e}`,{...n,headers:{"Content-Type":`application/json`,...t.O({"X-App-Id":String(t.b)}),...r?{Authorization:`Bearer ${r}`}:{},...n.headers||{}}}),a=await i.json().catch(()=>({}));if(!i.ok||a?.status===!1){let e=Error(a?.error||a?.message||a?.reason||`HTTP ${i.status}`);throw e.status=i.status,e}return a?.data??a}var p=()=>f(`/forms`),m=()=>f(`/courses`),h=()=>f(`/course-mappings`),ee=(e,t=!1)=>f(t?`/course-mappings/${encodeURIComponent(e.formId)}`:`/course-mappings`,{method:t?`PUT`:`POST`,body:JSON.stringify(e)}),g=e=>f(`/course-mappings/${encodeURIComponent(e)}`,{method:`DELETE`}),_=`${t.y}/admin/facebook`,v=`Could not connect. Check your internet connection and try again.`,y=`You don't have permission to do this. Ask your administrator for access.`,b=`Something went wrong. Please try again.`;function x(e,t=``){return e===401?`Your session has ended. Please sign in again.`:e===403?y:e===404?`This could not be found. Refresh the page and try again.`:e===409?t||`Someone else changed this. Refresh the page and try again.`:e>=500?`The server could not finish this. Please try again in a moment.`:t||b}function S(e,t=b,{hideServerText:n=!1}={}){if(e?.plain)return e.message;let r=String(e?.message||``);if(typeof e?.status==`number`)return x(e.status,r);let i=/^HTTP (\d{3})$/.exec(r);return i?x(Number(i[1])):e instanceof TypeError||/failed to fetch|networkerror|load failed/i.test(r)?v:/forbidden|permission|not allowed/i.test(r)?y:n?t:r||t}function C(e,t){let n=Error(e===0?v:x(e,t));return n.status=e,n.plain=!0,n.serverMessage=t,n}async function w(e,n={}){let r=t.u();if(!r)throw C(401,``);let i;try{i=await fetch(`${_}${e}`,{...n,headers:{"Content-Type":`application/json`,...t.O({"X-App-Id":String(t.b)}),Authorization:`Bearer ${r}`,...n.headers||{}}})}catch{throw C(0,``)}let a=await i.json().catch(()=>({}));if(!i.ok||a.status===!1)throw C(i.status,a.error||a.message||``);return a.data??a}var T=()=>w(`/distributions`).then(e=>Array.isArray(e)?e:e.distributions||[]);async function E(){let e=[];for(let t=1;t<=1e3;t++){let n=await w(`/counsellors?page=${t}&limit=100`);if(!Array.isArray(n.counsellors))throw Error(`Could not read the list of counsellors. Please try again.`);if(e.push(...n.counsellors),t>=Number(n.totalPages||0)||!n.counsellors.length)return e}throw Error(`The list of counsellors is too long to load. Please contact support.`)}var te=({formId:e,counsellorIds:t,isActive:n,version:r},i)=>w(i?`/distribution/${encodeURIComponent(e)}`:`/distribution`,{method:i?`PUT`:`POST`,body:JSON.stringify({formId:e,counsellorIds:t,isActive:n,...r==null?{}:{version:r}})});function D({page:e=1,limit:t=20,formId:n=``}={}){let r=new URLSearchParams({page:String(e),limit:String(t)});return n&&r.set(`formId`,n),w(`/distribution-skips?${r}`)}function ne({status:e=`unassigned`,page:t=1,limit:n=20,formId:r=``}={}){let i=new URLSearchParams({status:e,page:String(t),limit:String(n)});return r&&i.set(`formId`,r),w(`/unassigned-leads?${i}`)}var re=e=>w(`/distribution/${encodeURIComponent(e)}`,{method:`DELETE`}),O=()=>w(`/distribution-alerts`),k=()=>w(`/reassign/summary`).then(e=>e.counsellors||[]);function ie({fromUserId:e,formId:t=``,page:n=1,limit:r=20}={}){let i=new URLSearchParams({fromUserId:e,page:String(n),limit:String(r)});return t&&i.set(`formId`,t),w(`/reassign/leads?${i}`)}var ae=e=>w(`/reassign`,{method:`POST`,body:JSON.stringify(e)});function A({page:e=1,limit:t=20,formId:n=``,leadId:r=``}={}){let i=new URLSearchParams({page:String(e),limit:String(t)});return n&&i.set(`formId`,n),r&&i.set(`leadId`,r),w(`/reassignments?${i}`)}var oe=()=>w(`/meta`);function j({page:e=1,limit:t=20,formId:n=``}={}){let r=new URLSearchParams({page:String(e),limit:String(t)});return n&&r.set(`formId`,n),w(`/failed-leads?${r}`)}var se=e=>w(`/failed-leads/${encodeURIComponent(e)}/retry`,{method:`POST`});function ce({page:e=1,limit:t=20,formId:n=``}={}){let r=new URLSearchParams({page:String(e),limit:String(t)});return n&&r.set(`formId`,n),w(`/history?${r}`)}var M=e=>{let t=new URLSearchParams;Object.entries(e||{}).forEach(([e,n])=>{n!=null&&n!==``&&t.set(e,String(n))});let n=t.toString();return n?`?${n}`:``},N=e=>w(`/distribution/overview${M({date:e})}`),le=()=>w(`/distribution/settings`),P=e=>w(`/distribution/settings`,{method:`PUT`,body:JSON.stringify(e)}),F=(e,t,n=``)=>w(`/distribution/counsellors/${encodeURIComponent(e)}/enabled`,{method:`PUT`,body:JSON.stringify({enabled:t,reason:n})}),ue=e=>w(`/distribution/leaves${M({from:e})}`),de=e=>w(`/distribution/leaves`,{method:`POST`,body:JSON.stringify(e)}),I=e=>w(`/distribution/leaves/${encodeURIComponent(e)}`,{method:`DELETE`}),L=e=>w(`/distribution/queue${M(e)}`),R=e=>w(`/distribution/assignments${M(e)}`),{Text:z}=r.Typography,fe=e=>e?new Date(e).toLocaleString():`—`,B=(e,t)=>`${e} ${t}${e===1?``:`s`}`,V=[{value:`on_leave`,label:`On leave`},{value:`left_company`,label:`Left the company`},{value:`workload`,label:`Workload balancing`},{value:`other`,label:`Other`}],H={no_active_counsellor:`no active counsellor`,distribution_not_configured:`no counsellors set up for the form`,distribution_disabled:`automatic turns are paused`,default_owner_inactive_or_missing:`default owner inactive`},U={not_open_or_not_assigned_to_counsellor:`no longer open or no longer with this counsellor`,changed_during_reassign:`was updated by the counsellor while moving (run again)`,update_failed:`could not be saved`};function W({canEdit:e=!0,fromId:t,toId:n,movingCount:r,reasonOk:i,minReason:a}){if(!e)return`You don't have permission to move leads.`;let o=[];return t||o.push(`choose who the leads are moving from`),r||o.push(`choose at least one lead`),n||o.push(`choose who gets the leads`),i||o.push(`write a reason of at least ${a} characters`),o.length?`To continue, ${o.join(`, `)}.`:``}function G({id:e,rows:t=[],value:i,onChange:o,minWidth:s=260}){let c=(0,n.useMemo)(()=>t.map(e=>({value:e.formId,label:e.formName})),[t]);return(0,a.jsx)(r.Select,{id:e,showSearch:!0,optionFilterProp:`label`,allowClear:!0,style:{minWidth:s,maxWidth:`100%`},"aria-label":`Facebook form`,placeholder:`All Facebook forms`,value:i||void 0,onChange:e=>o(e||``),options:c,popupMatchSelectWidth:!1,notFoundContent:`No matching forms`})}function pe({refreshKey:e=0,pollMs:t=6e4}={}){let[r,i]=(0,n.useState)({alerts:null,alertsOk:!1,failedCount:null});return(0,n.useEffect)(()=>{let e=!0,n=()=>{typeof document<`u`&&document.hidden||Promise.allSettled([O(),j({page:1,limit:1})]).then(([t,n])=>{e&&i(e=>({alerts:t.status===`fulfilled`?t.value:e.alerts,alertsOk:t.status===`fulfilled`,failedCount:n.status===`fulfilled`?Number(n.value?.failedCount??n.value?.total??0):null}))})};n();let r=setInterval(n,t);return()=>{e=!1,clearInterval(r)}},[e,t]),r}function me(e){let t=[...e?.formsWithoutActiveCounsellor||[],...e?.waitingForms||[]].map(e=>String(e.formId)).filter(Boolean);return[...new Set(t)]}function K({alerts:e,failedCount:t=0,onViewLeads:n,onShowForms:i}){let o=Number(e?.unassignedCount||0),c=e?.formsWithoutActiveCounsellor||[],l=Number(t||0),u=me(e);if(!o&&!c.length&&!l)return null;let d=[];o&&d.push(`${B(o,`lead`)} waiting`),c.length&&d.push(`${B(c.length,`form`)} with no active counsellor`),l&&d.push(`${B(l,`lead`)} failed`);let f=[...new Set([...c,...e?.waitingForms||[]].map(e=>e.formName).filter(Boolean))],p=f.slice(0,2).join(`, `),m=f.length>2?` and ${f.length-2} more`:``;return(0,a.jsx)(s,{className:`fb-attention`,type:`warning`,title:d.join(` · `),description:p?`${p}${m}`:void 0,action:(0,a.jsxs)(`div`,{className:`fb-attention-actions`,children:[(o>0||l>0)&&n&&(0,a.jsx)(r.Button,{size:`small`,onClick:n,children:`View leads`}),u.length>0&&i&&(0,a.jsx)(r.Button,{size:`small`,onClick:()=>i(u),children:`Show these forms`})]})})}function he({rows:e=[],eligibleCounsellors:t=[],onChanged:o,limits:s,reasonTypes:c,canEdit:l=!0,refreshKey:u=0}){let[d,f]=(0,n.useState)([]),[p,m]=(0,n.useState)(!1),[h,ee]=(0,n.useState)(``),[g,_]=(0,n.useState)(``),[v,y]=(0,n.useState)({leads:[],total:0}),[b,x]=(0,n.useState)(!1),[S,C]=(0,n.useState)(1),[w,T]=(0,n.useState)([]),[E,te]=(0,n.useState)(!1),[D,ne]=(0,n.useState)(``),[re,O]=(0,n.useState)(`on_leave`),[oe,j]=(0,n.useState)(``),[se,ce]=(0,n.useState)(!1),[M,N]=(0,n.useState)(``),[le,P]=(0,n.useState)({reassignments:[],total:0}),[F,ue]=(0,n.useState)(1),[de,I]=(0,n.useState)(!1),L=Number(s?.minReason)||5,R=Number(s?.maxReason)||500,B=Number(s?.maxPerRun)||500,H=c?.length?c:V,pe=Object.fromEntries(H.map(e=>[e.value,e.label])),me=pe[re]?re:H[0]?.value,K=(0,n.useCallback)(async()=>{m(!0);try{f(await k()),N(``)}catch(e){N(e.message)}finally{m(!1)}},[]),he=(0,n.useCallback)(async()=>{if(!h){y({leads:[],total:0});return}x(!0);try{y(await ie({fromUserId:h,formId:g,page:S,limit:20})),N(``)}catch(e){N(e.message),y({leads:[],total:0})}finally{x(!1)}},[h,g,S]),q=(0,n.useCallback)(async()=>{I(!0);try{P(await A({page:F,limit:10}))}catch(e){N(e.message)}finally{I(!1)}},[F]);(0,n.useEffect)(()=>{K()},[K,u]),(0,n.useEffect)(()=>{he()},[he,u]),(0,n.useEffect)(()=>{q()},[q,u]);let J=d.find(e=>e.userId===h),ge=Number(v.total||0),Y=E?Math.min(ge,B):w.length,_e=(0,n.useMemo)(()=>t.filter(e=>e.userId!==h&&e.isActive!==!1).map(e=>({value:e.userId,label:e.name||e.email||e.userId})),[t,h]),X=_e.find(e=>e.value===D)?.label||``,ve=oe.trim().length>=L,ye=W({canEdit:l,fromId:h,toId:D,movingCount:Y,reasonOk:ve,minReason:L}),be=!ye&&!se,xe=e=>{ee(e),C(1),T([]),te(!1),ne(``)},Se=e=>{_(e),C(1),T([]),te(!1)},Ce=async()=>{ce(!0);try{let e=await ae({fromUserId:h,toUserId:D,reasonType:me,reason:oe.trim(),...g?{formId:g}:{},...E?{allOpen:!0}:{leadIds:w}}),t=e.skipped||[];if(r.message.success(`${e.moved} lead${e.moved===1?``:`s`} moved to ${e.to?.name||X}`),t.length){let e=t.reduce((e,t)=>({...e,[t.reason]:(e[t.reason]||0)+1}),{});r.Modal.warning({title:`${t.length} lead${t.length===1?` was`:`s were`} not moved`,content:(0,a.jsx)(`ul`,{style:{paddingLeft:18},children:Object.entries(e).map(([e,t])=>(0,a.jsxs)(`li`,{children:[t,` — `,U[e]||e]},e))})})}e.auditSaved===!1&&r.message.warning(`Leads were moved, but the history row could not be saved. Each lead still has its own activity entry.`),e.remaining>0&&r.message.info(`${e.remaining} open lead${e.remaining===1?``:`s`} still with ${e.from?.name||`this counsellor`}. Run again to move them.`),T([]),te(!1),j(``),await Promise.all([K(),he(),q()]),o&&o()}catch(e){r.message.error(e.message||`Could not reassign leads`)}finally{ce(!1)}},we=()=>r.Modal.confirm({title:`Move ${Y} lead${Y===1?``:`s`} to ${X}?`,okText:`Reassign`,width:520,content:(0,a.jsxs)(`div`,{children:[(0,a.jsxs)(`p`,{style:{marginBottom:6},children:[`From `,(0,a.jsx)(`strong`,{children:J?.name||`selected counsellor`}),` to `,(0,a.jsx)(`strong`,{children:X}),`.`]}),(0,a.jsxs)(`p`,{style:{marginBottom:6},children:[`Reason: `,(0,a.jsx)(`strong`,{children:pe[me]}),` — `,oe.trim()]}),(0,a.jsx)(z,{type:`secondary`,children:`Each lead gets an activity entry and a history row. The previous counsellor stops seeing these leads. Pending follow-up reminders are not moved.`})]}),onOk:Ce}),Te=[{title:`Lead`,dataIndex:`name`,render:(e,t)=>(0,a.jsxs)(`div`,{children:[(0,a.jsx)(z,{strong:!0,children:e||t.leadCode||t.facebookLeadId}),(0,a.jsx)(`div`,{children:(0,a.jsx)(z,{type:`secondary`,className:`fb-small`,children:t.leadCode||t.facebookLeadId})})]})},{title:`Facebook form`,dataIndex:`formName`,render:e=>e||`Unknown form`},{title:`Status`,dataIndex:`status`,render:e=>(0,a.jsx)(r.Tag,{children:e||`New Lead`})},{title:`Received`,dataIndex:`createdAt`,render:fe}],Ee=[{title:`When`,dataIndex:`reassignedAt`,render:fe},{title:`Lead`,dataIndex:`leadCode`,render:(e,t)=>e||t.facebookLeadId||`—`},{title:`From → To`,render:(e,t)=>(0,a.jsxs)(`span`,{children:[t.fromName,` `,(0,a.jsx)(i.SwapOutlined,{}),` `,t.toName]})},{title:`Reason`,render:(e,t)=>(0,a.jsxs)(`div`,{children:[(0,a.jsx)(r.Tag,{children:pe[t.reasonType]||`Other`}),(0,a.jsx)(`div`,{style:{fontSize:12},children:t.reason})]})},{title:`By`,dataIndex:`performedByName`}];return(0,a.jsxs)(`div`,{className:`fb-tab-body`,children:[(0,a.jsx)(z,{type:`secondary`,className:`fb-tab-intro`,children:`Automatic turns keep sending leads to a counsellor who is on leave. Move their open leads to someone else here.`}),M&&(0,a.jsx)(r.Alert,{type:`error`,showIcon:!0,title:`Could not load everything for this tab`,description:M,className:`fb-block`}),(0,a.jsxs)(`div`,{className:`fb-field-row`,children:[(0,a.jsxs)(`div`,{className:`fb-field`,children:[(0,a.jsx)(`label`,{className:`fb-field-label`,htmlFor:`fb-reassign-from`,children:`From`}),(0,a.jsx)(r.Select,{id:`fb-reassign-from`,showSearch:!0,optionFilterProp:`label`,placeholder:`Choose a counsellor`,value:h||void 0,onChange:xe,loading:p,notFoundContent:`No counsellor has open Facebook leads`,options:d.map(e=>({value:e.userId,label:`${e.name} — ${e.openLeads} open${e.isActive?``:` (inactive)`}`}))})]}),(0,a.jsxs)(`div`,{className:`fb-field`,children:[(0,a.jsx)(`label`,{className:`fb-field-label`,htmlFor:`fb-reassign-form`,children:`Form`}),(0,a.jsx)(G,{id:`fb-reassign-form`,rows:e,value:g,onChange:Se,minWidth:0})]})]}),h&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)(`div`,{className:`fb-block`,children:[(0,a.jsxs)(r.Radio.Group,{value:E?`all`:`pick`,onChange:e=>{te(e.target.value===`all`),e.target.value===`all`&&T([])},children:[(0,a.jsx)(r.Radio.Button,{value:`pick`,children:`Choose leads`}),(0,a.jsxs)(r.Radio.Button,{value:`all`,children:[`All `,ge,` open lead`,ge===1?``:`s`]})]}),E&&ge>B&&(0,a.jsxs)(z,{type:`secondary`,className:`fb-hint-inline`,children:[`Moves `,B,` per run. Run again for the rest.`]})]}),(0,a.jsx)(r.Table,{size:`small`,rowKey:`id`,loading:b,columns:Te,dataSource:v.leads,rowSelection:E?void 0:{selectedRowKeys:w,preserveSelectedRowKeys:!0,onChange:e=>T(e)},pagination:{current:S,pageSize:20,total:ge,showSizeChanger:!1,onChange:C},locale:{emptyText:`No open Facebook leads for this counsellor`},scroll:{x:640}}),(0,a.jsxs)(`div`,{className:`fb-reassign-fields`,children:[(0,a.jsxs)(`div`,{className:`fb-field`,children:[(0,a.jsx)(`label`,{className:`fb-field-label`,htmlFor:`fb-reassign-to`,children:`To`}),(0,a.jsx)(r.Select,{id:`fb-reassign-to`,showSearch:!0,optionFilterProp:`label`,placeholder:`Choose an active counsellor`,value:D||void 0,onChange:ne,options:_e,notFoundContent:`No other active counsellor available`})]}),(0,a.jsxs)(`div`,{className:`fb-field`,children:[(0,a.jsx)(`label`,{className:`fb-field-label`,htmlFor:`fb-reassign-type`,children:`Reason type`}),(0,a.jsx)(r.Select,{id:`fb-reassign-type`,value:me,onChange:O,options:H})]}),(0,a.jsxs)(`div`,{className:`fb-field`,children:[(0,a.jsx)(`label`,{className:`fb-field-label`,htmlFor:`fb-reassign-reason`,children:`Reason`}),(0,a.jsx)(r.Input.TextArea,{id:`fb-reassign-reason`,rows:2,maxLength:R,showCount:!0,value:oe,onChange:e=>j(e.target.value),placeholder:`For example, on leave 3–7 Nov`,"aria-describedby":`fb-reassign-reason-hint`,status:oe&&!ve?`error`:void 0}),!ve&&(0,a.jsxs)(`div`,{id:`fb-reassign-reason-hint`,className:`fb-hint`,children:[`At least `,L,` characters`]})]}),(0,a.jsxs)(`div`,{children:[(0,a.jsx)(r.Button,{type:`primary`,icon:(0,a.jsx)(i.SwapOutlined,{}),disabled:!be,loading:se,onClick:we,children:Y?`Reassign ${Y} lead${Y===1?``:`s`}`:`Reassign`}),ye&&(0,a.jsx)(`div`,{className:`fb-hint`,role:`status`,children:ye})]})]})]}),(0,a.jsx)(r.Collapse,{ghost:!0,className:`fb-history-collapse`,items:[{key:`history`,label:`Reassignment history`,children:(0,a.jsx)(r.Table,{size:`small`,rowKey:`id`,loading:de,columns:Ee,dataSource:le.reassignments,pagination:{current:F,pageSize:10,total:Number(le.total||0),showSizeChanger:!1,onChange:ue},locale:{emptyText:`No leads have been reassigned yet`},scroll:{x:720}})}]})]})}var{Text:q}=r.Typography,J=e=>String(e?.userId||``),ge=50,Y=e=>{let t=e?new Date(e):null;return t&&!Number.isNaN(t.getTime())?t.toLocaleString():`—`},_e=e=>e&&e.charAt(0).toUpperCase()+e.slice(1),X={ready:{label:`Ready`,tone:`good`},needs_setup:{label:`Needs setup`,tone:`warn`},paused:{label:`Paused`,tone:`muted`},no_active:{label:`No active counsellor`,tone:`bad`},unknown_form:{label:`Unknown form`,tone:`muted`}},ve={inactive:`Inactive`,locked:`Account locked`,deleted:`Deleted`,not_counsellor:`No longer a counsellor`,unavailable:`Unavailable`},ye=e=>ve[e]||`Unavailable`,be={meta_fetch:`Could not read the lead from Facebook`,lms_create:`Could not create the lead`,invalid_lead_fields:`The lead had unreadable details`,course_mapping:`Could not read the course for this form`,contact_lookup:`Could not check for a duplicate`,database_lookup:`Could not check for a duplicate`,distribution_lookup:`Could not find the counsellor list`,configuration_disabled:`Facebook import was switched off`,unassigned_audit:`Could not add the lead to the waiting list`,meta_forms:`Could not read the forms from Facebook`,mismatched_page_or_form:`The lead came from a different Facebook page or form`,mismatched_meta_form:`The lead came from a different Facebook page or form`},xe=e=>be[e]||`Failed`,Se=e=>_e(H[e])||`Waiting for setup`,Ce=e=>{if(!e||typeof e!=`object`)return null;let t=e.counsellorIds||e.counsellors;return Array.isArray(t)?t.map(e=>String(e?.userId??e?.legacyUserId??e)):null};function we(e){let{area:t,action:n,before:r,after:i}=e||{},a=String(t||``).toLowerCase(),o=String(n||``).toLowerCase(),s=/delete|remove/.test(o),c=/create|add/.test(o)||!r;if(/retry/.test(o)||/failed/.test(a))return`Retried failed lead`;if(/mapping|course/.test(a)){if(s)return`Course removed`;let e=i?.courseName,t=(r?.courseId??r?.courseName)!==(i?.courseId??i?.courseName);return e&&(c||t)?`Course ${c?`set to`:`changed to`} ${e}`:typeof r?.isActive==`boolean`&&typeof i?.isActive==`boolean`&&r.isActive!==i.isActive?i.isActive?`Course turned on`:`Course turned off`:`Course changed`}if(/distribution|counsellor/.test(a)){if(s)return`Counsellors removed`;if(c)return`Counsellors set up`;if(typeof r?.isActive==`boolean`&&typeof i?.isActive==`boolean`&&r.isActive!==i.isActive)return i.isActive?`Resumed`:`Paused`;let e=Ce(r),t=Ce(i);return e&&t&&e.length===t.length&&[...e].sort().join()===[...t].sort().join()?`Order changed`:`Counsellors changed`}return`Setup changed`}function Te({mapping:e,distribution:t,inFormsList:n=!0},r={}){let{forms:i=!0,mappings:a=!0,distributions:o=!0}=r;if(!a||!o)return null;if(i&&!n)return`unknown_form`;let s=t?.counsellors||[];return!e||!e.isActive||!t||!s.length?`needs_setup`:t.isActive===!1?`paused`:s.some(e=>e.isActive!==!1)?`ready`:`no_active`}function Ee(e){let t=e?.counsellors||[];if(!t.length)return``;let n=Math.max(t.findIndex(t=>J(t)===String(e.nextUserId||``)),0);return[...t.slice(n),...t.slice(0,n)].find(e=>e.isActive!==!1)?.name||``}function De(e,t,n){if(t===n||t<0||n<0||t>=e.length||n>=e.length)return e;let r=[...e],[i]=r.splice(t,1);return r.splice(n,0,i),r}function Oe(e,t){if(!t.length)return``;let n=(e?.counsellors||[]).map(J).filter(Boolean),r=String(e?.nextUserId||``);if(n.length===t.length&&n.every((e,n)=>e===t[n])&&t.includes(r))return r;let i=String(e?.lastAssignedUserId||``);if(!i&&n.includes(r)&&(i=n[(n.indexOf(r)-1+n.length)%n.length]),t.includes(i))return t[(t.indexOf(i)+1)%t.length];if(n.includes(i)){let e=n.indexOf(i);for(let r=1;r<=n.length;r++){let i=n[(e+r)%n.length];if(t.includes(i))return i}}return t.includes(r)?r:t[0]}async function ke({mapping:e,distribution:t,saveMapping:n,saveDistribution:r}){let i={mappingSaved:!1,distributionSaved:!1,failedPart:``,error:null};if(e)try{await n(e.input,e.isEdit),i.mappingSaved=!0}catch(e){return{...i,failedPart:`mapping`,error:e}}if(t)try{await r(t.input,t.isEdit),i.distributionSaved=!0}catch(e){return{...i,failedPart:`distribution`,error:e}}return i}var Ae=e=>e.length<2?e[0]||``:`${e.slice(0,-1).join(`, `)} and ${e[e.length-1]}`;function je(e){return e.length?e.length===1?`${e[0]} is inactive and will be skipped. Remove them or keep the place for when they return.`:`${Ae(e)} are inactive and will be skipped. Remove them or keep their places for when they return.`:``}function Me({status:e}){let t=X[e];return t?(0,a.jsxs)(r.Tag,{className:`fb-status fb-status--${t.tone}`,children:[(0,a.jsx)(`span`,{className:`fb-status-dot`,"aria-hidden":`true`}),t.label]}):(0,a.jsx)(q,{type:`secondary`,children:`—`})}function Ne({number:e,title:t,aside:n}){return(0,a.jsxs)(`div`,{className:`fb-setup-heading`,children:[(0,a.jsxs)(`h3`,{children:[(0,a.jsx)(`span`,{className:`fb-setup-number`,"aria-hidden":`true`,children:e}),t]}),n&&(0,a.jsx)(`span`,{className:`fb-setup-aside`,children:n})]})}var Pe=(e,t)=>({base:{mapping:e||null,current:t||null},courseId:e?.courseId||void 0,mappingActive:e?.isActive??!0,orderedIds:(t?.counsellors||[]).map(J).filter(Boolean),enabled:t?.isActive!==!1});function Fe({open:e,row:t,mapping:o,current:s,courses:c=[],counsellors:l=[],limits:u,permissions:d={},section:f=`course`,onClose:p,onSaved:m,onReload:h,onAfterClose:g}){let[_]=(0,n.useState)(()=>Pe(o,s)),[v,y]=(0,n.useState)(_.base),[b,x]=(0,n.useState)(_.courseId),[C,w]=(0,n.useState)(_.mappingActive),[T,E]=(0,n.useState)(_.orderedIds),[D,ne]=(0,n.useState)(_.enabled),[re,O]=(0,n.useState)(``),[k,ie]=(0,n.useState)(!1),[ae,A]=(0,n.useState)(``),[oe,j]=(0,n.useState)(``),[se,ce]=(0,n.useState)(null),[M,N]=(0,n.useState)(null),le=(0,n.useRef)(null),P=(0,n.useRef)(null),F=(0,n.useRef)(null),ue=(0,n.useRef)(!1),{canAdd:de=!0,canEdit:I=!0}=d,L=v.mapping?I:de,R=v.current?I:de,z=!L&&!R,fe=Number(u?.maxCounsellors)||ge,B=v.current?.counsellors,V=v.mapping,H=(0,n.useMemo)(()=>{let e=new Map(l.map(e=>[J(e),{...e,isActive:!0}]));return(B||[]).forEach(t=>{let n=J(t);e.has(n)||e.set(n,{...t,isActive:!1})}),e},[l,B]),U=(0,n.useCallback)(e=>H.get(e)?.name||`Unnamed counsellor`,[H]),W=(0,n.useMemo)(()=>new Set(T),[T]),G=T.map(e=>H.get(e)).filter(Boolean),pe=[...l].filter(e=>!W.has(J(e))).sort((e,t)=>String(e.name).localeCompare(String(t.name))),me=[...G,...pe].filter(e=>`${e.name||``} ${e.email||``}`.toLowerCase().includes(re.trim().toLowerCase())),K=G.filter(e=>!e.isActive),he=G.length-K.length,Y=(v.current?.counsellors||[]).map(J).filter(Boolean),_e=Y.length!==T.length||Y.some((e,t)=>e!==T[t]),X=v.current?_e||D!==(v.current.isActive!==!1):T.length>0,ve=v.mapping?String(b)!==String(v.mapping.courseId)||C!==v.mapping.isActive:!!b,ye=ve||X,be=Oe(v.current,T),xe=T.indexOf(be),Se=(xe<0?T:[...T.slice(xe),...T.slice(0,xe)]).find(e=>H.get(e)?.isActive)||``,Ce=H.get(Se)?.name||`No one yet`,we=(0,n.useMemo)(()=>{let e=c.map(e=>({value:e.courseId,label:e.courseName}));return V?.courseId&&!e.some(e=>e.value===V.courseId)&&e.unshift({value:V.courseId,label:V.courseName||`Course no longer available`}),e},[c,V]),Te=(e,t)=>{let n=Pe(e,t);y(n.base),x(n.courseId),w(n.mappingActive),E(n.orderedIds),ne(n.enabled)},Ee=(e,t)=>{E(n=>t?[...n.filter(t=>t!==e),e]:n.filter(t=>t!==e)),j(t?`${U(e)} added to the list`:`${U(e)} removed from the list`)},Ae=(e,t)=>{let n=T.indexOf(e),r=n+(t===`up`?-1:1);n<0||r<0||r>=T.length||(F.current={id:e,direction:t},E(e=>De(e,n,r)),j(`${U(e)} moved to place ${r+1} of ${T.length}`))};(0,n.useLayoutEffect)(()=>{let e=F.current;if(!e)return;F.current=null;let t=[...le.current?.querySelectorAll(`[data-move-id]`)||[]].filter(t=>t.dataset.moveId===e.id&&!t.disabled);(t.find(t=>t.dataset.moveDirection===e.direction)||t[0])?.focus()},[T]);let Me=(e,t)=>{N(t),e.dataTransfer.effectAllowed=`move`,e.dataTransfer.setData(`text/plain`,t)},Fe=(e,t,n)=>{!n||!M||M===t||(e.preventDefault(),ce(t))},Ie=()=>{N(null),ce(null)},Le=e=>{let t=M;Ie(),!(!W.has(t)||!W.has(e)||t===e)&&(E(n=>De(n,n.indexOf(t),n.indexOf(e))),j(`${U(t)} moved`))},Re=()=>{if(!k){if(!ye){p();return}ue.current||(ue.current=!0,r.Modal.confirm({title:`Discard your changes?`,content:`Your changes to this form have not been saved.`,okText:`Discard changes`,okType:`danger`,cancelText:`Keep editing`,autoFocusButton:`cancel`,onOk:()=>{ue.current=!1,p()},onCancel:()=>{ue.current=!1}}))}},ze=(0,a.jsxs)(`div`,{className:`fb-setup-footer`,children:[ae&&(0,a.jsx)(r.Alert,{type:`error`,showIcon:!0,title:ae,className:`fb-setup-problem`}),(0,a.jsxs)(`div`,{className:`fb-setup-footer-actions`,children:[(0,a.jsx)(r.Button,{onClick:Re,disabled:k,children:z?`Close`:`Cancel`}),!z&&(0,a.jsx)(r.Button,{type:`primary`,loading:k,disabled:!ye,onClick:async()=>{if(A(``),X&&!T.length){A(`Choose at least one counsellor. To stop using counsellors on this form, use Remove distribution in the form menu.`);return}if(X&&T.length>fe){A(`You can choose up to ${fe} counsellors. You have chosen ${T.length}.`);return}ie(!0);let e=await ke({mapping:ve?{input:{formId:t.formId,courseId:b,isActive:C},isEdit:!!v.mapping}:null,distribution:X?{input:{formId:t.formId,counsellorIds:T,isActive:D,version:v.current?.version??0},isEdit:!!v.current}:null,saveMapping:ee,saveDistribution:te});if(!e.error){ie(!1),r.message.success(`Form setup saved`),m?.(),p();return}let n=e.mappingSaved?`The course was saved. `:``;if(e.failedPart===`mapping`)A(`Nothing was saved. The course could not be saved: ${S(e.error)}`);else if(e.error?.status===409)try{let e=await h();Te(e?.mapping,e?.current),A(`${n}Someone else changed these counsellors while you were editing, so yours were not saved. The latest list is now showing. Check it and save again.`)}catch{A(`${n}Someone else changed these counsellors while you were editing, so yours were not saved. The latest list could not be loaded. Close this panel and open it again.`)}else e.mappingSaved&&y(e=>({...e,mapping:{...e.mapping||{},formId:t.formId,courseId:b,isActive:C,courseName:we.find(e=>e.value===b)?.label||e.mapping?.courseName||``}})),A(`${n}The counsellors were not saved: ${S(e.error)}`);e.mappingSaved&&m?.(),ie(!1)},children:`Save`})]})]}),Be=!!(v.mapping||v.current);return(0,a.jsxs)(r.Drawer,{open:e,size:560,rootClassName:`fb-setup-drawer`,keyboard:!0,mask:{closable:!0},title:(0,a.jsxs)(`span`,{className:`fb-setup-title`,children:[Be?`Edit`:`Set up`,` form`]}),onClose:Re,footer:ze,afterOpenChange:e=>{e&&f===`counsellors`&&P.current?.scrollIntoView?.({block:`start`}),e||g?.()},children:[(0,a.jsxs)(`div`,{className:`fb-setup-form-name`,children:[(0,a.jsx)(q,{strong:!0,children:t?.formName}),(0,a.jsxs)(q,{type:`secondary`,className:`fb-small`,copyable:{text:t?.formId,tooltips:[`Copy Form ID`,`Copied`]},children:[`Form ID: `,t?.formId]})]}),z&&(0,a.jsx)(r.Alert,{type:`info`,showIcon:!0,title:`You can view this setup, but your role cannot change it.`,className:`fb-block`}),(0,a.jsxs)(`section`,{className:`fb-setup-section`,"aria-label":`Course`,children:[(0,a.jsx)(Ne,{number:`1`,title:`Course`}),(0,a.jsx)(r.Select,{className:`fb-setup-select`,showSearch:!0,optionFilterProp:`label`,"aria-label":`Course`,placeholder:`Choose a course`,value:b,onChange:x,options:we,disabled:!L||k,notFoundContent:`No matching courses`}),b?(0,a.jsxs)(`label`,{className:`fb-setup-toggle`,children:[(0,a.jsxs)(`span`,{children:[(0,a.jsx)(`span`,{className:`fb-setup-toggle-title`,children:`Use this course for new leads`}),(0,a.jsx)(`span`,{className:`fb-hint`,children:`When off, new leads still come in, but without a course.`})]}),(0,a.jsx)(r.Switch,{"aria-label":`Use this course for new leads`,checked:C,onChange:w,disabled:!L||k})]}):(0,a.jsx)(`div`,{className:`fb-hint`,children:`No course yet. You can still choose counsellors, and leads will arrive without a course until you pick one.`})]}),(0,a.jsxs)(`section`,{className:`fb-setup-section`,"aria-label":`Counsellors and order`,ref:P,children:[(0,a.jsx)(Ne,{number:`2`,title:`Counsellors and order`,aside:`${he} active${K.length?`, ${K.length} inactive`:``}`}),K.length>0&&(0,a.jsx)(r.Alert,{type:`warning`,showIcon:!0,className:`fb-block`,title:je(K.map(e=>e.name||`Unnamed counsellor`)),description:R&&(0,a.jsx)(`div`,{className:`fb-inactive-actions`,children:K.map(e=>(0,a.jsxs)(r.Button,{size:`small`,disabled:k,onClick:()=>Ee(J(e),!1),children:[`Remove `,e.name||`Unnamed counsellor`]},J(e)))})}),(0,a.jsx)(r.Input,{allowClear:!0,value:re,prefix:(0,a.jsx)(i.SearchOutlined,{"aria-hidden":`true`}),className:`fb-block`,placeholder:`Search counsellors`,"aria-label":`Search counsellors`,onChange:e=>O(e.target.value)}),(0,a.jsx)(`div`,{className:`fb-dist-draggable-list`,ref:le,children:me.length===0?(0,a.jsx)(r.Empty,{description:l.length||T.length?`No matching counsellors`:`No active counsellors to choose from`}):me.map(e=>{let t=J(e),n=e.name||`Unnamed counsellor`,o=W.has(t),s=T.indexOf(t);return(0,a.jsxs)(`div`,{"data-person-row":t,className:`fb-dist-unified-row ${o?`selected`:``} ${se===t?`drag-over`:``}`,draggable:o&&!k&&R,onDragStart:e=>Me(e,t),onDragOver:e=>Fe(e,t,o),onDrop:e=>{e.preventDefault(),Le(t)},onDragEnd:Ie,children:[(0,a.jsx)(`span`,{className:`fb-dist-check`,children:(0,a.jsx)(r.Checkbox,{"aria-label":`Include ${n}`,checked:o,disabled:k||!R,onChange:e=>Ee(t,e.target.checked)})}),(0,a.jsx)(`span`,{className:`fb-dist-grip ${o?``:`placeholder`}`,"aria-hidden":`true`,children:(0,a.jsx)(i.DragOutlined,{})}),(0,a.jsx)(`span`,{className:`fb-dist-rank`,"aria-hidden":!o,children:o?s+1:``}),(0,a.jsxs)(`div`,{className:`fb-dist-person-name`,children:[(0,a.jsx)(q,{strong:o,children:n}),e.email&&(0,a.jsx)(q,{type:`secondary`,className:`fb-small`,ellipsis:!0,children:e.email})]}),!e.isActive&&(0,a.jsxs)(r.Tag,{className:`fb-status fb-status--bad`,children:[(0,a.jsx)(`span`,{className:`fb-status-dot`,"aria-hidden":`true`}),`Inactive`]}),o&&(0,a.jsxs)(`span`,{className:`fb-dist-order-buttons`,children:[(0,a.jsx)(r.Tooltip,{title:`Move ${n} up`,children:(0,a.jsx)(r.Button,{type:`text`,icon:(0,a.jsx)(i.ArrowUpOutlined,{"aria-hidden":`true`}),"aria-label":`Move ${n} up`,"data-move-id":t,"data-move-direction":`up`,disabled:s<=0||k||!R,onClick:()=>Ae(t,`up`)})}),(0,a.jsx)(r.Tooltip,{title:`Move ${n} down`,children:(0,a.jsx)(r.Button,{type:`text`,icon:(0,a.jsx)(i.ArrowDownOutlined,{"aria-hidden":`true`}),"aria-label":`Move ${n} down`,"data-move-id":t,"data-move-direction":`down`,disabled:s>=T.length-1||k||!R,onClick:()=>Ae(t,`down`)})})]})]},t)})}),(0,a.jsx)(`div`,{className:`fb-sr-only`,"aria-live":`polite`,children:oe}),(0,a.jsxs)(`div`,{className:`fb-dist-next-line`,children:[(0,a.jsx)(i.CheckCircleOutlined,{"aria-hidden":`true`}),(0,a.jsxs)(`span`,{children:[_e?`Next after save`:`Next in saved order`,`: `,(0,a.jsx)(`strong`,{children:Ce})]})]}),(0,a.jsx)(`div`,{className:`fb-hint`,children:`Changes apply to future leads only. Turns carry on from the last person who got a lead, and leads people already have stay with them.`})]}),(0,a.jsxs)(`section`,{className:`fb-setup-section`,"aria-label":`Automatic turns`,children:[(0,a.jsx)(Ne,{number:`3`,title:`Automatic turns`}),(0,a.jsxs)(`label`,{className:`fb-setup-toggle`,children:[(0,a.jsxs)(`span`,{children:[(0,a.jsx)(`span`,{className:`fb-setup-toggle-title`,children:`Send leads to this form automatically`}),(0,a.jsx)(`span`,{className:`fb-hint`,children:`When paused, new leads wait until you turn this back on.`})]}),(0,a.jsx)(r.Switch,{"aria-label":`Send leads to this form automatically`,checked:D,onChange:ne,checkedChildren:`On`,unCheckedChildren:`Paused`,disabled:!R||k})]})]})]})}function Ie(e,t){let[r,i]=(0,n.useState)(0),[a,o]=(0,n.useState)({data:null,error:``,settled:null}),s=(0,n.useMemo)(()=>({load:e,refreshKey:t,tick:r}),[e,t,r]);(0,n.useEffect)(()=>{let e=!0;return s.load().then(t=>{e&&o({data:t,error:``,settled:s})}).catch(t=>{e&&o(e=>({...e,error:S(t),settled:s}))}),()=>{e=!1}},[s]);let c=(0,n.useCallback)(()=>i(e=>e+1),[]),l=a.settled!==s;return{data:a.data,loading:l,error:l?``:a.error,reload:c}}function Le({title:e,resource:t}){return t.error?(0,a.jsx)(r.Alert,{type:`error`,showIcon:!0,className:`fb-block`,title:e,description:`${t.error}${t.data?` Showing the last information we could load.`:``}`,action:(0,a.jsx)(r.Button,{size:`small`,onClick:t.reload,children:`Try again`})}):null}var Re=(e,t)=>t.formName||e.find(e=>e.formId===String(t.formId))?.formName||`Unknown form`;function ze({rows:e=[],canEdit:t=!0,refreshKey:i=0,onChanged:o}){let[s,c]=(0,n.useState)(``),[l,u]=(0,n.useState)(`unassigned`),[d,f]=(0,n.useState)(1),[p,m]=(0,n.useState)(1),h=(0,n.useCallback)(()=>ne({status:l,page:d,limit:20,formId:s}),[l,d,s]),ee=(0,n.useCallback)(()=>j({page:p,limit:20,formId:s}),[p,s]),g=Ie(h,i),_=Ie(ee,i),v=_.reload,y=e=>{c(e),f(1),m(1)},b=t=>{r.Modal.confirm({title:`Try this lead again?`,content:(0,a.jsxs)(`span`,{children:[`We will try to bring in lead `,(0,a.jsx)(`strong`,{children:t.facebookLeadId}),` from `,(0,a.jsx)(`strong`,{children:Re(e,t)}),` again.`]}),okText:`Retry`,cancelText:`Cancel`,autoFocusButton:`cancel`,onOk:async()=>{try{await se(t.facebookLeadId),r.message.success(`This lead will be tried again`)}catch(e){r.message.error(e?.status===409?`This lead is no longer failed. The list has been updated.`:S(e))}v(),o?.()}})},x=[{title:`Form`,dataIndex:`formName`,render:(t,n)=>Re(e,n)},{title:`Lead ID`,dataIndex:`facebookLeadId`},{title:`Why it is waiting`,dataIndex:`reason`,render:Se},{title:`Status`,dataIndex:`status`,render:e=>e===`unassigned`?`Waiting`:e===`resolved`?`Sorted`:`—`},{title:`First seen`,dataIndex:`firstSeenAt`,render:Y},...l===`unassigned`?[]:[{title:`Sorted at`,dataIndex:`resolvedAt`,render:Y}]],C=[{title:`Form`,dataIndex:`formName`,render:(t,n)=>Re(e,n)},{title:`Lead ID`,dataIndex:`facebookLeadId`},{title:`What went wrong`,dataIndex:`reason`,render:xe},{title:`Tries`,dataIndex:`attempts`,width:72,render:e=>e??`—`},{title:`When`,dataIndex:`lastFailedAt`,render:(e,t)=>Y(e||t.firstSeenAt)},{title:``,key:`retry`,width:96,render:(e,n)=>(0,a.jsx)(r.Tooltip,{title:t?``:`You don't have permission to retry leads`,children:(0,a.jsx)(`span`,{children:(0,a.jsx)(r.Button,{size:`small`,className:`fb-inline-btn`,disabled:!t,"aria-label":`Retry lead ${n.facebookLeadId}`,onClick:()=>b(n),children:`Retry`})})})}],w=g.data?.unassignedCount,T=_.data?.failedCount??_.data?.total;return(0,a.jsxs)(`div`,{className:`fb-tab-body`,children:[(0,a.jsx)(`div`,{className:`fb-toolbar`,children:(0,a.jsxs)(`div`,{className:`fb-field`,children:[(0,a.jsx)(`label`,{className:`fb-field-label`,htmlFor:`fb-attention-form`,children:`Form`}),(0,a.jsx)(G,{id:`fb-attention-form`,rows:e,value:s,onChange:y})]})}),(0,a.jsxs)(`div`,{className:`fb-subhead`,children:[(0,a.jsxs)(`h4`,{children:[`Waiting leads`,w===void 0?``:` (${w})`]}),(0,a.jsx)(r.Select,{"aria-label":`Show waiting leads`,value:l,className:`fb-subhead-select`,onChange:e=>{u(e),f(1)},options:[{value:`unassigned`,label:`Waiting`},{value:`resolved`,label:`Sorted`},{value:`all`,label:`All`}]})]}),(0,a.jsx)(Le,{title:`Could not load waiting leads`,resource:g}),(0,a.jsx)(r.Table,{size:`small`,rowKey:e=>String(e.id||`${e.facebookLeadId}-${e.formId}`),loading:g.loading,dataSource:g.data?.leads||[],columns:x,scroll:{x:760},locale:{emptyText:g.loading||g.error?` `:`No leads are waiting.`},pagination:{current:d,pageSize:20,total:Number(g.data?.total||0),showSizeChanger:!1,hideOnSinglePage:!0,onChange:f}}),(0,a.jsx)(`div`,{className:`fb-subhead`,children:(0,a.jsxs)(`h4`,{children:[`Failed leads`,T===void 0?``:` (${T})`]})}),(0,a.jsx)(Le,{title:`Could not load failed leads`,resource:_}),(0,a.jsx)(r.Table,{size:`small`,rowKey:e=>String(e.facebookLeadId),loading:_.loading,dataSource:_.data?.leads||[],columns:C,scroll:{x:760},locale:{emptyText:_.loading||_.error?` `:`No failed leads.`},pagination:{current:p,pageSize:20,total:Number(_.data?.total||0),showSizeChanger:!1,hideOnSinglePage:!0,onChange:m}})]})}function Be({rows:e=[],refreshKey:t=0}){let[i,o]=(0,n.useState)(``),[s,c]=(0,n.useState)(1),l=Ie((0,n.useCallback)(()=>D({page:s,limit:20,formId:i}),[s,i]),t),u=[{title:`Form`,dataIndex:`formName`,render:(t,n)=>Re(e,n)},{title:`Lead ID`,dataIndex:`facebookLeadId`},{title:`Skipped counsellor`,dataIndex:`skippedCounsellorName`,render:e=>e||`Unknown counsellor`},{title:`Reason`,dataIndex:`reason`,render:ye},{title:`Went to`,dataIndex:`assignedToName`,render:e=>e||`—`},{title:`When`,dataIndex:`skippedAt`,render:Y}];return(0,a.jsxs)(`div`,{className:`fb-tab-body`,children:[(0,a.jsx)(`div`,{className:`fb-toolbar`,children:(0,a.jsxs)(`div`,{className:`fb-field`,children:[(0,a.jsx)(`label`,{className:`fb-field-label`,htmlFor:`fb-skips-form`,children:`Form`}),(0,a.jsx)(G,{id:`fb-skips-form`,rows:e,value:i,onChange:e=>{o(e),c(1)}})]})}),(0,a.jsx)(Le,{title:`Could not load skipped counsellors`,resource:l}),(0,a.jsx)(r.Table,{size:`small`,rowKey:e=>String(e.id||`${e.facebookLeadId}-${e.skippedCounsellorLegacyId}`),loading:l.loading,dataSource:l.data?.skips||[],columns:u,scroll:{x:860},locale:{emptyText:l.loading||l.error?` `:`No one has been skipped yet.`},pagination:{current:s,pageSize:20,total:Number(l.data?.total||0),showSizeChanger:!1,hideOnSinglePage:!0,onChange:c}})]})}function Ve({rows:e=[],refreshKey:t=0}){let[i,o]=(0,n.useState)(``),[s,c]=(0,n.useState)(1),l=Ie((0,n.useCallback)(()=>ce({page:s,limit:20,formId:i}),[s,i]),t),u=[{title:`When`,dataIndex:`at`,width:190,render:Y},{title:`Form`,dataIndex:`formName`,render:(t,n)=>Re(e,n)},{title:`What changed`,key:`change`,render:(e,t)=>we(t)},{title:`By`,dataIndex:`performedByName`,render:e=>e||`—`}];return(0,a.jsxs)(`div`,{className:`fb-tab-body`,children:[(0,a.jsx)(`div`,{className:`fb-toolbar`,children:(0,a.jsxs)(`div`,{className:`fb-field`,children:[(0,a.jsx)(`label`,{className:`fb-field-label`,htmlFor:`fb-history-form`,children:`Form`}),(0,a.jsx)(G,{id:`fb-history-form`,rows:e,value:i,onChange:e=>{o(e),c(1)}})]})}),(0,a.jsx)(Le,{title:`Could not load history`,resource:l}),(0,a.jsx)(r.Table,{size:`small`,rowKey:e=>String(e.id||`${e.formId}-${e.at}`),loading:l.loading,dataSource:l.data?.history||[],columns:u,scroll:{x:720},locale:{emptyText:l.loading||l.error?` `:`No setup changes yet. They will appear here when someone changes a form.`},pagination:{current:s,pageSize:20,total:Number(l.data?.total||0),showSizeChanger:!1,hideOnSinglePage:!0,onChange:c}})]})}var{Text:Z,Paragraph:He}=r.Typography,Ue={eligible:{label:`Active – Eligible`,color:`green`},logged_out:{label:`Logged Out – Not Eligible`,color:`default`},waiting_for_login:{label:`Waiting for Login`,color:`blue`},on_leave:{label:`On Leave – Skipped`,color:`orange`},admin_disabled:{label:`Admin Disabled – Skipped`,color:`red`},inactive:{label:`Inactive user – Skipped`,color:`red`},past_day:{label:`Past day`,color:`default`}},We={awaiting_cutoff:`Waiting for cut-off`,no_active_counsellor:`Waiting for a counsellor to log in`,distribution_not_configured:`Form has no counsellor list`,distribution_disabled:`Form distribution is switched off`},Ge=e=>e?(0,o.default)(e).format(`h:mm A`):`–`,Ke=e=>e?(0,o.default)(e).format(`D MMM, h:mm A`):`–`,qe=e=>{if(!e)return`–`;let t=Math.max(0,(0,o.default)().diff((0,o.default)(e),`minute`));return t<60?`${t} min`:`${Math.floor(t/60)} h ${t%60} min`};function Q(e,t){let[r,i]=(0,n.useState)({loading:!0}),[a,o]=(0,n.useState)(0);return(0,n.useEffect)(()=>{let t=!0;return e().then(e=>t&&i({loading:!1,data:e}),e=>t&&i({loading:!1,error:S(e,`This could not be loaded.`)})),()=>{t=!1}},[a,...t]),[r,()=>{i(e=>({...e,loading:!0})),o(e=>e+1)}]}var Je=({text:e,onRetry:t})=>(0,a.jsx)(r.Alert,{type:`error`,showIcon:!0,message:e,action:(0,a.jsx)(r.Button,{size:`small`,onClick:t,children:`Try again`})});function Ye({canEdit:e=!1}){let[t,s]=(0,n.useState)(null),[c,l]=Q(()=>N(t?t.format(`YYYY-MM-DD`):``),[t]),[u,d]=(0,n.useState)(null),[f,p]=(0,n.useState)(``),m=c.data??{},h=m.summary??{},ee=!t||m.day===m.today,g=async(e,t)=>{p(`t${e.legacyUserId}`);try{await F(e.legacyUserId,t,t?``:`Disabled by admin`),r.message.success(`${e.name} ${t?`will receive new leads again`:`will not receive new leads`}`),l()}catch(e){r.message.error(S(e))}finally{p(``)}},_=[{title:`Counsellor`,key:`name`,render:(e,t)=>(0,a.jsxs)(r.Space,{direction:`vertical`,size:0,children:[(0,a.jsx)(Z,{strong:!0,children:t.name}),(0,a.jsx)(Z,{type:`secondary`,style:{fontSize:12},children:(t.forms??[]).join(`, `)})]})},{title:`First login`,dataIndex:`firstLoginAt`,render:Ge,sorter:(e,t)=>String(e.firstLoginAt??``).localeCompare(String(t.firstLoginAt??``))},{title:`Last seen / logout`,key:`seen`,render:(e,t)=>t.loggedOutAt&&(!t.lastSeenAt||t.loggedOutAt>t.lastSeenAt)?`Logged out ${Ge(t.loggedOutAt)}`:Ge(t.lastSeenAt)},{title:`Status`,dataIndex:`status`,render:e=>(0,a.jsx)(r.Tag,{color:Ue[e]?.color,children:Ue[e]?.label??e}),filters:Object.entries(Ue).map(([e,t])=>({value:e,text:t.label})),onFilter:(e,t)=>t.status===e},{title:`Leads today`,dataIndex:`assigned`,align:`right`,sorter:(e,t)=>e.assigned-t.assigned},{title:`Target`,dataIndex:`target`,align:`right`},{title:`Progress`,key:`progress`,width:140,render:(e,t)=>(0,a.jsx)(r.Progress,{percent:t.target?Math.min(100,Math.round(t.assigned/t.target*100)):0,size:`small`,showInfo:!1})},{title:`Difference`,dataIndex:`difference`,align:`right`,render:(e,t)=>t.status===`eligible`&&e>0?(0,a.jsxs)(Z,{type:`warning`,children:[e,` behind`]}):t.status===`eligible`?`On target`:`–`},...e&&ee?[{title:``,key:`act`,width:210,render:(e,t)=>t.status===`inactive`?null:(0,a.jsxs)(r.Space,{children:[t.status===`admin_disabled`?(0,a.jsx)(r.Button,{size:`small`,loading:f===`t${t.legacyUserId}`,onClick:()=>g(t,!0),children:`Enable`}):(0,a.jsx)(r.Popconfirm,{title:`Stop new leads for ${t.name}?`,description:`Leads they already have stay with them.`,okText:`Disable`,okButtonProps:{danger:!0},onConfirm:()=>g(t,!1),children:(0,a.jsx)(r.Button,{size:`small`,danger:!0,loading:f===`t${t.legacyUserId}`,children:`Disable`})}),(0,a.jsx)(r.Button,{size:`small`,onClick:()=>d(t),children:`Leave`})]})}]:[]];return(0,a.jsxs)(`div`,{className:`ld-today`,children:[(0,a.jsxs)(r.Space,{wrap:!0,style:{marginBottom:12,width:`100%`,justifyContent:`space-between`},children:[(0,a.jsxs)(r.Space,{wrap:!0,children:[(0,a.jsx)(r.DatePicker,{value:t,onChange:s,allowClear:!0,placeholder:`Today`,disabledDate:e=>e&&e.isAfter((0,o.default)(),`day`)}),m.settings?(0,a.jsx)(r.Tag,{color:m.settings.mode===`equal_daily`?`magenta`:`default`,children:m.settings.mode===`equal_daily`?`Equal daily distribution`:`Round-robin (earlier behaviour)`}):null]}),(0,a.jsx)(r.Button,{icon:(0,a.jsx)(i.ReloadOutlined,{}),onClick:l,children:`Refresh`})]}),c.loading&&!c.data?(0,a.jsx)(r.Skeleton,{active:!0}):c.error?(0,a.jsx)(Je,{text:c.error,onRetry:l}):(0,a.jsxs)(a.Fragment,{children:[m.settings?.mode===`equal_daily`&&ee?(0,a.jsx)(r.Alert,{style:{marginBottom:12},showIcon:!0,type:m.holding?`info`:`success`,message:m.holding?`Leads received until ${Ge(m.cutoffAt)} wait, then they are shared equally among counsellors who are online at ${Ge(m.cutoffAt)}.`:`Cut-off ${Ge(m.cutoffAt)} has passed: each new lead goes to the online counsellor with the fewest leads today.`}):null,(0,a.jsxs)(r.Row,{gutter:[16,16],style:{marginBottom:16},children:[(0,a.jsx)(r.Col,{xs:12,md:6,xl:3,children:(0,a.jsx)(r.Statistic,{title:`Received`,value:h.received??0})}),(0,a.jsx)(r.Col,{xs:12,md:6,xl:3,children:(0,a.jsx)(r.Statistic,{title:`Assigned`,value:h.assigned??0})}),(0,a.jsx)(r.Col,{xs:12,md:6,xl:3,children:(0,a.jsx)(r.Statistic,{title:`Waiting`,value:h.pending??0})}),(0,a.jsx)(r.Col,{xs:12,md:6,xl:3,children:(0,a.jsx)(r.Statistic,{title:`Eligible now`,value:h.eligible??0})}),(0,a.jsx)(r.Col,{xs:12,md:6,xl:3,children:(0,a.jsx)(r.Statistic,{title:`Unavailable`,value:h.unavailable??0})}),(0,a.jsx)(r.Col,{xs:12,md:6,xl:3,children:(0,a.jsx)(r.Statistic,{title:`Target each`,value:h.target??0})}),(0,a.jsx)(r.Col,{xs:24,md:12,xl:6,children:(0,a.jsx)(r.Statistic,{title:`Balance`,valueRender:()=>(0,a.jsx)(r.Tag,{color:h.balance===`balanced`?`green`:`gold`,style:{fontSize:14,padding:`4px 10px`},children:h.balance===`balanced`?`Balanced`:`Catching up (gap ${h.spread})`})})})]}),h.balance!==`balanced`&&(h.spread??0)>1?(0,a.jsx)(He,{type:`secondary`,style:{fontSize:12},children:`Counsellors who joined later get new leads first until they catch up. Leads already assigned are never moved, so an exact match is not always possible.`}):null,(0,a.jsx)(r.Table,{rowKey:`legacyUserId`,size:`small`,columns:_,dataSource:m.counsellors??[],pagination:!1,scroll:{x:`max-content`},loading:c.loading,locale:{emptyText:(0,a.jsx)(r.Empty,{description:`No counsellor is on any form's list yet. Add counsellors in the Forms tab.`})}})]}),u?(0,a.jsx)(Xe,{counsellor:u,onClose:e=>{d(null),e&&l()}}):null]})}function Xe({counsellor:e,onClose:t}){let[i]=r.Form.useForm(),[s,c]=Q(()=>ue((0,o.default)().format(`YYYY-MM-DD`)),[]),[l,u]=(0,n.useState)(!1),[d,f]=(0,n.useState)(!1),p=(Array.isArray(s.data)?s.data:[]).filter(t=>Number(t.legacyUserId)===Number(e.legacyUserId)),m=async()=>{let t=await i.validateFields();u(!0);try{await de({legacyUserId:e.legacyUserId,from:t.range[0].format(`YYYY-MM-DD`),to:t.range[1].format(`YYYY-MM-DD`),reason:t.reason??``}),r.message.success(`Leave saved: no new leads on those days`),i.resetFields(),f(!0),c()}catch(e){r.message.error(S(e))}finally{u(!1)}},h=async e=>{try{await I(e),r.message.success(`Leave removed`),f(!0),c()}catch(e){r.message.error(S(e))}};return(0,a.jsxs)(r.Modal,{open:!0,title:`Leave · ${e.name}`,onCancel:()=>t(d),footer:(0,a.jsx)(r.Button,{onClick:()=>t(d),children:`Close`}),children:[(0,a.jsxs)(r.Form,{form:i,layout:`vertical`,children:[(0,a.jsx)(r.Form.Item,{name:`range`,label:`Days on leave`,rules:[{required:!0,message:`Choose the days`}],children:(0,a.jsx)(r.DatePicker.RangePicker,{style:{width:`100%`},disabledDate:e=>e&&e.isBefore((0,o.default)(),`day`)})}),(0,a.jsx)(r.Form.Item,{name:`reason`,label:`Reason (optional)`,children:(0,a.jsx)(r.Input,{maxLength:300})}),(0,a.jsx)(r.Button,{type:`primary`,loading:l,onClick:m,children:`Add leave`})]}),(0,a.jsx)(He,{type:`secondary`,style:{margin:`12px 0 4px`},children:`Upcoming leave`}),s.loading?(0,a.jsx)(r.Skeleton,{active:!0,paragraph:{rows:1}}):s.error?(0,a.jsx)(Je,{text:s.error,onRetry:c}):p.length?(0,a.jsx)(r.Space,{direction:`vertical`,style:{width:`100%`},children:p.map(e=>(0,a.jsxs)(r.Space,{style:{justifyContent:`space-between`,width:`100%`},children:[(0,a.jsxs)(Z,{children:[(0,o.default)(e.from).format(`D MMM`),` – `,(0,o.default)(e.to).format(`D MMM YYYY`),e.reason?` · ${e.reason}`:``]}),(0,a.jsx)(r.Popconfirm,{title:`Remove this leave?`,okText:`Remove`,onConfirm:()=>h(String(e._id)),children:(0,a.jsx)(r.Button,{size:`small`,type:`link`,danger:!0,children:`Remove`})})]},String(e._id)))}):(0,a.jsx)(Z,{type:`secondary`,children:`None.`})]})}function Ze({rows:e=[]}){let[t,o]=(0,n.useState)(`waiting`),[s,c]=(0,n.useState)(``),[l,u]=(0,n.useState)(1),[d,f]=Q(()=>L({status:t===`waiting`?``:t,formId:s,page:l,limit:25}),[t,s,l]),p=[{title:`Lead reference`,dataIndex:`facebookLeadId`},{title:`Form`,dataIndex:`facebookFormId`,render:t=>e.find(e=>e.formId===t)?.formName??`Form ${t}`},{title:`Received`,dataIndex:`createdAt`,render:Ke},{title:`Waiting`,dataIndex:`createdAt`,key:`waited`,render:(e,t)=>t.status===`dead`?`–`:qe(e)},{title:`Status`,dataIndex:`status`,render:(e,t)=>e===`dead`?(0,a.jsx)(r.Tag,{color:`red`,children:`Assignment Failed`}):e===`processing`?(0,a.jsx)(r.Tag,{color:`blue`,children:`Assigning…`}):(0,a.jsx)(r.Tag,{color:t.lastResult===`awaiting_cutoff`?`purple`:`gold`,children:We[t.lastResult]??`Pending Assignment`})},{title:`Next try`,dataIndex:`nextAttemptAt`,render:(e,t)=>t.status===`dead`?`–`:Ke(e)},{title:`Detail`,key:`detail`,render:(e,t)=>t.lastErrorCode||(We[t.lastResult]?``:t.lastResult)||`–`}];return(0,a.jsxs)(`div`,{className:`ld-queue`,children:[(0,a.jsxs)(r.Space,{wrap:!0,style:{marginBottom:12},children:[(0,a.jsx)(r.Segmented,{value:t,onChange:e=>{o(e),u(1)},options:[{value:`waiting`,label:`Waiting`},{value:`failed`,label:`Failed`},{value:`all`,label:`All`}]}),(0,a.jsx)(r.Select,{style:{minWidth:220},value:s,onChange:e=>{c(e),u(1)},options:[{value:``,label:`All forms`},...e.map(e=>({value:e.formId,label:e.formName??e.formId}))]}),(0,a.jsx)(r.Button,{icon:(0,a.jsx)(i.ReloadOutlined,{}),onClick:f,children:`Refresh`})]}),(0,a.jsx)(He,{type:`secondary`,style:{fontSize:12},children:`Leads stay here safely until a counsellor can take them; nothing is lost when nobody is logged in. A lead becomes an LMS lead when it is assigned.`}),d.error?(0,a.jsx)(Je,{text:d.error,onRetry:f}):(0,a.jsx)(r.Table,{rowKey:e=>String(e._id??e.facebookLeadId),size:`small`,loading:d.loading,columns:p,dataSource:d.data?.rows??[],scroll:{x:`max-content`},pagination:{current:l,pageSize:25,total:d.data?.total??0,onChange:u,showSizeChanger:!1},locale:{emptyText:(0,a.jsx)(r.Empty,{description:t===`failed`?`No failed leads.`:`No leads are waiting.`})}})]})}function Qe(){let[e,t]=(0,n.useState)((0,o.default)()),[s,c]=(0,n.useState)(1),[l,u]=Q(()=>R({date:e?e.format(`YYYY-MM-DD`):``,page:s,limit:25}),[e,s]),d=[{title:`Lead reference`,dataIndex:`facebookLeadId`},{title:`Form`,dataIndex:`formName`},{title:`Received`,dataIndex:`receivedAt`,render:Ke},{title:`Assigned`,dataIndex:`assignedAt`,render:Ke},{title:`Counsellor`,dataIndex:`counsellorName`},{title:`Their leads that day`,dataIndex:`countAtAssignment`,align:`right`},{title:`Skipped`,dataIndex:`skipped`,render:e=>Array.isArray(e)&&e.length?(0,a.jsx)(r.Tooltip,{title:e.map(e=>`${e.name||`#${e.legacyUserId}`}: ${Ue[e.reason]?.label??e.reason}`).join(`
|
|
2
|
-
`),children:(0,a.jsxs)(r.Tag,{children:[e.length,` skipped`]})}):`–`}];return(0,a.jsxs)(`div`,{className:`ld-history`,children:[(0,a.jsxs)(r.Space,{wrap:!0,style:{marginBottom:12},children:[(0,a.jsx)(r.DatePicker,{value:e,onChange:e=>{t(e),c(1)},allowClear:!0,placeholder:`All days`}),(0,a.jsx)(r.Button,{icon:(0,a.jsx)(i.ReloadOutlined,{}),onClick:u,children:`Refresh`})]}),(0,a.jsx)(He,{type:`secondary`,style:{fontSize:12},children:`Every automatic assignment in equal daily mode. Manual reassignments are in the Reassign leads tab and History.`}),l.error?(0,a.jsx)(Je,{text:l.error,onRetry:u}):(0,a.jsx)(r.Table,{rowKey:e=>String(e._id),size:`small`,loading:l.loading,columns:d,dataSource:l.data?.rows??[],scroll:{x:`max-content`},pagination:{current:s,pageSize:25,total:l.data?.total??0,onChange:c,showSizeChanger:!1},locale:{emptyText:(0,a.jsx)(r.Empty,{description:`No assignments for this day yet.`})}})]})}var $e=[`Asia/Kolkata`,`Asia/Dubai`,`Asia/Singapore`,`Europe/London`,`America/New_York`,`UTC`];function et({canEdit:e=!1}){let[t]=r.Form.useForm(),[i,s]=Q(()=>le(),[]),[c,l]=(0,n.useState)(!1),u=i.data?.settings;(0,n.useEffect)(()=>{u&&t.setFieldsValue({...u,startTime:(0,o.default)(u.startTime,`HH:mm`),cutoffTime:(0,o.default)(u.cutoffTime,`HH:mm`),resetTime:(0,o.default)(u.resetTime,`HH:mm`)})},[u,t]);let d=r.Form.useWatch(`mode`,t);return i.loading&&!i.data?(0,a.jsx)(r.Skeleton,{active:!0}):i.error?(0,a.jsx)(Je,{text:i.error,onRetry:s}):(0,a.jsxs)(r.Form,{form:t,layout:`vertical`,disabled:!e,style:{maxWidth:720},children:[(0,a.jsx)(r.Form.Item,{name:`mode`,label:`How leads are shared`,children:(0,a.jsx)(r.Segmented,{block:!0,options:[{value:`equal_daily`,label:`Equal daily distribution`},{value:`round_robin`,label:`Round-robin (earlier behaviour)`}]})}),(0,a.jsx)(He,{type:`secondary`,children:d===`equal_daily`?`Only counsellors who are logged in, enabled and not on leave get leads. Each lead goes to the one with the fewest leads today; equal counts take turns.`:`Leads take turns through each form's counsellor list, skipping inactive users. Login and leave are not checked.`}),(0,a.jsxs)(r.Row,{gutter:12,children:[(0,a.jsx)(r.Col,{xs:12,md:6,children:(0,a.jsx)(r.Form.Item,{name:`startTime`,label:`Day starts`,rules:[{required:!0}],children:(0,a.jsx)(r.TimePicker,{format:`HH:mm`,minuteStep:5,style:{width:`100%`}})})}),(0,a.jsx)(r.Col,{xs:12,md:6,children:(0,a.jsx)(r.Form.Item,{name:`cutoffTime`,label:`Initial cut-off`,rules:[{required:!0}],extra:`Morning leads wait until this time.`,children:(0,a.jsx)(r.TimePicker,{format:`HH:mm`,minuteStep:5,style:{width:`100%`}})})}),(0,a.jsx)(r.Col,{xs:12,md:6,children:(0,a.jsx)(r.Form.Item,{name:`resetTime`,label:`Daily reset`,rules:[{required:!0}],children:(0,a.jsx)(r.TimePicker,{format:`HH:mm`,minuteStep:5,style:{width:`100%`}})})}),(0,a.jsx)(r.Col,{xs:12,md:6,children:(0,a.jsx)(r.Form.Item,{name:`timezone`,label:`Time zone`,rules:[{required:!0}],children:(0,a.jsx)(r.Select,{options:$e.map(e=>({value:e,label:e}))})})}),(0,a.jsx)(r.Col,{xs:24,md:12,children:(0,a.jsx)(r.Form.Item,{name:`holdUntilCutoff`,label:`Hold morning leads until the cut-off`,valuePropName:`checked`,extra:`Off: leads are shared as soon as they arrive.`,children:(0,a.jsx)(r.Switch,{})})}),(0,a.jsx)(r.Col,{xs:24,md:12,children:(0,a.jsx)(r.Form.Item,{name:`onlineWindowMinutes`,label:`Offline after no activity for`,rules:[{required:!0}],children:(0,a.jsx)(r.InputNumber,{min:2,max:120,addonAfter:`minutes`,style:{width:`100%`}})})})]}),e?(0,a.jsx)(r.Button,{type:`primary`,loading:c,onClick:async()=>{let e=await t.validateFields(),n={...e,startTime:e.startTime.format(`HH:mm`),cutoffTime:e.cutoffTime.format(`HH:mm`),resetTime:e.resetTime.format(`HH:mm`)};r.Modal.confirm({title:`Save distribution settings?`,content:n.mode===`equal_daily`?`New leads will go to the online counsellor with the fewest leads today. Leads already assigned do not move.`:`New leads will go back to plain round-robin.`,okText:`Save`,onOk:async()=>{l(!0);try{await P(n),r.message.success(`Distribution settings saved`),s()}catch(e){r.message.error(S(e))}finally{l(!1)}}})},children:`Save settings`}):(0,a.jsx)(Z,{type:`secondary`,children:`Only users who can edit lead mapping can change these settings.`})]})}var tt=e.t({default:()=>pt}),{Text:nt,Title:rt}=r.Typography,it=10,at=`—`,ot=`You don't have permission to do this.`,st=`This could not be loaded. Press Try again first.`;function $(e,t){return Array.isArray(e)?e:Array.isArray(e?.[t])?e[t]:[]}var ct={forms:{load:p,read:e=>$(e,`forms`),label:`Facebook forms`},courses:{load:m,read:e=>$(e,`courses`),label:`courses`},mappings:{load:h,read:e=>$(e,`mappings`),label:`chosen courses`},distributions:{load:T,read:e=>$(e,`distributions`),label:`counsellor lists`},counsellors:{load:E,read:e=>$(e,`counsellors`),label:`active counsellors`}},lt=Object.keys(ct),ut=Object.fromEntries(lt.map(e=>[e,[]])),dt=Object.fromEntries(lt.map(e=>[e,{loaded:!1,ok:!1,error:``}]));function ft({distribution:e}){let t=e?.counsellors||[];if(!t.length)return(0,a.jsx)(nt,{type:`secondary`,children:`Not set up`});let n=t.map(e=>e.name||`Unnamed counsellor`),i=Ee(e);return(0,a.jsxs)(`div`,{className:`fb-who`,children:[(0,a.jsx)(r.Tooltip,{title:n.join(`, `),trigger:[`hover`,`focus`],children:(0,a.jsxs)(`span`,{className:`fb-avatars`,role:`group`,tabIndex:0,"aria-label":`Gets leads: ${n.join(`, `)}`,children:[n.slice(0,3).map((e,t)=>(0,a.jsx)(`span`,{className:`fb-avatar`,"aria-hidden":`true`,children:(Array.from(e)[0]||`?`).toUpperCase()},`${e}-${t}`)),n.length>3&&(0,a.jsxs)(`span`,{className:`fb-avatar fb-avatar--more`,"aria-hidden":`true`,children:[`+`,n.length-3]})]})}),(0,a.jsxs)(`span`,{className:`fb-next`,children:[`Next: `,i||`No one active`]})]})}function pt(){let[e,t]=(0,n.useState)(ut),[o,c]=(0,n.useState)(dt),[l,d]=(0,n.useState)(!0),[f,p]=(0,n.useState)(null),[ee,_]=(0,n.useState)(`forms`),[v,y]=(0,n.useState)(``),[b,x]=(0,n.useState)(`all`),[C,w]=(0,n.useState)(null),[te,D]=(0,n.useState)(1),[ne,O]=(0,n.useState)(``),[k,ie]=(0,n.useState)(null),[ae,A]=(0,n.useState)(!1),[j,se]=(0,n.useState)(0),ce=(0,n.useRef)(0),M=(0,n.useRef)(0),N=(0,n.useRef)({element:null,formId:``}),le=(0,n.useRef)(null),P=(0,n.useCallback)(async()=>{let e=++ce.current;d(!0);let n=await Promise.allSettled(lt.map(e=>ct[e].load()));e===ce.current&&(t(e=>{let t={...e};return n.forEach((e,n)=>{e.status===`fulfilled`&&(t[lt[n]]=ct[lt[n]].read(e.value))}),t}),c(e=>{let t={...e};return n.forEach((n,r)=>{let i=lt[r];t[i]=n.status===`fulfilled`?{loaded:!0,ok:!0,error:``}:{loaded:e[i].loaded,ok:!1,error:S(n.reason,`Please try again.`,{hideServerText:!0})}}),t}),d(!1))},[]),F=(0,n.useCallback)(()=>(se(e=>e+1),P()),[P]);(0,n.useEffect)(()=>{P()},[P]),(0,n.useEffect)(()=>{let e=!0;return oe().then(t=>{e&&p(t)}).catch(()=>{}),()=>{e=!1}},[]);let{alerts:ue,alertsOk:de,failedCount:I}=pe({refreshKey:j}),L={add:f?.permissions?.canAdd!==!1,edit:f?.permissions?.canEdit!==!1,remove:f?.permissions?.canDelete!==!1},{forms:R,courses:z,mappings:fe,distributions:B,counsellors:V}=e,H=o.forms.loaded,U=o.mappings.loaded,W=o.distributions.loaded,G=!H||!U||!W,me=l&&!lt.some(e=>o[e].loaded),q=(0,n.useMemo)(()=>new Map(B.map(e=>[String(e.formId),e])),[B]),J=(0,n.useMemo)(()=>new Map(fe.map(e=>[String(e.formId),e])),[fe]),ge=(0,n.useMemo)(()=>new Map(z.map(e=>[String(e.courseId),e.courseName])),[z]),Y=(0,n.useMemo)(()=>{let e=R.map(e=>({formId:String(e.id),formName:e.name||`Unnamed form`,inFormsList:!0})),t=new Set(e.map(e=>e.formId));return[...fe,...B].forEach(n=>{let r=String(n.formId);t.has(r)||(t.add(r),e.push({formId:r,formName:n.formName||`Unnamed form`,inFormsList:!1}))}),e.map(e=>{let t=J.get(e.formId),n=q.get(e.formId);return{...e,key:e.formId,mapping:t,distribution:n,courseName:t&&(ge.get(String(t.courseId))||t.courseName)||``,status:Te({mapping:t,distribution:n,inFormsList:e.inFormsList},{forms:H,mappings:U,distributions:W})}})},[R,fe,B,J,q,ge,H,U,W]),_e=(0,n.useMemo)(()=>{let e=v.trim().toLowerCase();return Y.filter(t=>C&&!C.includes(t.formId)||b!==`all`&&t.status!==b?!1:`${t.formName} ${t.formId} ${t.courseName}`.toLowerCase().includes(e))},[Y,C,b,v]),ve=!!v.trim()||b!==`all`||!!C,ye=Math.min(te,Math.max(1,Math.ceil(_e.length/it))),be=()=>{y(``),x(`all`),w(null),D(1)},xe=e=>{y(``),x(`all`),w(e),D(1),_(`forms`)},Se=e=>{y(``),w(null),x(e),D(1),_(`forms`)},Ce=o.forms.ok&&o.mappings.ok&&o.distributions.ok,we=e=>Y.filter(t=>t.status===e).length,Ee=de?Number(ue?.unassignedCount||0):null,De=Ee===null||I===null?null:Ee+I,Oe=[{key:`ready`,label:`forms ready`,value:Ce?we(`ready`):at,onClick:Ce?()=>Se(`ready`):void 0},{key:`setup`,label:`need setup`,value:Ce?we(`needs_setup`):at,onClick:Ce?()=>Se(`needs_setup`):void 0},{key:`waiting`,label:`leads waiting`,value:Ee??at,onClick:Ee===null?void 0:()=>_(`attention`)},{key:`failed`,label:`failed leads`,value:I??at,onClick:I===null?void 0:()=>_(`attention`)},{key:`counsellors`,label:`active counsellors`,value:o.counsellors.ok?V.length:at}],ke=e=>{t(t=>({...t,...e})),c(t=>{let n={...t};return Object.keys(e).forEach(e=>{n[e]={loaded:!0,ok:!0,error:``}}),n})},Ae=async()=>{let[e,t,n,r]=await Promise.all([m(),h(),T(),E()]),i={courses:$(e,`courses`),mappings:$(t,`mappings`),distributions:$(n,`distributions`),counsellors:$(r,`counsellors`)};return ke(i),i},je=async(e,t,n=null)=>{if(!G){N.current={element:n,formId:e.formId},O(e.formId);try{await Ae(),M.current+=1,ie({token:M.current,row:e,section:t}),A(!0)}catch(e){r.message.error(S(e,`Could not open this form. Please try again.`))}finally{O(``)}}},Ne=()=>{let{element:e,formId:t}=N.current;if(e?.isConnected){e.focus();return}[...le.current?.querySelectorAll(`[data-form-menu]`)||[]].find(e=>e.dataset.formMenu===t)?.focus()},Pe=()=>{se(e=>e+1),P()},Ie=e=>{r.Modal.confirm({title:`Remove course mapping?`,content:(0,a.jsxs)(`span`,{children:[`Remove the course mapping for `,(0,a.jsx)(`strong`,{children:e.formName}),`? Existing lead courses remain unchanged. `,e.distribution?`This form has saved counsellors. They stay in place unless you remove them separately.`:`Future leads from this form will arrive without a course.`]}),okText:`Remove mapping`,okType:`danger`,cancelText:`Cancel`,autoFocusButton:`cancel`,onOk:async()=>{O(e.formId);try{await g(e.formId),r.message.success(`Course mapping removed`),Pe()}catch(e){throw r.message.error(S(e,`Could not remove the mapping. Please try again.`)),e}finally{O(``)}}})},Le=e=>{r.Modal.confirm({title:`Remove counsellor distribution?`,content:(0,a.jsxs)(`span`,{children:[`Remove the saved counsellors and whose turn is next for `,(0,a.jsx)(`strong`,{children:e.formName}),`? Leads already given out will not change. New leads from this form will wait until counsellors are set up again. Its course mapping stays as it is.`]}),okText:`Remove distribution`,okType:`danger`,cancelText:`Cancel`,autoFocusButton:`cancel`,onOk:async()=>{O(e.formId);try{if((await re(e.formId))?.deleted===!1)throw Error(`This has already been removed. Refresh and try again.`);r.message.success(`Counsellor distribution removed`),Pe()}catch(e){throw r.message.error(S(e,`Could not remove the distribution. Please try again.`)),e}finally{O(``)}}})},Re=e=>{let t=e=>G?st:e?``:ot,n=t(e.mapping?L.edit:L.add),r=t(e.distribution?L.edit:L.add);return{items:[{key:`mapping`,icon:e.mapping?(0,a.jsx)(i.EditOutlined,{}):(0,a.jsx)(i.PlusOutlined,{}),label:e.mapping?`Edit mapping`:`Set up mapping`,disabled:!!n,title:n},...e.mapping&&L.remove?[{key:`removeMapping`,icon:(0,a.jsx)(i.DeleteOutlined,{}),label:`Remove mapping`,danger:!0,disabled:G}]:[],{type:`divider`},{key:`distribution`,icon:(0,a.jsx)(i.TeamOutlined,{}),label:e.distribution?`Edit distribution`:`Set up distribution`,disabled:!!r,title:r},...e.distribution&&L.remove?[{key:`removeDistribution`,icon:(0,a.jsx)(i.DeleteOutlined,{}),label:`Remove distribution`,danger:!0,disabled:G}]:[]],onClick:({key:t})=>{t===`mapping`?je(e,`course`):t===`distribution`?je(e,`counsellors`):t===`removeMapping`?Ie(e):t===`removeDistribution`&&Le(e)}}},Z=e=>e.stopPropagation(),He=[{title:`Form`,dataIndex:`formName`,key:`form`,render:(e,t)=>(0,a.jsxs)(`div`,{children:[(0,a.jsx)(`button`,{type:`button`,className:`fb-form-name`,disabled:G,onClick:e=>{Z(e),je(t,`course`,e.currentTarget)},children:e}),(0,a.jsx)(`div`,{children:(0,a.jsxs)(nt,{type:`secondary`,className:`fb-small`,children:[`Form ID: `,t.formId]})})]})},{title:`Course`,key:`course`,render:(e,t)=>U?t.mapping?(0,a.jsxs)(`span`,{className:`fb-course`,children:[t.courseName||`Course no longer available`,!t.mapping.isActive&&(0,a.jsx)(nt,{type:`secondary`,children:` (off)`})]}):L.add?(0,a.jsx)(r.Button,{size:`small`,className:`fb-inline-btn`,disabled:G,loading:ne===t.formId,onClick:e=>{Z(e),je(t,`course`,e.currentTarget)},"aria-label":`Map course for ${t.formName}`,children:`Map course`}):(0,a.jsx)(nt,{type:`secondary`,children:`No course yet`}):(0,a.jsx)(nt,{type:`secondary`,children:at})},{title:`Who gets leads`,key:`who`,render:(e,t)=>W?(0,a.jsx)(ft,{distribution:t.distribution}):(0,a.jsx)(nt,{type:`secondary`,children:at})},{title:`Status`,dataIndex:`status`,key:`status`,width:170,render:e=>(0,a.jsx)(Me,{status:e})},{title:(0,a.jsx)(`span`,{className:`fb-sr-only`,children:`Actions`}),key:`actions`,width:56,align:`center`,render:(e,t)=>(0,a.jsx)(`span`,{onClick:Z,children:(0,a.jsx)(r.Dropdown,{menu:Re(t),trigger:[`click`],placement:`bottomRight`,children:(0,a.jsx)(r.Button,{size:`small`,className:`fb-form-actions-trigger`,"aria-label":`Actions for ${t.formName}`,"data-form-menu":t.formId,loading:ne===t.formId,icon:(0,a.jsx)(i.MoreOutlined,{})})})})}],Ue=()=>l?` `:G?(0,a.jsx)(r.Empty,{description:`Forms can't be shown right now.`}):ve?(0,a.jsx)(r.Empty,{description:`No forms match these filters.`,children:(0,a.jsx)(r.Button,{onClick:be,children:`Clear filters`})}):(0,a.jsx)(r.Empty,{description:`No Facebook forms yet. Create a lead form on Facebook, then refresh.`,children:(0,a.jsx)(r.Button,{onClick:F,children:`Refresh`})}),We=lt.filter(e=>!o[e].ok&&o[e].error),Ge=We.every(e=>o[e].loaded),Ke=()=>`Could not load ${We.map(e=>ct[e].label).join(`, `)}. ${[...new Set(We.map(e=>o[e].error))].join(` `)}`,qe=(0,a.jsxs)(`div`,{className:`fb-tab-body`,children:[(0,a.jsxs)(`div`,{className:`fb-toolbar`,children:[(0,a.jsxs)(`div`,{className:`fb-field fb-field--grow`,children:[(0,a.jsx)(`label`,{className:`fb-field-label`,htmlFor:`fb-forms-search`,children:`Search forms`}),(0,a.jsx)(r.Input,{id:`fb-forms-search`,allowClear:!0,prefix:(0,a.jsx)(i.SearchOutlined,{"aria-hidden":`true`}),placeholder:`Form or course name`,value:v,onChange:e=>{y(e.target.value),D(1)}})]}),(0,a.jsxs)(`div`,{className:`fb-field`,children:[(0,a.jsx)(`label`,{className:`fb-field-label`,htmlFor:`fb-forms-show`,children:`Show`}),(0,a.jsx)(r.Select,{id:`fb-forms-show`,className:`fb-show-select`,value:b,disabled:!U||!W,onChange:e=>{x(e),D(1)},options:[{value:`all`,label:`All forms`},...Object.entries(X).map(([e,t])=>({value:e,label:t.label}))]})]})]}),C&&(0,a.jsxs)(`div`,{className:`fb-filter-note`,role:`status`,children:[(0,a.jsx)(`span`,{children:C.length===1?`Showing 1 form that needs attention.`:`Showing ${C.length} forms that need attention.`}),(0,a.jsx)(r.Button,{size:`small`,type:`link`,onClick:()=>{w(null),D(1)},children:`Show all forms`})]}),me?(0,a.jsx)(r.Skeleton,{active:!0,title:!1,paragraph:{rows:6}}):(0,a.jsx)(r.Table,{rowKey:`formId`,className:`fb-forms-table${G?``:` fb-forms-table--open`}`,columns:He,dataSource:_e,loading:l,size:`middle`,scroll:{x:860},onRow:e=>({onClick:()=>je(e,`course`)}),pagination:{current:ye,pageSize:it,showSizeChanger:!1,onChange:D,showTotal:e=>`${e} Facebook form${e===1?``:`s`}`},locale:{emptyText:Ue()}}),(0,a.jsx)(nt,{type:`secondary`,className:`fb-small`,children:`Changing a form affects future leads only. Leads you already have keep their course and counsellor.`})]}),Q={rows:Y,refreshKey:j},Je=[{key:`forms`,label:`Forms`,children:qe},{key:`attention`,label:`Needs attention${De===null?``:` (${De})`}`,children:(0,a.jsx)(ze,{...Q,canEdit:L.edit,onChanged:()=>se(e=>e+1)})},{key:`skips`,label:`Skipped counsellors`,children:(0,a.jsx)(Be,{...Q})},{key:`reassign`,label:`Reassign leads`,children:(0,a.jsx)(he,{...Q,eligibleCounsellors:V,limits:f?.limits,reasonTypes:f?.reasonTypes,canEdit:L.edit,onChanged:()=>se(e=>e+1)})},{key:`history`,label:`History`,children:(0,a.jsx)(Ve,{...Q})},{key:`today`,label:`Today`,children:(0,a.jsx)(Ye,{canEdit:L.edit})},{key:`queue`,label:`Pending queue`,children:(0,a.jsx)(Ze,{rows:Y})},{key:`assignments`,label:`Assignment history`,children:(0,a.jsx)(Qe,{})},{key:`distributionSettings`,label:`Distribution settings`,children:(0,a.jsx)(et,{canEdit:L.edit})}],Xe=k?Y.find(e=>e.formId===k.row.formId)||k.row:null;return(0,a.jsxs)(`div`,{className:`facebook-course-mapping`,ref:le,children:[(0,a.jsxs)(`div`,{className:`admin-section-head fb-head`,children:[(0,a.jsxs)(`div`,{children:[(0,a.jsx)(rt,{level:4,children:`Facebook Leads`}),(0,a.jsx)(nt,{type:`secondary`,children:`Choose the course and counsellors for each Facebook form.`})]}),(0,a.jsx)(r.Button,{icon:(0,a.jsx)(i.ReloadOutlined,{"aria-hidden":`true`}),onClick:F,loading:l,children:`Refresh`})]}),(0,a.jsx)(u,{items:Oe,className:`fb-health`,ariaLabel:`Facebook leads health`}),We.length>0&&!l&&(0,a.jsx)(s,{className:`fb-load-problem`,type:Ge?`warning`:`error`,title:Ge?`Showing the last information we could load`:`Some information didn't load`,description:Ke(),action:(0,a.jsx)(r.Button,{size:`small`,onClick:F,children:`Try again`})}),f&&(!L.add||!L.edit||!L.remove)&&(0,a.jsx)(s,{className:`fb-load-problem`,type:`info`,title:`Your role can't make some changes here, so those actions are turned off.`}),(0,a.jsx)(K,{alerts:ue,failedCount:I??0,onViewLeads:()=>_(`attention`),onShowForms:xe}),(0,a.jsx)(r.Tabs,{size:`small`,activeKey:ee,onChange:_,items:Je,className:`fb-tabs`}),k&&(0,a.jsx)(Fe,{open:ae,row:Xe,section:k.section,mapping:J.get(k.row.formId),current:q.get(k.row.formId),courses:z,counsellors:V,limits:f?.limits,permissions:{canAdd:L.add,canEdit:L.edit},onClose:()=>A(!1),onSaved:Pe,onAfterClose:Ne,onReload:async()=>{let e=await Ae(),t=k.row.formId;return{mapping:e.mappings.find(e=>String(e.formId)===t),current:e.distributions.find(e=>String(e.formId)===t)}}},k.token)]})}Object.defineProperty(exports,"a",{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,"i",{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return tt}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return le}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return pt}});
|
|
3
|
-
//# sourceMappingURL=FacebookCourseMappingsSection-
|
|
1
|
+
const e=require("./rolldown-runtime-Chgba0Kb.cjs"),t=require("./authApi-D0LZjLV6.cjs");let n=require("react"),r=require("antd"),i=require("@ant-design/icons"),a=require("react/jsx-runtime"),o=require("dayjs");o=e.n(o,1);function s({className:e=``,variant:t=`default`,showIcon:n=!0,...i}){return(0,a.jsx)(r.Alert,{className:`app-alert app-alert--${t} ${e}`.trim(),showIcon:n,...i})}var c=new Intl.NumberFormat;function l(e){return e==null||e===``?`–`:typeof e==`number`&&Number.isFinite(e)?c.format(e):String(e)}function u({items:e=[],loading:t=!1,className:n=``,ariaLabel:i=`Summary`}){return t&&e.length===0?(0,a.jsx)(`div`,{className:`cc-stat-strip ${n}`.trim(),"aria-busy":`true`,"aria-label":i,children:[0,1,2,3].map(e=>(0,a.jsx)(`div`,{className:`cc-stat`,children:(0,a.jsx)(r.Skeleton.Button,{active:!0,size:`small`,style:{width:56}})},e))}):e.length===0?null:(0,a.jsx)(`div`,{className:`cc-stat-strip ${n}`.trim(),role:`group`,"aria-label":i,"aria-busy":t||void 0,children:e.map(e=>{let t=(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(`span`,{className:`cc-stat__value`,children:l(e.value)}),(0,a.jsx)(`span`,{className:`cc-stat__label`,children:e.label})]});return typeof e.onClick==`function`?(0,a.jsx)(`button`,{type:`button`,className:`cc-stat cc-stat--button${e.active?` is-active`:``}`,onClick:e.onClick,"aria-pressed":e.active?!0:void 0,children:t},e.key):(0,a.jsx)(`div`,{className:`cc-stat`,children:t},e.key)})})}var d=`${t.y}/admin/facebook`;async function f(e,n={}){let r=t.u(),i=await fetch(`${d}${e}`,{...n,headers:{"Content-Type":`application/json`,...t.O({"X-App-Id":String(t.b)}),...r?{Authorization:`Bearer ${r}`}:{},...n.headers||{}}}),a=await i.json().catch(()=>({}));if(!i.ok||a?.status===!1){let e=Error(a?.error||a?.message||a?.reason||`HTTP ${i.status}`);throw e.status=i.status,e}return a?.data??a}var p=()=>f(`/forms`),m=()=>f(`/courses`),h=()=>f(`/course-mappings`),ee=(e,t=!1)=>f(t?`/course-mappings/${encodeURIComponent(e.formId)}`:`/course-mappings`,{method:t?`PUT`:`POST`,body:JSON.stringify(e)}),g=e=>f(`/course-mappings/${encodeURIComponent(e)}`,{method:`DELETE`}),_=`${t.y}/admin/facebook`,v=`Could not connect. Check your internet connection and try again.`,y=`You don't have permission to do this. Ask your administrator for access.`,b=`Something went wrong. Please try again.`;function x(e,t=``){return e===401?`Your session has ended. Please sign in again.`:e===403?y:e===404?`This could not be found. Refresh the page and try again.`:e===409?t||`Someone else changed this. Refresh the page and try again.`:e>=500?`The server could not finish this. Please try again in a moment.`:t||b}function S(e,t=b,{hideServerText:n=!1}={}){if(e?.plain)return e.message;let r=String(e?.message||``);if(typeof e?.status==`number`)return x(e.status,r);let i=/^HTTP (\d{3})$/.exec(r);return i?x(Number(i[1])):e instanceof TypeError||/failed to fetch|networkerror|load failed/i.test(r)?v:/forbidden|permission|not allowed/i.test(r)?y:n?t:r||t}function C(e,t){let n=Error(e===0?v:x(e,t));return n.status=e,n.plain=!0,n.serverMessage=t,n}async function w(e,n={}){let r=t.u();if(!r)throw C(401,``);let i;try{i=await fetch(`${_}${e}`,{...n,headers:{"Content-Type":`application/json`,...t.O({"X-App-Id":String(t.b)}),Authorization:`Bearer ${r}`,...n.headers||{}}})}catch{throw C(0,``)}let a=await i.json().catch(()=>({}));if(!i.ok||a.status===!1)throw C(i.status,a.error||a.message||``);return a.data??a}var T=()=>w(`/distributions`).then(e=>Array.isArray(e)?e:e.distributions||[]);async function E(){let e=[];for(let t=1;t<=1e3;t++){let n=await w(`/counsellors?page=${t}&limit=100`);if(!Array.isArray(n.counsellors))throw Error(`Could not read the list of counsellors. Please try again.`);if(e.push(...n.counsellors),t>=Number(n.totalPages||0)||!n.counsellors.length)return e}throw Error(`The list of counsellors is too long to load. Please contact support.`)}var te=({formId:e,counsellorIds:t,isActive:n,version:r},i)=>w(i?`/distribution/${encodeURIComponent(e)}`:`/distribution`,{method:i?`PUT`:`POST`,body:JSON.stringify({formId:e,counsellorIds:t,isActive:n,...r==null?{}:{version:r}})});function D({page:e=1,limit:t=20,formId:n=``}={}){let r=new URLSearchParams({page:String(e),limit:String(t)});return n&&r.set(`formId`,n),w(`/distribution-skips?${r}`)}function ne({status:e=`unassigned`,page:t=1,limit:n=20,formId:r=``}={}){let i=new URLSearchParams({status:e,page:String(t),limit:String(n)});return r&&i.set(`formId`,r),w(`/unassigned-leads?${i}`)}var re=e=>w(`/distribution/${encodeURIComponent(e)}`,{method:`DELETE`}),O=()=>w(`/distribution-alerts`),k=()=>w(`/reassign/summary`).then(e=>e.counsellors||[]);function ie({fromUserId:e,formId:t=``,page:n=1,limit:r=20}={}){let i=new URLSearchParams({fromUserId:e,page:String(n),limit:String(r)});return t&&i.set(`formId`,t),w(`/reassign/leads?${i}`)}var ae=e=>w(`/reassign`,{method:`POST`,body:JSON.stringify(e)});function A({page:e=1,limit:t=20,formId:n=``,leadId:r=``}={}){let i=new URLSearchParams({page:String(e),limit:String(t)});return n&&i.set(`formId`,n),r&&i.set(`leadId`,r),w(`/reassignments?${i}`)}var oe=()=>w(`/meta`);function j({page:e=1,limit:t=20,formId:n=``}={}){let r=new URLSearchParams({page:String(e),limit:String(t)});return n&&r.set(`formId`,n),w(`/failed-leads?${r}`)}var se=e=>w(`/failed-leads/${encodeURIComponent(e)}/retry`,{method:`POST`});function ce({page:e=1,limit:t=20,formId:n=``}={}){let r=new URLSearchParams({page:String(e),limit:String(t)});return n&&r.set(`formId`,n),w(`/history?${r}`)}var M=e=>{let t=new URLSearchParams;Object.entries(e||{}).forEach(([e,n])=>{n!=null&&n!==``&&t.set(e,String(n))});let n=t.toString();return n?`?${n}`:``},N=e=>w(`/distribution/overview${M({date:e})}`),le=()=>w(`/distribution/settings`),P=e=>w(`/distribution/settings`,{method:`PUT`,body:JSON.stringify(e)}),F=(e,t,n=``)=>w(`/distribution/counsellors/${encodeURIComponent(e)}/enabled`,{method:`PUT`,body:JSON.stringify({enabled:t,reason:n})}),ue=e=>w(`/distribution/leaves${M({from:e})}`),de=e=>w(`/distribution/leaves`,{method:`POST`,body:JSON.stringify(e)}),I=e=>w(`/distribution/leaves/${encodeURIComponent(e)}`,{method:`DELETE`}),L=e=>w(`/distribution/queue${M(e)}`),R=e=>w(`/distribution/assignments${M(e)}`),{Text:z}=r.Typography,fe=e=>e?new Date(e).toLocaleString():`—`,B=(e,t)=>`${e} ${t}${e===1?``:`s`}`,V=[{value:`on_leave`,label:`On leave`},{value:`left_company`,label:`Left the company`},{value:`workload`,label:`Workload balancing`},{value:`other`,label:`Other`}],H={no_active_counsellor:`no active counsellor`,distribution_not_configured:`no counsellors set up for the form`,distribution_disabled:`automatic turns are paused`,default_owner_inactive_or_missing:`default owner inactive`},U={not_open_or_not_assigned_to_counsellor:`no longer open or no longer with this counsellor`,changed_during_reassign:`was updated by the counsellor while moving (run again)`,update_failed:`could not be saved`};function W({canEdit:e=!0,fromId:t,toId:n,movingCount:r,reasonOk:i,minReason:a}){if(!e)return`You don't have permission to move leads.`;let o=[];return t||o.push(`choose who the leads are moving from`),r||o.push(`choose at least one lead`),n||o.push(`choose who gets the leads`),i||o.push(`write a reason of at least ${a} characters`),o.length?`To continue, ${o.join(`, `)}.`:``}function G({id:e,rows:t=[],value:i,onChange:o,minWidth:s=260}){let c=(0,n.useMemo)(()=>t.map(e=>({value:e.formId,label:e.formName})),[t]);return(0,a.jsx)(r.Select,{id:e,showSearch:!0,optionFilterProp:`label`,allowClear:!0,style:{minWidth:s,maxWidth:`100%`},"aria-label":`Facebook form`,placeholder:`All Facebook forms`,value:i||void 0,onChange:e=>o(e||``),options:c,popupMatchSelectWidth:!1,notFoundContent:`No matching forms`})}function pe({refreshKey:e=0,pollMs:t=6e4}={}){let[r,i]=(0,n.useState)({alerts:null,alertsOk:!1,failedCount:null});return(0,n.useEffect)(()=>{let e=!0,n=()=>{typeof document<`u`&&document.hidden||Promise.allSettled([O(),j({page:1,limit:1})]).then(([t,n])=>{e&&i(e=>({alerts:t.status===`fulfilled`?t.value:e.alerts,alertsOk:t.status===`fulfilled`,failedCount:n.status===`fulfilled`?Number(n.value?.failedCount??n.value?.total??0):null}))})};n();let r=setInterval(n,t);return()=>{e=!1,clearInterval(r)}},[e,t]),r}function me(e){let t=[...e?.formsWithoutActiveCounsellor||[],...e?.waitingForms||[]].map(e=>String(e.formId)).filter(Boolean);return[...new Set(t)]}function K({alerts:e,failedCount:t=0,onViewLeads:n,onShowForms:i}){let o=Number(e?.unassignedCount||0),c=e?.formsWithoutActiveCounsellor||[],l=Number(t||0),u=me(e);if(!o&&!c.length&&!l)return null;let d=[];o&&d.push(`${B(o,`lead`)} waiting`),c.length&&d.push(`${B(c.length,`form`)} with no active counsellor`),l&&d.push(`${B(l,`lead`)} failed`);let f=[...new Set([...c,...e?.waitingForms||[]].map(e=>e.formName).filter(Boolean))],p=f.slice(0,2).join(`, `),m=f.length>2?` and ${f.length-2} more`:``;return(0,a.jsx)(s,{className:`fb-attention`,type:`warning`,title:d.join(` · `),description:p?`${p}${m}`:void 0,action:(0,a.jsxs)(`div`,{className:`fb-attention-actions`,children:[(o>0||l>0)&&n&&(0,a.jsx)(r.Button,{size:`small`,onClick:n,children:`View leads`}),u.length>0&&i&&(0,a.jsx)(r.Button,{size:`small`,onClick:()=>i(u),children:`Show these forms`})]})})}function he({rows:e=[],eligibleCounsellors:t=[],onChanged:o,limits:s,reasonTypes:c,canEdit:l=!0,refreshKey:u=0}){let[d,f]=(0,n.useState)([]),[p,m]=(0,n.useState)(!1),[h,ee]=(0,n.useState)(``),[g,_]=(0,n.useState)(``),[v,y]=(0,n.useState)({leads:[],total:0}),[b,x]=(0,n.useState)(!1),[S,C]=(0,n.useState)(1),[w,T]=(0,n.useState)([]),[E,te]=(0,n.useState)(!1),[D,ne]=(0,n.useState)(``),[re,O]=(0,n.useState)(`on_leave`),[oe,j]=(0,n.useState)(``),[se,ce]=(0,n.useState)(!1),[M,N]=(0,n.useState)(``),[le,P]=(0,n.useState)({reassignments:[],total:0}),[F,ue]=(0,n.useState)(1),[de,I]=(0,n.useState)(!1),L=Number(s?.minReason)||5,R=Number(s?.maxReason)||500,B=Number(s?.maxPerRun)||500,H=c?.length?c:V,pe=Object.fromEntries(H.map(e=>[e.value,e.label])),me=pe[re]?re:H[0]?.value,K=(0,n.useCallback)(async()=>{m(!0);try{f(await k()),N(``)}catch(e){N(e.message)}finally{m(!1)}},[]),he=(0,n.useCallback)(async()=>{if(!h){y({leads:[],total:0});return}x(!0);try{y(await ie({fromUserId:h,formId:g,page:S,limit:20})),N(``)}catch(e){N(e.message),y({leads:[],total:0})}finally{x(!1)}},[h,g,S]),q=(0,n.useCallback)(async()=>{I(!0);try{P(await A({page:F,limit:10}))}catch(e){N(e.message)}finally{I(!1)}},[F]);(0,n.useEffect)(()=>{K()},[K,u]),(0,n.useEffect)(()=>{he()},[he,u]),(0,n.useEffect)(()=>{q()},[q,u]);let J=d.find(e=>e.userId===h),ge=Number(v.total||0),Y=E?Math.min(ge,B):w.length,_e=(0,n.useMemo)(()=>t.filter(e=>e.userId!==h&&e.isActive!==!1).map(e=>({value:e.userId,label:e.name||e.email||e.userId})),[t,h]),X=_e.find(e=>e.value===D)?.label||``,ve=oe.trim().length>=L,ye=W({canEdit:l,fromId:h,toId:D,movingCount:Y,reasonOk:ve,minReason:L}),be=!ye&&!se,xe=e=>{ee(e),C(1),T([]),te(!1),ne(``)},Se=e=>{_(e),C(1),T([]),te(!1)},Ce=async()=>{ce(!0);try{let e=await ae({fromUserId:h,toUserId:D,reasonType:me,reason:oe.trim(),...g?{formId:g}:{},...E?{allOpen:!0}:{leadIds:w}}),t=e.skipped||[];if(r.message.success(`${e.moved} lead${e.moved===1?``:`s`} moved to ${e.to?.name||X}`),t.length){let e=t.reduce((e,t)=>({...e,[t.reason]:(e[t.reason]||0)+1}),{});r.Modal.warning({title:`${t.length} lead${t.length===1?` was`:`s were`} not moved`,content:(0,a.jsx)(`ul`,{style:{paddingLeft:18},children:Object.entries(e).map(([e,t])=>(0,a.jsxs)(`li`,{children:[t,` — `,U[e]||e]},e))})})}e.auditSaved===!1&&r.message.warning(`Leads were moved, but the history row could not be saved. Each lead still has its own activity entry.`),e.remaining>0&&r.message.info(`${e.remaining} open lead${e.remaining===1?``:`s`} still with ${e.from?.name||`this counsellor`}. Run again to move them.`),T([]),te(!1),j(``),await Promise.all([K(),he(),q()]),o&&o()}catch(e){r.message.error(e.message||`Could not reassign leads`)}finally{ce(!1)}},we=()=>r.Modal.confirm({title:`Move ${Y} lead${Y===1?``:`s`} to ${X}?`,okText:`Reassign`,width:520,content:(0,a.jsxs)(`div`,{children:[(0,a.jsxs)(`p`,{style:{marginBottom:6},children:[`From `,(0,a.jsx)(`strong`,{children:J?.name||`selected counsellor`}),` to `,(0,a.jsx)(`strong`,{children:X}),`.`]}),(0,a.jsxs)(`p`,{style:{marginBottom:6},children:[`Reason: `,(0,a.jsx)(`strong`,{children:pe[me]}),` — `,oe.trim()]}),(0,a.jsx)(z,{type:`secondary`,children:`Each lead gets an activity entry and a history row. The previous counsellor stops seeing these leads. Pending follow-up reminders are not moved.`})]}),onOk:Ce}),Te=[{title:`Lead`,dataIndex:`name`,render:(e,t)=>(0,a.jsxs)(`div`,{children:[(0,a.jsx)(z,{strong:!0,children:e||t.leadCode||t.facebookLeadId}),(0,a.jsx)(`div`,{children:(0,a.jsx)(z,{type:`secondary`,className:`fb-small`,children:t.leadCode||t.facebookLeadId})})]})},{title:`Facebook form`,dataIndex:`formName`,render:e=>e||`Unknown form`},{title:`Status`,dataIndex:`status`,render:e=>(0,a.jsx)(r.Tag,{children:e||`New Lead`})},{title:`Received`,dataIndex:`createdAt`,render:fe}],Ee=[{title:`When`,dataIndex:`reassignedAt`,render:fe},{title:`Lead`,dataIndex:`leadCode`,render:(e,t)=>e||t.facebookLeadId||`—`},{title:`From → To`,render:(e,t)=>(0,a.jsxs)(`span`,{children:[t.fromName,` `,(0,a.jsx)(i.SwapOutlined,{}),` `,t.toName]})},{title:`Reason`,render:(e,t)=>(0,a.jsxs)(`div`,{children:[(0,a.jsx)(r.Tag,{children:pe[t.reasonType]||`Other`}),(0,a.jsx)(`div`,{style:{fontSize:12},children:t.reason})]})},{title:`By`,dataIndex:`performedByName`}];return(0,a.jsxs)(`div`,{className:`fb-tab-body`,children:[(0,a.jsx)(z,{type:`secondary`,className:`fb-tab-intro`,children:`Automatic turns keep sending leads to a counsellor who is on leave. Move their open leads to someone else here.`}),M&&(0,a.jsx)(r.Alert,{type:`error`,showIcon:!0,title:`Could not load everything for this tab`,description:M,className:`fb-block`}),(0,a.jsxs)(`div`,{className:`fb-field-row`,children:[(0,a.jsxs)(`div`,{className:`fb-field`,children:[(0,a.jsx)(`label`,{className:`fb-field-label`,htmlFor:`fb-reassign-from`,children:`From`}),(0,a.jsx)(r.Select,{id:`fb-reassign-from`,showSearch:!0,optionFilterProp:`label`,placeholder:`Choose a counsellor`,value:h||void 0,onChange:xe,loading:p,notFoundContent:`No counsellor has open Facebook leads`,options:d.map(e=>({value:e.userId,label:`${e.name} — ${e.openLeads} open${e.isActive?``:` (inactive)`}`}))})]}),(0,a.jsxs)(`div`,{className:`fb-field`,children:[(0,a.jsx)(`label`,{className:`fb-field-label`,htmlFor:`fb-reassign-form`,children:`Form`}),(0,a.jsx)(G,{id:`fb-reassign-form`,rows:e,value:g,onChange:Se,minWidth:0})]})]}),h&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)(`div`,{className:`fb-block`,children:[(0,a.jsxs)(r.Radio.Group,{value:E?`all`:`pick`,onChange:e=>{te(e.target.value===`all`),e.target.value===`all`&&T([])},children:[(0,a.jsx)(r.Radio.Button,{value:`pick`,children:`Choose leads`}),(0,a.jsxs)(r.Radio.Button,{value:`all`,children:[`All `,ge,` open lead`,ge===1?``:`s`]})]}),E&&ge>B&&(0,a.jsxs)(z,{type:`secondary`,className:`fb-hint-inline`,children:[`Moves `,B,` per run. Run again for the rest.`]})]}),(0,a.jsx)(r.Table,{size:`small`,rowKey:`id`,loading:b,columns:Te,dataSource:v.leads,rowSelection:E?void 0:{selectedRowKeys:w,preserveSelectedRowKeys:!0,onChange:e=>T(e)},pagination:{current:S,pageSize:20,total:ge,showSizeChanger:!1,onChange:C},locale:{emptyText:`No open Facebook leads for this counsellor`},scroll:{x:640}}),(0,a.jsxs)(`div`,{className:`fb-reassign-fields`,children:[(0,a.jsxs)(`div`,{className:`fb-field`,children:[(0,a.jsx)(`label`,{className:`fb-field-label`,htmlFor:`fb-reassign-to`,children:`To`}),(0,a.jsx)(r.Select,{id:`fb-reassign-to`,showSearch:!0,optionFilterProp:`label`,placeholder:`Choose an active counsellor`,value:D||void 0,onChange:ne,options:_e,notFoundContent:`No other active counsellor available`})]}),(0,a.jsxs)(`div`,{className:`fb-field`,children:[(0,a.jsx)(`label`,{className:`fb-field-label`,htmlFor:`fb-reassign-type`,children:`Reason type`}),(0,a.jsx)(r.Select,{id:`fb-reassign-type`,value:me,onChange:O,options:H})]}),(0,a.jsxs)(`div`,{className:`fb-field`,children:[(0,a.jsx)(`label`,{className:`fb-field-label`,htmlFor:`fb-reassign-reason`,children:`Reason`}),(0,a.jsx)(r.Input.TextArea,{id:`fb-reassign-reason`,rows:2,maxLength:R,showCount:!0,value:oe,onChange:e=>j(e.target.value),placeholder:`For example, on leave 3–7 Nov`,"aria-describedby":`fb-reassign-reason-hint`,status:oe&&!ve?`error`:void 0}),!ve&&(0,a.jsxs)(`div`,{id:`fb-reassign-reason-hint`,className:`fb-hint`,children:[`At least `,L,` characters`]})]}),(0,a.jsxs)(`div`,{children:[(0,a.jsx)(r.Button,{type:`primary`,icon:(0,a.jsx)(i.SwapOutlined,{}),disabled:!be,loading:se,onClick:we,children:Y?`Reassign ${Y} lead${Y===1?``:`s`}`:`Reassign`}),ye&&(0,a.jsx)(`div`,{className:`fb-hint`,role:`status`,children:ye})]})]})]}),(0,a.jsx)(r.Collapse,{ghost:!0,className:`fb-history-collapse`,items:[{key:`history`,label:`Reassignment history`,children:(0,a.jsx)(r.Table,{size:`small`,rowKey:`id`,loading:de,columns:Ee,dataSource:le.reassignments,pagination:{current:F,pageSize:10,total:Number(le.total||0),showSizeChanger:!1,onChange:ue},locale:{emptyText:`No leads have been reassigned yet`},scroll:{x:720}})}]})]})}var{Text:q}=r.Typography,J=e=>String(e?.userId||``),ge=50,Y=e=>{let t=e?new Date(e):null;return t&&!Number.isNaN(t.getTime())?t.toLocaleString():`—`},_e=e=>e&&e.charAt(0).toUpperCase()+e.slice(1),X={ready:{label:`Ready`,tone:`good`},needs_setup:{label:`Needs setup`,tone:`warn`},paused:{label:`Paused`,tone:`muted`},no_active:{label:`No active counsellor`,tone:`bad`},unknown_form:{label:`Unknown form`,tone:`muted`}},ve={inactive:`Inactive`,locked:`Account locked`,deleted:`Deleted`,not_counsellor:`No longer a counsellor`,unavailable:`Unavailable`},ye=e=>ve[e]||`Unavailable`,be={meta_fetch:`Could not read the lead from Facebook`,lms_create:`Could not create the lead`,invalid_lead_fields:`The lead had unreadable details`,course_mapping:`Could not read the course for this form`,contact_lookup:`Could not check for a duplicate`,database_lookup:`Could not check for a duplicate`,distribution_lookup:`Could not find the counsellor list`,configuration_disabled:`Facebook import was switched off`,unassigned_audit:`Could not add the lead to the waiting list`,meta_forms:`Could not read the forms from Facebook`,mismatched_page_or_form:`The lead came from a different Facebook page or form`,mismatched_meta_form:`The lead came from a different Facebook page or form`},xe=e=>be[e]||`Failed`,Se=e=>_e(H[e])||`Waiting for setup`,Ce=e=>{if(!e||typeof e!=`object`)return null;let t=e.counsellorIds||e.counsellors;return Array.isArray(t)?t.map(e=>String(e?.userId??e?.legacyUserId??e)):null};function we(e){let{area:t,action:n,before:r,after:i}=e||{},a=String(t||``).toLowerCase(),o=String(n||``).toLowerCase(),s=/delete|remove/.test(o),c=/create|add/.test(o)||!r;if(/retry/.test(o)||/failed/.test(a))return`Retried failed lead`;if(/mapping|course/.test(a)){if(s)return`Course removed`;let e=i?.courseName,t=(r?.courseId??r?.courseName)!==(i?.courseId??i?.courseName);return e&&(c||t)?`Course ${c?`set to`:`changed to`} ${e}`:typeof r?.isActive==`boolean`&&typeof i?.isActive==`boolean`&&r.isActive!==i.isActive?i.isActive?`Course turned on`:`Course turned off`:`Course changed`}if(/distribution|counsellor/.test(a)){if(s)return`Counsellors removed`;if(c)return`Counsellors set up`;if(typeof r?.isActive==`boolean`&&typeof i?.isActive==`boolean`&&r.isActive!==i.isActive)return i.isActive?`Resumed`:`Paused`;let e=Ce(r),t=Ce(i);return e&&t&&e.length===t.length&&[...e].sort().join()===[...t].sort().join()?`Order changed`:`Counsellors changed`}return`Setup changed`}function Te({mapping:e,distribution:t,inFormsList:n=!0},r={}){let{forms:i=!0,mappings:a=!0,distributions:o=!0}=r;if(!a||!o)return null;if(i&&!n)return`unknown_form`;let s=t?.counsellors||[];return!e||!e.isActive||!t||!s.length?`needs_setup`:t.isActive===!1?`paused`:s.some(e=>e.isActive!==!1)?`ready`:`no_active`}function Ee(e){let t=e?.counsellors||[];if(!t.length)return``;let n=Math.max(t.findIndex(t=>J(t)===String(e.nextUserId||``)),0);return[...t.slice(n),...t.slice(0,n)].find(e=>e.isActive!==!1)?.name||``}function De(e,t,n){if(t===n||t<0||n<0||t>=e.length||n>=e.length)return e;let r=[...e],[i]=r.splice(t,1);return r.splice(n,0,i),r}function Oe(e,t){if(!t.length)return``;let n=(e?.counsellors||[]).map(J).filter(Boolean),r=String(e?.nextUserId||``);if(n.length===t.length&&n.every((e,n)=>e===t[n])&&t.includes(r))return r;let i=String(e?.lastAssignedUserId||``);if(!i&&n.includes(r)&&(i=n[(n.indexOf(r)-1+n.length)%n.length]),t.includes(i))return t[(t.indexOf(i)+1)%t.length];if(n.includes(i)){let e=n.indexOf(i);for(let r=1;r<=n.length;r++){let i=n[(e+r)%n.length];if(t.includes(i))return i}}return t.includes(r)?r:t[0]}async function ke({mapping:e,distribution:t,saveMapping:n,saveDistribution:r}){let i={mappingSaved:!1,distributionSaved:!1,failedPart:``,error:null};if(e)try{await n(e.input,e.isEdit),i.mappingSaved=!0}catch(e){return{...i,failedPart:`mapping`,error:e}}if(t)try{await r(t.input,t.isEdit),i.distributionSaved=!0}catch(e){return{...i,failedPart:`distribution`,error:e}}return i}var Ae=e=>e.length<2?e[0]||``:`${e.slice(0,-1).join(`, `)} and ${e[e.length-1]}`;function je(e){return e.length?e.length===1?`${e[0]} is inactive and will be skipped. Remove them or keep the place for when they return.`:`${Ae(e)} are inactive and will be skipped. Remove them or keep their places for when they return.`:``}function Me({status:e}){let t=X[e];return t?(0,a.jsxs)(r.Tag,{className:`fb-status fb-status--${t.tone}`,children:[(0,a.jsx)(`span`,{className:`fb-status-dot`,"aria-hidden":`true`}),t.label]}):(0,a.jsx)(q,{type:`secondary`,children:`—`})}function Ne({number:e,title:t,aside:n}){return(0,a.jsxs)(`div`,{className:`fb-setup-heading`,children:[(0,a.jsxs)(`h3`,{children:[(0,a.jsx)(`span`,{className:`fb-setup-number`,"aria-hidden":`true`,children:e}),t]}),n&&(0,a.jsx)(`span`,{className:`fb-setup-aside`,children:n})]})}var Pe=(e,t)=>({base:{mapping:e||null,current:t||null},courseId:e?.courseId||void 0,mappingActive:e?.isActive??!0,orderedIds:(t?.counsellors||[]).map(J).filter(Boolean),enabled:t?.isActive!==!1});function Fe({open:e,row:t,mapping:o,current:s,courses:c=[],counsellors:l=[],limits:u,permissions:d={},section:f=`course`,onClose:p,onSaved:m,onReload:h,onAfterClose:g}){let[_]=(0,n.useState)(()=>Pe(o,s)),[v,y]=(0,n.useState)(_.base),[b,x]=(0,n.useState)(_.courseId),[C,w]=(0,n.useState)(_.mappingActive),[T,E]=(0,n.useState)(_.orderedIds),[D,ne]=(0,n.useState)(_.enabled),[re,O]=(0,n.useState)(``),[k,ie]=(0,n.useState)(!1),[ae,A]=(0,n.useState)(``),[oe,j]=(0,n.useState)(``),[se,ce]=(0,n.useState)(null),[M,N]=(0,n.useState)(null),le=(0,n.useRef)(null),P=(0,n.useRef)(null),F=(0,n.useRef)(null),ue=(0,n.useRef)(!1),{canAdd:de=!0,canEdit:I=!0}=d,L=v.mapping?I:de,R=v.current?I:de,z=!L&&!R,fe=Number(u?.maxCounsellors)||ge,B=v.current?.counsellors,V=v.mapping,H=(0,n.useMemo)(()=>{let e=new Map(l.map(e=>[J(e),{...e,isActive:!0}]));return(B||[]).forEach(t=>{let n=J(t);e.has(n)||e.set(n,{...t,isActive:!1})}),e},[l,B]),U=(0,n.useCallback)(e=>H.get(e)?.name||`Unnamed counsellor`,[H]),W=(0,n.useMemo)(()=>new Set(T),[T]),G=T.map(e=>H.get(e)).filter(Boolean),pe=[...l].filter(e=>!W.has(J(e))).sort((e,t)=>String(e.name).localeCompare(String(t.name))),me=[...G,...pe].filter(e=>`${e.name||``} ${e.email||``}`.toLowerCase().includes(re.trim().toLowerCase())),K=G.filter(e=>!e.isActive),he=G.length-K.length,Y=(v.current?.counsellors||[]).map(J).filter(Boolean),_e=Y.length!==T.length||Y.some((e,t)=>e!==T[t]),X=v.current?_e||D!==(v.current.isActive!==!1):T.length>0,ve=v.mapping?String(b)!==String(v.mapping.courseId)||C!==v.mapping.isActive:!!b,ye=ve||X,be=Oe(v.current,T),xe=T.indexOf(be),Se=(xe<0?T:[...T.slice(xe),...T.slice(0,xe)]).find(e=>H.get(e)?.isActive)||``,Ce=H.get(Se)?.name||`No one yet`,we=(0,n.useMemo)(()=>{let e=c.map(e=>({value:e.courseId,label:e.courseName}));return V?.courseId&&!e.some(e=>e.value===V.courseId)&&e.unshift({value:V.courseId,label:V.courseName||`Course no longer available`}),e},[c,V]),Te=(e,t)=>{let n=Pe(e,t);y(n.base),x(n.courseId),w(n.mappingActive),E(n.orderedIds),ne(n.enabled)},Ee=(e,t)=>{E(n=>t?[...n.filter(t=>t!==e),e]:n.filter(t=>t!==e)),j(t?`${U(e)} added to the list`:`${U(e)} removed from the list`)},Ae=(e,t)=>{let n=T.indexOf(e),r=n+(t===`up`?-1:1);n<0||r<0||r>=T.length||(F.current={id:e,direction:t},E(e=>De(e,n,r)),j(`${U(e)} moved to place ${r+1} of ${T.length}`))};(0,n.useLayoutEffect)(()=>{let e=F.current;if(!e)return;F.current=null;let t=[...le.current?.querySelectorAll(`[data-move-id]`)||[]].filter(t=>t.dataset.moveId===e.id&&!t.disabled);(t.find(t=>t.dataset.moveDirection===e.direction)||t[0])?.focus()},[T]);let Me=(e,t)=>{N(t),e.dataTransfer.effectAllowed=`move`,e.dataTransfer.setData(`text/plain`,t)},Fe=(e,t,n)=>{!n||!M||M===t||(e.preventDefault(),ce(t))},Ie=()=>{N(null),ce(null)},Le=e=>{let t=M;Ie(),!(!W.has(t)||!W.has(e)||t===e)&&(E(n=>De(n,n.indexOf(t),n.indexOf(e))),j(`${U(t)} moved`))},Re=()=>{if(!k){if(!ye){p();return}ue.current||(ue.current=!0,r.Modal.confirm({title:`Discard your changes?`,content:`Your changes to this form have not been saved.`,okText:`Discard changes`,okType:`danger`,cancelText:`Keep editing`,autoFocusButton:`cancel`,onOk:()=>{ue.current=!1,p()},onCancel:()=>{ue.current=!1}}))}},ze=(0,a.jsxs)(`div`,{className:`fb-setup-footer`,children:[ae&&(0,a.jsx)(r.Alert,{type:`error`,showIcon:!0,title:ae,className:`fb-setup-problem`}),(0,a.jsxs)(`div`,{className:`fb-setup-footer-actions`,children:[(0,a.jsx)(r.Button,{onClick:Re,disabled:k,children:z?`Close`:`Cancel`}),!z&&(0,a.jsx)(r.Button,{type:`primary`,loading:k,disabled:!ye,onClick:async()=>{if(A(``),X&&!T.length){A(`Choose at least one counsellor. To stop using counsellors on this form, use Remove distribution in the form menu.`);return}if(X&&T.length>fe){A(`You can choose up to ${fe} counsellors. You have chosen ${T.length}.`);return}ie(!0);let e=await ke({mapping:ve?{input:{formId:t.formId,courseId:b,isActive:C},isEdit:!!v.mapping}:null,distribution:X?{input:{formId:t.formId,counsellorIds:T,isActive:D,version:v.current?.version??0},isEdit:!!v.current}:null,saveMapping:ee,saveDistribution:te});if(!e.error){ie(!1),r.message.success(`Form setup saved`),m?.(),p();return}let n=e.mappingSaved?`The course was saved. `:``;if(e.failedPart===`mapping`)A(`Nothing was saved. The course could not be saved: ${S(e.error)}`);else if(e.error?.status===409)try{let e=await h();Te(e?.mapping,e?.current),A(`${n}Someone else changed these counsellors while you were editing, so yours were not saved. The latest list is now showing. Check it and save again.`)}catch{A(`${n}Someone else changed these counsellors while you were editing, so yours were not saved. The latest list could not be loaded. Close this panel and open it again.`)}else e.mappingSaved&&y(e=>({...e,mapping:{...e.mapping||{},formId:t.formId,courseId:b,isActive:C,courseName:we.find(e=>e.value===b)?.label||e.mapping?.courseName||``}})),A(`${n}The counsellors were not saved: ${S(e.error)}`);e.mappingSaved&&m?.(),ie(!1)},children:`Save`})]})]}),Be=!!(v.mapping||v.current);return(0,a.jsxs)(r.Drawer,{open:e,size:560,rootClassName:`fb-setup-drawer`,keyboard:!0,mask:{closable:!0},title:(0,a.jsxs)(`span`,{className:`fb-setup-title`,children:[Be?`Edit`:`Set up`,` form`]}),onClose:Re,footer:ze,afterOpenChange:e=>{e&&f===`counsellors`&&P.current?.scrollIntoView?.({block:`start`}),e||g?.()},children:[(0,a.jsxs)(`div`,{className:`fb-setup-form-name`,children:[(0,a.jsx)(q,{strong:!0,children:t?.formName}),(0,a.jsxs)(q,{type:`secondary`,className:`fb-small`,copyable:{text:t?.formId,tooltips:[`Copy Form ID`,`Copied`]},children:[`Form ID: `,t?.formId]})]}),z&&(0,a.jsx)(r.Alert,{type:`info`,showIcon:!0,title:`You can view this setup, but your role cannot change it.`,className:`fb-block`}),(0,a.jsxs)(`section`,{className:`fb-setup-section`,"aria-label":`Course`,children:[(0,a.jsx)(Ne,{number:`1`,title:`Course`}),(0,a.jsx)(r.Select,{className:`fb-setup-select`,showSearch:!0,optionFilterProp:`label`,"aria-label":`Course`,placeholder:`Choose a course`,value:b,onChange:x,options:we,disabled:!L||k,notFoundContent:`No matching courses`}),b?(0,a.jsxs)(`label`,{className:`fb-setup-toggle`,children:[(0,a.jsxs)(`span`,{children:[(0,a.jsx)(`span`,{className:`fb-setup-toggle-title`,children:`Use this course for new leads`}),(0,a.jsx)(`span`,{className:`fb-hint`,children:`When off, new leads still come in, but without a course.`})]}),(0,a.jsx)(r.Switch,{"aria-label":`Use this course for new leads`,checked:C,onChange:w,disabled:!L||k})]}):(0,a.jsx)(`div`,{className:`fb-hint`,children:`No course yet. You can still choose counsellors, and leads will arrive without a course until you pick one.`})]}),(0,a.jsxs)(`section`,{className:`fb-setup-section`,"aria-label":`Counsellors and order`,ref:P,children:[(0,a.jsx)(Ne,{number:`2`,title:`Counsellors and order`,aside:`${he} active${K.length?`, ${K.length} inactive`:``}`}),K.length>0&&(0,a.jsx)(r.Alert,{type:`warning`,showIcon:!0,className:`fb-block`,title:je(K.map(e=>e.name||`Unnamed counsellor`)),description:R&&(0,a.jsx)(`div`,{className:`fb-inactive-actions`,children:K.map(e=>(0,a.jsxs)(r.Button,{size:`small`,disabled:k,onClick:()=>Ee(J(e),!1),children:[`Remove `,e.name||`Unnamed counsellor`]},J(e)))})}),(0,a.jsx)(r.Input,{allowClear:!0,value:re,prefix:(0,a.jsx)(i.SearchOutlined,{"aria-hidden":`true`}),className:`fb-block`,placeholder:`Search counsellors`,"aria-label":`Search counsellors`,onChange:e=>O(e.target.value)}),(0,a.jsx)(`div`,{className:`fb-dist-draggable-list`,ref:le,children:me.length===0?(0,a.jsx)(r.Empty,{description:l.length||T.length?`No matching counsellors`:`No active counsellors to choose from`}):me.map(e=>{let t=J(e),n=e.name||`Unnamed counsellor`,o=W.has(t),s=T.indexOf(t);return(0,a.jsxs)(`div`,{"data-person-row":t,className:`fb-dist-unified-row ${o?`selected`:``} ${se===t?`drag-over`:``}`,draggable:o&&!k&&R,onDragStart:e=>Me(e,t),onDragOver:e=>Fe(e,t,o),onDrop:e=>{e.preventDefault(),Le(t)},onDragEnd:Ie,children:[(0,a.jsx)(`span`,{className:`fb-dist-check`,children:(0,a.jsx)(r.Checkbox,{"aria-label":`Include ${n}`,checked:o,disabled:k||!R,onChange:e=>Ee(t,e.target.checked)})}),(0,a.jsx)(`span`,{className:`fb-dist-grip ${o?``:`placeholder`}`,"aria-hidden":`true`,children:(0,a.jsx)(i.DragOutlined,{})}),(0,a.jsx)(`span`,{className:`fb-dist-rank`,"aria-hidden":!o,children:o?s+1:``}),(0,a.jsxs)(`div`,{className:`fb-dist-person-name`,children:[(0,a.jsx)(q,{strong:o,children:n}),e.email&&(0,a.jsx)(q,{type:`secondary`,className:`fb-small`,ellipsis:!0,children:e.email})]}),!e.isActive&&(0,a.jsxs)(r.Tag,{className:`fb-status fb-status--bad`,children:[(0,a.jsx)(`span`,{className:`fb-status-dot`,"aria-hidden":`true`}),`Inactive`]}),o&&(0,a.jsxs)(`span`,{className:`fb-dist-order-buttons`,children:[(0,a.jsx)(r.Tooltip,{title:`Move ${n} up`,children:(0,a.jsx)(r.Button,{type:`text`,icon:(0,a.jsx)(i.ArrowUpOutlined,{"aria-hidden":`true`}),"aria-label":`Move ${n} up`,"data-move-id":t,"data-move-direction":`up`,disabled:s<=0||k||!R,onClick:()=>Ae(t,`up`)})}),(0,a.jsx)(r.Tooltip,{title:`Move ${n} down`,children:(0,a.jsx)(r.Button,{type:`text`,icon:(0,a.jsx)(i.ArrowDownOutlined,{"aria-hidden":`true`}),"aria-label":`Move ${n} down`,"data-move-id":t,"data-move-direction":`down`,disabled:s>=T.length-1||k||!R,onClick:()=>Ae(t,`down`)})})]})]},t)})}),(0,a.jsx)(`div`,{className:`fb-sr-only`,"aria-live":`polite`,children:oe}),(0,a.jsxs)(`div`,{className:`fb-dist-next-line`,children:[(0,a.jsx)(i.CheckCircleOutlined,{"aria-hidden":`true`}),(0,a.jsxs)(`span`,{children:[_e?`Next after save`:`Next in saved order`,`: `,(0,a.jsx)(`strong`,{children:Ce})]})]}),(0,a.jsx)(`div`,{className:`fb-hint`,children:`Changes apply to future leads only. Turns carry on from the last person who got a lead, and leads people already have stay with them.`})]}),(0,a.jsxs)(`section`,{className:`fb-setup-section`,"aria-label":`Automatic turns`,children:[(0,a.jsx)(Ne,{number:`3`,title:`Automatic turns`}),(0,a.jsxs)(`label`,{className:`fb-setup-toggle`,children:[(0,a.jsxs)(`span`,{children:[(0,a.jsx)(`span`,{className:`fb-setup-toggle-title`,children:`Send leads to this form automatically`}),(0,a.jsx)(`span`,{className:`fb-hint`,children:`When paused, new leads wait until you turn this back on.`})]}),(0,a.jsx)(r.Switch,{"aria-label":`Send leads to this form automatically`,checked:D,onChange:ne,checkedChildren:`On`,unCheckedChildren:`Paused`,disabled:!R||k})]})]})]})}function Ie(e,t){let[r,i]=(0,n.useState)(0),[a,o]=(0,n.useState)({data:null,error:``,settled:null}),s=(0,n.useMemo)(()=>({load:e,refreshKey:t,tick:r}),[e,t,r]);(0,n.useEffect)(()=>{let e=!0;return s.load().then(t=>{e&&o({data:t,error:``,settled:s})}).catch(t=>{e&&o(e=>({...e,error:S(t),settled:s}))}),()=>{e=!1}},[s]);let c=(0,n.useCallback)(()=>i(e=>e+1),[]),l=a.settled!==s;return{data:a.data,loading:l,error:l?``:a.error,reload:c}}function Le({title:e,resource:t}){return t.error?(0,a.jsx)(r.Alert,{type:`error`,showIcon:!0,className:`fb-block`,title:e,description:`${t.error}${t.data?` Showing the last information we could load.`:``}`,action:(0,a.jsx)(r.Button,{size:`small`,onClick:t.reload,children:`Try again`})}):null}var Re=(e,t)=>t.formName||e.find(e=>e.formId===String(t.formId))?.formName||`Unknown form`;function ze({rows:e=[],canEdit:t=!0,refreshKey:i=0,onChanged:o}){let[s,c]=(0,n.useState)(``),[l,u]=(0,n.useState)(`unassigned`),[d,f]=(0,n.useState)(1),[p,m]=(0,n.useState)(1),h=(0,n.useCallback)(()=>ne({status:l,page:d,limit:20,formId:s}),[l,d,s]),ee=(0,n.useCallback)(()=>j({page:p,limit:20,formId:s}),[p,s]),g=Ie(h,i),_=Ie(ee,i),v=_.reload,y=e=>{c(e),f(1),m(1)},b=t=>{r.Modal.confirm({title:`Try this lead again?`,content:(0,a.jsxs)(`span`,{children:[`We will try to bring in lead `,(0,a.jsx)(`strong`,{children:t.facebookLeadId}),` from `,(0,a.jsx)(`strong`,{children:Re(e,t)}),` again.`]}),okText:`Retry`,cancelText:`Cancel`,autoFocusButton:`cancel`,onOk:async()=>{try{await se(t.facebookLeadId),r.message.success(`This lead will be tried again`)}catch(e){r.message.error(e?.status===409?`This lead is no longer failed. The list has been updated.`:S(e))}v(),o?.()}})},x=[{title:`Form`,dataIndex:`formName`,render:(t,n)=>Re(e,n)},{title:`Lead ID`,dataIndex:`facebookLeadId`},{title:`Why it is waiting`,dataIndex:`reason`,render:Se},{title:`Status`,dataIndex:`status`,render:e=>e===`unassigned`?`Waiting`:e===`resolved`?`Sorted`:`—`},{title:`First seen`,dataIndex:`firstSeenAt`,render:Y},...l===`unassigned`?[]:[{title:`Sorted at`,dataIndex:`resolvedAt`,render:Y}]],C=[{title:`Form`,dataIndex:`formName`,render:(t,n)=>Re(e,n)},{title:`Lead ID`,dataIndex:`facebookLeadId`},{title:`What went wrong`,dataIndex:`reason`,render:xe},{title:`Tries`,dataIndex:`attempts`,width:72,render:e=>e??`—`},{title:`When`,dataIndex:`lastFailedAt`,render:(e,t)=>Y(e||t.firstSeenAt)},{title:``,key:`retry`,width:96,render:(e,n)=>(0,a.jsx)(r.Tooltip,{title:t?``:`You don't have permission to retry leads`,children:(0,a.jsx)(`span`,{children:(0,a.jsx)(r.Button,{size:`small`,className:`fb-inline-btn`,disabled:!t,"aria-label":`Retry lead ${n.facebookLeadId}`,onClick:()=>b(n),children:`Retry`})})})}],w=g.data?.unassignedCount,T=_.data?.failedCount??_.data?.total;return(0,a.jsxs)(`div`,{className:`fb-tab-body`,children:[(0,a.jsx)(`div`,{className:`fb-toolbar`,children:(0,a.jsxs)(`div`,{className:`fb-field`,children:[(0,a.jsx)(`label`,{className:`fb-field-label`,htmlFor:`fb-attention-form`,children:`Form`}),(0,a.jsx)(G,{id:`fb-attention-form`,rows:e,value:s,onChange:y})]})}),(0,a.jsxs)(`div`,{className:`fb-subhead`,children:[(0,a.jsxs)(`h4`,{children:[`Waiting leads`,w===void 0?``:` (${w})`]}),(0,a.jsx)(r.Select,{"aria-label":`Show waiting leads`,value:l,className:`fb-subhead-select`,onChange:e=>{u(e),f(1)},options:[{value:`unassigned`,label:`Waiting`},{value:`resolved`,label:`Sorted`},{value:`all`,label:`All`}]})]}),(0,a.jsx)(Le,{title:`Could not load waiting leads`,resource:g}),(0,a.jsx)(r.Table,{size:`small`,rowKey:e=>String(e.id||`${e.facebookLeadId}-${e.formId}`),loading:g.loading,dataSource:g.data?.leads||[],columns:x,scroll:{x:760},locale:{emptyText:g.loading||g.error?` `:`No leads are waiting.`},pagination:{current:d,pageSize:20,total:Number(g.data?.total||0),showSizeChanger:!1,hideOnSinglePage:!0,onChange:f}}),(0,a.jsx)(`div`,{className:`fb-subhead`,children:(0,a.jsxs)(`h4`,{children:[`Failed leads`,T===void 0?``:` (${T})`]})}),(0,a.jsx)(Le,{title:`Could not load failed leads`,resource:_}),(0,a.jsx)(r.Table,{size:`small`,rowKey:e=>String(e.facebookLeadId),loading:_.loading,dataSource:_.data?.leads||[],columns:C,scroll:{x:760},locale:{emptyText:_.loading||_.error?` `:`No failed leads.`},pagination:{current:p,pageSize:20,total:Number(_.data?.total||0),showSizeChanger:!1,hideOnSinglePage:!0,onChange:m}})]})}function Be({rows:e=[],refreshKey:t=0}){let[i,o]=(0,n.useState)(``),[s,c]=(0,n.useState)(1),l=Ie((0,n.useCallback)(()=>D({page:s,limit:20,formId:i}),[s,i]),t),u=[{title:`Form`,dataIndex:`formName`,render:(t,n)=>Re(e,n)},{title:`Lead ID`,dataIndex:`facebookLeadId`},{title:`Skipped counsellor`,dataIndex:`skippedCounsellorName`,render:e=>e||`Unknown counsellor`},{title:`Reason`,dataIndex:`reason`,render:ye},{title:`Went to`,dataIndex:`assignedToName`,render:e=>e||`—`},{title:`When`,dataIndex:`skippedAt`,render:Y}];return(0,a.jsxs)(`div`,{className:`fb-tab-body`,children:[(0,a.jsx)(`div`,{className:`fb-toolbar`,children:(0,a.jsxs)(`div`,{className:`fb-field`,children:[(0,a.jsx)(`label`,{className:`fb-field-label`,htmlFor:`fb-skips-form`,children:`Form`}),(0,a.jsx)(G,{id:`fb-skips-form`,rows:e,value:i,onChange:e=>{o(e),c(1)}})]})}),(0,a.jsx)(Le,{title:`Could not load skipped counsellors`,resource:l}),(0,a.jsx)(r.Table,{size:`small`,rowKey:e=>String(e.id||`${e.facebookLeadId}-${e.skippedCounsellorLegacyId}`),loading:l.loading,dataSource:l.data?.skips||[],columns:u,scroll:{x:860},locale:{emptyText:l.loading||l.error?` `:`No one has been skipped yet.`},pagination:{current:s,pageSize:20,total:Number(l.data?.total||0),showSizeChanger:!1,hideOnSinglePage:!0,onChange:c}})]})}function Ve({rows:e=[],refreshKey:t=0}){let[i,o]=(0,n.useState)(``),[s,c]=(0,n.useState)(1),l=Ie((0,n.useCallback)(()=>ce({page:s,limit:20,formId:i}),[s,i]),t),u=[{title:`When`,dataIndex:`at`,width:190,render:Y},{title:`Form`,dataIndex:`formName`,render:(t,n)=>Re(e,n)},{title:`What changed`,key:`change`,render:(e,t)=>we(t)},{title:`By`,dataIndex:`performedByName`,render:e=>e||`—`}];return(0,a.jsxs)(`div`,{className:`fb-tab-body`,children:[(0,a.jsx)(`div`,{className:`fb-toolbar`,children:(0,a.jsxs)(`div`,{className:`fb-field`,children:[(0,a.jsx)(`label`,{className:`fb-field-label`,htmlFor:`fb-history-form`,children:`Form`}),(0,a.jsx)(G,{id:`fb-history-form`,rows:e,value:i,onChange:e=>{o(e),c(1)}})]})}),(0,a.jsx)(Le,{title:`Could not load history`,resource:l}),(0,a.jsx)(r.Table,{size:`small`,rowKey:e=>String(e.id||`${e.formId}-${e.at}`),loading:l.loading,dataSource:l.data?.history||[],columns:u,scroll:{x:720},locale:{emptyText:l.loading||l.error?` `:`No setup changes yet. They will appear here when someone changes a form.`},pagination:{current:s,pageSize:20,total:Number(l.data?.total||0),showSizeChanger:!1,hideOnSinglePage:!0,onChange:c}})]})}var{Text:Z,Paragraph:He}=r.Typography,Ue={eligible:{label:`Active – Eligible`,color:`green`},logged_out:{label:`Logged Out – Not Eligible`,color:`default`},waiting_for_login:{label:`Waiting for Login`,color:`blue`},on_leave:{label:`On Leave – Skipped`,color:`orange`},admin_disabled:{label:`Admin Disabled – Skipped`,color:`red`},at_cap:{label:`At open-lead limit – Skipped`,color:`gold`},inactive:{label:`Inactive user – Skipped`,color:`red`},past_day:{label:`Past day`,color:`default`}},We={awaiting_cutoff:`Waiting for cut-off`,no_active_counsellor:`Waiting for a counsellor who is online and under the open-lead limit`,distribution_not_configured:`Form has no counsellor list`,distribution_disabled:`Form distribution is switched off`},Ge=e=>e?(0,o.default)(e).format(`h:mm A`):`–`,Ke=e=>e?(0,o.default)(e).format(`D MMM, h:mm A`):`–`,qe=e=>{if(!e)return`–`;let t=Math.max(0,(0,o.default)().diff((0,o.default)(e),`minute`));return t<60?`${t} min`:`${Math.floor(t/60)} h ${t%60} min`};function Q(e,t){let[r,i]=(0,n.useState)({loading:!0}),[a,o]=(0,n.useState)(0);return(0,n.useEffect)(()=>{let t=!0;return e().then(e=>t&&i({loading:!1,data:e}),e=>t&&i({loading:!1,error:S(e,`This could not be loaded.`)})),()=>{t=!1}},[a,...t]),[r,()=>{i(e=>({...e,loading:!0})),o(e=>e+1)}]}var Je=({text:e,onRetry:t})=>(0,a.jsx)(r.Alert,{type:`error`,showIcon:!0,message:e,action:(0,a.jsx)(r.Button,{size:`small`,onClick:t,children:`Try again`})});function Ye({canEdit:e=!1}){let[t,s]=(0,n.useState)(null),[c,l]=Q(()=>N(t?t.format(`YYYY-MM-DD`):``),[t]),[u,d]=(0,n.useState)(null),[f,p]=(0,n.useState)(``),m=c.data??{},h=m.summary??{},ee=!t||m.day===m.today,g=async(e,t)=>{p(`t${e.legacyUserId}`);try{await F(e.legacyUserId,t,t?``:`Disabled by admin`),r.message.success(`${e.name} ${t?`will receive new leads again`:`will not receive new leads`}`),l()}catch(e){r.message.error(S(e))}finally{p(``)}},_=[{title:`Counsellor`,key:`name`,render:(e,t)=>(0,a.jsxs)(r.Space,{direction:`vertical`,size:0,children:[(0,a.jsx)(Z,{strong:!0,children:t.name}),(0,a.jsx)(Z,{type:`secondary`,style:{fontSize:12},children:(t.forms??[]).join(`, `)})]})},{title:`First login`,dataIndex:`firstLoginAt`,render:Ge,sorter:(e,t)=>String(e.firstLoginAt??``).localeCompare(String(t.firstLoginAt??``))},{title:`Last seen / logout`,key:`seen`,render:(e,t)=>t.loggedOutAt&&(!t.lastSeenAt||t.loggedOutAt>t.lastSeenAt)?`Logged out ${Ge(t.loggedOutAt)}`:Ge(t.lastSeenAt)},{title:`Status`,dataIndex:`status`,render:e=>(0,a.jsx)(r.Tag,{color:Ue[e]?.color,children:Ue[e]?.label??e}),filters:Object.entries(Ue).map(([e,t])=>({value:e,text:t.label})),onFilter:(e,t)=>t.status===e},{title:`Leads today`,dataIndex:`assigned`,align:`right`,sorter:(e,t)=>e.assigned-t.assigned},{title:`Untouched now`,dataIndex:`untouched`,align:`right`,sorter:(e,t)=>(e.untouched??0)-(t.untouched??0),render:(e,t)=>{let n=m.settings?.openLeadCap??0,r=n>0?`${e??0} / ${n}`:String(e??0);return t.atCap?(0,a.jsx)(Z,{type:`warning`,strong:!0,children:r}):r}},{title:`Target`,dataIndex:`target`,align:`right`},{title:`Progress`,key:`progress`,width:140,render:(e,t)=>(0,a.jsx)(r.Progress,{percent:t.target?Math.min(100,Math.round(t.assigned/t.target*100)):0,size:`small`,showInfo:!1})},{title:`Difference`,dataIndex:`difference`,align:`right`,render:(e,t)=>t.status===`eligible`&&e>0?(0,a.jsxs)(Z,{type:`warning`,children:[e,` behind`]}):t.status===`eligible`?`On target`:`–`},...e&&ee?[{title:``,key:`act`,width:210,render:(e,t)=>t.status===`inactive`?null:(0,a.jsxs)(r.Space,{children:[t.status===`admin_disabled`?(0,a.jsx)(r.Button,{size:`small`,loading:f===`t${t.legacyUserId}`,onClick:()=>g(t,!0),children:`Enable`}):(0,a.jsx)(r.Popconfirm,{title:`Stop new leads for ${t.name}?`,description:`Leads they already have stay with them.`,okText:`Disable`,okButtonProps:{danger:!0},onConfirm:()=>g(t,!1),children:(0,a.jsx)(r.Button,{size:`small`,danger:!0,loading:f===`t${t.legacyUserId}`,children:`Disable`})}),(0,a.jsx)(r.Button,{size:`small`,onClick:()=>d(t),children:`Leave`})]})}]:[]];return(0,a.jsxs)(`div`,{className:`ld-today`,children:[(0,a.jsxs)(r.Space,{wrap:!0,style:{marginBottom:12,width:`100%`,justifyContent:`space-between`},children:[(0,a.jsxs)(r.Space,{wrap:!0,children:[(0,a.jsx)(r.DatePicker,{value:t,onChange:s,allowClear:!0,placeholder:`Today`,disabledDate:e=>e&&e.isAfter((0,o.default)(),`day`)}),m.settings?(0,a.jsx)(r.Tag,{color:m.settings.mode===`equal_daily`?`magenta`:`default`,children:m.settings.mode===`equal_daily`?`Equal daily distribution`:`Round-robin (earlier behaviour)`}):null]}),(0,a.jsx)(r.Button,{icon:(0,a.jsx)(i.ReloadOutlined,{}),onClick:l,children:`Refresh`})]}),c.loading&&!c.data?(0,a.jsx)(r.Skeleton,{active:!0}):c.error?(0,a.jsx)(Je,{text:c.error,onRetry:l}):(0,a.jsxs)(a.Fragment,{children:[m.settings?.mode===`equal_daily`&&ee?(0,a.jsx)(r.Alert,{style:{marginBottom:12},showIcon:!0,type:m.holding?`info`:`success`,message:m.holding?`Leads received until ${Ge(m.cutoffAt)} wait, then they are shared equally among counsellors who are online at ${Ge(m.cutoffAt)}.`:`Cut-off ${Ge(m.cutoffAt)} has passed: each new lead goes to the online counsellor with the fewest leads today.`}):null,(0,a.jsxs)(r.Row,{gutter:[16,16],style:{marginBottom:16},children:[(0,a.jsx)(r.Col,{xs:12,md:6,xl:3,children:(0,a.jsx)(r.Statistic,{title:`Received`,value:h.received??0})}),(0,a.jsx)(r.Col,{xs:12,md:6,xl:3,children:(0,a.jsx)(r.Statistic,{title:`Assigned`,value:h.assigned??0})}),(0,a.jsx)(r.Col,{xs:12,md:6,xl:3,children:(0,a.jsx)(r.Statistic,{title:`Waiting`,value:h.pending??0})}),(0,a.jsx)(r.Col,{xs:12,md:6,xl:3,children:(0,a.jsx)(r.Statistic,{title:`Eligible now`,value:h.eligible??0})}),(0,a.jsx)(r.Col,{xs:12,md:6,xl:3,children:(0,a.jsx)(r.Statistic,{title:`At open-lead limit`,value:h.atCap??0})}),(0,a.jsx)(r.Col,{xs:12,md:6,xl:3,children:(0,a.jsx)(r.Statistic,{title:`Unavailable`,value:h.unavailable??0})}),(0,a.jsx)(r.Col,{xs:12,md:6,xl:3,children:(0,a.jsx)(r.Statistic,{title:`Target each`,value:h.target??0})}),(0,a.jsx)(r.Col,{xs:24,md:12,xl:6,children:(0,a.jsx)(r.Statistic,{title:`Balance`,valueRender:()=>(0,a.jsx)(r.Tag,{color:h.balance===`balanced`?`green`:`gold`,style:{fontSize:14,padding:`4px 10px`},children:h.balance===`balanced`?`Balanced`:`Catching up (gap ${h.spread})`})})})]}),h.balance!==`balanced`&&(h.spread??0)>1?(0,a.jsx)(He,{type:`secondary`,style:{fontSize:12},children:`Counsellors who joined later get new leads first until they catch up. Leads already assigned are never moved, so an exact match is not always possible.`}):null,(0,a.jsx)(r.Table,{rowKey:`legacyUserId`,size:`small`,columns:_,dataSource:m.counsellors??[],pagination:!1,scroll:{x:`max-content`},loading:c.loading,locale:{emptyText:(0,a.jsx)(r.Empty,{description:`No counsellor is on any form's list yet. Add counsellors in the Forms tab.`})}})]}),u?(0,a.jsx)(Xe,{counsellor:u,onClose:e=>{d(null),e&&l()}}):null]})}function Xe({counsellor:e,onClose:t}){let[i]=r.Form.useForm(),[s,c]=Q(()=>ue((0,o.default)().format(`YYYY-MM-DD`)),[]),[l,u]=(0,n.useState)(!1),[d,f]=(0,n.useState)(!1),p=(Array.isArray(s.data)?s.data:[]).filter(t=>Number(t.legacyUserId)===Number(e.legacyUserId)),m=async()=>{let t=await i.validateFields();u(!0);try{await de({legacyUserId:e.legacyUserId,from:t.range[0].format(`YYYY-MM-DD`),to:t.range[1].format(`YYYY-MM-DD`),reason:t.reason??``}),r.message.success(`Leave saved: no new leads on those days`),i.resetFields(),f(!0),c()}catch(e){r.message.error(S(e))}finally{u(!1)}},h=async e=>{try{await I(e),r.message.success(`Leave removed`),f(!0),c()}catch(e){r.message.error(S(e))}};return(0,a.jsxs)(r.Modal,{open:!0,title:`Leave · ${e.name}`,onCancel:()=>t(d),footer:(0,a.jsx)(r.Button,{onClick:()=>t(d),children:`Close`}),children:[(0,a.jsxs)(r.Form,{form:i,layout:`vertical`,children:[(0,a.jsx)(r.Form.Item,{name:`range`,label:`Days on leave`,rules:[{required:!0,message:`Choose the days`}],children:(0,a.jsx)(r.DatePicker.RangePicker,{style:{width:`100%`},disabledDate:e=>e&&e.isBefore((0,o.default)(),`day`)})}),(0,a.jsx)(r.Form.Item,{name:`reason`,label:`Reason (optional)`,children:(0,a.jsx)(r.Input,{maxLength:300})}),(0,a.jsx)(r.Button,{type:`primary`,loading:l,onClick:m,children:`Add leave`})]}),(0,a.jsx)(He,{type:`secondary`,style:{margin:`12px 0 4px`},children:`Upcoming leave`}),s.loading?(0,a.jsx)(r.Skeleton,{active:!0,paragraph:{rows:1}}):s.error?(0,a.jsx)(Je,{text:s.error,onRetry:c}):p.length?(0,a.jsx)(r.Space,{direction:`vertical`,style:{width:`100%`},children:p.map(e=>(0,a.jsxs)(r.Space,{style:{justifyContent:`space-between`,width:`100%`},children:[(0,a.jsxs)(Z,{children:[(0,o.default)(e.from).format(`D MMM`),` – `,(0,o.default)(e.to).format(`D MMM YYYY`),e.reason?` · ${e.reason}`:``]}),(0,a.jsx)(r.Popconfirm,{title:`Remove this leave?`,okText:`Remove`,onConfirm:()=>h(String(e._id)),children:(0,a.jsx)(r.Button,{size:`small`,type:`link`,danger:!0,children:`Remove`})})]},String(e._id)))}):(0,a.jsx)(Z,{type:`secondary`,children:`None.`})]})}function Ze({rows:e=[]}){let[t,o]=(0,n.useState)(`waiting`),[s,c]=(0,n.useState)(``),[l,u]=(0,n.useState)(1),[d,f]=Q(()=>L({status:t===`waiting`?``:t,formId:s,page:l,limit:25}),[t,s,l]),p=[{title:`Lead reference`,dataIndex:`facebookLeadId`},{title:`Form`,dataIndex:`facebookFormId`,render:t=>e.find(e=>e.formId===t)?.formName??`Form ${t}`},{title:`Received`,dataIndex:`createdAt`,render:Ke},{title:`Waiting`,dataIndex:`createdAt`,key:`waited`,render:(e,t)=>t.status===`dead`?`–`:qe(e)},{title:`Status`,dataIndex:`status`,render:(e,t)=>e===`dead`?(0,a.jsx)(r.Tag,{color:`red`,children:`Assignment Failed`}):e===`processing`?(0,a.jsx)(r.Tag,{color:`blue`,children:`Assigning…`}):(0,a.jsx)(r.Tag,{color:t.lastResult===`awaiting_cutoff`?`purple`:`gold`,children:We[t.lastResult]??`Pending Assignment`})},{title:`Next try`,dataIndex:`nextAttemptAt`,render:(e,t)=>t.status===`dead`?`–`:Ke(e)},{title:`Detail`,key:`detail`,render:(e,t)=>t.lastErrorCode||(We[t.lastResult]?``:t.lastResult)||`–`}];return(0,a.jsxs)(`div`,{className:`ld-queue`,children:[(0,a.jsxs)(r.Space,{wrap:!0,style:{marginBottom:12},children:[(0,a.jsx)(r.Segmented,{value:t,onChange:e=>{o(e),u(1)},options:[{value:`waiting`,label:`Waiting`},{value:`failed`,label:`Failed`},{value:`all`,label:`All`}]}),(0,a.jsx)(r.Select,{style:{minWidth:220},value:s,onChange:e=>{c(e),u(1)},options:[{value:``,label:`All forms`},...e.map(e=>({value:e.formId,label:e.formName??e.formId}))]}),(0,a.jsx)(r.Button,{icon:(0,a.jsx)(i.ReloadOutlined,{}),onClick:f,children:`Refresh`})]}),(0,a.jsx)(He,{type:`secondary`,style:{fontSize:12},children:`Leads stay here safely until a counsellor can take them; nothing is lost when nobody is logged in. A lead becomes an LMS lead when it is assigned.`}),d.error?(0,a.jsx)(Je,{text:d.error,onRetry:f}):(0,a.jsx)(r.Table,{rowKey:e=>String(e._id??e.facebookLeadId),size:`small`,loading:d.loading,columns:p,dataSource:d.data?.rows??[],scroll:{x:`max-content`},pagination:{current:l,pageSize:25,total:d.data?.total??0,onChange:u,showSizeChanger:!1},locale:{emptyText:(0,a.jsx)(r.Empty,{description:t===`failed`?`No failed leads.`:`No leads are waiting.`})}})]})}function Qe(){let[e,t]=(0,n.useState)((0,o.default)()),[s,c]=(0,n.useState)(1),[l,u]=Q(()=>R({date:e?e.format(`YYYY-MM-DD`):``,page:s,limit:25}),[e,s]),d=[{title:`Lead reference`,dataIndex:`facebookLeadId`},{title:`Form`,dataIndex:`formName`},{title:`Received`,dataIndex:`receivedAt`,render:Ke},{title:`Assigned`,dataIndex:`assignedAt`,render:Ke},{title:`Counsellor`,dataIndex:`counsellorName`},{title:`Their leads that day`,dataIndex:`countAtAssignment`,align:`right`},{title:`Skipped`,dataIndex:`skipped`,render:e=>Array.isArray(e)&&e.length?(0,a.jsx)(r.Tooltip,{title:e.map(e=>`${e.name||`#${e.legacyUserId}`}: ${Ue[e.reason]?.label??e.reason}`).join(`
|
|
2
|
+
`),children:(0,a.jsxs)(r.Tag,{children:[e.length,` skipped`]})}):`–`}];return(0,a.jsxs)(`div`,{className:`ld-history`,children:[(0,a.jsxs)(r.Space,{wrap:!0,style:{marginBottom:12},children:[(0,a.jsx)(r.DatePicker,{value:e,onChange:e=>{t(e),c(1)},allowClear:!0,placeholder:`All days`}),(0,a.jsx)(r.Button,{icon:(0,a.jsx)(i.ReloadOutlined,{}),onClick:u,children:`Refresh`})]}),(0,a.jsx)(He,{type:`secondary`,style:{fontSize:12},children:`Every automatic assignment in equal daily mode. Manual reassignments are in the Reassign leads tab and History.`}),l.error?(0,a.jsx)(Je,{text:l.error,onRetry:u}):(0,a.jsx)(r.Table,{rowKey:e=>String(e._id),size:`small`,loading:l.loading,columns:d,dataSource:l.data?.rows??[],scroll:{x:`max-content`},pagination:{current:s,pageSize:25,total:l.data?.total??0,onChange:c,showSizeChanger:!1},locale:{emptyText:(0,a.jsx)(r.Empty,{description:`No assignments for this day yet.`})}})]})}var $e=[`Asia/Kolkata`,`Asia/Dubai`,`Asia/Singapore`,`Europe/London`,`America/New_York`,`UTC`];function et({canEdit:e=!1}){let[t]=r.Form.useForm(),[i,s]=Q(()=>le(),[]),[c,l]=(0,n.useState)(!1),u=i.data?.settings;(0,n.useEffect)(()=>{u&&t.setFieldsValue({openLeadCap:15,capWindowDays:0,...u,startTime:(0,o.default)(u.startTime,`HH:mm`),cutoffTime:(0,o.default)(u.cutoffTime,`HH:mm`),resetTime:(0,o.default)(u.resetTime,`HH:mm`)})},[u,t]);let d=r.Form.useWatch(`mode`,t);return i.loading&&!i.data?(0,a.jsx)(r.Skeleton,{active:!0}):i.error?(0,a.jsx)(Je,{text:i.error,onRetry:s}):(0,a.jsxs)(r.Form,{form:t,layout:`vertical`,disabled:!e,style:{maxWidth:720},children:[(0,a.jsx)(r.Form.Item,{name:`mode`,label:`Only give leads to counsellors who are logged in`,valuePropName:`checked`,getValueProps:e=>({checked:e===`equal_daily`}),normalize:e=>e?`equal_daily`:`round_robin`,children:(0,a.jsx)(r.Switch,{checkedChildren:`On`,unCheckedChildren:`Off`})}),(0,a.jsx)(He,{type:`secondary`,children:d===`equal_daily`?`Only counsellors who are logged in right now, enabled, not on leave and under the open-lead limit get leads. Each lead goes to the one with the fewest leads today; equal counts take turns (round robin). A lead nobody can take waits and is offered again every 2 minutes.`:`Off: round robin as before. Leads take turns through each form's counsellor list, skipping only inactive users. Login, leave and the open-lead limit are not checked, and nothing waits for a login.`}),(0,a.jsxs)(`div`,{className:`ld-settings-group`,hidden:d!==`equal_daily`,children:[(0,a.jsx)(Z,{strong:!0,children:`Open-lead limit`}),(0,a.jsx)(He,{type:`secondary`,style:{margin:`4px 0 8px`,fontSize:13},children:`A counsellor who has this many untouched leads gets no new lead until they work some (a call, a follow-up, a status change or a save). Their leads are never moved. 0 = no limit.`}),(0,a.jsxs)(r.Row,{gutter:12,children:[(0,a.jsx)(r.Col,{xs:24,md:12,children:(0,a.jsx)(r.Form.Item,{name:`openLeadCap`,label:`Untouched leads per counsellor`,rules:[{required:!0}],children:(0,a.jsx)(r.InputNumber,{min:0,max:500,addonAfter:`leads`,style:{width:`100%`}})})}),(0,a.jsx)(r.Col,{xs:24,md:12,children:(0,a.jsx)(r.Form.Item,{name:`capWindowDays`,label:`Count untouched leads from`,rules:[{required:!0}],children:(0,a.jsx)(r.Select,{options:[{value:0,label:`Today`},{value:1,label:`Today and yesterday`},{value:2,label:`The last 3 days`},{value:6,label:`The last 7 days`}]})})})]})]}),(0,a.jsx)(`div`,{hidden:d!==`equal_daily`,children:(0,a.jsxs)(r.Row,{gutter:12,children:[(0,a.jsx)(r.Col,{xs:12,md:6,children:(0,a.jsx)(r.Form.Item,{name:`startTime`,label:`Day starts`,rules:[{required:!0}],children:(0,a.jsx)(r.TimePicker,{format:`HH:mm`,minuteStep:5,style:{width:`100%`}})})}),(0,a.jsx)(r.Col,{xs:12,md:6,children:(0,a.jsx)(r.Form.Item,{name:`cutoffTime`,label:`Initial cut-off`,rules:[{required:!0}],extra:`Morning leads wait until this time.`,children:(0,a.jsx)(r.TimePicker,{format:`HH:mm`,minuteStep:5,style:{width:`100%`}})})}),(0,a.jsx)(r.Col,{xs:12,md:6,children:(0,a.jsx)(r.Form.Item,{name:`resetTime`,label:`Daily reset`,rules:[{required:!0}],children:(0,a.jsx)(r.TimePicker,{format:`HH:mm`,minuteStep:5,style:{width:`100%`}})})}),(0,a.jsx)(r.Col,{xs:12,md:6,children:(0,a.jsx)(r.Form.Item,{name:`timezone`,label:`Time zone`,rules:[{required:!0}],children:(0,a.jsx)(r.Select,{options:$e.map(e=>({value:e,label:e}))})})}),(0,a.jsx)(r.Col,{xs:24,md:12,children:(0,a.jsx)(r.Form.Item,{name:`holdUntilCutoff`,label:`Hold morning leads until the cut-off`,valuePropName:`checked`,extra:`Off (recommended): leads go to whoever is online as they arrive; the open-lead limit spreads the morning backlog.`,children:(0,a.jsx)(r.Switch,{})})}),(0,a.jsx)(r.Col,{xs:24,md:12,children:(0,a.jsx)(r.Form.Item,{name:`onlineWindowMinutes`,label:`Offline after no activity for`,rules:[{required:!0}],children:(0,a.jsx)(r.InputNumber,{min:2,max:120,addonAfter:`minutes`,style:{width:`100%`}})})})]})}),e?(0,a.jsx)(r.Button,{type:`primary`,loading:c,onClick:async()=>{let e=await t.validateFields(),n={...e,startTime:e.startTime.format(`HH:mm`),cutoffTime:e.cutoffTime.format(`HH:mm`),resetTime:e.resetTime.format(`HH:mm`)};r.Modal.confirm({title:`Save distribution settings?`,content:n.mode===`equal_daily`?`New leads will go to the online counsellor with the fewest leads today. Leads already assigned do not move.`:`New leads will go back to plain round-robin.`,okText:`Save`,onOk:async()=>{l(!0);try{await P(n),r.message.success(`Distribution settings saved`),s()}catch(e){r.message.error(S(e))}finally{l(!1)}}})},children:`Save settings`}):(0,a.jsx)(Z,{type:`secondary`,children:`Only users who can edit lead mapping can change these settings.`})]})}var tt=e.t({default:()=>pt}),{Text:nt,Title:rt}=r.Typography,it=10,at=`—`,ot=`You don't have permission to do this.`,st=`This could not be loaded. Press Try again first.`;function $(e,t){return Array.isArray(e)?e:Array.isArray(e?.[t])?e[t]:[]}var ct={forms:{load:p,read:e=>$(e,`forms`),label:`Facebook forms`},courses:{load:m,read:e=>$(e,`courses`),label:`courses`},mappings:{load:h,read:e=>$(e,`mappings`),label:`chosen courses`},distributions:{load:T,read:e=>$(e,`distributions`),label:`counsellor lists`},counsellors:{load:E,read:e=>$(e,`counsellors`),label:`active counsellors`}},lt=Object.keys(ct),ut=Object.fromEntries(lt.map(e=>[e,[]])),dt=Object.fromEntries(lt.map(e=>[e,{loaded:!1,ok:!1,error:``}]));function ft({distribution:e}){let t=e?.counsellors||[];if(!t.length)return(0,a.jsx)(nt,{type:`secondary`,children:`Not set up`});let n=t.map(e=>e.name||`Unnamed counsellor`),i=Ee(e);return(0,a.jsxs)(`div`,{className:`fb-who`,children:[(0,a.jsx)(r.Tooltip,{title:n.join(`, `),trigger:[`hover`,`focus`],children:(0,a.jsxs)(`span`,{className:`fb-avatars`,role:`group`,tabIndex:0,"aria-label":`Gets leads: ${n.join(`, `)}`,children:[n.slice(0,3).map((e,t)=>(0,a.jsx)(`span`,{className:`fb-avatar`,"aria-hidden":`true`,children:(Array.from(e)[0]||`?`).toUpperCase()},`${e}-${t}`)),n.length>3&&(0,a.jsxs)(`span`,{className:`fb-avatar fb-avatar--more`,"aria-hidden":`true`,children:[`+`,n.length-3]})]})}),(0,a.jsxs)(`span`,{className:`fb-next`,children:[`Next: `,i||`No one active`]})]})}function pt(){let[e,t]=(0,n.useState)(ut),[o,c]=(0,n.useState)(dt),[l,d]=(0,n.useState)(!0),[f,p]=(0,n.useState)(null),[ee,_]=(0,n.useState)(`forms`),[v,y]=(0,n.useState)(``),[b,x]=(0,n.useState)(`all`),[C,w]=(0,n.useState)(null),[te,D]=(0,n.useState)(1),[ne,O]=(0,n.useState)(``),[k,ie]=(0,n.useState)(null),[ae,A]=(0,n.useState)(!1),[j,se]=(0,n.useState)(0),ce=(0,n.useRef)(0),M=(0,n.useRef)(0),N=(0,n.useRef)({element:null,formId:``}),le=(0,n.useRef)(null),P=(0,n.useCallback)(async()=>{let e=++ce.current;d(!0);let n=await Promise.allSettled(lt.map(e=>ct[e].load()));e===ce.current&&(t(e=>{let t={...e};return n.forEach((e,n)=>{e.status===`fulfilled`&&(t[lt[n]]=ct[lt[n]].read(e.value))}),t}),c(e=>{let t={...e};return n.forEach((n,r)=>{let i=lt[r];t[i]=n.status===`fulfilled`?{loaded:!0,ok:!0,error:``}:{loaded:e[i].loaded,ok:!1,error:S(n.reason,`Please try again.`,{hideServerText:!0})}}),t}),d(!1))},[]),F=(0,n.useCallback)(()=>(se(e=>e+1),P()),[P]);(0,n.useEffect)(()=>{P()},[P]),(0,n.useEffect)(()=>{let e=!0;return oe().then(t=>{e&&p(t)}).catch(()=>{}),()=>{e=!1}},[]);let{alerts:ue,alertsOk:de,failedCount:I}=pe({refreshKey:j}),L={add:f?.permissions?.canAdd!==!1,edit:f?.permissions?.canEdit!==!1,remove:f?.permissions?.canDelete!==!1},{forms:R,courses:z,mappings:fe,distributions:B,counsellors:V}=e,H=o.forms.loaded,U=o.mappings.loaded,W=o.distributions.loaded,G=!H||!U||!W,me=l&&!lt.some(e=>o[e].loaded),q=(0,n.useMemo)(()=>new Map(B.map(e=>[String(e.formId),e])),[B]),J=(0,n.useMemo)(()=>new Map(fe.map(e=>[String(e.formId),e])),[fe]),ge=(0,n.useMemo)(()=>new Map(z.map(e=>[String(e.courseId),e.courseName])),[z]),Y=(0,n.useMemo)(()=>{let e=R.map(e=>({formId:String(e.id),formName:e.name||`Unnamed form`,inFormsList:!0})),t=new Set(e.map(e=>e.formId));return[...fe,...B].forEach(n=>{let r=String(n.formId);t.has(r)||(t.add(r),e.push({formId:r,formName:n.formName||`Unnamed form`,inFormsList:!1}))}),e.map(e=>{let t=J.get(e.formId),n=q.get(e.formId);return{...e,key:e.formId,mapping:t,distribution:n,courseName:t&&(ge.get(String(t.courseId))||t.courseName)||``,status:Te({mapping:t,distribution:n,inFormsList:e.inFormsList},{forms:H,mappings:U,distributions:W})}})},[R,fe,B,J,q,ge,H,U,W]),_e=(0,n.useMemo)(()=>{let e=v.trim().toLowerCase();return Y.filter(t=>C&&!C.includes(t.formId)||b!==`all`&&t.status!==b?!1:`${t.formName} ${t.formId} ${t.courseName}`.toLowerCase().includes(e))},[Y,C,b,v]),ve=!!v.trim()||b!==`all`||!!C,ye=Math.min(te,Math.max(1,Math.ceil(_e.length/it))),be=()=>{y(``),x(`all`),w(null),D(1)},xe=e=>{y(``),x(`all`),w(e),D(1),_(`forms`)},Se=e=>{y(``),w(null),x(e),D(1),_(`forms`)},Ce=o.forms.ok&&o.mappings.ok&&o.distributions.ok,we=e=>Y.filter(t=>t.status===e).length,Ee=de?Number(ue?.unassignedCount||0):null,De=Ee===null||I===null?null:Ee+I,Oe=[{key:`ready`,label:`forms ready`,value:Ce?we(`ready`):at,onClick:Ce?()=>Se(`ready`):void 0},{key:`setup`,label:`need setup`,value:Ce?we(`needs_setup`):at,onClick:Ce?()=>Se(`needs_setup`):void 0},{key:`waiting`,label:`leads waiting`,value:Ee??at,onClick:Ee===null?void 0:()=>_(`attention`)},{key:`failed`,label:`failed leads`,value:I??at,onClick:I===null?void 0:()=>_(`attention`)},{key:`counsellors`,label:`active counsellors`,value:o.counsellors.ok?V.length:at}],ke=e=>{t(t=>({...t,...e})),c(t=>{let n={...t};return Object.keys(e).forEach(e=>{n[e]={loaded:!0,ok:!0,error:``}}),n})},Ae=async()=>{let[e,t,n,r]=await Promise.all([m(),h(),T(),E()]),i={courses:$(e,`courses`),mappings:$(t,`mappings`),distributions:$(n,`distributions`),counsellors:$(r,`counsellors`)};return ke(i),i},je=async(e,t,n=null)=>{if(!G){N.current={element:n,formId:e.formId},O(e.formId);try{await Ae(),M.current+=1,ie({token:M.current,row:e,section:t}),A(!0)}catch(e){r.message.error(S(e,`Could not open this form. Please try again.`))}finally{O(``)}}},Ne=()=>{let{element:e,formId:t}=N.current;if(e?.isConnected){e.focus();return}[...le.current?.querySelectorAll(`[data-form-menu]`)||[]].find(e=>e.dataset.formMenu===t)?.focus()},Pe=()=>{se(e=>e+1),P()},Ie=e=>{r.Modal.confirm({title:`Remove course mapping?`,content:(0,a.jsxs)(`span`,{children:[`Remove the course mapping for `,(0,a.jsx)(`strong`,{children:e.formName}),`? Existing lead courses remain unchanged. `,e.distribution?`This form has saved counsellors. They stay in place unless you remove them separately.`:`Future leads from this form will arrive without a course.`]}),okText:`Remove mapping`,okType:`danger`,cancelText:`Cancel`,autoFocusButton:`cancel`,onOk:async()=>{O(e.formId);try{await g(e.formId),r.message.success(`Course mapping removed`),Pe()}catch(e){throw r.message.error(S(e,`Could not remove the mapping. Please try again.`)),e}finally{O(``)}}})},Le=e=>{r.Modal.confirm({title:`Remove counsellor distribution?`,content:(0,a.jsxs)(`span`,{children:[`Remove the saved counsellors and whose turn is next for `,(0,a.jsx)(`strong`,{children:e.formName}),`? Leads already given out will not change. New leads from this form will wait until counsellors are set up again. Its course mapping stays as it is.`]}),okText:`Remove distribution`,okType:`danger`,cancelText:`Cancel`,autoFocusButton:`cancel`,onOk:async()=>{O(e.formId);try{if((await re(e.formId))?.deleted===!1)throw Error(`This has already been removed. Refresh and try again.`);r.message.success(`Counsellor distribution removed`),Pe()}catch(e){throw r.message.error(S(e,`Could not remove the distribution. Please try again.`)),e}finally{O(``)}}})},Re=e=>{let t=e=>G?st:e?``:ot,n=t(e.mapping?L.edit:L.add),r=t(e.distribution?L.edit:L.add);return{items:[{key:`mapping`,icon:e.mapping?(0,a.jsx)(i.EditOutlined,{}):(0,a.jsx)(i.PlusOutlined,{}),label:e.mapping?`Edit mapping`:`Set up mapping`,disabled:!!n,title:n},...e.mapping&&L.remove?[{key:`removeMapping`,icon:(0,a.jsx)(i.DeleteOutlined,{}),label:`Remove mapping`,danger:!0,disabled:G}]:[],{type:`divider`},{key:`distribution`,icon:(0,a.jsx)(i.TeamOutlined,{}),label:e.distribution?`Edit distribution`:`Set up distribution`,disabled:!!r,title:r},...e.distribution&&L.remove?[{key:`removeDistribution`,icon:(0,a.jsx)(i.DeleteOutlined,{}),label:`Remove distribution`,danger:!0,disabled:G}]:[]],onClick:({key:t})=>{t===`mapping`?je(e,`course`):t===`distribution`?je(e,`counsellors`):t===`removeMapping`?Ie(e):t===`removeDistribution`&&Le(e)}}},Z=e=>e.stopPropagation(),He=[{title:`Form`,dataIndex:`formName`,key:`form`,render:(e,t)=>(0,a.jsxs)(`div`,{children:[(0,a.jsx)(`button`,{type:`button`,className:`fb-form-name`,disabled:G,onClick:e=>{Z(e),je(t,`course`,e.currentTarget)},children:e}),(0,a.jsx)(`div`,{children:(0,a.jsxs)(nt,{type:`secondary`,className:`fb-small`,children:[`Form ID: `,t.formId]})})]})},{title:`Course`,key:`course`,render:(e,t)=>U?t.mapping?(0,a.jsxs)(`span`,{className:`fb-course`,children:[t.courseName||`Course no longer available`,!t.mapping.isActive&&(0,a.jsx)(nt,{type:`secondary`,children:` (off)`})]}):L.add?(0,a.jsx)(r.Button,{size:`small`,className:`fb-inline-btn`,disabled:G,loading:ne===t.formId,onClick:e=>{Z(e),je(t,`course`,e.currentTarget)},"aria-label":`Map course for ${t.formName}`,children:`Map course`}):(0,a.jsx)(nt,{type:`secondary`,children:`No course yet`}):(0,a.jsx)(nt,{type:`secondary`,children:at})},{title:`Who gets leads`,key:`who`,render:(e,t)=>W?(0,a.jsx)(ft,{distribution:t.distribution}):(0,a.jsx)(nt,{type:`secondary`,children:at})},{title:`Status`,dataIndex:`status`,key:`status`,width:170,render:e=>(0,a.jsx)(Me,{status:e})},{title:(0,a.jsx)(`span`,{className:`fb-sr-only`,children:`Actions`}),key:`actions`,width:56,align:`center`,render:(e,t)=>(0,a.jsx)(`span`,{onClick:Z,children:(0,a.jsx)(r.Dropdown,{menu:Re(t),trigger:[`click`],placement:`bottomRight`,children:(0,a.jsx)(r.Button,{size:`small`,className:`fb-form-actions-trigger`,"aria-label":`Actions for ${t.formName}`,"data-form-menu":t.formId,loading:ne===t.formId,icon:(0,a.jsx)(i.MoreOutlined,{})})})})}],Ue=()=>l?` `:G?(0,a.jsx)(r.Empty,{description:`Forms can't be shown right now.`}):ve?(0,a.jsx)(r.Empty,{description:`No forms match these filters.`,children:(0,a.jsx)(r.Button,{onClick:be,children:`Clear filters`})}):(0,a.jsx)(r.Empty,{description:`No Facebook forms yet. Create a lead form on Facebook, then refresh.`,children:(0,a.jsx)(r.Button,{onClick:F,children:`Refresh`})}),We=lt.filter(e=>!o[e].ok&&o[e].error),Ge=We.every(e=>o[e].loaded),Ke=()=>`Could not load ${We.map(e=>ct[e].label).join(`, `)}. ${[...new Set(We.map(e=>o[e].error))].join(` `)}`,qe=(0,a.jsxs)(`div`,{className:`fb-tab-body`,children:[(0,a.jsxs)(`div`,{className:`fb-toolbar`,children:[(0,a.jsxs)(`div`,{className:`fb-field fb-field--grow`,children:[(0,a.jsx)(`label`,{className:`fb-field-label`,htmlFor:`fb-forms-search`,children:`Search forms`}),(0,a.jsx)(r.Input,{id:`fb-forms-search`,allowClear:!0,prefix:(0,a.jsx)(i.SearchOutlined,{"aria-hidden":`true`}),placeholder:`Form or course name`,value:v,onChange:e=>{y(e.target.value),D(1)}})]}),(0,a.jsxs)(`div`,{className:`fb-field`,children:[(0,a.jsx)(`label`,{className:`fb-field-label`,htmlFor:`fb-forms-show`,children:`Show`}),(0,a.jsx)(r.Select,{id:`fb-forms-show`,className:`fb-show-select`,value:b,disabled:!U||!W,onChange:e=>{x(e),D(1)},options:[{value:`all`,label:`All forms`},...Object.entries(X).map(([e,t])=>({value:e,label:t.label}))]})]})]}),C&&(0,a.jsxs)(`div`,{className:`fb-filter-note`,role:`status`,children:[(0,a.jsx)(`span`,{children:C.length===1?`Showing 1 form that needs attention.`:`Showing ${C.length} forms that need attention.`}),(0,a.jsx)(r.Button,{size:`small`,type:`link`,onClick:()=>{w(null),D(1)},children:`Show all forms`})]}),me?(0,a.jsx)(r.Skeleton,{active:!0,title:!1,paragraph:{rows:6}}):(0,a.jsx)(r.Table,{rowKey:`formId`,className:`fb-forms-table${G?``:` fb-forms-table--open`}`,columns:He,dataSource:_e,loading:l,size:`middle`,scroll:{x:860},onRow:e=>({onClick:()=>je(e,`course`)}),pagination:{current:ye,pageSize:it,showSizeChanger:!1,onChange:D,showTotal:e=>`${e} Facebook form${e===1?``:`s`}`},locale:{emptyText:Ue()}}),(0,a.jsx)(nt,{type:`secondary`,className:`fb-small`,children:`Changing a form affects future leads only. Leads you already have keep their course and counsellor.`})]}),Q={rows:Y,refreshKey:j},Je=[{key:`forms`,label:`Forms`,children:qe},{key:`attention`,label:`Needs attention${De===null?``:` (${De})`}`,children:(0,a.jsx)(ze,{...Q,canEdit:L.edit,onChanged:()=>se(e=>e+1)})},{key:`skips`,label:`Skipped counsellors`,children:(0,a.jsx)(Be,{...Q})},{key:`reassign`,label:`Reassign leads`,children:(0,a.jsx)(he,{...Q,eligibleCounsellors:V,limits:f?.limits,reasonTypes:f?.reasonTypes,canEdit:L.edit,onChanged:()=>se(e=>e+1)})},{key:`history`,label:`History`,children:(0,a.jsx)(Ve,{...Q})},{key:`today`,label:`Today`,children:(0,a.jsx)(Ye,{canEdit:L.edit})},{key:`queue`,label:`Pending queue`,children:(0,a.jsx)(Ze,{rows:Y})},{key:`assignments`,label:`Assignment history`,children:(0,a.jsx)(Qe,{})},{key:`distributionSettings`,label:`Distribution settings`,children:(0,a.jsx)(et,{canEdit:L.edit})}],Xe=k?Y.find(e=>e.formId===k.row.formId)||k.row:null;return(0,a.jsxs)(`div`,{className:`facebook-course-mapping`,ref:le,children:[(0,a.jsxs)(`div`,{className:`admin-section-head fb-head`,children:[(0,a.jsxs)(`div`,{children:[(0,a.jsx)(rt,{level:4,children:`Facebook Leads`}),(0,a.jsx)(nt,{type:`secondary`,children:`Choose the course and counsellors for each Facebook form.`})]}),(0,a.jsx)(r.Button,{icon:(0,a.jsx)(i.ReloadOutlined,{"aria-hidden":`true`}),onClick:F,loading:l,children:`Refresh`})]}),(0,a.jsx)(u,{items:Oe,className:`fb-health`,ariaLabel:`Facebook leads health`}),We.length>0&&!l&&(0,a.jsx)(s,{className:`fb-load-problem`,type:Ge?`warning`:`error`,title:Ge?`Showing the last information we could load`:`Some information didn't load`,description:Ke(),action:(0,a.jsx)(r.Button,{size:`small`,onClick:F,children:`Try again`})}),f&&(!L.add||!L.edit||!L.remove)&&(0,a.jsx)(s,{className:`fb-load-problem`,type:`info`,title:`Your role can't make some changes here, so those actions are turned off.`}),(0,a.jsx)(K,{alerts:ue,failedCount:I??0,onViewLeads:()=>_(`attention`),onShowForms:xe}),(0,a.jsx)(r.Tabs,{size:`small`,activeKey:ee,onChange:_,items:Je,className:`fb-tabs`}),k&&(0,a.jsx)(Fe,{open:ae,row:Xe,section:k.section,mapping:J.get(k.row.formId),current:q.get(k.row.formId),courses:z,counsellors:V,limits:f?.limits,permissions:{canAdd:L.add,canEdit:L.edit},onClose:()=>A(!1),onSaved:Pe,onAfterClose:Ne,onReload:async()=>{let e=await Ae(),t=k.row.formId;return{mapping:e.mappings.find(e=>String(e.formId)===t),current:e.distributions.find(e=>String(e.formId)===t)}}},k.token)]})}Object.defineProperty(exports,"a",{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,"i",{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return tt}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return le}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return pt}});
|
|
3
|
+
//# sourceMappingURL=FacebookCourseMappingsSection-AYu5JiEt.cjs.map
|