PageSourceSearch

https://anbit-air-solutions--facilityguides.replit.app/assets/SPCrew-DBYpiFGP.js

js anbit-air-solutions--facilityguides.replit.app collected 2026-10-03 03:53:25 UTC 7,176 bytes, 1 lines download raw bytes

1import{ap as E,Y as A,r as m,f as N,$ as p,j as e,B as d,ab as D,b as I,I as n,i as v,n as y,bp as P,ag as q,az as T,P as L,M as $,q as H,a5 as K,a9 as Q,ac as z,ad as B,ae as J,o as l,ay as R}from"./index-C-XGTDPc.js";function Y(){const{toast:j}=E(),x=A(),[c,C]=m.useState(""),[S,o]=m.useState(!1),[U,b]=m.useState(null),[t,a]=m.useState({memberName:"",role:"",phone:"",email:"",projectId:"",certifications:"",notes:""}),{data:h=[],isLoading:O}=N({queryKey:["sp-crew"],queryFn:async()=>{const s=await fetch("/api/sp/crew",{credentials:"include"});return s.ok?s.json():[]}}),{data:u=[]}=N({queryKey:["sp-projects"],queryFn:async()=>{const s=await fetch("/api/sp/projects",{credentials:"include"});return s.ok?s.json():[]}}),g=p({mutationFn:async s=>{const i=await fetch("/api/sp/crew",{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify({...s,projectId:s.projectId?parseInt(s.projectId):u[0]?.id||1,certifications:s.certifications?s.certifications.split(",").map(r=>r.trim()):[]})});if(!i.ok)throw new Error("Failed to add crew member");return i.json()},onSuccess:()=>{x.invalidateQueries({queryKey:["sp-crew"]}),j({title:"Crew member added"}),o(!1),w()}}),M=p({mutationFn:async({id:s,isOnSite:i})=>{const r=await fetch(`/api/sp/crew/${s}`,{method:"PATCH",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify({isOnSite:i})});if(!r.ok)throw new Error("Failed to update");return r.json()},onSuccess:()=>{x.invalidateQueries({queryKey:["sp-crew"]})}}),k=p({mutationFn:async s=>{if(!(await fetch(`/api/sp/crew/${s}`,{method:"DELETE",credentials:"include"})).ok)throw new Error("Failed to delete")},onSuccess:()=>{x.invalidateQueries({queryKey:["sp-crew"]}),j({title:"Crew member removed"})}}),w=()=>{a({memberName:"",role:"",phone:"",email:"",projectId:"",certifications:"",notes:""}),b(null)},f=h.filter(s=>!c||(s.memberName||"").toLowerCase().includes(c.toLowerCase())||(s.role||"").toLowerCase().includes(c.toLowerCase())),F=h.filter(s=>s.isOnSite).length;return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-xl sm:text-2xl font-bold","data-testid":"text-sp-crew-title",children:"Crew Management"}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:[h.length," members · ",F," on-site"]})]}),e.jsxs(d,{onClick:()=>{w(),o(!0)},"data-testid":"button-add-crew",className:"w-full sm:w-auto",children:[e.jsx(D,{className:"h-4 w-4 mr-2"})," Add Member"]})]}),e.jsxs("div",{className:"relative max-w-sm",children:[e.jsx(I,{className:"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground"}),e.jsx(n,{placeholder:"Search crew...",className:"pl-9",value:c,onChange:s=>C(s.target.value),"data-testid":"input-search-crew","aria-label":"Search crew members"})]}),O?e.jsxs("div",{className:"flex items-center justify-center py-12",children:[e.jsx("div",{className:"w-8 h-8 border-4 border-blue-500 border-t-transparent rounded-full animate-spin"}),e.jsx("span",{className:"ml-3 text-muted-foreground",children:"Loading crew..."})]}):f.length===0?e.jsx(v,{children:e.jsxs(y,{className:"py-12 text-center",children:[e.jsx(P,{className:"h-12 w-12 text-gray-300 mx-auto mb-3"}),e.jsx("p",{className:"text-gray-500 font-medium",children:"No crew members"}),e.jsx("p",{className:"text-sm text-gray-400 mt-1",children:c?"Try adjusting your search":"Add crew members to track assignments and availability"})]})}):e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4",children:f.map(s=>e.jsx(v,{className:"relative","data-testid":`crew-card-${s.id}`,children:e.jsxs(y,{className:"p-4",children:[e.jsxs("div",{className:"flex items-start justify-between mb-3",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:`h-10 w-10 rounded-full flex items-center justify-center ${s.isOnSite?"bg-green-100":"bg-gray-100"}`,children:e.jsx(q,{className:`h-5 w-5 ${s.isOnSite?"text-green-600":"text-gray-500"}`})}),e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-semibold",children:s.memberName}),s.role&&e.jsx("p",{className:"text-xs text-muted-foreground",children:s.role})]})]}),e.jsx("div",{className:"flex gap-1",children:e.jsx(d,{variant:"ghost",size:"sm",className:"h-7 w-7 p-0",onClick:()=>k.mutate(s.id),"data-testid":`button-delete-crew-${s.id}`,children:e.jsx(T,{className:"h-3 w-3 text-red-500"})})})]}),e.jsxs("div",{className:"space-y-1.5 text-xs",children:[s.phone&&e.jsxs("p",{className:"flex items-center gap-2 text-muted-foreground",children:[e.jsx(L,{className:"h-3 w-3"})," ",s.phone]}),s.email&&e.jsxs("p",{className:"flex items-center gap-2 text-muted-foreground",children:[e.jsx($,{className:"h-3 w-3"})," ",s.email]}),s.certifications&&s.certifications.length>0&&e.jsxs("div",{className:"flex items-center gap-1 flex-wrap mt-2",children:[e.jsx(H,{className:"h-3 w-3 text-muted-foreground"}),s.certifications.map((i,r)=>e.jsx(K,{variant:"outline",className:"text-[10px]",children:i},r))]})]}),e.jsx("div",{className:"mt-3 pt-3 border-t",children:e.jsx(d,{variant:s.isOnSite?"default":"outline",size:"sm",className:"w-full text-xs",onClick:()=>M.mutate({id:s.id,isOnSite:!s.isOnSite}),"data-testid":`button-toggle-onsite-${s.id}`,children:s.isOnSite?"✓ On-Site":"Mark On-Site"})})]})},s.id))}),e.jsx(Q,{open:S,onOpenChange:o,children:e.jsxs(z,{children:[e.jsx(B,{children:e.jsx(J,{children:"Add Crew Member"})}),e.jsxs("div",{className:"space-y-3 py-2",children:[e.jsxs("div",{children:[e.jsx(l,{children:"Name *"}),e.jsx(n,{value:t.memberName,onChange:s=>a({...t,memberName:s.target.value}),"data-testid":"input-crew-name"})]}),e.jsxs("div",{children:[e.jsx(l,{children:"Role"}),e.jsx(n,{placeholder:"e.g., HVAC Mechanic, Foreman",value:t.role,onChange:s=>a({...t,role:s.target.value}),"data-testid":"input-crew-role"})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsxs("div",{children:[e.jsx(l,{children:"Phone"}),e.jsx(n,{value:t.phone,onChange:s=>a({...t,phone:s.target.value}),"data-testid":"input-crew-phone"})]}),e.jsxs("div",{children:[e.jsx(l,{children:"Email"}),e.jsx(n,{value:t.email,onChange:s=>a({...t,email:s.target.value}),"data-testid":"input-crew-email"})]})]}),u.length>0&&e.jsxs("div",{children:[e.jsx(l,{children:"Project"}),e.jsxs("select",{className:"w-full h-9 border rounded-md px-2 text-sm",value:t.projectId,onChange:s=>a({...t,projectId:s.target.value}),"data-testid":"select-crew-project",children:[e.jsx("option",{value:"",children:"Select project..."}),u.map(s=>e.jsx("option",{value:s.id,children:s.title},s.id))]})]}),e.jsxs("div",{children:[e.jsx(l,{children:"Certifications (comma-separated)"}),e.jsx(n,{placeholder:"EPA 608, OSHA 30",value:t.certifications,onChange:s=>a({...t,certifications:s.target.value}),"data-testid":"input-crew-certs"})]})]}),e.jsxs(R,{children:[e.jsx(d,{variant:"outline",onClick:()=>o(!1),children:"Cancel"}),e.jsx(d,{onClick:()=>g.mutate(t),disabled:!t.memberName||g.isPending,"data-testid":"button-save-crew",children:"Add Member"})]})]})})]})}export{Y 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.