PageSourceSearch

https://workait.com/assets/SystemSettings-DNDbeQA4.js

js workait.com collected 2026-10-08 08:27:17 UTC 76,940 bytes, 11 lines download raw bytes

1import{dr as ut,g0 as Ne,es as i,e9 as e,P as le,S as oe,T as ce,R as ge,Q as de,bc as M,E as ve,b6 as X,c5 as Ie,c8 as Ue,c9 as We,c6 as Me,c7 as $e,b1 as V,K as E,eN as H,dj as J,cD as Be,$ as $t,al as Tt,am as Dt,ap as Et,y as ht,B as pt,z as xt,aq as Ft,an as Pt,t as Ot,cO as At,aY as It,X as ft,ak as et,d7 as Ut,c4 as Wt,bT as gt,bA as Mt,dw as Lt,ey as Rt,fk as vt,e0 as jt,J as qt,bE as Bt,cs as st,em as at,bF as Ht,fO as zt,f_ as Vt,cc as Jt,a9 as Yt,dJ as nt,df as Gt}from"./index-D2yE0WFs.js";import{A as Kt}from"./AdminLayout-CuVddbA7.js";import{S as ye}from"./save-vnLq58RH.js";import{H as Zt}from"./handshake-H0PcAUeO.js";import{K as Xt}from"./key-round-CMGSbYEc.js";import{D as Qt}from"./dollar-sign-CQ1rj1Tf.js";import{T as es}from"./trending-down-DUfxcq3-.js";import"./chart-column-Bi7_7fla.js";import"./trending-up-Bks0iuZo.js";import"./banknote-v5qEX3yY.js";import"./activity-D50GHC8x.js";import"./users-314H31wg.js";/**
2 * @license lucide-react v0.462.0 - ISC
3 *
4 * This source code is licensed under the ISC license.
5 * See the LICENSE file in the root directory of this source tree.
6 */const ts=ut("Cpu",[["rect",{width:"16",height:"16",x:"4",y:"4",rx:"2",key:"14l7u7"}],["rect",{width:"6",height:"6",x:"9",y:"9",rx:"1",key:"5aljv4"}],["path",{d:"M15 2v2",key:"13l42r"}],["path",{d:"M15 20v2",key:"15mkzm"}],["path",{d:"M2 15h2",key:"1gxd5l"}],["path",{d:"M2 9h2",key:"1bbxkp"}],["path",{d:"M20 15h2",key:"19e6y8"}],["path",{d:"M20 9h2",key:"19tzq7"}
6],["path",{d:"M9 2v2",key:"165o2o"}],["path",{d:"M9 20v2",key:"i2bqo8"}]]);/**
7 * @license lucide-react v0.462.0 - ISC
8 *
9 * This source code is licensed under the ISC license.
10 * See the LICENSE file in the root directory of this source tree.
11 */const rt=ut("FlaskConical",[["path",{d:"M10 2v7.527a2 2 0 0 1-.211.896L4.72 20.55a1 1 0 0 0 .9 1.45h12.76a1 1 0 0 0 .9-1.45l-5.069-10.127A2 2 0 0 1 14 9.527V2",key:"pzvekw"}],["path",{d:"M8.5 2h7",key:"csnxdl"}],["path",{d:"M7 16h10",key:"wp8him"}]]),Ve=[{value:"dm_turn",label:"DM turn",unit:"event"},{value:"channel_turn",label:"Channel turn",unit:"event"},{value:"heartbeat",label:"Heartbeat",unit:"event"},{value:"voice_minute",label:"Voice minute",unit:"minute"},{value:"doc_generation",label:"Document generation",unit:"event"},{value:"base_worker_month",label:"Base infra / worker-month",unit:"worker_month"}];function ss(){const{toast:s}=Ne(),[t,a]=i.useState([]),[n,d]=i.useState(!0),[m,h]=i.useState(!1),[o,p]=i.useState(1.25),[g,j]=i.useState(null),[v,f]=i.useState(!1),[y,$]=i.useState("dm_turn"),[A,_]=i.useState(""),O=()=>new Date().toLocaleDateString("en-CA"),[w,U]=i.useState(O),[F,N]=i.useState("calibrated"),z=async()=>{d(!0);try{const[x,S]=await Promise.all([H.from("worker_cost_rates").select("*").order("event_type").order("effective_from",{ascending:!1}),H.from("system_config").select("id, value").eq("key","worker_cost_safety_margin").maybeSingle()]);if(a(x.data??[]),S.data){j(S.data.id);const T=parseFloat(S.data.value);T>0&&p(T)}}finally{d(!1)}};i.useEffect(()=>{z()},[]);const te=i.useMemo(()=>{const x=new Date().toLocaleDateString("en-CA"),S=new Map;for(const T of t){if(T.effective_from>x)continue;const L=S.get(T.event_type);(!L||T.effective_from>L.effective_from)&&S.set(T.event_type,T)}return S},[t]),K=async()=>{var S;const x=parseFloat(A);if(!(x>=0)){s({title:"Invalid cost",description:"Enter a unit cost ≥ 0.",variant:"destructive"});return}h(!0);try{const T=((S=Ve.find(B=>B.value===y))==null?void 0:S.unit)??"event",{error:L}=await H.from("worker_cost_rates").insert({event_type:y,unit:T,unit_cost_usd:x,effective_from:w,status:F,note:F==="calibrated"?"Set from /admin/settings":"Provisional, set from /admin/settings"});if(L)throw L;s({title:"Rate added",description:`${y} = $${x} from ${w}. Past months are untouched.`}),_(""),await z()}catch(T){s({title:"Error",description:(T==null?void 0:T.message)??String(T),variant:"destructive"})}finally{h(!1)}},I=async()=>{if(!(!g||!(o>0))){f(!0);try{const{error:x}=await H.from("system_config").update({value:String(o)}).eq("id",g);if(x)throw x;s({title:"Safety margin saved",description:`Computed costs are multiplied by ×${o}.`})}catch(x){s({title:"Error",description:(x==null?void 0:x.message)??String(x),variant:"destructive"})}finally{f(!1)}}};return e.jsxs(le,{children:[e.jsxs(oe,{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(ts,{className:"h-5 w-5 text-muted-foreground"}),e.jsx(ce,{children:"Worker Cost Rates"})]}),e.jsx(ge,{children:"Standard unit costs behind expert-earnings net math (gross − operational cost, then 70/30). Saving creates a NEW effective-dated rate — historical months never change."})]}),e.jsx(de,{className:"space-y-5",children:n?e.jsx("div",{className:"flex items-center justify-center py-8",children:e.jsx(M,{className:"h-6 w-6 animate-spin text-muted-foreground"})}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"space-y-1.5",children:Ve.map(x=>{const S=te.get(x.value);return e.jsxs("div",{className:"flex items-center justify-between text-sm border-b last:border-b-0 pb-1.5",children:[e.jsx("span",{className:"text-muted-foreground",children:x.label}),e.jsxs("span",{className:"flex items-center gap-2 font-mono",children:[S?`$${Number(S.unit_cost_usd).toFixed(3)}/${S.unit}`:"—",S&&e.jsx(ve,{variant:S.status==="calibrated"?"default":"secondary",className:S.status==="calibrated"?"bg-green-100 text-green-800 hover:bg-green-100":"",children:S.status})]})]},x.value)})}),e.jsxs("div",{className:"grid grid-cols-2 gap-3 items-end border rounded-lg p-3",children:[e.jsxs("div",{className:"space-y-1 col-span-2",children:[e.jsx(X,{className:"text-xs",children:"New rate (effective-dated)"}),e.jsxs(Ie,{value:y,onValueChange:$,children:[e.jsx(Ue,{children:e.jsx(We,{})}),e.jsx(Me,{children:Ve.map(x=>e.jsx($e,{value:x.value,children:x.label},x.value))})]})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx(X,{className:"text-xs",children:"Unit cost (USD)"}),e.jsx(V,{type:"number",min:0,step:"0.001",value:A,onChange:x=>_(x.target.value),placeholder:"0.050"})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx(X,{className:"text-xs",children:"Effective from"}),e.jsx(V,{type:"date",value:w,onChange:x=>U(x.target.value)})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx(X,{className:"text-xs",children:"Status"}),e.jsxs(Ie,{value:F,onValueChange:x=>N(x),children:[e.jsx(Ue,{children:e.jsx(We,{})}),e.jsxs(Me,{children:[e.jsx($e,{value:"calibrated",children:"calibrated"}),e.jsx($e,{value:"provisional",children:"provisional"})]})]})]}),e.jsxs(E,{onClick:K,disabled:m||!A,children:[m?e.jsx(M,{className:"h-4 w-4 animate-spin mr-2"}):e.jsx(ye,{className:"h-4 w-4 mr-2"}),"Add rate"]})]}),e.jsxs("div",{className:"flex items-end gap-3",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx(X,{htmlFor:"cost-margin",className:"text-xs",children:"Safety margin (× on computed cost)"}),e.jsx(V,{id:"cost-margin",type:"number",min:1,step:"0.05",value:o,onChange:x=>p(parseFloat(x.target.value)||1),className:"w-28"})]}),e.jsxs(E,{onClick:I,disabled:v||!g,variant:"outline",children:[v?e.jsx(M,{className:"h-4 w-4 animate-spin mr-2"}):e.jsx(ye,{className:"h-4 w-4 mr-2"}),"Save margin"]})]})]})})]})}const Le=500,wt=864e5,as=/^\d{4}-\d{2}-\d{2}$/,D=s=>{if(!s)return"";const t=new Date(s);return Number.isNaN(t.getTime())?"":t.toISOString().slice(0,10)},ae=s=>{if(!as.test(s))return!1;const t=Date.parse(`${s}T00:00:00Z`);return!Number.isNaN(t)&&new Date(t).toISOString().slice(0,10)===s},be=s=>new Date(`${s}T23:59:59Z`).toISOString(),tt=(s=new Date)=>s.toISOString().slice(0,10),ns=(s,t)=>new Date(Date.parse(`${s}T00:00:00Z`)+t*wt).toISOString().slice(0,10),Ce=(s,t)=>{const[a,n,d]=s.split("-").map(Number),m=new Date(Date.UTC(a,n-1+t,1)),h=new Date(Date.UTC(m.getUTCFullYear(),m.getUTCMonth()+1,0)).getUTCDate();return m.setUTCDate(Math.min(d,h)),m.toISOString().slice(0,10)},Te=(s,t)=>Math.round((Date.parse(`${t}T00:00:00Z`)-Date.parse(`${s}T00:00:00Z`))/wt),yt=(s,t=new Date)=>Te(tt(t),D(s)),bt=(s,t=new Date)=>{const a=yt(s,t);return a<=0?"ends today":a===1?"1 day left":`${a} days left`},rs=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],k=s=>{if(!ae(s))return s;const[t,a,n]=s.split("-").map(Number);return`${n} ${rs[a-1]} ${t}`},Nt=s=>{const t=new Date(s);if(Number.isNaN(t.getTime()))return s;const a=t.toISOString().slice(11,16);return`${k(t.toISOString().slice(0,10))}, ${a} UTC`},ee=s=>
11`$${s.toLocaleString("en-US",{minimumFractionDigits:2,maximumFractionDigits:2})}`,Qe=s=>Math.round(Number(s)*100),De=s=>{const t=s.trim().replace(",",".");if(!t)return{cents:null,problem:"empty"};if(!/^(\d+\.?\d*|\.\d+)$/.test(t))return{cents:null,problem:"not_a_number"};if(/\.\d{3,}$/.test(t))return{cents:null,problem:"too_precise"};const a=Math.round(parseFloat(t)*100);return a>0?{cents:a,problem:null}:{cents:null,problem:"not_positive"}},Je=s=>({price:Number(s.team_worker_monthly).toFixed(2),until:D(s.expires_at),freeUntil:D(s.team_free_until),note:s.note??""}),it=(s=new Date)=>({price:"49.99",until:Ce(tt(s),2),freeUntil:"",note:""}),xe=(s,t=new Date)=>new Date(s).getTime()>t.getTime()?"active":"ended",ke=(s,t)=>{if(!s)return["price","until","freeUntil","note"];const a=[],n=De(t.price);return(n.cents===null||n.cents!==Qe(s.team_worker_monthly))&&a.push("price"),t.until!==D(s.expires_at)&&a.push("until"),t.freeUntil!==D(s.team_free_until)&&a.push("freeUntil"),t.note.trim()!==(s.note??"").trim()&&a.push("note"),a},He=(s,t)=>{const a=ke(s,t);return{priceCents:De(t.price).cents,expiresAt:a.includes("until")||!s?ae(t.until)?be(t.until):null:s.expires_at,freeUntil:a.includes("freeUntil")||!s?t.freeUntil&&ae(t.freeUntil)?be(t.freeUntil):null:s.team_free_until,note:t.note.trim()||null}},Re=(s,t,a=new Date)=>{const n={},d=ke(t,s),m=a.getTime(),h=De(s.price);if(h.problem==="too_precise"?n.price="Use at most two decimals (for example 49.99).":h.problem&&(n.price="Enter a monthly price above 0 (for example 49.99)."),ae(s.until)?d.includes("until")&&Date.parse(be(s.until))<=m&&(n.until=t?'Pick today or a later day. To stop a POC, use "End POC now".':"Pick today or a later day."):n.until="Pick the day the POC ends.",s.freeUntil){const o=He(t,s);if(!ae(s.freeUntil))n.freeUntil="That is not a valid day.";else if(d.includes("freeUntil")&&Date.parse(be(s.freeUntil))<=m)n.freeUntil='A free period that is already over changes nothing. Pick today or a later day, or choose "No free period".';else if(o.freeUntil&&o.expiresAt&&Date.parse(o.freeUntil)>Date.parse(o.expiresAt)){const p=Date.parse(o.expiresAt)<=m;n.freeUntil=`The free period cannot outlast the POC, which ${p?"ended":"ends"} on ${k(D(o.expiresAt))}.`}}return s.note.length>Le&&(n.note=`Keep the note under ${Le} characters.`),{errors:n,ok:Object.keys(n).length===0}},kt=(s,t)=>{const a=ke(s,t),n={},d=De(t.price);return a.includes("price")&&d.cents!==null&&(n.team_worker_monthly=d.cents/100),a.includes("until")&&ae(t.until)&&(n.expires_at=be(t.until)),a.includes("freeUntil")&&(n.team_free_until=t.freeUntil&&ae(t.freeUntil)?be(t.freeUntil):null),a.includes("note")&&(n.note=t.note.trim()||null),n},lt=(s,t)=>!s||!t?!s&&!t:new Date(s).getTime()===new Date(t).getTime(),ot=(s,t)=>{const a=[];return t.team_worker_monthly!==void 0&&Qe(s.team_worker_monthly)!==Qe(t.team_worker_monthly)&&a.push("team_worker_monthly"),t.expires_at!==void 0&&!lt(s.expires_at,t.expires_at)&&a.push("expires_at"),t.team_free_until!==void 0&&!lt(s.team_free_until,t.team_free_until)&&a.push("team_free_until"),t.note!==void 0&&(s.note??null)!==(t.note??null)&&a.push("note"),a},is=s=>s&&s>0?`the standard price (${ee(s)}/month)`:"the standard price",Ye=(s,t,a)=>Math.abs(s)===1?`1 ${t}`:`${Math.abs(s)} ${a}`,ls=(s,t,a,n=new Date)=>{const d=ke(s,t),m=He(s,t),h=n.getTime(),o=xe(s.expires_at,n)==="active",p=!!m.expiresAt&&new Date(m.expiresAt).getTime()>h,g=[];if(d.includes("price")&&g.push({field:"price",label:"Monthly price",before:`${ee(Number(s.team_worker_monthly))}/month`,after:m.priceCents===null?"not a valid price":`${ee(m.priceCents/100)}/month`,effect:m.priceCents===null?null:p?"Paywalls and new activations show it right away, and the next monthly statement uses it. A month already paid is not billed again.":"No effect while the POC is ended. It applies if you start the POC again.",caution:!1}),d.includes("until")){const j=D(s.expires_at),v=ae(t.until)&&j?Te(j,t.until):0;let f=null;!o&&p?f=`Starts the POC again: the POC price applies from now until ${k(t.until)}.`:p&&v>0?f=`The POC price runs ${Ye(v,"day","days")} longer.`:p&&v<0&&(f=`The POC price stops ${Ye(v,"day","days")} sooner. After that day, paywalls, activations and statements go back to ${is(a)}.`),g.push({field:"until",label:"POC ends on",before:`${k(j)}${o?"":" (ended)"}`,after:ae(t.until)?k(t.until):"not a valid day",effect:f,caution:!o&&p})}if(d.includes("freeUntil")){const j=D(s.team_free_until),v=!!s.team_free_until&&new Date(s.team_free_until).getTime()>h,f=!!m.freeUntil&&new Date(m.freeUntil).getTime()>h;let y,$=!1;f&&(!v||t.freeUntil>j)?y=`No paywall on this workplace's own Team Workers until ${k(t.freeUntil)}.`:f?y=`The free period ends ${Ye(Te(t.freeUntil,j),"day","days")} sooner.`:v?(y="The free period stops now: this workplace's own Team Workers who are past the free allowance meet the paywall on their next message.",$=!0):y="Nothing changes for the customer: that period was already over.",g.push({field:"freeUntil",label:"Team Workers free until",before:j?`${k(j)}${v?"":" (over)"}`:"no free period",after:t.freeUntil?ae(t.freeUntil)?k(t.freeUntil):"not a valid day":"no free period",effect:y,caution:$})}return d.includes("note")&&g.push({field:"note",label:"Note",before:(s.note??"").trim()||"no note",after:t.note.trim()||"no note",effect:null,caution:!1}),g},_t=(s,t,a=new Date)=>{if(!s.expiresAt)return[];const n=a.getTime(),d=D(s.expiresAt),m=new Date(s.expiresAt).getTime()<=n,h=!m&&!!s.freeUntil&&new Date(s.freeUntil).getTime()>n,o=[];if(s.freeUntil){const j=D(s.freeUntil);o.push({key:"free",title:"Team Workers free",detail:h?`until ${k(j)}`:`ended ${k(j)}`,state:h?"now":"past"})}const p=s.priceCents===null?"POC price":`${ee(s.priceCents/100)}/month`;o.push({key:"poc",title:"POC price",detail:m?`${p}, ended ${k(d)}`:`${p} until ${k(d)}`,state:m?"past":h?"next":"now"});const g=t&&t>0?`${ee(t)}/month`:"Platform price";return o.push({key:"standard",title:"Standard price",detail:m?`${g} since ${k(d)}`:`${g} after ${k(d)}`,state:m?"now":"next"}),o},ct=(s,t=new Date)=>{const a=`${ee(Number(s.team_worker_monthly))}/month`,n=k(D(s.expires_at)),d=xe(s.expires_at,t)==="active",h=d&&!!s.team_free_until&&new Date(s.team_free_until).getTime()>t.getTime()?`, Team Workers free until ${k(D(s.team_free_until))}`:"";return d?`${a} until ${n}${h}`:`${a}, ended ${n}`},os=(s,t)=>{if(s===null||!t||!(t>0))return null;const a=Math.round(t*100);if(s===a)return{text:"same as the standard price",above:!1};const n=Math.round(Math.abs(a-s)/a*100);return s<a?{text:`${n}% below the standard price`,above:!1}:{text:`${n}% above the standard price`,above:!0}},Ee="text-xs font-semibold uppercase tracking-wide text-muted-foreground",Fe="text-[11px] leading-snug text-muted-foreground",Pe=({id:s,children:t})=>e.jsx("p",{id:s,role:"alert",className:"text-[11px] font-medium leading-snug text-destructive",children:t}),Oe=({children:s,onClick:t,disabled:a,title:n})=>e.jsx("button",{type:"button",onClick:t,disabled:a,title:n,className:"rounded-full border bg-background px-2.5 py-1 text-xs font-medium text-foreground
11/80 transition-colors hover:border-[#5A60F1]/50 hover:bg-[#5A60F1]/5 hover:text-[#5A60F1] disabled:pointer-events-none disabled:opacity-50",children:s}),dt=s=>s===0?"tonight":s===1?"in 1 day":`in ${s} days`,St=({idPrefix:s,form:t,onChange:a,errors:n,original:d,standardPrice:m,now:h,disabled:o=!1})=>{const p=tt(h),g=ke(d,t),j=N=>a({...t,...N}),v=De(t.price),f=os(v.cents,m),y=!!d&&xe(d.expires_at,h)==="ended",$=ae(t.until),A=$&&t.until>=p?t.until:p;let _;y&&!g.includes("until")?_=e.jsxs(e.Fragment,{children:["This POC ended on ",k(D(d.expires_at)),". Saving keeps it ended. Pick a later day to start it again."]}):$&&t.until>=p?_=y?e.jsxs(e.Fragment,{children:["Starts the POC again, through the end of ",k(t.until)," (UTC), ",dt(Te(p,t.until)),"."]}):e.jsxs(e.Fragment,{children:["Through the end of ",k(t.until)," (UTC), ",dt(Te(p,t.until)),". After that, back to the standard price."]}):_=e.jsx(e.Fragment,{children:"The POC price applies through the end of that day (UTC)."});const O=!!t.freeUntil&&ae(t.freeUntil),w=O&&t.freeUntil<p,U=[{label:"+2 weeks",day:ns(p,14)},{label:"+1 month",day:Ce(p,1)}].filter(N=>!$||N.day<=t.until),F=v.cents!==null?`${ee(v.cents/100)}/month`:"the POC price";return e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"grid grid-cols-1 gap-4 sm:grid-cols-2",children:[e.jsxs("div",{className:"min-w-0 space-y-1.5",children:[e.jsx("label",{htmlFor:`${s}-price`,className:Ee,children:"Monthly price"}),e.jsxs("div",{className:J("flex h-10 items-center rounded-md border bg-background px-3 focus-within:ring-2 focus-within:ring-ring",n.price&&"border-destructive focus-within:ring-destructive/40"),children:[e.jsx("span",{className:"mr-1 text-muted-foreground",children:"$"}),e.jsx("input",{id:`${s}-price`,type:"text",inputMode:"decimal",autoComplete:"off",spellCheck:!1,className:"w-full min-w-0 bg-transparent font-mono font-semibold outline-none",value:t.price,onChange:N=>j({price:N.target.value}),disabled:o,"aria-invalid":!!n.price,"aria-describedby":`${s}-price-help`}),e.jsx("span",{className:"shrink-0 whitespace-nowrap text-xs text-muted-foreground",children:"/month"})]}),n.price?e.jsx(Pe,{id:`${s}-price-help`,children:n.price}):e.jsxs("p",{id:`${s}-price-help`,className:Fe,children:["Per Team Worker."," ",f&&m?e.jsxs("span",{className:J(f.above&&"font-semibold text-amber-700"),children:[f.text.charAt(0).toUpperCase()+f.text.slice(1)," (",ee(m),")."]}):m?e.jsxs(e.Fragment,{children:["Standard price: ",ee(m),"."]}):null]})]}),e.jsxs("div",{className:"min-w-0 space-y-1.5",children:[e.jsx("label",{htmlFor:`${s}-until`,className:Ee,children:"POC ends on"}),e.jsx(V,{id:`${s}-until`,type:"date",className:J("h-10 w-full min-w-0",n.until&&"border-destructive focus-visible:ring-destructive/40"),value:t.until,min:p,onChange:N=>j({until:N.target.value}),disabled:o,"aria-invalid":!!n.until,"aria-describedby":`${s}-until-help`}),e.jsx("div",{className:"flex flex-wrap gap-1.5",children:[1,3,6].map(N=>e.jsxs(Oe,{disabled:o,onClick:()=>j({until:Ce(A,N)}),title:A===p?`Ends ${k(Ce(p,N))}`:`Extends to ${k(Ce(A,N))}`,children:["+",N," ",N===1?"month":"months"]},N))}),n.until?e.jsx(Pe,{id:`${s}-until-help`,children:n.until}):e.jsx("p",{id:`${s}-until-help`,className:Fe,children:_})]})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsxs("label",{htmlFor:`${s}-free`,className:Ee,children:["Team Workers free until ",e.jsx("span",{className:"font-normal normal-case",children:"(optional)"})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-1.5",children:[e.jsx(V,{id:`${s}-free`,type:"date",className:J("h-10 w-full sm:w-52",n.freeUntil&&"border-destructive focus-visible:ring-destructive/40"),value:t.freeUntil,min:p,max:$?t.until:void 0,onChange:N=>j({freeUntil:N.target.value}),disabled:o,"aria-invalid":!!n.freeUntil,"aria-describedby":`${s}-free-help`}),U.map(N=>e.jsx(Oe,{disabled:o,onClick:()=>j({freeUntil:N.day}),title:`Free until ${k(N.day)}`,children:N.label},N.label)),$&&t.until>=p&&e.jsx(Oe,{disabled:o,onClick:()=>j({freeUntil:t.until}),title:`Free until ${k(t.until)}`,children:"Whole POC"}),t.freeUntil&&e.jsx(Oe,{disabled:o,onClick:()=>j({freeUntil:""}),title:"Remove the free period",children:"No free period"})]}),n.freeUntil?e.jsx(Pe,{id:`${s}-free-help`,children:n.freeUntil}):e.jsxs("p",{id:`${s}-free-help`,className:Fe,children:[!t.freeUntil&&e.jsx(e.Fragment,{children:"No paywall at all on this workplace's own Team Workers until that day, however much they work. Hired marketplace Workers keep their normal paywall. Leave empty for no free period."}),O&&w&&e.jsxs(e.Fragment,{children:["This free period ended on ",k(t.freeUntil)," and has no effect any more. You can leave it or clear it."]}),O&&!w&&e.jsxs(e.Fragment,{children:["No paywall on this workplace's own Team Workers through the end of ",k(t.freeUntil)," (UTC), then ",F,". Hired marketplace Workers keep their normal paywall."]})]})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsxs("div",{className:"flex items-baseline justify-between gap-2",children:[e.jsxs("label",{htmlFor:`${s}-note`,className:Ee,children:["Note ",e.jsx("span",{className:"font-normal normal-case",children:"(optional, internal)"})]}),e.jsxs("span",{className:J("text-[11px] tabular-nums text-muted-foreground",t.note.length>Le&&"font-semibold text-destructive"),children:[t.note.length,"/",Le]})]}),e.jsx(Be,{id:`${s}-note`,rows:2,className:J("min-h-[64px] resize-y",n.note&&"border-destructive focus-visible:ring-destructive/40"),placeholder:'For example "Agreement signed 27 July: 2 months, 3 Team Workers minimum"',value:t.note,onChange:N=>j({note:N.target.value}),disabled:o,"aria-invalid":!!n.note,"aria-describedby":`${s}-note-help`}),n.note?e.jsx(Pe,{id:`${s}-note-help`,children:n.note}):e.jsx("p",{id:`${s}-note-help`,className:Fe,children:"Not shown anywhere in the customer's app. It is stored with the price and the dates, which members of that workplace can read, so write nothing here that the customer must not see."})]})]})},cs={past:"border-dashed bg-transparent text-muted-foreground",now:"border-emerald-300 bg-emerald-50 text-emerald-950",next:"bg-background text-foreground"}
11,ds={past:"bg-muted-foreground/40",now:"bg-emerald-500",next:"bg-[#5A60F1]"},Ct=({phases:s,stacked:t=!1})=>s.length===0?null:e.jsx("ol",{className:J("flex gap-1.5",t?"flex-col":"flex-col sm:flex-row sm:items-stretch"),"aria-label":"What the customer gets, in order",children:s.map((a,n)=>e.jsxs("li",{className:J("flex min-w-0 items-center gap-1.5",!t&&"sm:flex-1"),children:[n>0&&e.jsx($t,{"aria-hidden":!0,className:J("h-4 w-4 shrink-0 text-muted-foreground/60",t?"hidden":"hidden sm:block")}),e.jsxs("div",{className:J("min-w-0 flex-1 rounded-lg border px-3 py-2",cs[a.state]),children:[e.jsxs("div",{className:"flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wide",children:[e.jsx("span",{className:J("h-1.5 w-1.5 shrink-0 rounded-full",ds[a.state])}),e.jsx("span",{className:"truncate",children:a.title}),a.state==="now"&&e.jsx("span",{className:"ml-auto shrink-0 rounded-full bg-emerald-600 px-1.5 py-px text-[10px] font-semibold normal-case tracking-normal text-white",children:"Now"})]}),e.jsx("div",{className:"mt-0.5 text-sm leading-snug",children:a.detail})]})]},a.key))}),Ge=s=>s==null?"no price":`${ee(Number(s))}/month`,mt=(s,t)=>!s||!t?!s&&!t:new Date(s).getTime()===new Date(t).getTime(),ms=s=>{const t=s.before,a=s.after;if(!a)return[];if(!t)return[Ge(a.team_worker_monthly),`ends ${k(D(a.expires_at))}`,a.team_free_until?`Team Workers free until ${k(D(a.team_free_until))}`:"no free period",...a.note?[`note: ${a.note}`]:[]];const n=[];if(Math.round(Number(t.team_worker_monthly)*100)!==Math.round(Number(a.team_worker_monthly)*100)&&n.push(`Price ${Ge(t.team_worker_monthly)} to ${Ge(a.team_worker_monthly)}`),!mt(t.expires_at,a.expires_at)){const d=D(t.expires_at)===D(a.expires_at);n.push(d?`End moved within ${k(D(a.expires_at))} (${Nt(a.expires_at??"")})`:`End ${k(D(t.expires_at))} to ${k(D(a.expires_at))}`)}if(!mt(t.team_free_until,a.team_free_until)){const d=t.team_free_until?k(D(t.team_free_until)):"no free period",m=a.team_free_until?k(D(a.team_free_until)):"no free period";n.push(`Free period ${d} to ${m}`)}return(t.note??"")!==(a.note??"")&&n.push(a.note?`Note: ${a.note}`:"Note removed"),n},us={created:"POC created",updated:"Terms changed",baseline:"Terms on record when history started"},hs=({history:s})=>{const[t,a]=i.useState(!1);if(!s)return e.jsx("p",{className:"text-xs text-muted-foreground",children:"Reading the history…"});if(s.state==="not_recording")return e.jsx("p",{className:"text-xs text-muted-foreground",children:"History is not being kept yet: it starts once the database update for POC history has been applied. Saves still work and are still checked."});if(s.state==="unavailable")return e.jsxs("p",{className:"text-xs text-muted-foreground",children:["The history could not be read just now (",s.message,")."]});if(s.entries.length===0)return e.jsx("p",{className:"text-xs text-muted-foreground",children:"No change has been recorded yet."});const n=t?s.entries:s.entries.slice(0,3);return e.jsxs("div",{className:"space-y-2",children:[e.jsx("ol",{className:"space-y-2",children:n.map(d=>e.jsxs("li",{className:"rounded-md border bg-muted/20 px-3 py-2 text-xs",children:[e.jsxs("div",{className:"flex flex-wrap items-baseline justify-between gap-x-3 gap-y-0.5",children:[e.jsx("span",{className:"font-semibold text-foreground",children:us[d.action]}),e.jsxs("span",{className:"text-muted-foreground",children:[Nt(d.changed_at),d.action!=="baseline"&&e.jsxs(e.Fragment,{children:[", ",d.changed_by_name??(d.changed_by?"an admin":"directly in the database")]})]})]}),e.jsx("ul",{className:"mt-1 space-y-0.5 text-muted-foreground",children:ms(d).map((m,h)=>e.jsx("li",{className:"break-words",children:m},h))})]},d.id))}),s.entries.length>3&&e.jsx("button",{type:"button",onClick:()=>a(d=>!d),className:"text-xs font-medium text-[#5A60F1] hover:underline",children:t?"Show the latest only":`Show all ${s.entries.length} changes`})]})},ps=s=>{switch(s.status){case"conflict":return"These terms were changed somewhere else while this editor was open (another admin, or another tab). Nothing was saved.";case"gone":return"This POC no longer exists. Nothing was saved.";case"refused":return"Nothing was saved: this account is not allowed to change POC pricing.";case"exists":return"This workplace already has a POC.";case"mismatch":return`The database holds something else than what was sent (${s.fields.join(", ")}). Close this editor: the list shows what is stored.`;default:return`Not saved. ${s.message}`}},xs=({row:s,open:t,onOpenChange:a,api:n,standardPrice:d,onSaved:m,onStale:h})=>{var me,re,l;const[o,p]=i.useState(s),[g,j]=i.useState(()=>Je(s)),[v,f]=i.useState(!1),[y,$]=i.useState(null),[A,_]=i.useState(null),[O,w]=i.useState(null),[U,F]=i.useState(!1),[N,z]=i.useState(!1),[te,K]=i.useState(null),I=i.useRef(null),[x,S]=i.useState(0);i.useEffect(()=>{if(!t)return;let c=!1;return n.history(s).then(b=>{c||w(b)}).catch(()=>{c||w({state:"unavailable",message:"no answer"})}),()=>{c=!0}},[n,t,s,x]);const T=i.useRef(!1);i.useEffect(()=>{if(!t)return;let c=!1;return n.read(s.id).then(b=>
11{c||!b||T.current||b.updated_at!==s.updated_at&&(p(b),j(Je(b)),h())}).catch(()=>{}),()=>{c=!0}},[n,t,s.id]);const L=new Date,B=((me=o.workplaces)==null?void 0:me.name)??"this workplace",ne=xe(o.expires_at,L),Y=ne==="active"&&!!o.team_free_until&&new Date(o.team_free_until).getTime()>L.getTime(),r=Re(g,o,L),P=ls(o,g,d,L),W=ke(o,g).length>0,Z=_t(He(o,g),d,L),R=v||N,C=c=>(c.status==="conflict"&&_(c.latest),(c.status==="conflict"||c.status==="gone"||c.status==="mismatch")&&h(),ps(c)),ue=async c=>{if(c==null||c.preventDefault(),!(R||!W)&&Re(g,o,new Date).ok){f(!0),$(null),_(null);try{const b=await n.update(o,kt(o,g));b.status==="saved"?m(b.row,"saved"):$(C(b))}catch(b){$(`Not saved. ${b instanceof Error?b.message:String(b)}`)}finally{f(!1)}}},se=async()=>{if(!R){z(!0),K(null);try{const c=await n.update(o,{expires_at:new Date().toISOString(),team_free_until:null});if(c.status==="saved")F(!1),m(c.row,"ended");else{const b=C(c);K(b),c.status==="conflict"&&$(b)}}catch(c){K(`Not ended. ${c instanceof Error?c.message:String(c)}`)}finally{z(!1)}}},he=()=>{A&&(p(A),j(Je(A)),_(null),$(null),S(c=>c+1))};return e.jsxs(e.Fragment,{children:[e.jsx(Tt,{open:t,onOpenChange:c=>{R||a(c)},children:e.jsxs(Dt,{ref:I,className:"flex max-h-[92vh] max-w-2xl flex-col gap-0 overflow-hidden p-0 outline-none",onInteractOutside:c=>{(W||R)&&c.preventDefault()},onOpenAutoFocus:c=>{var b;c.preventDefault(),(b=I.current)==null||b.focus()},children:[e.jsx(Et,{className:"border-b px-6 py-4",children:e.jsxs("div",{className:"flex items-center gap-3 pr-6",children:[e.jsxs(ht,{className:"h-10 w-10 shrink-0",children:[((re=o.workplaces)==null?void 0:re.logo_url)&&e.jsx(pt,{src:o.workplaces.logo_url,alt:""}),e.jsx(xt,{className:"bg-[#5A60F1]/10 text-sm font-semibold text-[#5A60F1]",children:((l=B[0])==null?void 0:l.toUpperCase())??"?"})]}),e.jsxs("div",{className:"min-w-0 text-left",children:[e.jsxs(Ft,{className:"break-words leading-tight",children:["Edit POC · ",B]}),e.jsx(Pt,{asChild:!0,children:e.jsxs("div",{className:"mt-1 flex flex-wrap items-center gap-x-2 gap-y-1 text-sm text-muted-foreground",children:[e.jsx("span",{className:J("inline-flex items-center rounded-full px-2 py-0.5 text-xs font-semibold",ne==="active"?"bg-emerald-100 text-emerald-800":"bg-muted text-muted-foreground"),children:ne==="active"?`Active, ${bt(o.expires_at,L)}`:`Ended ${k(D(o.expires_at))}`}),d&&e.jsxs("span",{children:["Standard price ",ee(d),"/month"]})]})})]})]})}),e.jsxs("form",{onSubmit:ue,noValidate:!0,className:"flex min-h-0 flex-1 flex-col",children:[e.jsxs("div",{className:"min-h-0 flex-1 space-y-5 overflow-y-auto px-6 py-5",children:[e.jsx(St,{idPrefix:`poc-edit-${o.id}`,form:g,onChange:c=>{T.current=!0,j(c),$(null)},errors:r.errors,original:o,standardPrice:d,now:L,disabled:R}),e.jsxs("section",{className:"space-y-2",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wide text-muted-foreground",children:"What the customer gets"}),e.jsx(Ct,{phases:Z})]}),e.jsxs("section",{className:"space-y-2","aria-live":"polite",children:[e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wide text-muted-foreground",children:"What changes when you save"}),P.length===0?e.jsx("p",{className:"rounded-md border border-dashed px-3 py-2 text-sm text-muted-foreground",children:"Nothing yet. Edit a field above."}):e.jsx("ul",{className:"divide-y rounded-md border",children:P.map(c=>e.jsxs("li",{className:J("space-y-1 px-3 py-2 text-sm",c.caution&&"bg-amber-50"),children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-x-2 gap-y-0.5",children:[e.jsx("span",{className:"font-medium",children:c.label}),e.jsx("span",{className:"break-words text-muted-foreground line-through decoration-muted-foreground/50",children:c.before}),e.jsx(Ot,{"aria-hidden":!0,className:"h-3.5 w-3.5 shrink-0 text-muted-foreground"}),e.jsx("span",{className:"break-words font-semibold",children:c.after})]}),c.effect&&e.jsxs("p",{className:J("flex items-start gap-1.5 text-xs",c.caution?"text-amber-900":"text-muted-foreground"),children:[c.caution&&e.jsx(At,{"aria-hidden":!0,className:"mt-px h-3.5 w-3.5 shrink-0"}),e.jsx("span",{children:c.effect})]})]},c.field))})]}),e.jsxs("section",{className:"space-y-2",children:[e.jsxs("h3",{className:"flex items-center gap-1.5 text-xs font-semibold uppercase tracking-wide text-muted-foreground",children:[e.jsx(It,{"aria-hidden":!0,
11className:"h-3.5 w-3.5"})," History"]}),e.jsx(hs,{history:O})]})]}),e.jsxs("div",{className:"space-y-3 border-t bg-muted/20 px-6 py-3",children:[y&&e.jsxs("div",{role:"alert",className:"space-y-2 rounded-md border border-destructive/40 bg-destructive/5 px-3 py-2 text-sm text-destructive",children:[e.jsx("p",{children:y}),A&&e.jsx(E,{type:"button",size:"sm",variant:"outline",onClick:he,children:"Load the latest terms"})]}),e.jsxs("div",{className:"flex flex-col-reverse gap-2 sm:flex-row sm:items-center sm:justify-between",children:[e.jsx("div",{children:ne==="active"&&e.jsx(E,{type:"button",variant:"outline",className:"w-full border-destructive/40 text-destructive hover:bg-destructive/5 hover:text-destructive sm:w-auto",onClick:()=>{K(null),F(!0)},disabled:R,children:"End POC now"})}),e.jsxs("div",{className:"flex flex-col-reverse gap-2 sm:flex-row",children:[e.jsx(E,{type:"button",variant:"ghost",onClick:()=>a(!1),disabled:R,children:W?"Discard changes":"Close"}),e.jsx(E,{type:"submit",disabled:R||!W||!r.ok,className:"min-w-36",children:v?e.jsxs(e.Fragment,{children:[e.jsx(M,{className:"mr-2 h-4 w-4 animate-spin"}),"Saving…"]}):W?e.jsxs(e.Fragment,{children:[e.jsx(ft,{className:"mr-2 h-4 w-4"}),"Save ",P.length===1?"1 change":`${P.length} changes`]}):"No changes"})]})]})]})]})]})}),e.jsx(et,{open:U,onOpenChange:c=>{N||F(c)},title:`End the POC for ${B} now?`,description:"The POC price stops at once. The agreement stays on record and can be started again later with a new end date.",consequences:[d?`Paywalls and new activations show the standard price (${ee(d)}/month) right away.`:"Paywalls and new activations show the standard price right away.","From the next monthly statement, Team Workers who joined at the POC price are billed the standard price. A month already paid is not billed again.",...Y?[`The free period ends too (it was running until ${k(D(o.team_free_until))}): this workplace's own Team Workers who are past the free allowance meet the paywall on their next message.`]:[],...W?["The edits you have not saved in the editor are dropped."]:[]],error:te,confirmLabel:"End POC now",busyLabel:"Ending…",busy:N,onConfirm:se})]})},_e="workplace_price_overrides",fs="workplace_price_override_history",Se="id, workplace_id, team_worker_monthly, expires_at, team_free_until, note, created_at, updated_at, created_by, workplaces(name, slug, logo_url, closed_at)",pe=H,gs=(s,t)=>!!s&&!!t&&new Date(s).getTime()===new Date(t).getTime(),Ke=s=>s.code==="42501"?{status:"refused"}:s.code==="23505"?{status:"exists"}:s.code==="23514"?{status:"error",message:/free/i.test(s.message??"")?"The free period cannot outlast the POC.":"The database refused these terms: the price must be above 0 and the free period cannot outlast the POC."}:{status:"error",message:s.message||"The database did not answer."},vs={async list(){const{data:s,error:t}=await pe.from(_e).select(Se).order("expires_at",{ascending:!1});return{rows:s??[],error:t?t.message:null}},async standardPrice(){try{const{data:s,error:t}=await pe.from("platform_prices").select("amount").eq("key","team_worker_monthly").maybeSingle(),a=Number(s==null?void 0:s.amount);return!t&&a>0?a:null}catch{return null}},async searchWorkplaces(s){const{data:t,error:a}=await pe.from("workplaces").select("id, name, slug, logo_url").ilike("name",`%${s}%`).is("closed_at",null).order("name").limit(8);if(a)throw new Error(a.message||"search failed");return t??[]},async read(s){const{data:t,error:a}=await pe.from(_e).select(Se).eq("id",s).maybeSingle();return a?null:t??null},async create(s,t){var o;const{data:a}=await H.auth.getUser(),{data:n,error:d}=await pe.from(_e).insert({workplace_id:s,...t,created_by:((o=a==null?void 0:a.user)==null?void 0:o.id)??null}).select(Se).maybeSingle();if(d)return Ke(d);if(!n)return{status:"refused"};const m=n,h=ot(m,t);return h.length>0?{status:"mismatch",row:m,fields:h}:{status:"saved",row:m}},async update(s,t){let a=pe.from(_e).update({...t,updated_at:new Date().toISOString()}).eq("id",s.id);s.updated_at&&(a=a.eq("updated_at",s.updated_at));const{data:n,error:d}=await a.select(Se).maybeSingle();if(d)return Ke(d);if(!n){const{data:o,error:p}=await pe.from(_e).select(Se).eq("id",s.id).maybeSingle();return p?Ke(p):o?s.updated_at&&!gs(o.updated_at,s.updated_at)?{status:"conflict",latest:o}:{status:"refused"}:{status:"gone"}}const m=n,h=ot(m,t);return h.length>0?{status:"mismatch",row:m,fields:h}:{status:"saved",row:m}},async history(s){const{data:t,error:a}=await pe.from(fs).select("id, action, changed_at, changed_by, old_terms, new_terms").eq("workplace_id",s.workplace_id).order("changed_at",{ascending:!1}).limit(50);if(a)return a.code==="PGRST205"||a.code==="42P01"||/schema cache|does not exist/i.test(a.message??"")?{state:"not_recording"}:{state:"unavailable",message:a.message};const n=t??[],d=[...new Set(n.map(h=>
11h.changed_by).filter(Boolean))],m=new Map;if(d.length>0){const{data:h}=await H.from("profiles").select("id, display_name, email").in("id",d);for(const o of h??[]){const p=o.display_name||o.email;p&&m.set(o.id,p)}}return{state:"ready",entries:n.map(h=>({id:h.id,action:h.action,changed_at:h.changed_at,changed_by:h.changed_by,changed_by_name:h.changed_by?m.get(h.changed_by)??null:null,before:h.old_terms,after:h.new_terms}))}}},js=14,Ze=({name:s,logoUrl:t,size:a="h-8 w-8"})=>{var n;return e.jsxs(ht,{className:`${a} shrink-0`,children:[t&&e.jsx(pt,{src:t,alt:""}),e.jsx(xt,{className:"bg-[#5A60F1]/10 text-xs font-semibold text-[#5A60F1]",children:(n=(s??"?")[0])==null?void 0:n.toUpperCase()})]})},Ae=({className:s,children:t})=>e.jsx("span",{className:J("inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[11px] font-semibold",s),children:t}),ws=({api:s=vs})=>{const{toast:t}=Ne(),[a,n]=i.useState([]),[d,m]=i.useState(!0),[h,o]=i.useState(null),[p,g]=i.useState(null),[j,v]=i.useState(""),[f,y]=i.useState([]),[$,A]=i.useState(!1),[_,O]=i.useState(!1),[w,U]=i.useState(null),[F,N]=i.useState(()=>it()),[z,te]=i.useState(!1),[K,I]=i.useState(null),[x,S]=i.useState(null),[T,L]=i.useState(null),B=i.useRef(null),ne=i.useRef(0),Y=i.useCallback(async()=>{const l=++ne.current,{rows:c,error:b}=await s.list();return l!==ne.current||(o(b),b||n(c),m(!1)),c},[s]);i.useEffect(()=>{Y(),s.standardPrice().then(g).catch(()=>g(null))},[s,Y]),i.useEffect(()=>()=>{B.current&&window.clearTimeout(B.current)},[]),i.useEffect(()=>{let l=!1;const c=j.trim();if(c.length<2||w){y([]),A(!1),O(!1);return}A(!0);const b=setTimeout(async()=>{try{const ie=await s.searchWorkplaces(c);l||(y(ie),O(!1))}catch{l||(y([]),O(!0))}finally{l||A(!1)}},250);return()=>{l=!0,clearTimeout(b)}},[s,j,w]);const r=new Date,P=Re(F,null,r),W=_t(He(null,F),p,r),Z=l=>{L(l),B.current&&window.clearTimeout(B.current),B.current=window.setTimeout(()=>L(null),6e3)},R=()=>{U(null),v(""),N(it()),I(null)},C=l=>{const c=a.find(b=>b.workplace_id===l.id);if(y([]),c){v(""),S(c);return}U(l),I(null)},ue=async()=>{if(!(!w||z)&&Re(F,null,new Date).ok){te(!0),I(null);try{const l=await s.create(w.id,kt(null,F));if(l.status==="saved")t({title:`POC saved and checked · ${w.name}`,description:`Stored: ${ct(l.row)}.`}),R(),Z(l.row.id),await Y();else if(l.status==="exists"){const b=(await Y()).find(ie=>ie.workplace_id===w.id);R(),b?(S(b),t({title:`${w.name} already has a POC`,description:"It is open in the editor. Nothing was replaced."})):I("This workplace already has a POC. Refresh the list and edit it there.")}else l.status==="refused"?I("Nothing was saved: this account is not allowed to change POC pricing."):l.status==="mismatch"?(await Y(),I(`The database holds something else than what was sent (${l.fields.join(", ")}). The list below shows what is stored.`)):l.status==="error"?I(`Not saved. ${l.message}`):I("Not saved. Refresh the list and try again.")}catch(l){I(`Not saved. ${l instanceof Error?l.message:String(l)}`)}finally{te(!1)}}},se=(l,c)=>{var ie;const b=((ie=l.workplaces)==null?void 0:ie.name)??"Workplace";S(null),Z(l.id),n(je=>je.map(fe=>fe.id===l.id?l:fe)),t(c==="ended"?{title:`POC ended · ${b}`,description:"Back on the standard price from now. Checked against what is stored."}:{title:`Saved and checked · ${b}`,description:`Stored: ${ct(l)}.`}),Y()},he=a.filter(l=>xe(l.expires_at,r)==="active").sort((l,c)=>new Date(l.expires_at).getTime()-new Date(c.expires_at).getTime()),me=a.filter(l=>xe(l.expires_at,r)==="ended").sort((l,c)=>new Date(c.expires_at).getTime()-new Date(l.expires_at).getTime()),re=l=>{var u,Q,G,q;const c=xe(l.expires_at,r)==="active",b=yt(l.expires_at,r),ie=c&&!!l.team_free_until&&new Date(l.team_free_until).getTime()>r.getTime(),je=((u=l.workplaces)==null?void 0:u.name)??l.workplace_id,fe=T===l.id;return e.jsxs("li",{className:J("flex items-start gap-3 p-3 transition-colors duration-700",fe&&"bg-emerald-50"),"data-testid":`poc-row-${l.id}`,children:[e.jsx(Ze,{name:((Q=l.workplaces)==null?void 0:Q.name)??null,logoUrl:((G=l.workplaces)==null?void 0:G.logo_url)??null}),e.jsxs("div",{className:"min-w-0 flex-1 space-y-1",children:[e.jsxs("div",{className:"flex flex-wrap items-baseline justify-between gap-x-3",children:[e.jsx("span",{className:"truncate font-medium",children:je}),e.jsxs("span",{className:J("whitespace-nowrap font-mono text-sm font-semibold",!c&&"text-muted-foreground"),children:[ee(Number(l.team_worker_monthly)),e.jsx("span",{className:"font-sans text-xs font-normal text-muted-foreground",children:"/month"})]})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-x-2 gap-y-1 text-xs text-muted-foreground",children:[c?e.jsxs("span",{children:["Ends ",k(D(l.expires_at)),", ",bt(l.expires_at,r)]}):e.jsxs("span",{children:["Ended ",k(D(l.expires_at)),", back on the standard price"]}),c&&b<=js&&e.jsx(Ae,{className:"bg-amber-100 text-amber-800",children:"Ends soon"}),ie&&e.jsxs(Ae,{className:"bg-[#5A60F1]/10 text-[#5A60F1]",children:["Team Workers free until ",k(D(l.team_free_until))]}),((q=l.workplaces)==null?void 0:q.closed_at)&&e.jsx(Ae,{className:"bg-muted text-muted-foreground",children:"Workplace closed"}),fe&&e.jsxs(Ae,{className:"bg-emerald-100 text-emerald-800",children:[e.jsx(ft,{className:"h-3 w-3"}),"Saved"]})]}),l.note&&e.jsx("p",{className:"truncate text-xs text-muted-foreground",title:l.note,children:l.note})]}),e.jsxs(E,{size:"sm",variant:"outline",className:"shrink-0",onClick:()=>S(l),"aria-label":`Edit the POC of ${je}`,children:[e.jsx(Mt,{className:"mr-1.5 h-3.5 w-3.5"}),"Edit"]})]},l.id)};return e.jsxs(le,{children:[e.jsxs(oe,{children:[e.jsxs(ce,{className:"flex items-center gap-2 text-lg",children:[e.jsx(Zt,{className:"h-5 w-5 text-[#5A60F1]"}),"POC pricing"]}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Per-workplace Team Worker price during a POC. The paywall, the checkout and the monthly statement all follow it, and at the end date everything returns to the standard price",p?` (${ee(p)}/month)`:""," on its own."]})]}),e.jsxs(de,{className:"space-y-6",children:[e.jsxs("div",{className:"space-y-4 rounded-lg border bg-muted/20 p-4",children:[e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{htmlFor:"poc-new-workplace",className:"text-xs font-semibold uppercase tracking-wide text-muted-foreground",children:"Workplace"}),e.jsx("div",{className:"relative",children:w?e.jsxs("div",{className:"flex h-10 min-w-0 items-center gap-2 rounded-md border bg-background px-3",children:[e.jsx(Ze,{name:w.name,logoUrl:w.logo_url,size:"h-6 w-6"}),e.jsx("span",{className:"flex-1 truncate font-medium",children:w.name}),e.jsx("button",{type:"button",onClick:R,className:"shrink-0 text-muted-foreground hover:text-foreground","aria-label":"Clear workplace",children:e.jsx(Ut,{className:"h-4 w-4"})})]}):e.jsxs(e.Fragment,{children:[e.jsx(Wt,{className:"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground"}),e.jsx(V,{id:"poc-new-workplace",className:"h-10 w-full pl-9",placeholder:"Type a workplace name (e.g. CD PARTNRS)…",value:j,onChange:l=>v(l.target.value),autoComplete:"off"}),j.trim().length>=2&&e.jsxs("div",{className:"absolute z-20 mt-1 w-full overflow-hidden rounded-md border bg-popover shadow-md",children:[$&&f.length===0&&e.jsx("div",{className:"px-3 py-2 text-sm text-muted-foreground",children:"Searching…"}),!$&&f.length===0&&e.jsx("div",{className:"px-3 py-2 text-sm text-muted-foreground",children:_?"The search did not answer. Type again to retry.":"No open w
11orkplace with that name."}),f.map(l=>{const c=a.find(b=>b.workplace_id===l.id);return e.jsxs("button",{type:"button",className:"flex w-full items-center gap-2 px-3 py-2 text-left text-sm hover:bg-muted",onClick:()=>C(l),children:[e.jsx(Ze,{name:l.name,logoUrl:l.logo_url,size:"h-6 w-6"}),e.jsx("span",{className:"flex-1 truncate",children:l.name}),c&&e.jsx("span",{className:"shrink-0 text-xs text-muted-foreground",children:xe(c.expires_at,r)==="active"?"Has a POC, opens it":"Had a POC, opens it"})]},l.id)})]})]})})]}),e.jsx(St,{idPrefix:"poc-new",form:F,onChange:l=>{N(l),I(null)},errors:P.errors,original:null,standardPrice:p,now:r,disabled:z}),W.length>0&&e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-xs font-semibold uppercase tracking-wide text-muted-foreground",children:"What the customer gets"}),e.jsx(Ct,{phases:W,stacked:!0})]}),K&&e.jsx("p",{role:"alert",className:"rounded-md border border-destructive/40 bg-destructive/5 px-3 py-2 text-sm text-destructive",children:K}),e.jsxs("div",{className:"flex items-center justify-between gap-3 pt-1",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:w?P.ok?" ":"Fix the fields marked in red.":"Pick a workplace above to enable the button."}),e.jsx(E,{onClick:ue,disabled:!w||z||!P.ok,className:"h-10 shrink-0 px-6",children:z?e.jsx(M,{className:"h-4 w-4 animate-spin"}):"Set POC price"})]})]}),d?e.jsx("div",{className:"flex justify-center p-6",children:e.jsx(M,{className:"h-5 w-5 animate-spin text-muted-foreground"})}):h?e.jsxs("div",{role:"alert",className:"flex flex-wrap items-center justify-between gap-3 rounded-md border border-destructive/40 bg-destructive/5 px-3 py-2 text-sm text-destructive",children:[e.jsxs("span",{children:["The POC list could not be read (",h,")."]}),e.jsxs(E,{size:"sm",variant:"outline",onClick:()=>{m(!0),Y()},children:[e.jsx(gt,{className:"mr-1.5 h-3.5 w-3.5"}),"Try again"]})]}):a.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"No POC pricing set. The standard price applies everywhere."}):e.jsxs("div",{className:"space-y-4",children:[he.length>0&&e.jsxs("section",{className:"space-y-2",children:[e.jsxs("h3",{className:"text-xs font-semibold uppercase tracking-wide text-muted-foreground",children:["Active (",he.length,")"]}),e.jsx("ul",{className:"divide-y rounded-md border",children:he.map(re)})]}),me.length>0&&e.jsxs("section",{className:"space-y-2",children:[e.jsxs("h3",{className:"text-xs font-semibold uppercase tracking-wide text-muted-foreground",children:["Ended (",me.length,")"]}),e.jsx("ul",{className:"divide-y rounded-md border",children:me.map(re)})]})]})]}),x&&e.jsx(xs,{row:x,open:!0,onOpenChange:l=>{l||S(null)},api:s,standardPrice:p,onSaved:se,onStale:()=>{Y()}},x.id)]})};async function qe(s){const t=s==null?void 0:s.context;let a=null;return t&&typeof t.clone=="function"&&(a=await t.clone().json().catch(()=>null)),{message:(a==null?void 0:a.reason)||(a==null?void 0:a.message)||(a==null?void 0:a.error)||(s==null?void 0:s.message)||"Request failed",body:a}}const ys={none:"bg-gray-100 text-gray-700",active:"bg-green-100 text-green-800",warning:"bg-amber-100 text-amber-800",expired:"bg-red-100 text-red-800",restricted:"bg-red-200 text-red-900"},bs=()=>{var j;const{toast:s}=Ne(),[t,a]=i.useState(null),[n,d]=i.useState(!0),[m,h]=i.useState(""),[o,p]=i.useState(!1);i.useEffect(()=>{Lt().then(v=>a((v==null?void 0:v.license)??null)).finally(()=>d(!1))},[]);const g=async v=>{p(!0);try{const{data:f,error:y}=await H.functions.invoke("admin-set-license",{body:{token:v}});if(y)throw new Error((await qe(y)).message);if(f!=null&&f.error)throw new Error(f.reason||f.error);Rt(),a((f==null?void 0:f.license)??null),h(""),s({title:v?"License installed":"License cleared"})}catch(f){s({title:"License not applied",description:f.message,variant:"destructive"})}finally{p(!1)}};return e.jsxs(le,{children:[e.jsx(oe,{children:e.jsxs(ce,{className:"flex items-center gap-2",children:[e.jsx(Xt,{className:"h-5 w-5"})," Install license"]})}),e.jsxs(de,{className:"space-y-4",children:[n?e.jsx(M,{className:"h-4 w-4 animate-spin"}):!t||!t.customer?e.jsxs("p",{className:"text-sm text-muted-foreground",children:["No license on this installation. The SaaS runs without one; a dedicated or self-hosted installation needs one to enforce seats and Worker limits.",(t==null?void 0:t.error)&&e.jsxs("span",{className:"block text-red-700 mt-1",children:["A token is present but invalid: ",t.error]})]}):e.jsxs("div",{className:"grid grid-cols-2 gap-x-6 gap-y-1 text-sm",children:[e.jsx("span",{className:"text-muted-foreground",children:"Customer"}),e.jsx("span",{children:t.customer}),e.jsx("span",{className:"text-muted-foreground",children:"State"}),e.jsxs("span",{children:[e.jsx(ve,{className:ys[t.state],children:t.state}),typeof t.daysToExpiry=="number"&&e.jsxs("span",{className:"ml-2 text-muted-foreground",children:[t.daysToExpiry," days"]})]}),e.jsx("span",{className:"text-muted-foreground",children:"Seats"}),e.jsx("span",{children:t.seats?t.seats:"unlimited"}),e.jsx("span",{className:"text-muted-foreground",children:"Workers"}),e.jsx("span",{children:t.maxWorkers?t.maxWorkers:"unlimited"}),e.jsx("span",{className:"text-muted-foreground",children:"Expires"}),e.jsx("span",{children:(j=t.expiresAt)==null?void 0:j.slice(0,10)}),e.jsx("span",{className:"text-muted-foreground",children:"Profile"}),e.jsx("span",{children:t.profile}),t.disabledCapabilities&&t.disabledCapabilities.length>0&&e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"text-muted-foreground",children:"Disabled"}),e.jsx("span",{children:t.disabledCapabilities.join(", ")})]}),e.jsx("span",{className:"text-muted-foreground",children:"License id"}),e.jsx("span",{className:"font-mono text-xs",children:t.licenseId})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(Be,{value:m,onChange:v=>h(v.target.value),placeholder:"Paste a license token issued by Workait",rows:3,className:"font-mono text-xs"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(E,{onClick:()=>g(m),disabled:o||!m.trim(),children:o?e.jsx(M,{className:"h-4 w-4 animate-spin"}):"Install license"}),(t==null?void 0:t.customer)&&e.jsx(E,{variant:"outline",onClick:()=>g(null),disabled:o,children:"Clear"})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Expiry never stops running Workers: it warns 30 days ahead, then pauses invitations and new Workers, then pauses administration changes after a 14-day grace peri
11od."})]})]})]})},Ns=()=>{const{toast:s}=Ne(),{profile:t}=vt(),[a,n]=i.useState(""),[d,m]=i.useState(null),[h,o]=i.useState(!0),[p,g]=i.useState(!1),[j,v]=i.useState(null),f=jt("autoJoinWorkplace");i.useEffect(()=>{if(!f){o(!1);return}H.functions.invoke("admin-install-settings",{method:"GET"}).then(async({data:_,error:O})=>{var U;if(O){v((await qe(O)).message);return}const w=(U=_==null?void 0:_.settings)==null?void 0:U.auto_join_workplace_id;m(typeof w=="string"?w:null),n(typeof w=="string"?w:"")}).finally(()=>o(!1))},[]);const[y,$]=i.useState(void 0),A=async _=>{var O;g(!0);try{const{data:w,error:U}=await H.functions.invoke("admin-install-settings",{body:{key:"auto_join_workplace_id",value:_}});if(U)throw new Error((await qe(U)).message);const F=(O=w==null?void 0:w.settings)==null?void 0:O.auto_join_workplace_id;m(typeof F=="string"?F:null),n(typeof F=="string"?F:""),s({title:_?"Auto-join workplace set":"Auto-join cleared"})}catch(w){s({title:"Not saved",description:w.message,variant:"destructive"})}finally{g(!1),$(void 0)}};return f?e.jsxs(le,{children:[e.jsx(oe,{children:e.jsxs(ce,{className:"flex items-center gap-2",children:[e.jsx(qt,{className:"h-5 w-5"})," Install settings"]})}),e.jsxs(de,{className:"space-y-3",children:[j&&e.jsxs("p",{className:"text-sm text-red-700",children:["Could not load install settings: ",j]}),h?e.jsx(M,{className:"h-4 w-4 animate-spin"}):e.jsxs(e.Fragment,{children:[e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Auto-join workplace: every new sign-in on this installation joins this workplace as a member and skips the onboarding wizard.",d?e.jsxs("span",{className:"block font-mono text-xs mt-1",children:["current: ",d]}):e.jsx("span",{className:"block mt-1",children:"Not set (new users go through onboarding)."})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(V,{value:a,onChange:_=>n(_.target.value),placeholder:"workplace id (uuid)",className:"font-mono text-xs"}),e.jsx(E,{onClick:()=>$(a.trim()||null),disabled:p||!a.trim(),children:p?e.jsx(M,{className:"h-4 w-4 animate-spin"}):"Save"}),(t==null?void 0:t.current_workplace_id)&&e.jsx(E,{variant:"outline",onClick:()=>n(t.current_workplace_id),disabled:p,children:"Use my current workplace"}),d&&e.jsx(E,{variant:"ghost",onClick:()=>$(null),disabled:p,children:"Clear"})]})]})]}),e.jsx(et,{open:y!==void 0,onOpenChange:_=>{!_&&!p&&$(void 0)},title:y?"Send every new sign-in to this workplace?":"Stop the auto-join?",description:y?"Every NEW sign-in on this installation will join this workplace and skip onboarding. People who already have an account are not moved.":"New sign-ins will go through onboarding again. Nobody who already joined is removed.",confirmLabel:y?"Set auto-join":"Clear auto-join",busyLabel:"Saving…",busy:p,onConfirm:()=>A(y??null)})]}):null};function ks(s){const t=[];return s.voiceServiceReady||t.push("voice_service_off"),s.switchOn||t.push("switch_off"),s.workplaceAllowed||t.push("workplace_not_allowed"),s.status!=="active"&&t.push("paused"),s.inboundEnabled||t.push("inbound_off"),s.answeredByItsLine||t.push("not_assigned_at_vendor"),t}const _s={voice_service_off:"the voice service is not ready (see the top of this card)",switch_off:"phone lines are off (the switch at the top of this card)",workplace_not_allowed:"this workplace is not allowed to use phone lines yet",paused:"this number is paused",inbound_off:"incoming calls are turned off for this number",not_assigned_at_vendor:"the voice vendor does not send its calls to this Line (bind it again)"},Ss=[["en","English"],["fr","French"],["de","German"],["it","Italian"],["es","Spanish"]],we=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;async function Xe(s){const{data:t,error:a}=await H.functions.invoke("hello-line-admin",{body:s});if(a)throw new Error((await qe(a)).message);if(!t||t.ok!==!0)throw new Error((t==null?void 0:t.error)||"Request failed");return t}const Cs=()=>{const{toast:s}=Ne(),{profile:t}
11=vt(),a=jt("telephony"),[n,d]=i.useState(null),[m,h]=i.useState(!0),[o,p]=i.useState(null),[g,j]=i.useState(null),[v,f]=i.useState(null),[y,$]=i.useState(""),[A,_]=i.useState(null),[O,w]=i.useState([]),[U,F]=i.useState(""),[N,z]=i.useState("en"),[te,K]=i.useState(""),[I,x]=i.useState(null),S=i.useCallback(async()=>{h(!0),p(null);try{d(await Xe({action:"overview"}))}catch(r){p(r.message)}finally{h(!1)}},[]);i.useEffect(()=>{a?S():h(!1)},[a,S]);const T=async(r,P,W)=>{j(r);try{return await Xe(P),s({title:W}),await S(),!0}catch(Z){return s({title:"Not done",description:Z.message,variant:"destructive"}),!1}finally{j(null)}},L=r=>{var W,Z,R,C;f(r);const P=((W=r.line)==null?void 0:W.workplaceId)??(t==null?void 0:t.current_workplace_id)??"";$(P),_(null),w([]),F(((Z=r.line)==null?void 0:Z.workerId)??""),z(((R=r.line)==null?void 0:R.language)??"en"),K(((C=r.line)==null?void 0:C.greetingNote)??""),we.test(P)&&B(P)},B=async r=>{if(w([]),_(null),!!we.test(r))try{const P=await Xe({action:"workplace_workers",workplaceId:r});_(P.workplace.name),w(P.workers)}catch(P){_(null),s({title:"Workplace not found",description:P.message,variant:"destructive"})}},ne=async()=>{if(!(v!=null&&v.providerNumberId)||!we.test(y)||!we.test(U))return;await T(`bind:${v.e164}`,{action:"bind",providerNumberId:v.providerNumberId,workplaceId:y,workerId:U,language:N,greetingNote:te},"Number bound")&&f(null)};if(!a)return null;const Y=new Set(((n==null?void 0:n.allowedWorkplaceIds)??[]).map(r=>r.toLowerCase()));return e.jsxs(le,{children:[e.jsxs(oe,{children:[e.jsxs(ce,{className:"flex items-center gap-2",children:[e.jsx(Bt,{className:"h-5 w-5"})," Phone lines"]}),e.jsx(ge,{children:"A worker's own phone number: people call it and the worker answers, and a member can ask their worker to call their phone. Binding a number is one action; nothing is set by hand at the voice vendor."})]}),e.jsxs(de,{className:"space-y-4",children:[o&&e.jsxs("p",{className:"text-sm text-red-700",children:["Could not load the phone lines: ",o]}),m&&!n?e.jsx(M,{className:"h-4 w-4 animate-spin"}):n&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(st,{checked:n.switchOn,disabled:g!==null,onCheckedChange:r=>void T("switch",{action:"set_switch",enabled:r},r?"Phone lines are on":"Phone lines are off"),"aria-label":"Phone lines switch"}),e.jsx("span",{className:"text-sm font-medium",children:n.switchOn?"On":"Off"}),e.jsx("span",{className:"text-xs text-muted-foreground",children:"(the kill switch: off means no call is placed or answered, anywhere)"})]}),e.jsx(E,{variant:"ghost",size:"sm",onClick:()=>void S(),disabled:m,children:e.jsx(gt,{className:`h-4 w-4 ${m?"animate-spin":""}`})})]}),e.jsxs("div",{className:"flex flex-wrap gap-2 text-xs",children:[e.jsx(ve,{variant:n.vendorReachable?"secondary":"destructive",children:n.vendorReachable?"Voice vendor reachable":"Voice vendor not reachable"}),e.jsx(ve,{variant:n.ready.voiceService?"secondary":"destructive",children:n.ready.voiceService?"Voice service ready":"Voice service not configured"}),e.jsx(ve,{variant:"secondary",children:n.ready.endOfCallWebhook?"End-of-call webhook in place":"End-of-call webhook: created at the first binding"})]}),n.numbers.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"No number yet. Buy one at the carrier and import it at the voice vendor: it shows up here, ready to bind."}):e.jsx("div",{className:"space-y-3",children:n.numbers.map(r=>{var R;const P=!!r.line&&Y.has(r.line.workplaceId.toLowerCase()),W=r.line?ks({switchOn:n.switchOn,workplaceAllowed:P,status:r.status,inboundEnabled:r.line.inboundEnabled,answeredByItsLine:r.answeredByItsLine,voiceServiceReady:n.ready.voiceService}):[],Z=n.vendorReachable;return e.jsxs("div",{className:"rounded-md border p-3 space-y-2",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2",children:[e.jsxs("div",{children:[e.jsx("div",{className:"font-mono text-sm",children:at(r.e164)}),e.jsxs("div",{className:"text-xs text-muted-foreground",children:[r.line?e.jsxs(e.Fragment,{children:["Answered by ",e.jsx("strong",{children:r.line.workerName??r.line.workerId})," for ",e.jsx("strong",{children:r.line.workplaceName??r.line.workplaceId})," (",r.line.language,")"]}):"Not bound: nobody answers it",r.label?` · ${r.label}`:""]})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[r.line&&r.status==="paused"&&e.jsx(ve,{variant:"outline",children:"Paused"}),r.line&&!r.answeredByItsLine&&e.jsx(ve,{variant:"destructive",children:"Not answered by its Line at the vendor: bind again"}),e.jsx(E,{size:"sm",variant:"outline",onClick:()=>L(r),disabled:g!==null||!r.providerNumberId,children:r.line?"Change":"Bind…"}),r.line&&r.endpointId&&e.jsxs(e.Fragment,{children:[e.jsx(E,{size:"sm",variant:"ghost",disabled:g!==null,onClick:()=>void T(`pause:${r.e164}`,{action:"update",endpointId:r.endpointId,paused:r.status!=="paused"},r.status==="paused"?"Number resumed":"Number paused"),children:r.status==="paused"?"Resume":"Pause"}),e.jsx(E,{size:"sm",variant:"ghost",disabled:g!==null,onClick:()=>x(r),children:e.jsx(Ht,{className:"h-4 w-4"})})]})]})]}),r.line&&!Z&&W.length===0&&e.jsx("p",{className:"text-sm text-muted-foreground",children:"Cannot tell whether this number is answering: the voice vendor could not be reached. Reload in a moment."}),r.line&&Z&&W.length===0&&e.jsxs("p",{className:"text-sm text-emerald-700 dark:text-emerald-400",children:["Answering: someone who calls this number reaches ",r.line.workerName??"the worker","."]}),r.line&&e.jsx("p",{className:"text-xs text-muted-foreground",children:r.line.greetingNote?e.jsxs(e.Fragment,{children:["What ",r.line.workerName??"the worker",' may tell callers: "',r.line.greetingNote,'"']}):e.jsxs(e.Fragment,{children:["No note: ",r.line.workerName??"the worker"," knows only the name of ",r.line.workplaceName??"the workplace",' and offers to take a message for anything else. Add one with "Change".']})}),r.line&&W.length>0&&e.jsxs("div",{role:"alert",className:"rounded-md border border-destructive/40 bg-destructive/5 p-2 text-sm space-y-2",children:[e.jsxs("p",{children:[e.jsx("strong",{children:"Not answering."}
11),` Someone who calls this number hears "we can't take your call":`," ",W.map(C=>_s[C]).join("; "),"."]}),W.includes("workplace_not_allowed")&&e.jsxs(E,{size:"sm",disabled:g!==null,onClick:()=>void T(`allow:${r.e164}`,{action:"allow_workplace",workplaceId:r.line.workplaceId,allowed:!0},"Workplace allowed"),children:["Allow ",r.line.workplaceName??"this workplace"]})]}),r.line&&e.jsxs("div",{className:"flex items-center gap-2 text-xs",children:[e.jsx(st,{checked:P,disabled:g!==null,onCheckedChange:C=>void T(`allow:${r.e164}`,{action:"allow_workplace",workplaceId:r.line.workplaceId,allowed:C},C?"Workplace allowed":"Workplace no longer allowed"),"aria-label":"Allow this workplace to use phone lines"}),e.jsx("span",{children:P?"This workplace may use phone lines":"This workplace may not use phone lines yet"}),e.jsxs("span",{className:"text-muted-foreground",children:["· ",r.line.dailyMinuteCap," min a day, calls of ",Math.round(r.line.maxCallSeconds/60)," min at most"]})]}),(v==null?void 0:v.e164)===r.e164&&e.jsxs("div",{className:"rounded-md bg-muted/40 p-3 space-y-2",children:[e.jsxs("div",{className:"flex gap-2",children:[e.jsx(V,{value:y,onChange:C=>$(C.target.value.trim()),onBlur:()=>void B(y),placeholder:"workplace id (uuid)",className:"font-mono text-xs"}),(t==null?void 0:t.current_workplace_id)&&e.jsx(E,{variant:"outline",size:"sm",onClick:()=>{const C=t.current_workplace_id;$(C),B(C)},children:"My current workplace"})]}),A&&e.jsxs("p",{className:"text-xs text-muted-foreground",children:["Workplace: ",e.jsx("strong",{children:A})]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsxs(Ie,{value:U,onValueChange:F,disabled:O.length===0,children:[e.jsx(Ue,{className:"w-64",children:e.jsx(We,{placeholder:O.length?"Who answers this number":"Enter a workplace first"})}),e.jsx(Me,{children:O.map(C=>e.jsxs($e,{value:C.id,children:[C.name,C.role?` · ${C.role}`:""]},C.id))})]}),e.jsxs(Ie,{value:N,onValueChange:z,children:[e.jsx(Ue,{className:"w-40",children:e.jsx(We,{})}),e.jsx(Me,{children:Ss.map(([C,ue])=>e.jsx($e,{value:C,children:ue},C))})]})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsxs("label",{htmlFor:`note-${r.e164}`,className:"text-xs font-medium",children:["What ",((R=O.find(C=>C.id===U))==null?void 0:R.name)??"the worker"," may tell callers about ",A??"this workplace"]}),e.jsx(Be,{id:`note-${r.e164}`,value:te,onChange:C=>K(C.target.value),rows:3,maxLength:1200,placeholder:"What the team does, opening hours, where to write. Anything not written here, the worker says they don't know and offers to take a message."})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(E,{size:"sm",onClick:()=>void ne(),disabled:g!==null||!we.test(y)||!we.test(U),children:g===`bind:${r.e164}`?e.jsx(M,{className:"h-4 w-4 animate-spin"}):"Bind this number"}),e.jsx(E,{size:"sm",variant:"ghost",onClick:()=>f(null),disabled:g!==null,children:"Cancel"})]})]})]},r.e164)})})]})]}),e.jsx(et,{open:I!==null,onOpenChange:r=>{r||x(null)},title:"Unbind this number?",description:I?`Nobody will answer ${at(I.e164)} any more, and workers can no longer call from it. Its call history stays.`:"",confirmLabel:"Unbind",onConfirm:async()=>{const r=I;x(null),r!=null&&r.endpointId&&await T(`unbind:${r.e164}`,{action:"unbind",endpointId:r.endpointId},"Number unbound")}})]})};function Ls(){zt("System Settings");const{toast:s}=Ne(),{t}=Vt(),[a,n]=i.useState(!0),[d,m]=i.useState(!1),[h,o]=i.useState(!1),[p,g]=i.useState(5),[j,v]=i.useState(null),[f,y]=i.useState(4),[$,A]=i.useState(null),[_,O]=i.useState(89),[w,U]=i.useState(null),[F,N]=i.useState(!1),[z,te]=i.useState([]),[K,I]=i.useState(null),[x,S]=i.useState(""),[T,L]=i.useState(""),[B,ne]=i.useState(""),[Y,r]=i.useState(""),[P,W]=i.useState(""),[Z,R]=i.useState(""),[C,ue]=i.useState(!1),[se,he]=i.useState(null),[me,re]=i.useState(null);i.useEffect(()=>{l()},[]);const l=async()=>{try{n(!0);const{data:u,error:Q}=await H.from("system_config").select("*").in("key",["free_interactions_limit","human_to_worker_price_divider","min_worker_monthly_price"]);if(Q){console.error("Error fetching config:",Q);return}const{data:G}=await H.from("platform_prices").select("key, amount, currency, description").order("key");if(G&&te(G.map(q=>({key:q.key,amount:Number(q.amount),currency:q.currency,description:q.description??null}))),u)for(const q of u){const ze=typeof q.value=="string"?parseFloat(q.value):Number(q.value);switch(q.key){case"free_interactions_limit":v(q.id),g(ze||5);break;case"human_to_worker_price_divider":A(q.id),y(ze||4);break;case"min_worker_monthly_price":U(q.id),O(ze||89);break}}}catch(u){console.error("Error fetching system config:",u)}finally{n(!1)}},c=async()=>
11{if(j)try{m(!0);const{error:u}=await H.from("system_config").update({value:p.toString()}).eq("id",j);if(u){s({title:t("common.error","Error"),description:t("admin.settings.save_error","Failed to save settings. Please try again."),variant:"destructive"});return}s({title:t("common.success","Success"),description:t("admin.settings.save_success","Settings saved successfully.")})}catch(u){console.error("Error saving system config:",u),s({title:t("common.error","Error"),description:t("admin.settings.save_error","Failed to save settings. Please try again."),variant:"destructive"})}finally{m(!1)}},b=async()=>{if(w)try{N(!0);const{error:u}=await H.from("system_config").update({value:_.toString()}).eq("id",w);if(u){s({title:t("common.error","Error"),description:t("admin.settings.save_error","Failed to save settings. Please try again."),variant:"destructive"});return}s({title:t("common.success","Success"),description:"Minimum price saved successfully."})}catch(u){console.error("Error saving min price config:",u),s({title:t("common.error","Error"),description:t("admin.settings.save_error","Failed to save settings. Please try again."),variant:"destructive"})}finally{N(!1)}},ie=async()=>{if($)try{o(!0);const{error:u}=await H.from("system_config").update({value:f.toString()}).eq("id",$);if(u){s({title:t("common.error","Error"),description:t("admin.settings.save_error","Failed to save settings. Please try again."),variant:"destructive"});return}s({title:t("common.success","Success"),description:"Price divider saved successfully."})}catch(u){console.error("Error saving divider config:",u),s({title:t("common.error","Error"),description:t("admin.settings.save_error","Failed to save settings. Please try again."),variant:"destructive"})}finally{o(!1)}},je=async u=>{const Q=z.find(G=>G.key===u);if(!(!Q||!(Q.amount>0)))try{I(u);const{error:G}=await H.from("platform_prices").update({amount:Q.amount,updated_at:new Date().toISOString()}).eq("key",u);if(G){s({title:t("common.error","Error"),description:G.message,variant:"destructive"});return}s({title:t("common.success","Success"),description:`${u} saved.`})}catch(G){console.error("Error saving platform price:",G),s({title:t("common.error","Error"),description:t("admin.settings.save_error","Failed to save settings. Please try again."),variant:"destructive"})}finally{I(null)}},fe=async()=>{if(x.trim())try{ue(!0),he(null),re(null);const{data:u,error:Q}=await H.functions.invoke("suggest-worker-price",{body:{role:x,name:T||void 0,description:B||void 0,skills:Y?Y.split(",").map(G=>G.trim()).filter(Boolean):void 0,expertise:P||void 0,country_code:Z.trim().toUpperCase()||void 0}});if(Q){re(Q.message||"Failed to simulate pricing.");return}if(u!=null&&u.error){re(u.error);return}he(u)}catch(u){console.error("Simulation error:",u),re("An unexpected error occurred.")}finally{ue(!1)}};return e.jsx(Kt,{title:t("admin.settings.title","System Settings"),children:e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-6",children:[e.jsxs(le,{children:[e.jsxs(oe,{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Jt,{className:"h-5 w-5 text-muted-foreground"}),e.jsx(ce,{children:t("admin.settings.freemium.title","Freemium Settings")})]}),e.jsx(ge,{children:t("admin.settings.freemium.description","Configure the trial experience for new worker hires.")})]}),e.jsx(de,{className:"space-y-4",children:a?e.jsx("div",{className:"flex items-center justify-center py-8",children:e.jsx(M,{className:"h-6 w-6 animate-spin text-muted-foreground"})}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(X,{htmlFor:"free-interactions",children:t("admin.settings.freemium.interactions_label","Free Interactions Limit")}),e.jsx(V,{id:"free-interactions",type:"number",min:1,max:100,value:p,onChange:u=>g(Math.max(1,Math.min(100,parseInt(u.target.value,10)||1))),className:"w-32"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:t("admin.settings.freemium.interactions_description","Number of free user turns per worker per workplace before payment is required.")})]}),e.jsx(E,{onClick:c,disabled:d,children:d?e.jsxs(e.Fragment,{children:[e.jsx(M,{className:"mr-2 h-4 w-4 animate-spin"}),t("common.saving","Saving...")]}):e.jsxs(e.Fragment,{children:[e.jsx(ye,{className:"mr-2 h-4 w-4"}),t("common.save","Save")]})})]})})]}),e.jsxs(le,{children:[e.jsxs(oe,{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Qt,{className:"h-5 w-5 text-muted-foreground"}),e.jsx(ce,{children:"Pricing Settings"})]}),e.jsx(ge,{children:"Configure how AI-suggested worker prices are calculated relative to human-equivalent salaries."})]}),e.jsx(de,{className:"space-y-4",children:a?e.jsx("div",{className:"flex items-center justify-center py-8",children:e.jsx(M,{className:"h-6 w-6 animate-spin text-muted-foreground"})}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(X,{htmlFor:"price-divider",children:"Human-to-Worker Price Divider"}),e.jsx(V,{id:"price-divider",type:"number",min:1,max:100,step:.5,value:f,onChange:u=>y(Math.max(1,parseFloat(u.target.value)||4)),className:"w-32"}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["The AI estimates a human-equivalent monthly salary, then divides it by this number to get the suggested worker price. Currently set to ",e.jsxs("strong",{children:[f,"×"]})," — a $4,000/month human equivalent would suggest a ",e.jsxs("strong",{children:["$",Math.round(4e3/f),"/month"]})," worker price."]})]}),e.jsx(E,{onClick:ie,disabled:h,children:h?e.jsxs(e.Fragment,{children:[e.jsx(M,{className:"mr-2 h-4 w-4 animate-spin"}),t("common.saving","Saving...")]}):e.jsxs(e.Fragment,{children:[e.jsx(ye,{className:"mr-2 h-4 w-4"}),t("common.save","Save")]})})]})})]}),e.jsxs(le,{children:[e.jsxs(oe,{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(es,{className:"h-5 w-5 text-muted-foreground"}),e.jsx(ce,{children:"Pricing Floor"})]}),e.jsx(ge,{children:"Set the minimum monthly price any worker can be listed for on the marketplace."})]}),e.jsx(de,{className:"space-y-4",children:a?e.jsx("div",{className:"flex items-center justify-center py-8",children:e.jsx(M,{className:"h-6 w-6 animate-spin text-muted-foreground"})}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(X,{htmlFor:"min-price",children:"Minimum Worker Monthly Price (USD)"}),e.jsx(V,{id:"min-price",type:"number",min:1,max:9999,step:1,value:_,onCh
11ange:u=>O(Math.max(1,parseInt(u.target.value,10)||89)),className:"w-32"}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Any creator trying to set a price below this threshold will be blocked. Currently: ",e.jsxs("strong",{children:["$",_,"/month"]})," minimum."]})]}),e.jsx(E,{onClick:b,disabled:F,children:F?e.jsxs(e.Fragment,{children:[e.jsx(M,{className:"mr-2 h-4 w-4 animate-spin"}),t("common.saving","Saving...")]}):e.jsxs(e.Fragment,{children:[e.jsx(ye,{className:"mr-2 h-4 w-4"}),t("common.save","Save")]})})]})})]}),e.jsxs(le,{children:[e.jsxs(oe,{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Yt,{className:"h-5 w-5 text-muted-foreground"}),e.jsx(ce,{children:"Platform Prices"})]}),e.jsx(ge,{children:"Flat platform-level amounts (USD, geo-converted at display). The Team Worker monthly fee shown on the publish pop-up and the team paywall lives here."})]}),e.jsx(de,{className:"space-y-4",children:a?e.jsx("div",{className:"flex items-center justify-center py-8",children:e.jsx(M,{className:"h-6 w-6 animate-spin text-muted-foreground"})}):z.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"No platform prices found. Paste the platform_prices superadmin-write migration and reload."}):z.map(u=>e.jsxs("div",{className:"space-y-2 border-b last:border-b-0 pb-4 last:pb-0",children:[e.jsx(X,{htmlFor:`price-${u.key}`,children:u.key}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-muted-foreground",children:"$"}),e.jsx(V,{id:`price-${u.key}`,type:"number",min:1,max:99999,step:1,value:u.amount,onChange:Q=>te(G=>G.map(q=>q.key===u.key?{...q,amount:Math.max(0,parseFloat(Q.target.value)||0)}:q)),className:"w-32"}),e.jsxs("span",{className:"text-muted-foreground text-sm",children:["/month · ",u.currency]}),e.jsx(E,{size:"sm",onClick:()=>je(u.key),disabled:K===u.key||!(u.amount>0),children:K===u.key?e.jsxs(e.Fragment,{children:[e.jsx(M,{className:"mr-2 h-4 w-4 animate-spin"}),t("common.saving","Saving...")]}):e.jsxs(e.Fragment,{children:[e.jsx(ye,{className:"mr-2 h-4 w-4"}),t("common.save","Save")]})})]}),u.description&&e.jsx("p",{className:"text-sm text-muted-foreground",children:u.description})]},u.key))})]}),e.jsx(bs,{}),e.jsx(Ns,{}),e.jsx(Cs,{}),e.jsx(ss,{}),e.jsx(ws,{}),e.jsxs(le,{children:[e.jsxs(oe,{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(rt,{className:"h-5 w-5 text-muted-foreground"}),e.jsx(ce,{children:"Pricing Simulator"})]}),e.jsx(ge,{children:"Test the AI pricing engine. Enter a role to estimate the human-equivalent salary and AI worker price."})]}),e.jsxs(de,{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(X,{htmlFor:"sim-role",children:"Role *"}),e.jsx(V,{id:"sim-role",placeholder:"e.g. Senior Software Engineer",value:x,onChange:u=>S(u.target.value)})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(X,{htmlFor:"sim-name",children:"Name"}),e.jsx(V,{id:"sim-name",placeholder:"e.g. CodeBot",value:T,onChange:u=>L(u.target.value)})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(X,{htmlFor:"sim-description",children:"Description"}),e.jsx(Be,{id:"sim-description",placeholder:"Free text description...",value:B,onChange:u=>
11ne(u.target.value),className:"min-h-[60px]"})]}),e.jsxs("div",{className:"grid grid-cols-3 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(X,{htmlFor:"sim-skills",children:"Skills"}),e.jsx(V,{id:"sim-skills",placeholder:"comma-separated",value:Y,onChange:u=>r(u.target.value)})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(X,{htmlFor:"sim-expertise",children:"Expertise"}),e.jsx(V,{id:"sim-expertise",placeholder:"e.g. Machine Learning",value:P,onChange:u=>W(u.target.value)})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(X,{htmlFor:"sim-country",children:"Country Code"}),e.jsx(V,{id:"sim-country",placeholder:"e.g. FR, IN, US",value:Z,onChange:u=>R(u.target.value),maxLength:2})]})]}),e.jsx(E,{onClick:fe,disabled:C||!x.trim(),children:C?e.jsxs(e.Fragment,{children:[e.jsx(M,{className:"mr-2 h-4 w-4 animate-spin"}),"Simulating..."]}):e.jsxs(e.Fragment,{children:[e.jsx(rt,{className:"mr-2 h-4 w-4"}),"Simulate"]})}),me&&e.jsx("div",{className:"rounded-md bg-destructive/10 p-3 text-sm text-destructive",children:me}),se&&e.jsxs("div",{className:"rounded-md border bg-muted/50 p-4 space-y-2",children:[se.detectedCountry&&e.jsxs("div",{className:"flex justify-between text-sm",children:[e.jsx("span",{className:"text-muted-foreground",children:"Detected Country"}),e.jsxs("span",{className:"font-semibold",children:[se.detectedCountry," (",se.currency,")"]})]}),e.jsxs("div",{className:"flex justify-between text-sm",children:[e.jsx("span",{className:"text-muted-foreground",children:"Human Equivalent Salary (USD)"}),e.jsxs("span",{className:"font-semibold",children:["$",nt(se.humanEquivalent),"/month"]})]}),e.jsxs("div",{className:"flex justify-between text-sm",children:[e.jsx("span",{className:"text-muted-foreground",children:"Divider used"}),e.jsxs("span",{className:"font-semibold",children:[se.divider,"×"]})]}),e.jsx("hr",{className:"border-border"}),e.jsxs("div",{className:"flex justify-between text-sm",children:[e.jsx("span",{className:"text-muted-foreground",children:"AI Worker Price"}),e.jsxs("span",{className:"font-semibold text-primary",children:["$",nt(se.suggestedPrice),"/month"," ","| $",Gt(se.suggestedPrice)??"—","/day"]})]})]})]})]})]})})}export{Ls as default};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.