PageSourceSearch

https://reant-cockpit-pro.lovable.app/assets/sickness-BXUmhB5j.js

js reant-cockpit-pro.lovable.app collected 2026-10-03 03:41:55 UTC 13,795 bytes, 1 lines download raw bytes

1import{u as H,r as h,aJ as I,j as e,am as K,bs as W,B as g,a5 as ae,an as q,ao as J,ap as Y,bk as re,d as D,aj as $,I as F,T as ne,ay as X,b1 as R,bB as Q,b0 as L,C as ee,af as ie,aE as le,aK as V,Z as de,aO as k,a2 as B,t as p,s as b,cz as U,b2 as ce,b3 as oe,aY as ue,U as me,a4 as xe,cA as pe,cB as G}from"./index-Db8-vjIs.js";import{T as he,a as ge,b as O,c as P}from"./tabs-BflZ6rYd.js";const fe=10*1024*1024,je=["application/pdf","image/png","image/jpeg","image/jpg"];function be(){const{profile:t,isManager:d,roles:u}=H(),r=d||u.some(a=>a==="back_office"||a==="hr"),{profiles:x}=ie(),{reports:c,refetch:s}=le(),m=h.useMemo(()=>{const a=new Map;for(const N of x)a.set(N.id,N);return a},[x]),n=h.useMemo(()=>c.filter(a=>a.salesperson_id===t?.id),[c,t?.id]),j=n.filter(V).length,f=n.filter(a=>!a.certificate_url&&a.status!=="closed").length,y=c.filter(V).length,_=c.filter(a=>!a.certificate_url&&a.status!=="closed").length,v=c.filter(a=>!a.certificate_url&&a.status!=="closed"&&L(a.start_date)>R).length,o=I(),w=c.filter(a=>a.certificate_uploaded_at?.startsWith(o)).length;return e.jsxs(e.Fragment,{children:[e.jsx(de,{title:"Ziekte",subtitle:"Digitale ziektemeldingen en medische attesten",actions:e.jsx(ye,{onCreated:s,profiles:x,canPickEmployee:d})}),e.jsxs("div",{className:"px-4 sm:px-8 py-6 sm:py-8 space-y-6",children:[d||r?e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-4 gap-4",children:[e.jsx(k,{label:"Actief ziek",value:String(y),accent:"gold"}),e.jsx(k,{label:"Attesten ontvangen vandaag",value:String(w)}),e.jsx(k,{label:"Openstaande attesten",value:String(_)}),e.jsx(k,{label:`Achterstallig (>${R} werkdagen)`,value:String(v),sublabel:v>0?"herinnering aanbevolen":"alles in orde"})]}):e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-4",children:[e.jsx(k,{label:"Mijn actieve meldingen",value:String(j),accent:"gold"}),e.jsx(k,{label:"Wachtende attesten",value:String(f)}),e.jsx(k,{label:"Totaal historiek",value:String(n.length)})]}),e.jsxs(he,{defaultValue:"mine",children:[e.jsxs(ge,{children:[e.jsx(O,{value:"mine",children:"Mijn meldingen"}),(d||r)&&e.jsx(O,{value:"team",children:"Overzicht team"}),r&&e.jsx(O,{value:"payroll",children:"Payroll / Attesten"}),e.jsx(O,{value:"history",children:"Historiek"})]}),e.jsx(P,{value:"mine",className:"mt-4",children:e.jsx(B,{title:"Mijn ziektemeldingen",children:e.jsx(Z,{reports:n,profileById:m,showOwner:!1,onChange:s,actorId:t?.id??""})})}),(d||r)&&e.jsx(P,{value:"team",className:"mt-4",children:e.jsx(B,{title:"Alle ziekteafwezigheden",children:e.jsx(Z,{reports:c,profileById:m,showOwner:!0,onChange:s,actorId:t?.id??""})})}),r&&e.jsx(P,{value:"payroll",className:"mt-4",children:e.jsx(B,{title:"Payroll-opvolging",children:e.jsx(Ne,{reports:c,profileById:m,actorId:t?.id??"",onChange:s})})}),e.jsx(P,{value:"history",className:"mt-4",children:e.jsx(B,{title:"Historiek",children:e.jsx(Z,{reports:d||r?c:n,profileById:m,showOwner:d||r,onChange:s,actorId:t?.id??"",historyMode:!0})})})]})]})]})}function ye({onCreated:t,profiles:d,canPickEmployee:u}){const{profile:r}=H(),[x,c]=h.useState(!1),[s,m]=h.useState(""),[n,j]=h.useState(I()),[f,y]=h.useState(""),[_,v]=h.useState(""),[o,w]=h.useState(!1),[a,N]=h.useState("am"),[z,E]=h.useState(!1),C=u&&s?s:r?.id??"",S=C===r?.id;async function l(){if(!(!r?.id||!C)){if(!n)return p.error("Startdatum verplicht");E(!0);try{const i=o?`[Halve dag — ${a==="am"?"voormiddag":"namiddag"}] `:"",A=S?`${i}${_.trim()}`.trim():`${i}[Geregistreerd door ${$(r)}] ${_.trim()}`.trim(),{data:M,error:T}=await b.from("sickness_reports").insert({salesperson_id:C,start_date:n,expected_end_date:o?n:f||null,end_date:o?n:null,half_day:o,half_day_period:o?a:null,note:A||null,status:o?"closed":"reported",manager_id:S?null:r.id}).select("id").single();if(T){p.error(T.message);return}await U(M.id,r.id,S?"reported":"reported_by_manager"),p.success(S?o?"Halve dag ziekte geregistreerd.":"Ziekte gemeld. Manager en payroll worden op de hoogte gebracht.":"Ziekte geregistreerd voor medewerker"),c(!1),y(""),v(""),j(I()),m(""),w(!1),N("am"),t()}finally{E(!1)}}}return e.jsxs(K,{open:x,onOpenChange:c,children:[e.jsx(W,{asChild:!0,children:e.jsxs(g,{children:[e.jsx(ae,{className:"h-4 w-4 mr-1"})," Ziekte melden"]})}),e.jsxs(q,{children:[e.jsxs(J,{children:[e.jsx(Y,{children:"Nieuwe ziektemelding"}),e.jsx(re,{children:"Je melding wordt automatisch doorgestuurd naar je manager en de payroll-verantwoordelijke."})]}),e.jsxs("div",{className:"grid gap-3",children:[u&&e.jsxs("div",{children:[e.jsx(D,{children:"Voor medewerker"}),e.jsx("select",{className:"w-full h-10 rounded-md border border-input bg-background px-3 text-sm",value:s||(r?.id??""),onChange:i=>m(i.target.value),children:d.map(i=>e.jsxs("option",{value:i.id,children:[$(i),i.id===r?.id?" (mezelf)":""]},i.id))})]}),e.jsxs("div",{children:[e.jsx(D,{children:"Startdatum ziekte *"}),e.jsx(F,{type:"date",value:n,onChange:i=>j(i.target.value)})]}),e.jsxs("label",{className:"flex items-center gap-2 text-sm cursor-pointer",children:[e.jsx("input",{type:"checkbox",className:"h-4 w-4 roun
1ded border-input",checked:o,onChange:i=>w(i.target.checked)}),e.jsx("span",{children:"Halve dag ziekte (geen attest nodig)"})]}),o&&e.jsxs("div",{className:"flex gap-2 pl-6",children:[e.jsx(g,{type:"button",size:"sm",variant:a==="am"?"default":"outline",onClick:()=>N("am"),children:"Voormiddag"}),e.jsx(g,{type:"button",size:"sm",variant:a==="pm"?"default":"outline",onClick:()=>N("pm"),children:"Namiddag"})]}),!o&&e.jsxs("div",{children:[e.jsx(D,{children:"Verwachte einddatum (optioneel)"}),e.jsx(F,{type:"date",value:f,onChange:i=>y(i.target.value)})]}),e.jsxs("div",{children:[e.jsx(D,{children:"Opmerking (optioneel)"}),e.jsx(ne,{rows:3,value:_,onChange:i=>v(i.target.value)})]}),!o&&e.jsxs("div",{className:"rounded-md border border-amber-500/40 bg-amber-500/10 p-3 text-xs text-amber-700 dark:text-amber-400 flex gap-2",children:[e.jsx(X,{className:"h-4 w-4 shrink-0 mt-0.5"}),e.jsxs("div",{children:["Vergeet niet binnen ",R," werkdagen je medisch attest op te laden."]})]})]}),e.jsxs(Q,{children:[e.jsx(g,{variant:"outline",onClick:()=>c(!1),children:"Annuleren"}),e.jsx(g,{onClick:l,disabled:z,children:z?"Bezig...":"Ziekte melden"})]})]})]})}function se({status:t}){return e.jsx("span",{className:`inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium ${oe[t]}`,children:ce[t]})}function Z({reports:t,profileById:d,showOwner:u,onChange:r,actorId:x,historyMode:c}){return t.length===0?e.jsx("div",{className:"text-sm text-muted-foreground py-8 text-center",children:"Geen ziektemeldingen."}):e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{className:"bg-primary text-xs uppercase text-primary-foreground",children:e.jsxs("tr",{className:"text-left",children:[u&&e.jsx("th",{className:"py-2 pr-3",children:"Medewerker"}),e.jsx("th",{className:"py-2 pr-3",children:"Gemeld op"}),e.jsx("th",{className:"py-2 pr-3",children:"Periode"}),e.jsx("th",{className:"py-2 pr-3",children:"Dagen"}),e.jsx("th",{className:"py-2 pr-3",children:"Status"}),e.jsx("th",{className:"py-2 pr-3",children:"Attest"}),e.jsx("th",{className:"py-2"})]})}),e.jsx("tbody",{children:t.map(s=>{const m=d.get(s.salesperson_id),n=s.end_date||s.expected_end_date,j=n?Math.max(1,Math.floor((new Date(n).getTime()-new Date(s.start_date).getTime())/864e5)+1):L(s.start_date),f=!s.certificate_url&&s.status!=="closed"&&L(s.start_date)>R;return e.jsxs("tr",{className:"border-t border-border",children:[u&&e.jsx("td",{className:"py-2 pr-3",children:$(m)}),e.jsx("td",{className:"py-2 pr-3 text-muted-foreground",children:s.created_at.slice(0,10)}),e.jsxs("td",{className:"py-2 pr-3",children:[s.start_date,n?e.jsxs(e.Fragment,{children:[" ","→ ",n,!s.end_date&&s.expected_end_date&&e.jsx("span",{className:"text-muted-foreground text-xs",children:" (verwacht)"})]}):e.jsx("span",{className:"text-muted-foreground",children:" → open"})]}),e.jsx("td",{className:"py-2 pr-3 num",children:s.half_day?`0,5${s.half_day_period?` (${s.half_day_period==="am"?"VM":"NM"})`:""}`:j}),e.jsx("td",{className:"py-2 pr-3",children:e.jsx(se,{status:s.status})}),e.jsx("td",{className:"py-2 pr-3",children:s.certificate_url?e.jsx(te,{path:s.certificate_url}):f?e.jsxs("span",{className:"inline-flex items-center gap-1 text-xs text-destructive",children:[e.jsx(X,{className:"h-3.5 w-3.5"})," ontbreekt"]}):e.jsx("span",{className:"text-xs text-muted-foreground",children:"in afwachting"})}),e.jsx("td",{className:"py-2",children:e.jsx(ve,{report:s,actorId:x,onChange:r,historyMode:c})})]},s.id)})})]})})}function te({path:t}){const[d,u]=h.useState(!1);async function r(){u(!0);const x=await pe(t);if(u(!1),!x)return p.error("Kon attest niet openen");window.open(x,"_blank","noopener,noreferrer")}return e.jsxs("button",{onClick:r,className:"inline-flex items-center gap-1 text-xs text-primary hover:underline",disabled:d,children:[e.jsx(ue,{className:"h-3.5 w-3.5"})," ",d?"...":"downloaden"]})}function ve({report:t,actorId:d,onChange:u,historyMode:r}){const{profile:x,isManager:c,roles:s}=H(),m=c||s.some(l=>l==="back_office"||l==="hr"),n=x?.id===t.salesperson_id,j=h.useRef(null),[f,y]=h.useState(!1),[_,v]=h.useState(!1),[o,w]=h.useState(I());async function a(l){if(!je.includes(l.type))return p.error("Enkel PDF, JPG of PNG toegestaan");if(l.size>fe)return p.error("Bestand is groter dan 10 MB");y(!0);try{const i=l.name.split(".").pop()||"bin",A=`${t.salesperson_id}/${t.id}-${Date.now()}.${i}`,{error:M}=await b.storage.from(G).upload(A,l,{contentType:l.type,upsert:!1});if(M){p.error(M.message);return}const{error:T}=await b.from("sickness_reports").update({certificate_url:A,certificate_uploaded_at:new Date().toISOString(),status:t.status==="reported"?"certificate_received":t.status}).eq("id",t.id);if(T){p.error(T.message);return}await U(t.id,d,"certificate_uploaded","certificate_url",null,A),p.success("Attest opgeladen. Payroll wordt verwittigd."),u()}finally{y(!1)}}async function N(){if(!o)return;const{error:l}=await b.from("sickness_reports").update({end_date:o,status:"closed"}).eq("id",t.id);if(l){p.error(l.message);return}await U(t.id,d,"closed","end_date",t.end_date,o),p.success("Ziekteperiode afgesloten"),v(!1),u()}async function z(){if(confirm("Ziektemelding definitief verwijderen?")){y(!0);try{t.certificate_url&&await b.storage.from(G).remove([t.certificate_url]);const{error:l}=await b.from("sickness_reports").delete().eq("id",t.id);if(l){p.error(l.message);return}p.success("Ziektemelding verwijderd"),u()}finally{y(!1)}}}const E=!r&&n&&!t.certificate_url&&t.status!=="closed",C=!r&&(n||m)&&t.status!=="closed",S=m||n&&t.status==="reported";return e.jsxs("div",{className:"flex items-center gap-2 justify-end",children:[E&&e.jsxs(e.Fragment,{children:[e.jsx("input",{ref:j,type:"file",accept:"application/pdf,image/png,image/jpeg",className:"hidden",onChange:l=>{const i=l.target.files?.[0];i&&a(i),l.target.value=""}}),e.jsxs(g,{size:"sm",variant:"outline",onClick:()=>j.current?.click(),disabled:f,children:[e.jsx(me,{className:"h-3.5 w-3.5 mr-1"})," ",f?"Bezig...":"Attest"]})]}),C&&e.jsxs(K,{open:_,onOpenChange:v,children:[e.jsx(W,{asChild:!0,children:e.jsxs(g,{size:"sm",variant:"ghost",children:[e.jsx(ee,{className:"h-3.5 w-3.5 mr-1"})," Afsluiten"]})}),e.jsxs(q,{children:[e.jsx(J,{children:e.jsx(Y,{children:"Ziekteperiode afsluiten"})}),e.jsxs("div",{children:[e.jsx(D,{children:"Werkelijke einddatum"}),e.jsx(F,{type:"date",value:o,onChange:l=>w(l.target.value)})]}),e.jsxs(Q,{children:[e.jsx(g,{variant:"outline",onClick:()=>v(!1),children:"Annuleren"}),e.jsx(g,{onClick:N,children:"Afsluiten"})]})]})]}),S&&e.jsxs(g,{size:"sm",variant:"ghost",onClick:z,disabled:f,className:"text-destructive hover:text-destructive",children:[e.jsx(xe,{className:"h-3.5 w-3.5 mr-1"})," Verwijderen"]})]})}function Ne({reports:t,profileById:d,actorId:u,onChange:r}){const x=t.filter(s=>s.status!=="closed");if(x.length===0)return e.jsx("div",{className:"text-sm text-muted-foreground py-8 text-center",children:"Geen openstaande dossiers."});async function c(s){const{error:m}=await b.from("sickness_reports").update({status:"processed",payroll_user_id:u,payroll_processed_at:new Date().toISOString()}).eq("id",s.id);if(m){p.error(m.message);return}await U(s.id,u,"payroll_processed"),p.success("Gemarkeerd als verwerkt"),r()}return e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{className:"bg-primary text-xs uppercase text-primary-foreground",children:e.jsxs("tr",{className:"text-left",children:[e.jsx("th",{className:"py-2 pr-3",children:"Medewerker"}),e.jsx("th",{className:"py-2 pr-3",children:"Start"}),e.jsx("th",{className:"py-2 pr-3",children:"Status"}),e.jsx("th",{className:"py-2 pr-3",children:"Attest"}),e.jsx("th",{className:"py-2 pr-3",children:"Werkdagen sinds"}),e.jsx("th",{className:"py-2"})]})}),e.jsx("tbody",{children:x.map(s=>{const m=d.get(s.salesperson_id),n=L(s.start_date);return e.jsxs("tr",{className:"border-t border-border",children:[e.jsx("td",{className:"py-2 pr-3",children:$(m)}),e.jsx("td",{className:"py-2 pr-3",children:s.start_date}),e.jsx("td",{className:"py-2 pr-3",children:e.jsx(se,{status:s.status})}),e.jsx("td",{className:"py-2 pr-3",children:s.certificate_url?e.jsx(te,{path:s.certificate_url}):e.jsx("span",{className:"text-xs text-destructive",children:"ontbreekt"})}),e.jsx("td",{className:"py-2 pr-3 num",children:n}),e.jsx("td",{className:"py-2 text-right",children:s.status!=="processed"&&s.certificate_url&&e.jsxs(g,{size:"sm",variant:"outline",onClick:()=>c(s),children:[e.jsx(ee,{className:"h-3.5 w-3.5 mr-1"})," Verwerkt"]})})]},s.id)})})]})})}export{ye as NewSicknessButton,Ne as PayrollList,Z as ReportList,be as component};

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.