1import{bi as M,bj as P,r as i,d3 as z,x as n,j as t,c6 as E,v as B,d4 as G,d5 as _,d6 as V}from"./index-BGXoFh6q.js";import{u as W}from"./audit-Bw_Hh5De.js";import{T as k}from"./trash-2-CxUJJUsq.js";function K(){const{t:N}=M(),{can:w}=P(),h=W(),p=w("write","schedule"),A=w("delete","schedule"),[u,m]=i.useState([]),[R,S]=i.useState(!0),[x,$]=i.useState("all"),[L,b]=i.useState(new Set),[f,y]=i.useState(""),[l,v]=i.useState({category:"firefighter",name:""});i.useEffect(()=>{I()},[]);async function I(){S(!0);try{const e=await z({data:{table:"schedule_grid",orderBy:[{column:"category",ascending:!0},{column:"display_order",ascending:!0}],limit:5e3}});m(e.rows??[])}catch(e){n.error(e instanceof Error?e.message:"Load failed"),m([])}finally{S(!1)}}const g=i.useMemo(()=>{const e=new Set;return u.forEach(r=>r.scheduled_dates.forEach(d=>e.add(d))),[...e].sort()},[u]),j=i.useMemo(()=>u.filter(e=>x==="all"||e.category===x),[u,x]);async function D(e,r){if(!p){n.error("You don't have permission to edit the schedule");return}const d=`${e.id}|${r}`;b(o=>new Set(o).add(d));const a=e.scheduled_dates.includes(r)?e.scheduled_dates.filter(o=>o!==r):[...e.scheduled_dates,r].sort();try{await _({data:{table:"schedule_grid",id:e.id,patch:{scheduled_dates:a,updated_at:new Date().toISOString()}}})}catch(o){return b(c=>{const C=new Set(c);return C.delete(d),C}),n.error(o instanceof Error?o.message:"Update failed")}b(o=>{const c=new Set(o);return c.delete(d),c}),m(o=>o.map(c=>c.id===e.id?{...c,scheduled_dates:a}:c)),h("update","schedule_grid",e.id,e,{...e,scheduled_dates:a},"Updated schedule dates")}async function Y(){if(!f)return;const e=j[0]??u[0];if(!e)return n.error("Add a sport first");if(g.includes(f)){y("");return}await D(e,f),y("")}async function F(e){if(!p){n.error("You don't have permission to edit the schedule");return}if(!confirm(`Remove ${e} from all sports?`))return;const r=u.filter(d=>d.scheduled_dates.includes(e));try{await Promise.all(r.map(d=>_({data:{table:"schedule_grid",id:d.id,patch:{scheduled_dates:d.scheduled_dates.filter(s=>s!==e),updated_at:new Date().toISOString()}}})))}catch(d){return n.error(d instanceof Error?d.message:"Failed to remove date")}m(d=>d.map(s=>({...s,scheduled_dates:s.scheduled_dates.filter(a=>a!==e)}))),r.forEach(d=>{const s={...d,scheduled_dates:d.scheduled_dates.filter(a=>a!==e)};h("update","schedule_grid",d.id,d,s,"Removed date column")})}async function O(){if(!p){n.error("You don't have permission to edit the schedule");return}if(!l.name.trim())return;const e=Math.max(0,...u.filter(r=>r.category===l.category).map(r=>r.display_order));try{const r=await G({data:{table:"schedule_grid",values:{category:l.category,sport_name:l.name.trim(),display_order:e+1,scheduled_dates:[]}}});if(!r.row)throw new Error("Insert failed");m(d=>[...d,r.row]),h("insert","schedule_grid",r.row.id,null,r.row,"Added sport to schedule")}catch(r){return n.error(r instanceof Error?r.message:"Insert failed")}v({...l,name:""})}async function T(e){if(!A){n.error("You don't have permission to delete schedule rows");return}if(confirm(`Delete "${e.sport_name}"?`)){try{await V({data:{table:"schedule_grid",id:e.id}})}catch(r){return n.error(r instanceof Error?r.message:"Delete failed")}m(r=>r.filter(d=>d.id!==e.id)),h("delete","schedule_grid",e.id,e,null,"Deleted sport from schedule")}}async function U(e,r){if(!p){n.error("You don't have permission to edit the schedule");return}const d=r.trim();if(!(!d||d===e.sport_name)){try{await _({data:{table:"schedule_grid",id:e.id,patch:{sport_name:d,updated_at:new Date().toISOString()}}})}catch(s){return n.error(s instanceof Error?s.message:"Update failed")}m(s=>s.map(a=>a.id===e.id?{...a,sport_name:d}:a)),h("update","schedule_grid",e.id,e,{...e,sport_name:d},"Renamed schedule sport")}}return t.jsxs("div",{children:[t.jsxs("header",{className:"mb-6",children:[t.jsx("h1",{className:"text-3xl font-extrabold text-foreground",children:N("pg.schedule")}),t.jsx("p",{className:"mt-1 text-sm text-muted-foreground",children:N("pg.scheduleSub")})]}),t.jsxs("div",{className:"mb-4 flex flex-wrap items-center gap-3",children:[t.jsx("div",{className:"flex gap-1.5 rounded-lg border border-border bg-card p-1",children:["all","firefighter","general"].map(e=>t.jsx("button",{onClick:()=>$(e),className:`rounded-md px-3 py-1.5 text-xs font-semibold ${x===e?"bg-brand-red text-brand-off":"text-foreground hover:bg-muted"}`,children:e==="all"?"All":e==="firefighter"?"Firefighter":"General"},e))}),t.jsxs("div",{className:"ml-auto flex flex-wrap items-center gap-2",children:[t.jsx("input",{type:"date",value:f,onChange:e=>y(e.target.value),className:"rounded-md border border-border bg-background px-3 py-1.5 text-sm"}),t.jsxs("button",{onClick:Y,className:"inline-flex items-center gap-1 rounded-md border border-border px-3 py-1.5 text-sm hover:bg-muted",children:[t.jsx(E,{className:"h-3.5 w-3.5"})," Add date"]})]})]}),t.jsxs("div",{className:"mb-4 flex flex-wrap items-center gap-2 rounded-lg border border-dashed border-border bg-muted/20 p-3",children:[t.jsxs("select",{value:l.category,onChange:e=>v({...l,category:e.target.value}),className:"rounded-md border border-border bg-background px-2 py-1.5 text-sm",children:[t.jsx("option",{value:"firefighter",children:"Firefighter"}),t.jsx("option",{value:"general",children:"General"})]}),t.jsx("input",{type:"text",value:l.name,onChange:e=>v({...l,name:e.target.value}),placeholder:"Sport name (e.g. Soccer)",className:"flex-1 min-w-[200px] rounded-md border border-border bg-background px-3 py-1.5 text-sm"}),t.jsxs("button",{onClick:O,className:"inline-flex items-center gap-1 rounded-md bg-brand-red px-3 py-1.5 text-sm font-semibold text-brand-off hover:brightness-110",children:[t.jsx(E,{className:"h-3.5 w-3.5"})," Add sport"]})]}),R?t.jsx("div",{className:"flex h-64 items-center justify-center",children:t.jsx(B,{className:"h-8 w-8 animate-spin text-brand-red"})}):t.jsx("div",{className:"overflow-x-auto rounded-2xl border border-border bg-card",children:t.jsxs("table",{className:"min-w-full text-sm",children:[t.jsx("thead",{className:"border-b border-border bg-muted/40",children:t.jsxs("tr",{children:[t.jsx("th",{className:"sticky left-0 z-10 bg-muted/40 px-4 py-3 text-left",children:"Sport"}),g.map(e=>t.jsxs("th",{className:"px-2 py-3 text-center",children:[t.jsx("div",{className:"text-[11px] font-semibold",children:new Date(e+"T00:00:00").toLocaleDateString("en",{month:"short",day:"numeric"})}),t.jsx("button",{onClick:()=>F(e),title:"Remove this date",className:"mt-1 inline-flex items-center justify-center rounded p-0.5 text-muted-foreground hover:bg-destructive/10 hover:text-destructive",children:t.jsx(k,{className:"h-3 w-3"})})]},e)),t.jsx("th",{className:"px-2 py-3"})]})}),t.jsxs("tbody",{children:[j.map(e=>t.jsxs("tr",{className:"border-b border-border last:border-0",children:[t.jsxs("td",{className:"sticky left-0 z-10 bg-card px-4 py-2.5",children:[t.jsx("input",{defaultValue:e.sport_name,onBlur:r=>U(e,r.target.value),className:"w-full rounded-md border border-transparent bg-transparent px-2 py-1 font-medium hover:border-border focus:border-border focus:bg-background"}),t.jsxs("div",{className:"px-2 text-xs text-muted-foreground",children:[e.category==="firefighter"?"ð":"â½"," ",e.category]})]}),g.map(r=>{const d=`${e.id}|${r}`,s=e.scheduled_dates.includes(r),a=L.has(d);return t.jsx("td",{className:"px-2 py-1.5 text-center",children:t.jsx("button",{onClick:()=>D(e,r),disabled:a,"aria-label":`Toggle ${e.sport_name} on ${r}`,className:`mx-auto h-7 w-7 rounded-full border transition-all ${s?e.category==="firefighter"?"border-brand-red bg-brand-red":"border-emerald-600 bg-emerald-600":"border-border bg-background hover:border-foreground
1/40"} ${a?"opacity-50":""}`})},r)}),t.jsx("td",{className:"px-2 py-1.5",children:t.jsx("button",{onClick:()=>T(e),className:"inline-flex items-center rounded-md border border-destructive/30 p-1.5 text-destructive hover:bg-destructive/10",title:"Delete sport",children:t.jsx(k,{className:"h-3.5 w-3.5"})})})]},e.id)),j.length===0&&t.jsx("tr",{children:t.jsx("td",{colSpan:g.length+2,className:"px-4 py-12 text-center text-sm text-muted-foreground",children:"No sports yet. Add one above."})})]})]})})]})}export{K 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.