1"use strict";(globalThis.webpackChunkhalcyon_placement_app=globalThis.webpackChunkhalcyon_placement_app||[]).push([[7368],{1021(e,t,a){a.d(t,{m3:()=>n});var r=a(65043),s=a(70579);function n(e){if(null==e)return"";if("string"===typeof e)return e;if("number"===typeof e||"boolean"===typeof e)return String(e);if("object"===typeof e&&!Array.isArray(e)&&e.target&&"object"===typeof e.target){const t=e.target.value;return null==t||"object"===typeof t?"":String(t)}return""}const i=(0,r.memo)(function(e){var t;let{label:a,options:n,value:i,onChange:l,width:o=160,placeholder:c,searchable:d=!1,disabled:h=!1,className:u="",buttonStyle:m}=e;const[p,f]=(0,r.useState)(!1),[y,g]=(0,r.useState)(""),b=(0,r.useRef)(null);(0,r.useEffect)(()=>{const e=e=>{b.current&&!b.current.contains(e.target)&&(f(!1),g(""))};return document.addEventListener("mousedown",e),()=>document.removeEventListener("mousedown",e)},[]);const x=(0,r.useMemo)(()=>n.map(e=>"string"===typeof e?{value:e,label:e}:e),[n]),v=(null===(t=x.find(e=>String(e.value)===String(i)))||void 0===t?void 0:t.label)||c||a||"Select...",w=""!==i&&void 0!==i&&null!==i,j=d&&y.trim()?x.filter(e=>String(e.label).toLowerCase().includes(y.trim().toLowerCase())):x,S=(0,r.useRef)(null),[k,_]=(0,r.useState)({top:0,left:0,width:0,maxH:300,openUp:!1});return(0,s.jsxs)("div",{ref:b,style:{position:"relative",minWidth:o},children:[(0,s.jsxs)("button",{ref:S,onClick:()=>{if(!h){if(!p&&S.current){const e=S.current.getBoundingClientRect(),t=300,a=window.innerHeight-e.bottom-8,r=e.top-8;if(a<Math.min(t,200)&&r>a){const a=Math.max(120,Math.min(t,r));_({top:e.top-4-a,left:e.left,width:e.width,maxH:a,openUp:!0})}else{const r=Math.max(120,Math.min(t,a));_({top:e.bottom+4,left:e.left,width:e.width,maxH:r,openUp:!1})}}p&&g(""),f(!p)}},disabled:h,className:u,style:{width:"100%",padding:"8px 12px",fontSize:13,textAlign:"left",cursor:h?"not-allowed":"pointer",background:"var(--surface)",border:"1px solid var(--border)",borderRadius:6,display:"flex",justifyContent:"space-between",alignItems:"center",color:w?"var(--text)":"var(--text-muted)",fontWeight:w?500:400,opacity:h?.6:1,...m||{}},children:[(0,s.jsx)("span",{style:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:v}),(0,s.jsx)("span",{style:{fontSize:10,color:"var(--text-faint)",transform:p?"rotate(180deg)":"rotate(0)",transition:"transform 0.2s"},children:"\u25bc"})]}),p&&(0,s.jsxs)("div",{style:{position:"fixed",top:k.top,left:k.left,width:k.width,zIndex:9999,background:"var(--surface)",border:"1px solid var(--border)",borderRadius:8,boxShadow:"var(--shadow-dropdown)",maxHeight:k.maxH||300,overflow:"auto"},children:[d&&(0,s.jsx)("div",{style:{position:"sticky",top:0,padding:6,background:"var(--surface)",borderBottom:"1px solid var(--border-light, #e5e7eb)"},children:(0,s.jsx)("input",{autoFocus:!0,"aria-label":"Search options",value:y,onChange:e=>g(e.target.value),onClick:e=>e.stopPropagation(),placeholder:"Search\u2026",style:{width:"100%",padding:"6px 8px",fontSize:13,border:"1px solid var(--border)",borderRadius:6,boxSizing:"border-box",background:"var(--bg)",color:"var(--text)"}})}),c&&!y.trim()&&(0,s.jsx)("div",{onClick:()=>{l({target:{value:""}}),f(!1),g("")},style:{padding:"8px 12px",fontSize:13,cursor:"pointer",background:w?"transparent":"var(--bg-selected)",color:"var(--text-faint)",fontStyle:"italic"},onMouseEnter:e=>e.currentTarget.style.background="var(--bg-hover)",onMouseLeave:e=>e.currentTarget.style.background=w?"transparent":"var(--bg-selected)",children:c}),0===j.length&&(0,s.jsx)("div",{style:{padding:"8px 12px",fontSize:12,color:"var(--text-faint)",fontStyle:"italic"},children:"No matches"}),j.map(e=>{const t=String(e.value)===String(i);return(0,s.jsxs)("div",{onClick:()=>{l({target:{value:e.value}}),f(!1),g("")},style:{padding:"8px 12px",fontSize:13,cursor:"pointer",background:t?"var(--bg-selected)":"transparent",color:"var(--text-dark)",display:"flex",alignItems:"center",gap:8,fontWeight:t?600:400},onMouseEnter:e=>e.currentTarget.style.background="var(--bg-hover)",onMouseLeave:e=>e.currentTarget.style.background=t?"var(--bg-selected)":"transparent",children:[(0,s.jsx)("span",{style:{width:16,height:16,borderRadius:8,border:"1.5px solid var(--border)",display:"flex",alignItems:"center",justifyContent:"center",background:t?"var(--navy)":"var(--surface)"},children:t&&(0,s.jsx)("span",{style:{width:6,height:6,borderRadius:3,background:"#fff"}})}),e.label]},e.value)})]})]})}),l=(0,r.memo)(function(e){let{label:t="",options:a,selected:n,onChange:i,width:l=200}=e;const[o,c]=(0,r.useState)(!1),[d,h]=(0,r.useState)(""),u=(0,r.useRef)(null);(0,r.useEffect)(()=>{const e=e=>{u.current&&!u.current.contains(e.target)&&c(!1)};return document.addEventListener("mousedown",e),()=>document.removeEventListener("mousedown",e)},[]);const m=(0,r.useMemo)(()=>(Array.isArray(a)?a:[]).filter(e=>null!=e).map(e=>String(e)),[a]),p=(0,r.useMemo)(()=>n instanceof Set?n:Array.isArray(n)?new Set(n):new Set,[n]),f=(0,r.useMemo)(()=>d?m.filter(e=>e.toLowerCase().includes(d.toLowerCase())):m,[m,d]),y=0===p.size||p.size===m.length,g=y?t?`All ${t}`:"All":1===p.size?[...p][0]:t?`${p.size} ${t}`:`${p.size} selected`,b=(0,r.useRef)(null),[x,v]=(0,r.useState)({top:0,left:0,width:0,maxH:300,openUp:!1}),w=(0,r.useCallback)(e=>i(Array.from(e)),[i]),j=(0,r.useCallback)(()=>w(y?new Set:new Set(m)),[y,w,m]),S=(0,r.useCallback)(e=>{const t=new Set(p);t.has(e)?t.delete(e):t.add(e),w(t)},[p,w]);return(0,s.jsxs)("div",{ref:u,style:{position:"relative",minWidth:l},children:[(0,s.jsxs)("button",{ref:b,onClick:()=>
1{if(!o&&b.current){const e=b.current.getBoundingClientRect(),t=300,a=window.innerHeight-e.bottom-8,r=e.top-8;if(a<Math.min(t,200)&&r>a){const a=Math.max(140,Math.min(t,r));v({top:e.top-4-a,left:e.left,width:e.width,maxH:a,openUp:!0})}else{const r=Math.max(140,Math.min(t,a));v({top:e.bottom+4,left:e.left,width:e.width,maxH:r,openUp:!1})}}c(!o),h("")},style:{width:"100%",padding:"8px 12px",fontSize:13,textAlign:"left",cursor:"pointer",background:"var(--surface)",border:"1px solid var(--border)",borderRadius:6,display:"flex",justifyContent:"space-between",alignItems:"center",color:y?"var(--text-muted)":"var(--text)",fontWeight:y?400:500},children:[(0,s.jsx)("span",{style:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:g}),(0,s.jsx)("span",{style:{fontSize:10,color:"var(--text-faint)",transform:o?"rotate(180deg)":"rotate(0)",transition:"transform 0.2s"},children:"\u25bc"})]}),o&&(0,s.jsxs)("div",{style:{position:"fixed",top:x.top,left:x.left,width:x.width,zIndex:9999,background:"var(--surface)",border:"1px solid var(--border)",borderRadius:8,boxShadow:"var(--shadow-dropdown)",maxHeight:300,display:"flex",flexDirection:"column"},children:[m.length>6&&(0,s.jsx)("div",{style:{padding:"8px 8px 4px"},children:(0,s.jsx)("input",{placeholder:t?`Search ${t.toLowerCase()}...`:"Search...",value:d,onChange:e=>h(e.target.value),autoFocus:!0,style:{width:"100%",padding:"6px 10px",fontSize:12,border:"1px solid var(--border-light)",borderRadius:4,boxSizing:"border-box"}})}),(0,s.jsx)("div",{style:{padding:"4px 8px",borderBottom:"1px solid var(--border-lighter)",display:"flex",gap:8},children:(0,s.jsx)("button",{onClick:j,style:{fontSize:11,color:"var(--blue)",background:"none",border:"none",cursor:"pointer",padding:0},children:y?"Clear All":"Select All"})}),(0,s.jsxs)("div",{style:{overflowY:"auto",maxHeight:220},children:[f.map(e=>{const t=p.has(e)||0===p.size;return(0,s.jsxs)("div",{onClick:()=>S(e),style:{padding:"6px 12px",fontSize:12,cursor:"pointer",background:t&&p.size>0?"var(--bg-selected)":"transparent",color:"var(--text-dark)",display:"flex",alignItems:"center",gap:8},onMouseEnter:e=>e.currentTarget.style.background="var(--bg-hover)",onMouseLeave:e=>e.currentTarget.style.background=t&&p.size>0?"var(--bg-selected)":"transparent",children:[(0,s.jsx)("span",{style:{width:16,height:16,borderRadius:3,border:"1.5px solid var(--border)",display:"flex",alignItems:"center",justifyContent:"center",background:t&&p.size>0?"var(--navy)":"var(--surface)",color:"#fff",fontSize:11,fontWeight:700},children:t&&p.size>0?"\u2713":""}),e]},e)}),0===f.length&&(0,s.jsx)("div",{style:{padding:12,color:"var(--text-faint)",fontSize:12,textAlign:"center"},children:"No matches"})]})]})]})});a.d(t,["KF",0,l,"Z",0,i])},92751(e,t,a){function r(e){return String(e||"").normalize("NFKD").replace(/[\u0300-\u036f]/g,"").toLowerCase().replace(/[\u2018\u2019\u02bb`\xb4']/g,"").replace(/\s+/g," ").trim()}a.d(t,{oS:()=>n,vz:()=>r});const s={"prime healthcare foundation, inc.":"Prime Healthcare Foundation",prime:"Prime Healthcare Foundation"};function n(e,t){var a;let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},l=arguments.length>4&&void 0!==arguments[4]?arguments[4]:"";const o=r(t),c=null!==(a=null!==e&&void 0!==e?e:i[o])&&void 0!==a?a:null;if(null!=c&&n[c])return n[c];const d=s[String(l||"").toLowerCase().trim()];return d||"\u2014"}},7368(e,t,a){a.r(t),a.d(t,{default:()=>v});var r=a(65043),s=a(85843),n=a(66280),i=a(1021),l=a(35824),o=a(28300),c=a(92751),d=(a(99533),a(13829)),h=a(65250),u=a(86013),m=a(70579);const p="true"==="True".toLowerCase(),f="\u2014",y="historical-linker";function g(e){const t=String(e||"").trim();return t?/per\s*diem|registry|\blta\b/i.test(t)?{label:"Per Diem",color:"#0a9060"}:/school/i.test(t)?{label:"School",color:"#7c3aed"}:{label:"Travel",color:"#1B4F8A"}:{label:f,color:"var(--text-muted)"}}function b(e){return(e||"").toLowerCase().replace(/\(.*?\)/g," ").replace(/[^a-z0-9]+/g," ").replace(/\s+/g," ").trim()}function x(e,t){switch(t){case"candidate":return(e.placement_name||"").toLowerCase();case"facility":return(e.facility_name||"").toLowerCase();case"system":return(e.healthcare_system||"").toLowerCase();case"start":return e.start_date?new Date(e.start_date).getTime():0;
1case"skillset":return(e.skillset||"").toLowerCase();case"type":{const t=g(e.assignment_type).label;return t===f?"":t}default:return""}}function v(){const[e,t]=(0,r.useState)([]),[a,v]=(0,r.useState)([]),[w,j]=(0,r.useState)({}),[S,k]=(0,r.useState)(!0),[_,C]=(0,r.useState)(""),[z,$]=(0,r.useState)(""),[L,M]=(0,r.useState)(""),[N,A]=(0,r.useState)(""),[E,R]=(0,r.useState)(""),[T,F]=(0,r.useState)(""),[W,B]=(0,r.useState)("facility"),[I,H]=(0,r.useState)("asc"),[P,U]=(0,r.useState)(null),[q,O]=(0,r.useState)(0),[Z,D]=(0,r.useState)(0),[K,Y]=(0,r.useState)(0),G=p&&!(0,s.$y)(),[J,Q]=(0,r.useState)(()=>new Set),[V,X]=(0,r.useState)(""),[ee,te]=(0,r.useState)(!1),[ae,re]=(0,r.useState)(null);(0,r.useEffect)(()=>{let e=!1;return(async()=>{k(!0),C("");try{const a=async()=>{let e=[],t=0;const a=1e3;for(;;){const{data:r,error:n}=await s.supabase.from("placements").select("id, placement_name, facility_name, healthcare_system, system_id, start_date, skillset, assignment_type, status").is("job_order_id",null).order("facility_name",{ascending:!0}).range(t,t+a-1);if(n)throw n;if(e=e.concat(r||[]),!r||r.length<a)break;t+=a}return e},[r,n,i,d]=await Promise.all([a(),(0,l.OW)(),s.supabase.from("facilities").select("facility_name, healthcare_system, system_id"),(0,o.Ah)().catch(()=>[])]);if(e)return;const h=r.filter(e=>"deleted"!==(e.status||"").toLowerCase()),u={},m={};(d||[]).forEach(e=>{e&&null!=e.id&&e.name&&(m[String(e.id)]=e.name)});const p={};(i.data||[]).forEach(e=>{e.facility_name&&(u[e.facility_name.trim().toLowerCase()]=(e.healthcare_system||"").trim(),null!=e.system_id&&(p[(0,c.vz)(e.facility_name)]=e.system_id))});const f=h.map(e=>{const t=(0,c.oS)(e.system_id,e.facility_name,m,p,e.healthcare_system);return{...e,_canonSystem:"\u2014"!==t?t:e.healthcare_system||""}});t(f),v(n||[]),j(u)}catch(a){e||C(a.message||"Failed to load placements / job orders")}finally{e||k(!1)}})(),()=>{e=!0}},[K]),(0,r.useEffect)(()=>{D(0)},[L,N,E,T,W,I]);const se=(0,r.useMemo)(()=>[...new Set(Object.values(w).filter(Boolean))].sort((e,t)=>t.length-e.length),[w]),ne=e=>{const t=(e.facilityName||"").trim().toLowerCase();if(w[t])return w[t];for(const a of se)if(a&&t.includes(a.toLowerCase()))return a;return e.healthcareSystem||""},{jobsByNormFac:ie,jobsBySystem:le}=(0,r.useMemo)(()=>{const e={},t={};for(const r of a){const a=b(r.facilityName);a&&(e[a]=e[a]||[]).push(r);const s=ne(r).trim().toLowerCase();s&&(t[s]=t[s]||[]).push(r)}return{jobsByNormFac:e,jobsBySystem:t}},[a,w]),oe=e=>{const t=b(e.facility_name),a=(e.healthcare_system||w[(e.facility_name||"").trim().toLowerCase()]||"").trim().toLowerCase();let r=ie[t]||[],s=!1;0===r.length&&a&&(r=le[a]||[],s=!0);const n=new Set,i=[];for(const l of r){if(n.has(l.id))continue;n.add(l.id);const e=l.specialtyUnit||l.skillset||l.title||f,t=`${l.jobNumber||l.id} \xb7 ${e}`+(s?` \xb7 ${l.facilityName||""}`:"")+(l.status?` (${l.status})`:"");i.push({value:String(l.id),label:t})}return i},ce=(0,r.useMemo)(()=>[...new Set(e.map(e=>e.facility_name).filter(Boolean))].sort(),[e]),de=(0,r.useMemo)(()=>[...new Set(e.map(e=>e._canonSystem).filter(Boolean))].sort(),[e]),he=(0,r.useMemo)(()=>[...new Set(e.map(e=>g(e.assignment_type).label).filter(e=>e&&e!==f))].sort(),[e]),ue=(0,r.useMemo)(()=>{const t=L.trim().toLowerCase(),a="desc"===I?-1:1;return e.filter(e=>{if(N&&e.facility_name!==N)return!1;if(E&&e._canonSystem!==E)return!1;if(T&&g(e.assignment_type).label!==T)return!1;if(t){if(![e.placement_name,e.facility_name,e.healthcare_system,e.skillset,e.assignment_type].filter(Boolean).join(" ").toLowerCase().includes(t))return!1}return!0}).sort((e,t)=>((e,t)=>{const r=x(e,W),s=x(t,W),n=""===r||0===r,i=""===s||0===s;return n&&i?0:n?1:i?-1:("number"===typeof r&&"number"===typeof s?r-s:String(r).localeCompare(String(s)))*a})(e,t)||(e.facility_name||"").localeCompare(t.facility_name||"")||(e.placement_name||"").localeCompare(t.placement_name||""))},[e,L,N,E,T,W,I]),me=Math.max(1,Math.ceil(ue.length/50)),pe=Math.min(Z,me-1),fe=ue.slice(50*pe,50*(pe+1)),ye=()=>{Q(new Set),X("")},ge=fe.length>0&&fe.every(e=>J.has(e.id)),be=e.filter(e=>J.has(e.id)),xe=(()=>{const e=new Set,t=[];for(const a of be)for(const r of oe(a))e.has(r.value)||(e.add(r.value),t.push(r));return t})(),ve=new Set(be.map(e=>e.facility_name||"")).size,we=async(e,t)=>{const a=(e=>[(e.facility_name||"").trim().toLowerCase(),(e.healthcare_system||"").trim().toLowerCase(),(e.skillset||"").trim().toLowerCase(),(e.assignment_type||"").trim().toLowerCase()].join("\xa6"))(e);if(t.has(a))return t.get(a);const r=e.facility_name||null,n=e.healthcare_system||null,i=e.skillset||null,l=e.assignment_type||null;let o=s.supabase.from("job_orders").select("id").eq("source",y).is("deleted_at",null);o=r?o.eq("facility_name",r):o.is("facility_name",null),o=n?o.eq("healthcare_system",n):o.is("healthcare_system",null),o=i?o.eq("skillset",i):o.is("skillset",null),o=l?o.eq("assignment_type",l):o.is("assignment_type",null);const{data:c,error:d}=await o.limit(1);if(d)throw d;if(c&&c.length>0)return t.set(a,c[0].id),c[0].id;const h=`Historical reference \u2014 ${i||"Unspecified"} \xb7 ${g(l).label}`,{data:u,error:m}=await s.supabase.from("job_orders").insert([{facility_name:r,healthcare_system:n,skillset:i,assignment_type:l,bill_rate:0,pay_rate:0,openings:0,status:"Closed",source:y,title:h}]).select("id").single();if(m)throw m;return t.set(a,u.id),u.id},je=(e,t,a)=>{const r=W===e,s=r?"asc"===I?"\u25b2":"\u25bc":"\u2195";return(0,m.jsxs)("th",{onClick:()=>(e=>{W===e?H(e=>"asc"===e?"desc":"asc"):(B(e),H("asc"))})(e),style:{cursor:"pointer",userSelect:"none",whiteSpace:"nowrap",...a},title:`Sort by ${t}`,"aria-sort":r?"asc"===I?"ascending":"descending":"none",children:[t,(0,m.jsx)("span",{style:{marginLeft:5,fontSize:10,
1color:r?"var(--primary)":"var(--text-muted)",opacity:r?1:.45},children:s})]})};return(0,m.jsxs)("div",{"data-testid":"placement-linker-panel",children:[(0,m.jsx)("h3",{className:"admin-panel-title",children:"Placement Linker"}),(0,m.jsxs)("p",{className:"admin-panel-desc",children:["Placements with no ",(0,m.jsx)("code",{children:"job_order_id"})," (the ones the backfill couldn't auto-match). Filter by facility or system, then pick the job order each placement filled. The picker shows job orders at that facility (names normalized), falling back to same-system jobs when the facility has none of its own. Each link improves the Exec Dashboard ",(0,m.jsx)("strong",{children:"Fill Rate"}),". Old placements with no real job order can be bulk-marked as a"," ",(0,m.jsx)("strong",{children:"historical reference (bill $0)"})," \u2014 they link to a closed, $0 synthetic job order and drop off this list without touching any bill/pay-rate or fill-rate statistic."]}),(0,m.jsxs)("div",{className:"dash-kpi-row",style:{marginBottom:16},children:[(0,m.jsx)(n.p,{label:"Unlinked placements",value:e.length,color:"#a16207",sub:"job_order_id is null"}),(0,m.jsx)(n.p,{label:"Facilities affected",value:ce.length,color:"#1B4F8A",sub:"distinct facilities"}),(0,m.jsx)(n.p,{label:"Linked this session",value:q,color:"#16a34a",sub:1===q?"1 placement":`${q} placements`})]}),(0,m.jsx)(h.Wu,{message:z}),(0,m.jsx)("div",{style:h.mw,children:(0,m.jsxs)("div",{className:"filter-bar",style:{display:"flex",gap:10,alignItems:"center",flexWrap:"wrap"},children:[(0,m.jsx)("input",{className:"field-input",type:"text",placeholder:"Search candidate, facility, system, skillset...",value:L,onChange:e=>M(e.target.value),style:{minWidth:260,maxWidth:420,flex:"1 1 260px"}}),(0,m.jsx)(i.Z,{label:"Facility",options:ce,value:N,onChange:e=>A(e.target.value),placeholder:"All facilities",searchable:!0}),(0,m.jsx)(i.Z,{label:"System",options:de,value:E,onChange:e=>R(e.target.value),placeholder:"All systems",searchable:!0}),(0,m.jsx)(i.Z,{label:"Type",options:he,value:T,onChange:e=>F(e.target.value),placeholder:"All types"}),(0,m.jsxs)("div",{style:{marginLeft:"auto",display:"flex",gap:8},children:[(L||N||E||T)&&(0,m.jsx)("button",{className:"btn-secondary",onClick:()=>{M(""),A(""),R(""),F("")},children:"Clear filters"}),(0,m.jsx)("button",{className:"btn-secondary",onClick:()=>Y(e=>e+1),disabled:S,children:S?"Loading...":"Reload"})]})]})}),J.size>0&&(0,m.jsxs)("div",{style:{...h.mw,borderColor:"var(--primary)",background:"var(--bg-info-subtle, #eff6ff)"},children:[(0,m.jsxs)("div",{style:{display:"flex",gap:10,alignItems:"center",flexWrap:"wrap"},children:[(0,m.jsxs)("span",{style:{fontWeight:700,color:"var(--primary)"},children:[J.size," selected"]}),ve>1&&(0,m.jsxs)("span",{style:{fontSize:12,color:"var(--error)"},children:["across ",ve," facilities \u2014 make sure they all filled this job order"]}),J.size<ue.length&&(0,m.jsxs)("button",{className:"btn-secondary",onClick:()=>Q(new Set(ue.map(e=>e.id))),children:["Select all ",ue.length," filtered"]}),(0,m.jsx)("div",{style:{flex:1,minWidth:220,maxWidth:460},children:(0,m.jsx)(i.Z,{options:xe,value:V,onChange:e=>X(e.target.value),placeholder:xe.length?`Pick 1 of ${xe.length} job orders\u2026`:"No job orders for this selection",searchable:!0,width:"100%"})}),(0,m.jsx)("button",{className:"btn-primary",disabled:!V||ee,onClick:async()=>{const e=[...J];if(V&&0!==e.length&&window.confirm(`Link ${e.length} placement${1===e.length?"":"s"} to job order ${V}?`)){te(!0),$("");try{const{data:a,error:r}=await s.supabase.from("placements").update({job_order_id:V}).in("id",e).select("id");if(r)throw r;const n=new Set((a||[]).map(e=>e.id));t(e=>e.filter(e=>!n.has(e.id))),O(e=>e+n.size),ye(),$(`Linked ${n.size} placement${1===n.size?"":"s"} to job order ${V}`)}catch(a){$("Bulk link failed: "+(a.message||"error"))}finally{te(!1)}}},children:ee?"Linking\u2026":`Apply to ${J.size}`}),(0,m.jsx)("button",{className:"btn-secondary",onClick:ye,disabled:ee,children:"Clear"})]}),(0,m.jsxs)("div",{style:{display:"flex",gap:10,alignItems:"center",flexWrap:"wrap",marginTop:10,paddingTop:10,borderTop:"1px solid var(--border)"},children:[(0,m.jsx)("span",{style:{fontSize:12,color:"var(--text-muted)"},children:"No real job order? Mark these as historical reference (bill $0) \u2014 closed, $0 bucket, excluded from all stats."}),(0,m.jsx)("button",{className:"btn-secondary",style:{marginLeft:"auto"},disabled:ee,onClick:async()=>{const a=e.filter(e=>J.has(e.id));if(0===a.length)return;if(!window.confirm(`Mark ${a.length} placement${1===a.length?"":"s"} as historical reference (bill $0)?\n\nEach will be linked to a closed, $0 synthetic job order keyed by (facility, system, skillset, type) and removed from this list. This will NOT affect any bill/p
1ay-rate or fill-rate statistic.`))return;te(!0),$("");const r=new Map,n=[];let i=0;try{const e=new Map;for(const t of a)try{const a=await we(t,r);e.has(a)||e.set(a,[]),e.get(a).push(t.id)}catch(l){i++}for(const[t,a]of e.entries()){const{data:e,error:r}=await s.supabase.from("placements").update({job_order_id:t}).in("id",a).select("id");r?i+=a.length:(e||[]).forEach(e=>n.push(e.id))}const o=new Set(n);t(e=>e.filter(e=>!o.has(e.id))),O(e=>e+o.size),ye(),$(`Marked ${o.size} placement${1===o.size?"":"s"} as historical reference across ${r.size} bucket${1===r.size?"":"s"}`+(i?` \u2014 ${i} failed.`:"."))}catch(l){$("Bulk mark historical failed: "+(l.message||"error"))}finally{te(!1)}},children:ee?"Marking\u2026":`Mark ${J.size} as historical reference`})]})]}),(0,m.jsxs)("div",{style:h.mw,children:[_&&(0,m.jsxs)("div",{style:{padding:"10px 16px",borderRadius:8,fontSize:13,marginBottom:12,background:"var(--bg-error-subtle)",border:"1px solid var(--error)",color:"var(--error)"},children:["Failed to load: ",_]}),S?(0,m.jsx)("div",{style:{padding:40,textAlign:"center",color:"var(--text-muted)"},children:"Loading placements & job orders..."}):0===ue.length?(0,m.jsx)("div",{style:{padding:40,textAlign:"center",color:"var(--text-muted)"},children:0===e.length?G?(0,m.jsxs)(m.Fragment,{children:[(0,m.jsx)("div",{style:{color:"var(--error)",fontWeight:600,marginBottom:8},children:"Session expired \u2014 data couldn't load."}),(0,m.jsx)("div",{children:"Log out and back in, then hit Reload below."}),(0,m.jsx)("button",{className:"btn-secondary",style:{marginTop:14},onClick:()=>Y(e=>e+1),children:"Reload"})]}):"Every placement is linked to a job order.":"No placements match the current filters."}):(0,m.jsxs)(m.Fragment,{children:[(0,m.jsx)("div",{className:"tracker-table-wrap",children:(0,m.jsxs)("table",{className:"tracker-table",children:[(0,m.jsx)("thead",{children:(0,m.jsxs)("tr",{children:[(0,m.jsx)("th",{style:{width:32,textAlign:"center"},children:(0,m.jsx)(u.Sc,{checked:ge,onChange:()=>Q(e=>{const t=new Set(e);return ge?fe.forEach(e=>t.delete(e.id)):fe.forEach(e=>t.add(e.id)),t}),title:"Select all on this page"})}),je("candidate","Candidate"),je("facility","Facility"),je("system","System"),je("start","Start"),je("skillset","Skillset"),je("type","Type"),(0,m.jsx)("th",{style:{minWidth:280},children:"Link to job order"})]})}),(0,m.jsx)("tbody",{children:fe.map((e,a)=>{const r=oe(e),n=P===e.id,l=ae===e.id;return(0,m.jsxs)("tr",{className:a%2===0?"tracker-row-even":"tracker-row-odd",children:[(0,m.jsx)("td",{style:{textAlign:"center"},children:(0,m.jsx)(u.Sc,{checked:J.has(e.id),onChange:()=>{return t=e.id,Q(e=>{const a=new Set(e);return a.has(t)?a.delete(t):a.add(t),a});var t}})}),(0,m.jsx)("td",{className:"tracker-name",style:{fontWeight:600},children:e.placement_name||f}),(0,m.jsx)("td",{style:{fontSize:12},children:e.facility_name||f}),(0,m.jsx)("td",{style:{fontSize:12,color:"var(--text-muted)"},children:e.healthcare_system||f}),(0,m.jsx)("td",{style:{whiteSpace:"nowrap",fontSize:12},children:(0,d.Yq)(e.start_date)}),(0,m.jsx)("td",{style:{fontSize:12},children:e.skillset||f}),(0,m.jsx)("td",{style:{fontSize:12},children:(()=>{const t=g(e.assignment_type);return(0,m.jsx)("span",{style:{fontWeight:600,color:t.color},title:e.assignment_type||"",children:t.label})})()}),(0,m.jsx)("td",{children:(0,m.jsxs)("div",{style:{display:"flex",gap:8,alignItems:"center"},children:[(0,m.jsx)("div",{style:{flex:1,minWidth:0},children:l?(0,m.jsx)("span",{style:{fontSize:12,color:"var(--text-muted)"},children:"Marking $0..."}):0===r.length?(0,m.jsx)("span",{style:{fontSize:12,color:"var(--text-muted)",fontStyle:"italic"},children:"No matching job orders"}):n?(0,m.jsx)("span",{style:{fontSize:12,color:"var(--text-muted)"},children:"Saving..."}):(0,m.jsx)(i.Z,{options:r,value:"",onChange:a=>(async(e,r)=>{if(r){U(e),$("");try{const{data:a,error:n}=await s.supabase.from("placements").update({job_order_id:r}).eq("id",e).select("id");if(n)throw n;if(!a||0===a.length)throw new Error("No row updated (RLS or row missing)");t(t=>t.filter(t=>t.id!==e)),O(e=>e+1),$(`Linked placement #${e} to job order ${r}`)}catch(a){$("Failed to link: "+(a.message||"error"))}finally{U(null)}}})(e.id,a.target.value),placeholder:`Pick 1 of ${r.length} job order${1===r.length?"":"s"}...`,searchable:!0,width:"100%"})}),(0,m.jsx)("button",{className:"btn-secondary",style:{whiteSpace:"nowrap",fontSize:12,padding:"6px 10px"},disabled:n||l,onClick:()=>(async e=>{if(window.confirm(`Mark this placement as a historical reference (bill $0)?\n\nIt will be linked to a closed, $0 synthetic job order for ${e.facility_name||"this facility"}
1 and removed from this list. It will NOT affect any bill/pay-rate or fill-rate statistic.`)){re(e.id),$("");try{const a=new Map,r=await we(e,a),{data:n,error:i}=await s.supabase.from("placements").update({job_order_id:r}).eq("id",e.id).select("id");if(i)throw i;if(!n||0===n.length)throw new Error("No row updated (RLS or row missing)");t(t=>t.filter(t=>t.id!==e.id)),O(e=>e+1),$(`Marked placement #${e.id} as historical reference ($0 bucket ${r}).`)}catch(a){$("Failed to mark historical: "+(a.message||"error"))}finally{re(null)}}})(e),title:"Mark as historical reference \u2014 links to a closed, $0 synthetic job order; excluded from all bill/pay-rate and fill-rate stats",children:"Mark $0"})]})})]},e.id)})})]})}),(0,m.jsxs)("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginTop:12,gap:12},children:[(0,m.jsxs)("div",{style:{fontSize:13,color:"var(--text-muted)"},children:["Showing ",50*pe+1,"-",Math.min(50*(pe+1),ue.length)," of ",ue.length]}),(0,m.jsxs)("div",{style:{display:"flex",gap:8,alignItems:"center"},children:[(0,m.jsx)("button",{className:"btn-secondary",onClick:()=>D(e=>Math.max(0,e-1)),disabled:0===pe,children:"\u2190 Previous"}),(0,m.jsxs)("span",{style:{fontSize:13,color:"var(--text-muted)"},children:["Page ",pe+1," of ",me]}),(0,m.jsx)("button",{className:"btn-secondary",onClick:()=>D(e=>Math.min(me-1,e+1)),disabled:pe>=me-1,children:"Next \u2192"})]})]})]})]})]})}}}]); 2//# sourceMappingURL=7368.a1e16cc1.chunk.js.map
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.