1import{c as Ge,a as De,u as Te,r as j,j as e,B as b,f as y,I as D,X as re,b as Ye,g as Ze,e as J}from"./index-MOR4JVtd.js";import{L as Je,b as Xe,F as fe}from"./layout-DjqN9vpB.js";import{S as Fe,a as Ee,b as Ue,c as Ae,d as te}from"./select-Dlf8QCls.js";import{D as z,a as K,b as Me,c as Re,e as Le}from"./dialog-CQqwRukW.js";import{u as O}from"./useMutation-BhISad-4.js";import{f as T,G as B,u as Oe,a as H,s as et}from"./format-DN4amf30.js";import{T as tt,a as st,b as he,c as ge}from"./tabs-Cz1P-3aM.js";import{T as je}from"./textarea-DjsHDXK-.js";import{C as at}from"./checkbox-DgxEfhzn.js";import{P as _}from"./plus-Iq7nw1Sd.js";import{T as Ie}from"./triangle-alert-DLcXj2Hs.js";import{U as it}from"./user-DqGv4bRb.js";import{S as se}from"./square-pen-D6dB3WYQ.js";import{T as ae}from"./trash-2-D9QR39xc.js";import{L as Pe,C as rt}from"./loader-circle-zO-VASMA.js";import{C as $e}from"./clock-CPnu1rOq.js";import{S as nt}from"./search-B5vd9wfe.js";import{C as be}from"./chevron-right-D-d1bJvU.js";import{A as ye}from"./award-CLlej5v0.js";import{C as Ne}from"./calendar-E4mOxihe.js";import{E as ve}from"./external-link-BBju78F8.js";import{U as lt}from"./upload-CG1IVUu-.js";import{C as ie}from"./circle-check-big-D86g2Jax.js";import{d as qe}from"./differenceInDays-DBfdx3YN.js";import"./offlineQueue-BSzSF9Rh.js";import"./users-BgTbKLCW.js";import"./trees-D_qBLDSo.js";import"./index-BREHRNxX.js";import"./chevron-up-DO-1rZcL.js";/** 2 * @license lucide-react v0.545.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 dt=[["path",{d:"m17 14 3 3.3a1 1 0 0 1-.7 1.7H4.7a1 1 0 0 1-.7-1.7L7 14h-.3a1 1 0 0 1-.7-1.7L9 9h-.2A1 1 0 0 1 8 7.3L12 3l4 4.3a1 1 0 0 1-.8 1.7H15l3 3.3a1 1 0 0 1-.7 1.7H17Z",key:"cpyugq"}],["path",{d:"M12 22v-3",key:"kmzjlo"}]],_e=Ge("tree-pine",dt),we=["Cutting Techniques","Tree Felling","Chainsaw Maintenance","Mapping","Understanding the Terrain","PPE Gear / H&S Requirements","Communication / Radio Use","Emergency Procedures","Other"],L={date:T(new Date,"yyyy-MM-dd"),topic:"",customTopic:"",notes:"",needsSupport:!1,supportNotes:"",photos:[]};function X({staffId:l,records:p,canRecord:c}){const{toast:m}=De(),A=Te(),[G,u]=j.useState(!1),[N,F]=j.useState(null),[r,o]=j.useState(L),[f,d]=j.useState(!1);async function x(s){if(!(!s||s.length===0)){d(!0);try{for(const i of Array.from(s)){if(!i.type.startsWith("image/")){m({title:"Only images allowed",description:`${i.name} is not an image.`,variant:"destructive"});continue}const{url:h}=await Oe(i);o(R=>({...R,photos:[...R.photos,h]}))}}catch{m({title:"Upload failed",description:"Couldn't upload photo. Please try again.",variant:"destructive"})}finally{d(!1)}}}const E=p.filter(s=>s.staffId===l).sort((s,i)=>s.date<i.date?1:-1),v=()=>A.invalidateQueries({queryKey:["/api/field-training"]}),I=O({mutationFn:B.create,onSuccess:()=>{v(),u(!1),o(L),m({title:"Field training recorded"})},onError:()=>m({title:"Error",description:"Failed to save record.",variant:"destructive"})}),w=O({mutationFn:({id:s,data:i})=>B.update(s,i),onSuccess:()=>{v(),u(!1),F(null),o(L),m({title:"Record updated"})},onError:()=>m({title:"Error",description:"Failed to update record.",variant:"destructive"})}),Y=O({mutationFn:s=>B.delete(s),onSuccess:()=>{v(),m({title:"Record deleted"})},onError:()=>m({title:"Error",description:"Failed to delete record.",variant:"destructive"})});function M(){F(null),o({...L,date:T(new Date,"yyyy-MM-dd")}),u(!0)}function C(s){F(s);const i=we.includes(s.topic);o({date:s.date,topic:i?s.topic:"Other",customTopic:i?"":s.topic,notes:s.notes||"",needsSupport:s.needsSupport,supportNotes:s.supportNotes||"",photos:s.photos||[]}),u(!0)}function V(s){s.preventDefault();const i=r.topic==="Other"?r.customTopic.trim():r.topic;if(!i||!r.date)return;const h={staffId:l,date:r.date,topic:i,notes:r.notes||null,needsSupport:r.needsSupport,supportNotes:r.needsSupport&&r.supportNotes||null,photos:r.photos};N?w.mutate({id:N.id,data:h}):I.mutate(h)}const S=I.isPending||w.isPending;return e.jsxs("div",{className:"space-y-3",children:[c&&e.jsx("div",{className:"flex justify-end",children:e.jsxs(b,{size:"sm",onClick:M,style:{backgroundColor:"#1b4a22"},className:"gap-1.5 text-white hover:opacity-90","data-testid":"button-add-field-training",children:[e.jsx(_,{className:"h-3.5 w-3.5"})," Record Field Training"]})}),E.length===0?e.jsxs("div",{className:"flex flex-col items-center justify-center py-12 text-center bg-gray-50 rounded-lg border border-dashed",children:[e.jsx(_e,{className:"h-10 w-10 text-muted-foreground
6/20 mb-2"}),e.jsx("p",{className:"text-sm font-medium text-gray-600",children:"No field training recorded yet"}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1 max-w-xs",children:"On-the-job training and discussions (cutting techniques, mapping, terrain, PPE) will show here as evidence of development."})]}):E.map(s=>e.jsx("div",{"data-testid":`card-field-training-${s.id}`,className:`bg-gray-50 rounded-lg border border-gray-100 border-l-4 ${s.needsSupport?"border-l-amber-400":"border-l-green-400"} p-4`,children:e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("p",{className:"font-semibold text-gray-900 text-sm",children:s.topic}),s.needsSupport&&e.jsxs("span",{className:"inline-flex items-center gap-1 px-1.5 py-0.5 rounded bg-amber-100 text-amber-700 text-xs font-semibold",children:[e.jsx(Ie,{className:"h-3 w-3"})," Needs more support"]})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-3 mt-1",children:[e.jsx("span",{className:"text-xs text-muted-foreground",children:T(new Date(s.date+"T00:00:00"),"dd MMM yyyy")}),s.trainerName&&e.jsxs("span",{className:"text-xs text-muted-foreground flex items-center gap-1",children:[e.jsx(it,{className:"h-3 w-3"})," Recorded by ",s.trainerName]})]}),s.notes&&e.jsx("p",{className:"text-xs text-gray-600 mt-2 whitespace-pre-wrap",children:s.notes}),s.needsSupport&&s.supportNotes&&e.jsxs("p",{className:"text-xs text-amber-700 mt-2 bg-amber-50 rounded px-2 py-1.5 whitespace-pre-wrap",children:[e.jsx("span",{className:"font-semibold",children:"Support plan:"})," ",s.supportNotes]}),s.photos&&s.photos.length>0&&e.jsx("div",{className:"flex flex-wrap gap-1.5 mt-2",children:s.photos.map((i,h)=>e.jsx("a",{href:i,target:"_blank",rel:"noopener noreferrer",title:"View photo","data-testid":`img-field-training-photo-${s.id}-${h}`,children:e.jsx("img",{src:i,alt:"Training evidence",className:"h-14 w-14 rounded object-cover border hover:opacity-80 transition-opacity"})},h))})]}),c&&e.jsxs("div",{className:"flex items-center gap-0.5 flex-shrink-0",children:[e.jsx("button",{onClick:()=>C(s),className:"p-1.5 rounded hover:bg-gray-200 text-muted-foreground hover:text-gray-700 transition-colors","data-testid":`button-edit-field-training-${s.id}`,title:"Edit record",children:e.jsx(se,{className:"h-3.5 w-3.5"})}),e.jsx("button",{onClick:()=>{confirm("Delete this field training record?")&&Y.mutate(s.id)},className:"p-1.5 rounded hover:bg-red-100 text-muted-foreground hover:text-red-600 transition-colors","data-testid":`button-delete-field-training-${s.id}`,title:"Delete record",children:e.jsx(ae,{className:"h-3.5 w-3.5"})})]})]})},s.id)),e.jsx(z,{open:G,onOpenChange:s=>{if(!s){if(f)return;u(!1),F(null),o(L)}},children:e.jsxs(K,{className:"max-w-md",children:[e.jsx(Me,{children:e.jsx(Re,{children:N?"Edit Field Training":"Record Field Training"})}),e.jsxs("form",{onSubmit:V,className:"space-y-4 pt-1",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsxs("div",{className:"space-y-1.5",children:[e.jsxs(y,{children:["Date ",e.jsx("span",{className:"text-red-500",children:"*"})]}),e.jsx(D,{type:"date",value:r.date,onChange:s=>o(i=>({...i,date:s.target.value})),required:!0,"data-testid":"input-field-training-date"})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsxs(y,{children:["Topic ",e.jsx("span",{className:"text-red-500",children:"*"})]}),e.jsxs(Fe,{value:r.topic,onValueChange:s=>o(i=>({...i,topic:s})),children:[e.jsx(Ee,{"data-testid":"select-field-training-topic",children:e.jsx(Ue,{placeholder:"Select topic..."})}),e.jsx(Ae,{className:"max-h-64",children:we.map(s=>e.jsx(te,{value:s,children:s},s))})]})]})]}),r.topic==="Other"&&e.jsx(D,{placeholder:"Enter topic...",value:r.customTopic,onChange:s=>o(i=>({...i,customTopic:s.target.value})),required:!0,"data-testid":"input-field-training-custom-topic"}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(y,{children:"What was covered / discussed"}),e.jsx(je,{rows:3,placeholder:"e.g. Went through bore cutting on leaning stems, discussed escape routes...",value:r.notes,onChange:s=>o(i=>({...i,notes:s.target.value})),"data-testid":"input-field-training-notes"})]}),e.jsxs("label",{className:"flex items-center gap-2.5 cursor-pointer",children:[e.jsx(at,{checked:r.needsSupport,onCheckedChange:s=>o(i=>({...i,needsSupport:s===!0})),"data-testid":"checkbox-needs-support"}),e.jsx("span",{className:"text-sm text-gray-800",children:"Needs more support in this area"})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(y,{children:"Photos (evidence of training)"}),e.jsxs("label",{className:"flex items-center justify-center gap-2 border-2 border-dashed rounded-md p-3 cursor-pointer hover:bg-muted/30 transition-colors",children:[f?e.jsxs(e.Fragment,{children:[e.jsx(Pe,{className:"h-4 w-4 text-muted-foreground animate-spin"}),e.jsx("span",{className:"text-xs text-muted-foreground",children:"Uploading..."})]}):e.jsxs(e.Fragment,{children:[e.jsx(rt,{className:"h-4 w-4 text-muted-foreground"}),e.jsx("span",{className:"text-xs font-medium",children:"Add photos"})]}),e.jsx("input",{type:"file",accept:"image/*",multiple:!0,className:"hidden",disabled:f,onChange:s=>{x(s.target.files),s.target.value=""},"data-testid":"input-field-training-photos"})]}),r.photos.length>0&&e.jsx("div",{className:"flex flex-wrap gap-2 pt-1",children:r.photos.map((s,i)=>e.jsxs("div",{className:"relative","data-testid":`field-training-photo-${i}`,children:[e.jsx("img",{src:s,alt:`Photo ${i+1}`,className:"h-16 w-16 rounded object-cover border"}),e.jsx("button",{type:"button",onClick:()=>o(h=>({...h,photos:h.photos.filter((R,W)=>W!==i)})),className:"absolute -top-1.5 -right-1.5 p-0.5 rounded-full bg-black/70 text-white hover:bg-black/90","data-testid":`button-remove-field-training-photo-${i}`,title:"Remove photo",children:e.jsx(re,{className:"h-3 w-3"})})]},i))})]}),r.needsSupport&&e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(y,{children:"Support plan"}),e.jsx(je,{rows:2,placeholder:"What support will be put in place? e.g. buddy up with senior operator next week...",value:r.supportNotes,onChange:s=>o(i=>({...i,supportNotes:s.target.value})),"data-testid":"input-support-notes"})]}),e.jsxs(Le,{className:"pt-2",children:[e.jsx(b,{type:"button",variant:"outline",disabled:f,onClick:()=>{u(!1),F(null),o(L)},"data-testid":"button-cancel-field-training",children:"Cancel"}),e.jsx(b,{type:"submit",style:{backgroundColor:"#1b4a22"},className:"text-white hover:opacity-90",disabled:S||f,"data-testid":"button-save-field-training",children:S?"Saving...":f?"Uploading photos...":N?"Update Record":"Save Record"})]})]})]})})]})}const Ce=["Safety Induction","First Aid Certificate","Growsafe","Chainsaw - Basic Level","Chainsaw - High Level (Unit Std 17763 & 17766)","Chainsaw - Advanced Level","Forestry - Machine Assisted Tree Felling","Arborist Level 3","Arborist Level 4","4WD Off Road","LUV - Light Utility Vehicle","Defensive Driving","Dangerous Goods - Class D","Controlled Substances Licence","Wheels Tracks Rollers","Pre-Employment Drug/Alcohol Assessment","Pre-Employment Health Assessment","Chemical Handling & Storage Course","Drug & Alcohol Testing"];function g(l){if(!l)return"current";const p=new Date(l),m=qe(p,new Date);return m<0?"expired":m<=90?"expiring_soon":"current"}function Se({expiryDate:l}){if(!l)return e.jsxs("span",{className:"text-xs text-green-600 font-medium flex items-center gap-1",children:[e.jsx(ie,{className:"h-3.5 w-3.5"})," No Expiry"]});const p=g(l),c=new Date(l),m=qe(c,new Date);return p==="expired"?e.jsxs("span",{className:"text-xs text-red-600 font-semibold flex items-center gap-1",children:[e.jsx(re,{className:"h-3.5 w-3.5"}),"Expired ",T(c,"dd MMM yyyy")]}):p==="expiring_soon"?e.jsxs("span",{className:"text-xs text-amber-600 font-semibold flex items-center gap-1",children:[e.jsx($e,{className:"h-3.5 w-3.5"}),"Expires ",T(c,"dd MMM yyyy")," (",m,"d)"]}):e.jsxs("span",{className:"text-xs text-green-600 font-medium flex items-center gap-1",children:[e.jsx(ie,{className:"h-3.5 w-3.5"}),"Expires ",T(c,"dd MMM yyyy")]})}function ke(l){return l.startsWith("http")||l.startsWith("/")?l:`https://${l}`}function ee(l){return l?.replace(/_/g," ").replace(/\b\w/g,p=>p.toUpperCase())||"Staff"}function Q(l){return l?.split(" ").map(p=>p[0]).join("").slice(0,2).toUpperCase()}const U={course:"",customCourse:"",provider:"",dateCompleted:"",expiryDate:"",certificateUrl:""};function Pt(){const{toast:l}=De(),p=Te(),{user:c}=Ye(),m=Ze(c?.role).canViewAllTraining,[A,G]=j.useState(""),[u,N]=j.useState(null),[F,r]=j.useState(!1),[o,f]=j.useState(null),[d,x]=j.useState(U),[E,v]=j.useState(!1),I=j.useRef(null),w=j.useRef(0);async function Y(t){const a=t.target.files?.[0];if(t.target.value="",!a)return;const n=++w.current;v(!0);try{const k=await Oe(a);if(n!==w.current)return;x(q=>({...q,certificateUrl:k.url})),l({title:"File uploaded",description:a.name})}catch{if(n!==w.current)return;l({title:"Upload failed",description:"Couldn't upload the file. Check your connection and try again.",variant:"destructive"})}finally{v(!1)}}const{data:M=[]}=J({queryKey:["/api/staff"],queryFn:et.getAll}),{data:C=[],isLoading:V}=J({queryKey:["/api/training"],queryFn:H.getAll}),{data:S=[]}=J({queryKey:["/api/field-training"],queryFn:B.getAll}),s=c?.role==="foreman"||c?.role==="health_safety_officer",[i,h]=j.useState(null),R=M.find(t=>
6t.id===i),W=O({mutationFn:H.create,onSuccess:()=>{p.invalidateQueries({queryKey:["/api/training"]}),r(!1),x(U),l({title:"Certificate added",description:"Training record saved successfully."})},onError:()=>l({title:"Error",description:"Failed to save record.",variant:"destructive"})}),ne=O({mutationFn:({id:t,data:a})=>H.update(t,a),onSuccess:()=>{p.invalidateQueries({queryKey:["/api/training"]}),r(!1),f(null),x(U),l({title:"Record updated"})},onError:()=>l({title:"Error",description:"Failed to update record.",variant:"destructive"})}),le=O({mutationFn:t=>H.delete(t),onSuccess:()=>{p.invalidateQueries({queryKey:["/api/training"]}),l({title:"Record deleted"})},onError:()=>l({title:"Error",description:"Failed to delete record.",variant:"destructive"})}),Ve=M.filter(t=>!A||t.name?.toLowerCase().includes(A.toLowerCase())||t.role?.toLowerCase().includes(A.toLowerCase())),We=C.filter(t=>g(t.expiryDate)==="expiring_soon").length,He=C.filter(t=>g(t.expiryDate)==="expired").length,P=M.find(t=>t.id===u),de=C.filter(t=>t.staffId===u).sort((t,a)=>{const n={expired:0,expiring_soon:1,current:2};return n[g(t.expiryDate)]-n[g(a.expiryDate)]});function Qe(t){const a=C.filter(n=>n.staffId===t);return{total:a.length,expired:a.filter(n=>g(n.expiryDate)==="expired").length,expiring:a.filter(n=>g(n.expiryDate)==="expiring_soon").length}}function oe(){f(null),x(U),r(!0)}function ce(t){f(t);const a=Ce.includes(t.course);x({course:a?t.course:"Other",customCourse:a?"":t.course,provider:t.provider||"",dateCompleted:t.dateCompleted?new Date(t.dateCompleted).toISOString().split("T")[0]:"",expiryDate:t.expiryDate?new Date(t.expiryDate).toISOString().split("T")[0]:"",certificateUrl:t.certificateUrl||""}),r(!0)}function ze(t){t.preventDefault();const a=d.course==="Other"?d.customCourse:d.course;if(!a||!d.dateCompleted||!u)return;const n=d.expiryDate?new Date(d.expiryDate):void 0,k=new Date,q=new Date;q.setDate(q.getDate()+90);let Z="current";n&&(n<k?Z="expired":n<=q&&(Z="expiring_soon"));const pe=u??c?.id;if(!pe)return;const ue={staffId:pe,course:a,provider:d.provider||void 0,dateCompleted:new Date(d.dateCompleted),expiryDate:n||null,certificateUrl:d.certificateUrl||void 0,status:Z};o?ne.mutate({id:o.id,data:ue}):W.mutate(ue)}const xe=W.isPending||ne.isPending,$=C.filter(t=>t.staffId===c?.id).sort((t,a)=>{const n={expired:0,expiring_soon:1,current:2};return n[g(t.expiryDate)]-n[g(a.expiryDate)]}),Ke=$.filter(t=>g(t.expiryDate)==="expiring_soon").length,Be=$.filter(t=>g(t.expiryDate)==="expired").length;function me(){f(null),x(U),N(c?.id??null),r(!0)}return e.jsxs(Je,{children:[m?e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-3xl font-extrabold tracking-tight uppercase",style:{color:"#1b4a22"},children:"Staff Training"}),e.jsx("p",{className:"text-muted-foreground text-sm mt-0.5",children:"Qualifications, certificates & expiry tracking for all crew members"})]}),e.jsxs("div",{className:"grid gap-4 grid-cols-3",children:[e.jsxs("div",{className:"bg-white rounded-xl border p-4",children:[e.jsx("p",{className:"text-xs font-semibold text-muted-foreground uppercase tracking-wide mb-1",children:"Total Qualifications"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("p",{className:"text-3xl font-bold",style:{color:"#1b4a22"},children:C.length}),e.jsx(Xe,{className:"h-5 w-5 text-muted-foreground/40"})]})]}),e.jsxs("div",{className:"bg-white rounded-xl border border-amber-200 p-4",children:[e.jsx("p",{className:"text-xs font-semibold text-amber-600 uppercase tracking-wide mb-1",children:"Expiring Soon"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("p",{className:"text-3xl font-bold text-amber-600",children:We}),e.jsx($e,{className:"h-5 w-5 text-amber-300"})]})]}),e.jsxs("div",{className:"bg-white rounded-xl border border-red-200 p-4",children:[e.jsx("p",{className:"text-xs font-semibold text-red-600 uppercase tracking-wide mb-1",children:"Expired"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("p",{className:"text-3xl font-bold text-red-600",children:He}),e.jsx(Ie,{className:"h-5 w-5 text-red-300"})]})]})]}),e.jsxs("div",{className:"relative max-w-xs",children:[e.jsx(nt,{className:"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground"}),e.jsx(D,{placeholder:"Search staff...",className:"pl-9 bg-white",value:A,onChange:t=>G(t.target.value),"data-testid":"input-search-staff"})]}),e.jsx("div",{className:"grid gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4",children:Ve.map(t=>{const a=Qe(t.id),n=a.expired>0?"border-red-300":a.expiring>0?"border-amber-300":"border-gray-200";return e.jsxs("button",{"data-testid":`card-staff-${t.id}`,onClick:()=>N(t.id),className:`bg-white rounded-xl border-2 ${n} p-4 text-left hover:shadow-md transition-all group w-full`,children:[e.jsxs("div",{className:"flex items-start justify-between mb-3",children:[e.jsx("div",{className:"flex h-10 w-10 items-center justify-center rounded-full text-sm font-bold text-white flex-shrink-0",style:{backgroundColor:"#1b4a22"},children:Q(t.name)}),e.jsx(be,{className:"h-4 w-4 text-muted-foreground group-hover:text-gray-700 transition-colors mt-1"})]}),e.jsxs("div",{children:[e.jsx("p",{className:"font-semibold text-gray-900 text-sm leading-tight",children:t.name}),e.jsx("p",{className:"text-xs text-muted-foreground capitalize mb-3",children:ee(t.role)})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-1.5 text-xs",children:[e.jsxs("span",{className:"text-muted-foreground",children:[a.total," records"]}),a.expired>0&&e.jsxs("span",{className:"px-1.5 py-0.5 rounded bg-red-100 text-red-700 font-semibold",children:[a.expired," expired"]}),a.expiring>0&&e.jsxs("span",{className:"px-1.5 py-0.5 rounded bg-amber-100 text-amber-700 font-semibold",children:[a.expiring," expiring"]}),a.total>0&&a.expired===0&&a.expiring===0&&e.jsx("span",{className:"px-1.5 py-0.5 rounded bg-green-100 text-green-700 font-semibold",children:"All current"})]})]},t.id)})})]}):e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-3xl font-extrabold tracking-tight uppercase",style:{color:"#1b4a22"},children:"My Training Records"}),e.jsx("p",{className:"text-muted-foreground text-sm mt-0.5",children:"Your qualifications, certificates & expiry dates"})]}),e.jsxs(b,{onClick:me,style:{backgroundColor:"#1b4a22"}
6,className:"text-white hover:opacity-90 gap-2 self-start","data-testid":"button-add-my-certificate",children:[e.jsx(_,{className:"h-4 w-4"})," Add Certificate"]})]}),e.jsxs("div",{className:"grid gap-4 grid-cols-3",children:[e.jsxs("div",{className:"bg-white rounded-xl border p-4",children:[e.jsx("p",{className:"text-xs font-semibold text-muted-foreground uppercase tracking-wide mb-1",children:"Total"}),e.jsx("p",{className:"text-3xl font-bold",style:{color:"#1b4a22"},children:$.length})]}),e.jsxs("div",{className:"bg-white rounded-xl border border-amber-200 p-4",children:[e.jsx("p",{className:"text-xs font-semibold text-amber-600 uppercase tracking-wide mb-1",children:"Expiring Soon"}),e.jsx("p",{className:"text-3xl font-bold text-amber-600",children:Ke})]}),e.jsxs("div",{className:"bg-white rounded-xl border border-red-200 p-4",children:[e.jsx("p",{className:"text-xs font-semibold text-red-600 uppercase tracking-wide mb-1",children:"Expired"}),e.jsx("p",{className:"text-3xl font-bold text-red-600",children:Be})]})]}),V?e.jsx("div",{className:"text-sm text-muted-foreground py-8 text-center",children:"Loading..."}):$.length===0?e.jsxs("div",{className:"flex flex-col items-center justify-center py-16 bg-white rounded-xl border text-center",children:[e.jsx(ye,{className:"h-12 w-12 text-muted-foreground/20 mb-3"}),e.jsx("p",{className:"text-sm font-medium text-gray-600",children:"No training records yet"}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1 mb-4",children:"Your certificates will appear here once added."}),e.jsxs(b,{size:"sm",variant:"outline",onClick:me,children:[e.jsx(_,{className:"h-3.5 w-3.5 mr-1"})," Add First Certificate"]})]}):e.jsx("div",{className:"space-y-3",children:$.map(t=>{const a=g(t.expiryDate),n=a==="expired"?"border-l-red-500":a==="expiring_soon"?"border-l-amber-400":"border-l-green-400";return e.jsx("div",{"data-testid":`card-training-${t.id}`,className:`bg-white rounded-lg border border-gray-100 border-l-4 ${n} p-4`,children:e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"font-semibold text-gray-900 text-sm",children:t.course}),t.provider&&e.jsx("p",{className:"text-xs text-muted-foreground mt-0.5",children:t.provider}),e.jsxs("div",{className:"flex flex-wrap items-center gap-3 mt-2",children:[t.dateCompleted&&e.jsxs("span",{className:"text-xs text-muted-foreground flex items-center gap-1",children:[e.jsx(Ne,{className:"h-3 w-3"}),"Completed ",T(new Date(t.dateCompleted),"dd MMM yyyy")]}),e.jsx(Se,{expiryDate:t.expiryDate})]}),t.certificateUrl&&e.jsxs("a",{href:ke(t.certificateUrl),target:"_blank",rel:"noopener noreferrer",className:"inline-flex items-center gap-1 mt-2 text-xs font-medium text-blue-600 hover:text-blue-800","data-testid":`link-certificate-${t.id}`,children:[e.jsx(fe,{className:"h-3 w-3"}),"View Certificate",e.jsx(ve,{className:"h-3 w-3"})]})]}),e.jsxs("div",{className:"flex items-center gap-0.5 flex-shrink-0",children:[e.jsx("button",{onClick:()=>ce(t),className:"p-1.5 rounded hover:bg-gray-200 text-muted-foreground hover:text-gray-700 transition-colors","data-testid":`button-edit-${t.id}`,title:"Edit record",children:e.jsx(se,{className:"h-3.5 w-3.5"})}),e.jsx("button",{onClick:()=>{confirm("Delete this training record?")&&le.mutate(t.id)},className:"p-1.5 rounded hover:bg-red-100 text-muted-foreground hover:text-red-600 transition-colors","data-testid":`button-delete-${t.id}`,title:"Delete record",children:e.jsx(ae,{className:"h-3.5 w-3.5"})})]})]})},t.id)})}),e.jsxs("div",{className:"space-y-3 pt-4",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-xl font-extrabold tracking-tight uppercase",style:{color:"#1b4a22"},children:"My Field Training"}),e.jsx("p",{className:"text-muted-foreground text-xs mt-0.5",children:"On-the-job training & discussions recorded by your foreman, H&S rep or manager"})]}),c?.id!=null&&e.jsx(X,{staffId:c.id,records:S,canRecord:!1})]}),s&&e.jsxs("div",{className:"space-y-3 pt-4",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-xl font-extrabold tracking-tight uppercase",style:{color:"#1b4a22"},children:"Crew Field Training"}),e.jsx("p",{className:"text-muted-foreground text-xs mt-0.5",children:"Record on-the-job training or discussions with a crew member"})]}),e.jsx("div",{className:"grid gap-3 sm:grid-cols-2 lg:grid-cols-3",children:M.filter(t=>t.id!==c?.id).map(t=>{const a=S.filter(k=>k.staffId===t.id).length,n=S.filter(k=>k.staffId===t.id&&k.needsSupport).length;return e.jsxs("button",{"data-testid":`card-field-staff-${t.id}`,onClick:()=>h(t.id),className:"bg-white rounded-xl border-2 border-gray-200 p-4 text-left hover:shadow-md transition-all group w-full",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"flex h-9 w-9 items-center justify-center rounded-full text-xs font-bold text-white flex-shrink-0",style:{backgroundColor:"#1b4a22"},children:Q(t.name)}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"font-semibold text-gray-900 text-sm leading-tight truncate",children:t.name}),e.jsx("p",{className:"text-xs text-muted-foreground capitalize",children:ee(t.role)})]}),e.jsx(be,{className:"h-4 w-4 text-muted-foreground group-hover:text-gray-700 transition-colors flex-shrink-0"})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-1.5 text-xs mt-2.5",children:[e.jsxs("span",{className:"text-muted-foreground",children:[a," session",a===1?"":"s"]}),n>0&&e.jsxs("span",{className:"px-1.5 py-0.5 rounded bg-amber-100 text-amber-700 font-semibold",children:[n," needs supp
6ort"]})]})]},t.id)})})]})]}),s&&e.jsx(z,{open:i!==null,onOpenChange:t=>{t||h(null)},children:e.jsxs(K,{className:"max-w-2xl max-h-[85vh] overflow-hidden flex flex-col gap-0 p-0",children:[e.jsxs("div",{className:"flex items-center gap-3 px-6 py-4 border-b flex-shrink-0",style:{backgroundColor:"#f7faf7"},children:[e.jsx("div",{className:"flex h-11 w-11 items-center justify-center rounded-full text-sm font-bold text-white",style:{backgroundColor:"#1b4a22"},children:Q(R?.name||"")}),e.jsxs("div",{children:[e.jsx("h2",{className:"font-bold text-gray-900",children:R?.name}),e.jsxs("p",{className:"text-xs text-muted-foreground flex items-center gap-1",children:[e.jsx(_e,{className:"h-3 w-3"})," Field Training"]})]})]}),e.jsx("div",{className:"flex-1 overflow-y-auto p-6",children:i!==null&&e.jsx(X,{staffId:i,records:S,canRecord:!0})})]})}),m&&e.jsx(z,{open:u!==null,onOpenChange:t=>{t||(N(null),r(!1))},children:e.jsxs(K,{className:"max-w-2xl max-h-[85vh] overflow-hidden flex flex-col gap-0 p-0",children:[e.jsxs("div",{className:"flex items-center justify-between px-6 py-4 border-b flex-shrink-0",style:{backgroundColor:"#f7faf7"},children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"flex h-11 w-11 items-center justify-center rounded-full text-sm font-bold text-white",style:{backgroundColor:"#1b4a22"},children:Q(P?.name||"")}),e.jsxs("div",{children:[e.jsx("h2",{className:"font-bold text-gray-900",children:P?.name}),e.jsx("p",{className:"text-xs text-muted-foreground capitalize",children:ee(P?.role)})]})]}),e.jsxs(b,{size:"sm",onClick:oe,style:{backgroundColor:"#1b4a22"},className:"gap-1.5 text-white hover:opacity-90","data-testid":"button-add-certificate",children:[e.jsx(_,{className:"h-3.5 w-3.5"})," Add Certificate"]})]}),e.jsxs(tt,{defaultValue:"certificates",className:"flex-1 flex flex-col overflow-hidden",children:[e.jsxs(st,{className:"mx-6 mt-4 self-start",children:[e.jsx(he,{value:"certificates","data-testid":"tab-certificates",children:"Certificates"}),e.jsx(he,{value:"field-training","data-testid":"tab-field-training",children:"Field Training"})]}),e.jsx(ge,{value:"certificates",className:"flex-1 overflow-y-auto p-6 space-y-3 mt-0",children:V?e.jsx("div",{className:"flex items-center justify-center py-10 text-muted-foreground text-sm",children:"Loading..."}):de.length===0?e.jsxs("div",{className:"flex flex-col items-center justify-center py-14 text-center",children:[e.jsx(ye,{className:"h-12 w-12 text-muted-foreground/20 mb-3"}),e.jsx("p",{className:"text-sm font-medium text-gray-600",children:"No training records yet"}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1 mb-4",children:"Add certificates and qualifications for this staff member."}),e.jsxs(b,{size:"sm",variant:"outline",onClick:oe,children:[e.jsx(_,{className:"h-3.5 w-3.5 mr-1"})," Add First Certificate"]})]}):de.map(t=>{const a=g(t.expiryDate),n=a==="expired"?"border-l-red-500":a==="expiring_soon"?"border-l-amber-400":"border-l-green-400";return e.jsx("div",{"data-testid":`card-training-${t.id}`,className:`bg-gray-50 rounded-lg border border-gray-100 border-l-4 ${n} p-4`,children:e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"font-semibold text-gray-900 text-sm",children:t.course}),t.provider&&e.jsx("p",{className:"text-xs text-muted-foreground mt-0.5",children:t.provider}),e.jsxs("div",{className:"flex flex-wrap items-center gap-3 mt-2",children:[t.dateCompleted&&e.jsxs("span",{className:"text-xs text-muted-foreground flex items-center gap-1",children:[e.jsx(Ne,{className:"h-3 w-3"}),"Completed"," ",T(new Date(t.dateCompleted),"dd MMM yyyy")]}),e.jsx(Se,{expiryDate:t.expiryDate})]}),t.certificateUrl&&e.jsxs("a",{href:ke(t.certificateUrl),target:"_blank",rel:"noopener noreferrer",className:"inline-flex items-center gap-1 mt-2 text-xs font-medium text-blue-600 hover:text-blue-800","data-testid":`link-certificate-${t.id}`,children:[e.jsx(fe,{className:"h-3 w-3"}),"View Certificate",e.jsx(ve,{className:"h-3 w-3"})]})]}),e.jsxs("div",{className:"flex items-center gap-0.5 flex-shrink-0",children:[e.jsx("button",{onClick:()=>ce(t),className:"p-1.5 rounded hover:bg-gray-200 text-muted-foreground hover:text-gray-700 transition-colors","data-testid":`button-edit-${t.id}`,title:"Edit record",children:e.jsx(se,{className:"h-3.5 w-3.5"})}),e.jsx("button",{onClick:()=>{confirm("Delete this training record?")&&le.mutate(t.id)},className:"p-1.5 rounded hover:bg-red-100 text-muted-foreground hover:text-red-600 transition-colors","data-testid":`button-delete-${t.id}`,title:"Delete record",children:e.jsx(ae,{className:"h-3.5 w-3.5"})})]})]})},t.id)})}),e.jsx(ge,{value:"field-training",className:"flex-1 overflow-y-auto p-6 mt-0",children:u!==null&&e.jsx(X,{staffId:u,records:S,canRecord:!0})})]})]})}),e.jsx(z,{open:F,onOpenChange:t=>{t||(w.current++,v(!1),r(!1),f(null),x(U))},children:e.jsxs(K,{className:"max-w-md",children:[e.jsxs(Me,{children:[e.jsx(Re,{children:o?"Edit Training Record":"Add Training Certificate"}),P&&e.jsxs("p",{className:"text-xs text-muted-foreground pt-0.5",children:["For: ",e.jsx("span",{className:"font-medium text-gray-700",children:P.name})]})]}),e.jsxs("form",{onSubmit:ze,className:"space-y-4 pt-1",children:[e.jsxs("div",{className:"space-y-1.5",children:[e.jsxs(y,{children:["Course / Qualification ",e.jsx("span",{className:"text-red-500",children:"*"})]}),e.jsxs(Fe,{value:d.course,onValueChange:t=>x(a=>({...a,course:t})),children:[e.jsx(Ee,{"data-testid":"select-course",children:e.jsx(Ue,{placeholder:"Select a course..."})}),e.jsxs(Ae,{className:"max-h-64",children:[Ce.map(t=>e.jsx(te,{value:t,children:t},t)),e.jsx(te,{value:"Other",children:"Other (custom)"})]})]}),d.course==="Other"&&e.jsx(D,{placeholder:"Enter course name...",value:d.customCourse,onChange:t=>x(a=>({...a,customCourse:t.target.value})),required:!0,"data-testid":"input-custom-course"})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(y,{children:"Provider / Issuer"}),e.jsx(D,{placeholder:"e.g. St John, Skills Active, NZQA",value:d.provider,onCh
6ange:t=>x(a=>({...a,provider:t.target.value})),"data-testid":"input-provider"})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsxs("div",{className:"space-y-1.5",children:[e.jsxs(y,{children:["Date Completed ",e.jsx("span",{className:"text-red-500",children:"*"})]}),e.jsx(D,{type:"date",value:d.dateCompleted,onChange:t=>x(a=>({...a,dateCompleted:t.target.value})),required:!0,"data-testid":"input-date-completed"})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(y,{children:"Expiry Date"}),e.jsx(D,{type:"date",value:d.expiryDate,onChange:t=>x(a=>({...a,expiryDate:t.target.value})),"data-testid":"input-expiry-date"})]})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(y,{children:"Certificate File / Link"}),e.jsx("input",{ref:I,type:"file",accept:"image/*,.pdf,.doc,.docx",className:"hidden",onChange:Y,"data-testid":"input-certificate-file"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs(b,{type:"button",variant:"outline",className:"gap-1.5",disabled:E,onClick:()=>I.current?.click(),"data-testid":"button-upload-certificate",children:[E?e.jsx(Pe,{className:"h-4 w-4 animate-spin"}):e.jsx(lt,{className:"h-4 w-4"}),E?"Uploading...":"Upload File"]}),d.certificateUrl.startsWith("/")&&e.jsxs("span",{className:"inline-flex items-center gap-1 text-xs text-green-700 font-medium",children:[e.jsx(ie,{className:"h-3.5 w-3.5"})," File attached",e.jsx("button",{type:"button",className:"ml-1 text-muted-foreground hover:text-destructive",onClick:()=>x(t=>({...t,certificateUrl:""})),"data-testid":"button-remove-certificate-file",children:e.jsx(re,{className:"h-3.5 w-3.5"})})]})]}),e.jsx(D,{placeholder:"Or paste a link (https://drive.google.com/...)",value:d.certificateUrl.startsWith("/")?"":d.certificateUrl,onChange:t=>x(a=>({...a,certificateUrl:t.target.value})),disabled:d.certificateUrl.startsWith("/"),"data-testid":"input-certificate-url"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Upload a photo/PDF of the certificate, or paste a Google Drive / Dropbox link"})]}),e.jsxs(Le,{className:"pt-2",children:[e.jsx(b,{type:"button",variant:"outline",onClick:()=>{w.current++,v(!1),r(!1),f(null),x(U)},"data-testid":"button-cancel",children:"Cancel"}),e.jsx(b,{type:"submit",style:{backgroundColor:"#1b4a22"},className:"text-white hover:opacity-90",disabled:xe||E,"data-testid":"button-save-certificate",children:xe?"Saving...":o?"Update Record":"Save Certificate"})]})]})]})})]})}export{Pt 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.