PageSourceSearch

https://healthserve.ae/assets/AdminApplications-gKO0UlYB.js

js healthserve.ae collected 2026-10-04 02:40:15 UTC 10,259 bytes, 2 lines download raw bytes

1import{r as i,j as e,a8 as R,y as g,aO as x,X as U,R as $,Q as M,M as T}from"./index-CzMEFmtw.js";import{P as q,a as I,C as V}from"./ui-BklIU2Vp.js";import{D as E}from"./download-D1O7GOuA.js";import{T as Q}from"./trash-2-gzkfqCHP.js";const C=["new","reviewing","shortlisted","interview","hired","rejected"];function W(){const[a,m]=i.useState([]),[p,j]=i.useState(!0),[h,v]=i.useState(""),[d,b]=i.useState("all"),[r,N]=i.useState("all"),[o,f]=i.useState(null);async function S(){j(!0);const{data:t,error:s}=await g.from("job_applications").select("*").order("created_at",{ascending:!1});s&&x.error(s.message),m(t??[]),j(!1)}i.useEffect(()=>{S()},[]);const P=i.useMemo(()=>{const t=new Set;return a.forEach(s=>t.add(s.position_title)),["all",...Array.from(t)]},[a]),y=i.useMemo(()=>{const t=h.toLowerCase().trim();return a.filter(s=>(d==="all"||s.status===d)&&(r==="all"||s.position_title===r)&&(!t||s.full_name.toLowerCase().includes(t)||s.email.toLowerCase().includes(t)||(s.phone??"").toLowerCase().includes(t)||s.position_title.toLowerCase().includes(t)))},[a,h,d,r]);async function _(t,s){const{error:l}=await g.from("job_applications").update({status:s}).eq("id",t);if(l)return x.error(l.message);m(u=>u.map(c=>c.id===t?{...c,status:s}:c)),(o==null?void 0:o.id)===t&&f({...o,status:s})}async function z(t,s){const{error:l}=await g.from("job_applications").update({notes:s}).eq("id",t);if(l)return x.error(l.message);x.success("Notes saved"),m(u=>u.map(c=>c.id===t?{...c,notes:s}:c))}async function O(t){if(!confirm(`Delete application from ${t.full_name}? This also removes their CV file.`))return;t.cv_url&&await g.storage.from("cvs").remove([t.cv_url]);const{error:s}=await g.from("job_applications").delete().eq("id",t.id);if(s)return x.error(s.message);f(null),S()}async function k(t){if(!t.cv_url)return x.error("No CV attached.");const{data:s,error:l}=await g.storage.from("cvs").createSignedUrl(t.cv_url,300);if(l||!s)return x.error((l==null?void 0:l.message)||"Could not open CV.");window.open(s.signedUrl,"_blank")}function B(){const t=Array.from(new Set(y.flatMap(n=>Object.keys(n.answers??{})))),s=["Submitted","Position","Name","Email","Phone","Location","Experience","Status","CV","Cover letter",...t],l=n=>`"${String(n??"").replace(/"/g,'""').replace(/\r?\n/g," ")}"`,u=[s.join(",")];y.forEach(n=>{u.push([new Date(n.created_at).toISOString(),n.position_title,n.full_name,n.email,n.phone,n.location,n.years_experience,n.status,n.cv_name??"",n.cover_letter??"",...t.map(F=>{var D;return((D=n.answers)==null?void 0:D[F])??""})].map(l).join(","))});const c=new Blob([u.join(`
2`)],{type:"text/csv;charset=utf-8"}),L=URL.createObjectURL(c),w=document.createElement("a");w.href=L,w.download=`applications-${new Date().toISOString().slice(0,10)}.csv`,w.click(),URL.revokeObjectURL(L)}return e.jsxs(q,{children:[e.jsx(I,{title:"Applications",description:"CV submissions from the /careers page. Filter, review, download CVs, or export as CSV.",actions:e.jsxs("button",{onClick:B,className:"inline-flex items-center gap-1.5 h-9 px-3 rounded-lg border border-gray-200 text-sm font-semibold hover:bg-gray-50",children:[e.jsx(E,{className:"w-4 h-4"})," Export CSV"]})}),e.jsx(V,{className:"p-3 mb-4",children:e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-[1fr_180px_220px] gap-2",children:[e.jsx("input",{placeholder:"Search name, email, position…",value:h,onChange:t=>v(t.target.value),className:"h-9 px-3 border border-gray-200 rounded-lg text-sm"}),e.jsxs("select",{value:d,onChange:t=>b(t.target.value),className:"h-9 px-3 border border-gray-200 rounded-lg text-sm",children:[e.jsx("option",{value:"all",children:"All statuses"}),C.map(t=>e.jsx("option",{value:t,children:t},t))]}),e.jsx("select",{value:r,onChange:t=>N(t.target.value),className:"h-9 px-3 border border-gray-200 rounded-lg text-sm",children:P.map(t=>e.jsx("option",{value:t,children:t==="all"?"All positions":t},t))})]})}),e.jsx(V,{className:"overflow-hidden",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{className:"bg-gray-50 text-xs uppercase tracking-wider text-gray-500",children:e.jsxs("tr",{children:[e.jsx("th",{className:"text-left px-4 py-2.5",children:"Applicant"}),e.jsx("th",{className:"text-left px-4 py-2.5",children:"Position"}),e.jsx("th",{className:"text-left px-4 py-2.5",children:"Submitted"}),e.jsx("th",{className:"text-left px-4 py-2.5",children:"Status"}),e.jsx("th",{className:"text-left px-4 py-2.5",children:"CV"}),e.jsx("th",{className:"px-4 py-2.5"})]})}),e.jsxs("tbody",{children:[p&&e.jsx("tr",{children:e.jsx("td",{colSpan:6,className:"text-center py-8 text-gray-500",children:"Loading…"})}),!p&&y.length===0&&e.jsx("tr",{children:e.jsx("td",{colSpan:6,className:"text-center py-10 text-gray-500",children:"No applications yet."})}),y.map(t=>e.jsxs("tr",{className:"border-t border-gray-100 hover:bg-gray-50/60",children:[e.jsxs("td",{className:"px-4 py-3",children:[e.jsx("div",{className:"font-semibold text-gray-900",children:t.full_name}),e.jsx("div",{className:"text-xs text-gray-500",children:t.email})]}),e.jsx("td",{className:"px-4 py-3 text-gray-700",children:t.position_title}),e.jsx("td",{className:"px-4 py-3 text-xs text-gray-500",children:new Date(t.created_at).toLocaleStr
2ing()}),e.jsx("td",{className:"px-4 py-3",children:e.jsx("select",{value:t.status,onChange:s=>_(t.id,s.target.value),className:`h-8 px-2 text-xs rounded-md border ${A(t.status)}`,children:C.map(s=>e.jsx("option",{value:s,children:s},s))})}),e.jsx("td",{className:"px-4 py-3",children:t.cv_url?e.jsxs("button",{onClick:()=>k(t),className:"inline-flex items-center gap-1 text-xs text-[#B26800] hover:underline",children:[e.jsx(R,{size:12})," Download"]}):e.jsx("span",{className:"text-xs text-gray-400",children:"—"})}),e.jsx("td",{className:"px-4 py-3 text-right",children:e.jsx("button",{onClick:()=>f(t),className:"text-xs font-semibold text-gray-700 hover:text-[#B26800]",children:"View →"})})]},t.id))]})]})}),o&&e.jsx(H,{app:o,onClose:()=>f(null),onDownload:()=>k(o),onDelete:()=>O(o),onStatus:t=>_(o.id,t),onSaveNotes:t=>z(o.id,t)})]})}function A(a){switch(a){case"new":return"bg-blue-50 text-blue-700 border-blue-200";case"reviewing":return"bg-amber-50 text-amber-700 border-amber-200";case"shortlisted":return"bg-purple-50 text-purple-700 border-purple-200";case"interview":return"bg-indigo-50 text-indigo-700 border-indigo-200";case"hired":return"bg-green-50 text-green-700 border-green-200";case"rejected":return"bg-gray-100 text-gray-500 border-gray-200";default:return"bg-gray-50 text-gray-700 border-gray-200"}}function H({app:a,onClose:m,onDownload:p,onDelete:j,onStatus:h,onSaveNotes:v}){const[d,b]=i.useState(a.notes??"");return i.useEffect(()=>b(a.notes??""),[a.id]),e.jsx("div",{className:"fixed inset-0 z-[999] flex justify-end bg-black/30",onClick:m,children:e.jsxs("div",{className:"w-full max-w-xl h-full bg-white overflow-y-auto shadow-2xl",onClick:r=>r.stopPropagation(),children:[e.jsxs("div",{className:"p-5 border-b border-gray-200 flex items-start justify-between",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[11px] font-bold uppercase tracking-wider text-[#B26800]",children:a.position_title}),e.jsx("h3",{className:"text-xl font-bold text-gray-900 mt-0.5",children:a.full_name}),e.jsxs("div",{className:"text-xs text-gray-500 mt-1",children:["Submitted ",new Date(a.created_at).toLocaleString()]})]}),e.jsx("button",{onClick:m,className:"text-gray-500 hover:text-gray-900",children:e.jsx(U,{size:18})})]}),e.jsxs("div",{className:"p-5 space-y-4",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-3 text-sm",children:[e.jsxs("a",{href:`mailto:${a.email}`,className:"inline-flex items-center gap-2 text-gray-700 hover:text-[#B26800]",children:[e.jsx($,{size:14})," ",a.email]}),a.phone&&e.jsxs("a",{href:`https://wa.me/${a.phone.replace(/[^\d]/g,"")}`,target:"_blank",rel:"noreferrer",className:"inline-flex items-center gap-2 text-gray-700 hover:text-[#B26800]",children:[e.jsx(M,{size:14})," ",a.phone]}),a.location&&e.jsxs("div",{className:"inline-flex items-center gap-2 text-gray-700",children:[e.jsx(T,{size:14})," ",a.location]}),a.years_experience&&e.jsxs("div",{className:"text-gray-700",children:[e.jsx("b",{children:"Experience:"})," ",a.years_experience]})]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsxs("button",{onClick:p,disabled:!a.cv_url,className:"inline-flex items-center gap-1.5 h-9 px-3 rounded-lg bg-[#F9A01B] text-white text-sm font-semibold disabled:opacity-40",children:[e.jsx(E,{size:14})," Download CV"]}),e.jsx("select",{value:a.status,onChange:r=>h(r.target.value),className:`h-9 px-2 text-xs rounded-lg border ${A(a.status)}`,children:C.map(r=>e.jsx("option",{value:r,children:r},r))}),e.jsxs("button",{onClick:j,className:"ml-auto inline-flex items-center gap-1.5 h-9 px-3 rounded-lg border border-red-200 text-red-600 text-sm hover:bg-red-50",children:[e.jsx(Q,{size:14})," Delete"]})]}),a.cover_letter&&e.jsxs("div",{children:[e.jsx("div",{className:"text-xs font-semibold uppercase tracking-wider text-gray-500 mb-1",children:"Cover note"}),e.jsx("div",{className:"text-sm text-gray-700 bg-gray-50 rounded-lg p-3 whitespace-pre-wrap",children:a.cover_letter})]}),a.answers&&Object.keys(a.answers).length>0&&e.jsxs("div",{children:[e.jsx("div",{className:"text-xs font-semibold uppercase tracking-wider text-gray-500 mb-1",children:"Screening answers"}),e.jsx("dl",{className:"space-y-2",children:Object.entries(a.answers).map(([r,N])=>e.jsxs("div",{className:"bg-gray-50 rounded-lg p-3",children:[e.jsx("dt",{className:"text-[11px] font-semibold uppercase tracking-wider text-gray-500",children:r}),e.jsx("dd",{className:"text-sm text-gray-800 mt-0.5",children:N||"—"})]},r))})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-xs font-semibold uppercase tracking-wider text-gray-500 mb-1",children:"Internal notes"}),e.jsx("textarea",{rows:4,value:d,onChange:r=>b(r.target.value),className:"w-full px-3 py-2 border border-gray-200 rounded-lg text-sm",placeholder:"Notes for the hiring team…"}),e.jsx("button",{onClick:()=>v(d),className:"mt-2 inline-flex items-center gap-1.5 h-9 px-3 rounded-lg bg-gray-900 text-white text-sm font-semibold",children:"Save notes"})]})]})]})})}export{W 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.