1import{e as ts,f as C,a0 as $,r as d,s as X,j as e,B as w,a1 as T,d as B,t as E,g as Re,k as $e,l as Be,m as Ue,n as Le,v as R,T as ns,a2 as rs,U as Te,h as ls,i as is,o as os,p as cs,a3 as ds,D as ms,a as us,b as ps,c as Me,I as ae,L as xs}from"./main-DzucdYFc.js";import{A as hs}from"./AppHeader-zmdn_azq.js";import{C as Y}from"./card-DRlqGCcU.js";import{S as q,a as I,b as F,c as G,d as P}from"./select-0zCWln3Q.js";import{c as fs,e as gs,C as js}from"./rotationPlan-IUMOuhJy.js";import{u as ue,w as bs}from"./xlsx-DK-yVfHF.js";import{C as z}from"./circle-check-CL8FDcmm.js";import{C as V}from"./circle-x-BF9LenNS.js";import{A as le}from"./arrow-left-right-TQLXtcNy.js";import{C as ys}from"./calendar-days-A-vILz8z.js";import{R as De}from"./RoleBadge-BRSickhS.js";import{F as Ns}from"./file-down-BPNHl8_Y.js";import{C as vs}from"./chevron-down-4yJIr9A4.js";import{S as ws}from"./shield-DS4qf56E.js";import{T as ks}from"./trash-2-ClAiatyc.js";import{S as _s}from"./save-BIq-bziB.js";import"./index-CMrPrpxb.js";import"./chevron-up-BCahGwIb.js";import"./jspdf.es.min-Rv2UFLCC.js";import"./shield-check-BoIZqIn9.js";const Cs=[["path",{d:"m17 2 4 4-4 4",key:"nntrym"}],["path",{d:"M3 11v-1a4 4 0 0 1 4-4h14",key:"84bu3i"}],["path",{d:"m7 22-4-4 4-4",key:"1wqhfi"}],["path",{d:"M21 13v1a4 4 0 0 1-4 4H3",key:"1rx37r"}]],pe=ts("repeat",Cs);function Ss(t){const o=[];o.push(["ARCCC 2M Net â Net Control Schedule"]),o.push([`Generated ${C(new Date,"MMM d, yyyy 'at' HH:mm")}`,"","","",""]),o.push([]),o.push(["Date","Day","Primary Call","Primary Name","Backup Call","Backup Name","One-time?","Notes"]);for(const x of t){let k="",b=x.scheduled_date;try{const A=$(x.scheduled_date);k=C(A,"EEE"),b=C(A,"yyyy-MM-dd")}catch{}o.push([b,k,x.primary_call??"",x.primary_name??"",x.backup_call??"",x.backup_name??"",x.is_override?"Yes":"",x.notes??""])}const c=ue.aoa_to_sheet(o);c["!cols"]=[{wch:12},{wch:6},{wch:12},{wch:22},{wch:12},{wch:22},{wch:10},{wch:40}];const n=ue.book_new();ue.book_append_sheet(n,c,"Schedule");const u=bs(n,{type:"array",bookType:"xlsx"}),r=new Uint8Array(u),g=new Blob([r],{type:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}),f=URL.createObjectURL(g),h=document.createElement("a");h.href=f,h.download=`ARCCC-NC-Schedule-${C(new Date,"yyyy-MM-dd")}.xlsx`,document.body.appendChild(h),h.click(),document.body.removeChild(h),URL.revokeObjectURL(f)}function Es(){const[t,o]=d.useState([]),[c,n]=d.useState([]),[u,r]=d.useState(!0),g=d.useCallback(async()=>{r(!0);const[{data:f},{data:h}]=await Promise.all([X.from("schedule_confirmations").select("*"),X.from("schedule_swap_requests").select("*").order("created_at",{ascending:!1})]);o(f??[]),n(h??[]),r(!1)},[]);return d.useEffect(()=>{g()},[g]),{confirmations:t,swaps:c,loading:u,reload:g}}function Ms(t,o,c){return t.find(n=>n.schedule_id===o&&n.role===c)}function Ds(t,o,c){const n=t.filter(r=>r.status==="pending"&&r.to_schedule_id===o&&r.to_role===c),u=t.filter(r=>r.status==="pending"&&r.from_schedule_id===o&&r.from_role===c);return{incoming:n,outgoing:u}}const Pe={pending:"Available",confirmed:"Confirmed",unavailable:"Unavailable",swap_requested:"Swap requested"};function Ps({role:t,confirmation:o,hasIncomingSwap:c}){const n=o?.status??"pending",u=(()=>{switch(n){case"confirmed":return"bg-emerald-500/15 text-emerald-600 dark:text-emerald-400 border-emerald-500/30";
1case"unavailable":return"bg-rose-500/15 text-rose-600 dark:text-rose-400 border-rose-500/30";case"swap_requested":return"bg-blue-500/15 text-blue-600 dark:text-blue-400 border-blue-500/30";default:return"bg-emerald-500/10 text-emerald-700/80 dark:text-emerald-400/80 border-emerald-500/20"}})(),r=n==="confirmed"?z:n==="unavailable"?V:n==="swap_requested"?le:z;return e.jsxs("span",{className:`inline-flex items-center gap-1 font-mono text-[10px] uppercase tracking-wider px-1.5 py-0.5 rounded border ${u}`,title:Pe[n],children:[e.jsx(r,{className:"h-3 w-3"}),e.jsxs("span",{children:[t==="primary"?"P":"B",": ",Pe[n]]}),c&&e.jsx("span",{className:"ml-1 inline-block h-1.5 w-1.5 rounded-full bg-blue-500",title:"Incoming swap request"})]})}function As({slot:t,swappableTargets:o,onChanged:c}){const[n,u]=d.useState(null),[r,g]=d.useState(!1),f=async(h,x)=>{u(h);const k=await B({op:"confirmation.set",data:{schedule_id:t.schedule_id,role:t.role,call_sign:t.call_sign,status:h,note:x??null}});u(null),k.ok&&(E.success(h==="confirmed"?"Availability confirmed":"Marked unavailable"),c())};return e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex flex-wrap gap-1.5",children:[e.jsxs(w,{size:"sm",variant:"secondary",className:"h-7 text-xs font-mono uppercase",onClick:()=>f("confirmed"),disabled:!!n,children:[n==="confirmed"?e.jsx(T,{className:"h-3 w-3 mr-1 animate-spin"}):e.jsx(z,{className:"h-3 w-3 mr-1"}),"Confirm"]}),e.jsxs(w,{size:"sm",variant:"ghost",className:"h-7 text-xs font-mono uppercase",onClick:()=>{const h=window.prompt("Optional note (reason / context):")??void 0;f("unavailable",h||void 0)},disabled:!!n,children:[n==="unavailable"?e.jsx(T,{className:"h-3 w-3 mr-1 animate-spin"}):e.jsx(V,{className:"h-3 w-3 mr-1"}),"Can't make it"]}),e.jsxs(w,{size:"sm",variant:"ghost",className:"h-7 text-xs font-mono uppercase",onClick:()=>g(!0),disabled:!!n||o.length===0,title:o.length===0?"No other upcoming slots are available to swap with":"Request a swap",children:[e.jsx(le,{className:"h-3 w-3 mr-1"}),"Request swap"]})]}),e.jsx(Os,{open:r,onClose:()=>g(!1),slot:t,targets:o,onCreated:()=>{g(!1),c()}})]})}function Os({open:t,onClose:o,slot:c,targets:n,onCreated:u}){const[r,g]=d.useState(""),[f,h]=d.useState(""),[x,k]=d.useState(!1),b=d.useMemo(()=>{if(!r)return null;const[m,y]=r.split("::");return n.find(M=>M.schedule_id===m&&M.role===y)??null},[r,n]),A=async()=>{if(!b)return;k(!0);const m=await B({op:"swap.request",data:{from_schedule_id:c.schedule_id,from_role:c.role,from_call:c.call_sign,to_schedule_id:b.schedule_id,to_role:b.role,to_call:b.call_sign,note:f.trim()||null}});k(!1),m.ok&&(E.success(`Swap request sent to ${b.call_sign}`),g(""),h(""),u())},p=m=>{try{return C($(m),"EEE, MMM d")}catch{return m}};return e.jsx(Re,{open:t,onOpenChange:m=>m?null:o(),children:e.jsxs($e,{children:[e.jsxs(Be,{children:[e.jsx(Ue,{children:"Request a swap"}),e.jsxs(Le,{children:["Propose to swap your"," ",e.jsx("span",{className:"font-mono",children:c.role})," slot on"," ",e.jsx("span",{className:"font-mono",children:p(c.scheduled_date)})," ","with another upcoming slot. The receiving operator must accept before the swap takes effect."]})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{children:[e.jsx(R,{className:"text-xs font-mono uppercase text-muted-foreground",children:"Swap with"}),e.jsxs(q,{value:r,onValueChange:g,children:[e.jsx(I,{children:e.jsx(F,{placeholder:"Select an upcoming slot"})}),e.jsx(G,{children:n.map(m=>e.jsxs(P,{value:`${m.schedule_id}::${m.role}`,children:[p(m.scheduled_date)," â ",m.role==="primary"?"Primary":"Backup"," ",m.call_sign,m.call_name?` (${m.call_name})`:""]},`${m.schedule_id}::${m.role}`))})]})]}),e.jsxs("div",{children:[e.jsx(R,{className:"text-xs font-mono uppercase text-muted-foreground",children:"Note (optional)"}),e.jsx(ns,{rows:2,value:f,onChange:m=>h(m.target.value),placeholder:"Reason or context (visible to the other op and editors)",maxLength:500})]})]}),e.jsxs(rs,{children:[e.jsx(w,{variant:"ghost",onClick:o,disabled:x,children:"Cancel"}),e.jsxs(w,{onClick:A,disabled:x||!b,className:"font-mono uppercase",children:[x?e.jsx(T,{className:"h-4 w-4 mr-1 animate-spin"}):e.jsx(le,{className:"h-4 w-4 mr-1"}),"Send request"]})]})]})})}function Ae({swap:t,scheduleDateLookup:o,onResolved:c}){const[n,u]=d.useState(null),r=o(t.from_schedule_id),g=r?(()=>{try{return C($(r),"EEE, MMM d")}catch{return r}})():"another date",f=async()=>{u("accept");const x=await B({op:"swap.accept",id:t.id});u(null),x.ok&&(E.success("Swap accepted â schedule updated"),c())},h=async()=>{u("decline");const x=await B({op:"swap.decline",id:t.id});u(null),x.ok&&(E.success("Swap declined"),c())};return e.jsx("div",{className:"mt-2 rounded-md border border-blue-500/40 bg-blue-500/10 p-2.5 text-xs",children:e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2",children:[e.jsxs("div",{children:[e.jsx("span",{className:"font-mono font-semibold text-blue-700 dark:text-blue-300",children:t.from_call})," ","wants to swap their"," ",e.jsx("span",{className:"font-mono",children:t.from_role})," slot on"," ",e.jsx("span",{className:"font-mono",children:g})," ","for your ",e.jsx("span",{className:"font-mono",children:t.to_role}
1)," slot here.",t.note&&e.jsxs("div",{className:"mt-1 italic text-muted-foreground",children:['"',t.note,'"']})]}),e.jsxs("div",{className:"flex gap-1.5 shrink-0",children:[e.jsxs(w,{size:"sm",className:"h-7 text-xs font-mono uppercase",onClick:f,disabled:!!n,children:[n==="accept"?e.jsx(T,{className:"h-3 w-3 mr-1 animate-spin"}):e.jsx(z,{className:"h-3 w-3 mr-1"}),"Accept"]}),e.jsxs(w,{size:"sm",variant:"ghost",className:"h-7 text-xs font-mono uppercase",onClick:h,disabled:!!n,children:[n==="decline"?e.jsx(T,{className:"h-3 w-3 mr-1 animate-spin"}):e.jsx(V,{className:"h-3 w-3 mr-1"}),"Decline"]})]})]})})}function Rs({swap:t,scheduleDateLookup:o,onCanceled:c}){const[n,u]=d.useState(!1),r=o(t.to_schedule_id),g=r?(()=>{try{return C($(r),"EEE, MMM d")}catch{return r}})():"another date",f=async()=>{if(!confirm("Cancel this swap request?"))return;u(!0);const h=await B({op:"swap.cancel",id:t.id});u(!1),h.ok&&(E.success("Swap request canceled"),c())};return e.jsx("div",{className:"mt-2 rounded-md border border-blue-500/30 bg-blue-500/5 p-2.5 text-xs",children:e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2",children:[e.jsxs("div",{children:["Pending swap with ",e.jsx("span",{className:"font-mono",children:t.to_call})," on"," ",e.jsx("span",{className:"font-mono",children:g})," (",t.to_role,").",t.note&&e.jsxs("div",{className:"mt-1 italic text-muted-foreground",children:['"',t.note,'"']})]}),e.jsxs(w,{size:"sm",variant:"ghost",className:"h-7 text-xs font-mono uppercase",onClick:f,disabled:n,children:[n?e.jsx(T,{className:"h-3 w-3 mr-1 animate-spin"}):e.jsx(V,{className:"h-3 w-3 mr-1"}),"Cancel"]})]})})}function $s(){const[t,o]=d.useState([]),[c,n]=d.useState(!0),u=d.useCallback(async()=>{const{data:r}=await X.from("controller_availability").select("call_sign,role,status,note,updated_by_call,updated_at");o(r??[]),n(!1)},[]);return d.useEffect(()=>{u()},[u]),{rows:t,loading:c,refresh:u}}function te(t,o,c){const n=o.trim().toUpperCase();return t.find(u=>u.call_sign.toUpperCase()===n&&u.role===c)}function Bs({rotationItems:t,availability:o,myCall:c,isEditor:n,onChanged:u}){const r=c.trim().toUpperCase(),[g,f]=d.useState(null),h=new Map,x=p=>{const m=p.call_sign.toUpperCase();let y=h.get(m);return y||(y={call_sign:m,name:p.name,primaryDates:[],backupDates:[]},h.set(m,y)),y};for(const p of t)x(p.primary).primaryDates.push(p.date),x(p.backup).backupDates.push(p.date);const k=[...h.values()].sort((p,m)=>p.call_sign.localeCompare(m.call_sign)),b=async(p,m,y,M)=>{f(`${p}:${m}:${y}`);const J=await B({op:"controller.availability.set",data:{call_sign:p,role:m,status:y,note:M??null}});f(null),J.ok&&(E.success(`${p} ${m} ${y==="available"?"available":"unavailable"}`),u())},A=k.reduce((p,m)=>{const y=te(o,m.call_sign,"primary")?.status,M=te(o,m.call_sign,"backup")?.status;return p+(y==="unavailable"?1:0)+(M==="unavailable"?1:0)},0);return e.jsxs(Y,{className:"panel p-5 sm:p-6 mb-6",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[e.jsx(Te,{className:"h-4 w-4 text-primary"}),e.jsx("h2",{className:"font-display text-lg font-semibold",children:"N/C Availability"})]}),e.jsxs("p",{className:"text-xs text-muted-foreground mb-4",children:["Operators assigned in the proposed rotation below. Each duty defaults to"," ",e.jsx("span",{className:"font-mono uppercase tracking-wider text-emerald-600 dark:text-emerald-400",children:"available"}),". Confirm Primary and Backup duties separately. Editors may update on behalf of any operator.",A>0&&e.jsxs("span",{className:"block mt-1 font-mono text-[11px] uppercase tracking-widest text-rose-600 dar
1k:text-rose-400",children:[A," duty",A===1?"":" slots"," flagged unavailable"]})]}),k.length===0?e.jsx("p",{className:"text-sm text-muted-foreground italic",children:"No proposed rotation yet. Set a number of weeks in Generate Rotation below to populate this list."}):e.jsx("ul",{className:"divide-y divide-border/40",children:k.map(p=>{const m=n||r===p.call_sign;return e.jsxs("li",{className:"py-3 space-y-2",children:[e.jsxs("div",{className:"flex items-baseline gap-2 flex-wrap",children:[e.jsx("span",{className:"font-mono text-sm",children:p.call_sign}),e.jsx("span",{className:"text-sm text-muted-foreground truncate",children:p.name})]}),e.jsx(Oe,{label:"Primary",role:"primary",dates:p.primaryDates,current:te(o,p.call_sign,"primary"),canEdit:m,busy:g,onSet:(y,M)=>b(p.call_sign,"primary",y,M)}),e.jsx(Oe,{label:"Backup",role:"backup",dates:p.backupDates,current:te(o,p.call_sign,"backup"),canEdit:m,busy:g,onSet:(y,M)=>b(p.call_sign,"backup",y,M)})]},p.call_sign)})})]})}function Oe({label:t,role:o,dates:c,current:n,canEdit:u,busy:r,onSet:g}){const f=n?.status??"available",h=n?.call_sign??"",x=b=>`${h}:${o}:${b}`,k=c.length?c.slice(0,4).map(Ls).join(", ")+(c.length>4?` +${c.length-4} more`:""):"â";return e.jsxs("div",{className:"pl-3 border-l-2 border-border/60 flex flex-wrap items-center gap-x-3 gap-y-1.5 justify-between",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[e.jsx("span",{className:"font-mono text-[10px] uppercase tracking-widest text-muted-foreground",children:t}),e.jsx(Us,{status:f}),e.jsxs("span",{className:"text-xs text-muted-foreground",children:[c.length," week",c.length===1?"":"s"]})]}),e.jsx("p",{className:"font-mono text-[11px] text-muted-foreground mt-0.5",children:k}),n?.note&&e.jsxs("p",{className:"text-xs text-muted-foreground mt-0.5",children:["â",n.note,"â"]})]}),u&&e.jsxs("div",{className:"flex gap-1.5 shrink-0",children:[e.jsxs(w,{size:"sm",variant:f==="available"?"secondary":"ghost",className:"h-7 text-xs font-mono uppercase",onClick:()=>g("available"),disabled:r===x("available")||f==="available",children:[r===x("available")?e.jsx(T,{className:"h-3 w-3 mr-1 animate-spin"}):e.jsx(z,{className:"h-3 w-3 mr-1"}),"Available"]}),e.jsxs(w,{size:"sm",variant:f==="unavailable"?"secondary":"ghost",className:"h-7 text-xs font-mono uppercase",onClick:()=>{const b=window.prompt("Optional reason / dates:")??void 0;g("unavailable",b||null)},disabled:r===x("unavailable"),children:[r===x("unavailable")?e.jsx(T,{className:"h-3 w-3 mr-1 animate-spin"}):e.jsx(V,{className:"h-3 w-3 mr-1"}),"Unavailable"]})]})]})}function Us({status:t}){const o=t==="available",c=o?"bg-emerald-500/15 text-emerald-700 dark:text-emerald-400 border-emerald-500/30":"bg-rose-500/15 text-rose-600 dar
1k:text-rose-400 border-rose-500/30",n=o?z:V;return e.jsxs("span",{className:`inline-flex items-center gap-1 font-mono text-[10px] uppercase tracking-wider px-1.5 py-0.5 rounded border ${c}`,children:[e.jsx(n,{className:"h-3 w-3"}),o?"Available":"Unavailable"]})}function Ls(t){try{return C($(t),"MMM d")}catch{return t}}function Ts(){const[t,o]=d.useState(!1);return e.jsxs(Re,{open:t,onOpenChange:o,children:[e.jsx(ls,{asChild:!0,children:e.jsxs(w,{size:"sm",variant:"default",className:"font-mono uppercase text-xs gap-1.5 bg-primary text-primary-foreground hover:bg-primary/90 shadow-sm ring-1 ring-primary/40",title:"Help: how to use the schedule and availability",children:[e.jsx(is,{className:"h-4 w-4"}),"Help & Guide"]})}),e.jsxs($e,{className:"max-w-2xl max-h-[85vh] overflow-y-auto",children:[e.jsxs(Be,{children:[e.jsx(Ue,{className:"font-display text-xl",children:"Using the N/C Schedule & Availability"}),e.jsx(Le,{children:"A quick guide for primary and backup net control operators."})]}),e.jsxs("div",{className:"space-y-6 text-sm leading-relaxed",children:[e.jsxs("section",{children:[e.jsxs("h3",{className:"font-display text-base font-semibold flex items-center gap-2 mb-2",children:[e.jsx(ys,{className:"h-4 w-4 text-primary"}),"N/C Schedule"]}),e.jsxs("p",{className:"text-muted-foreground mb-3",children:["The schedule lists the upcoming weeks with the assigned"," ",e.jsx("span",{className:"font-mono uppercase tracking-wider text-foreground",children:"Primary"})," ","and"," ",e.jsx("span",{className:"font-mono uppercase tracking-wider text-foreground",children:"Backup"})," ","net control operators. Each row shows the date, both ops, any notes, and a status pill per role."]}),e.jsx("h4",{className:"font-mono text-[11px] uppercase tracking-widest text-muted-foreground mt-4 mb-1",children:"Reading the status pills"}),e.jsxs("ul",{className:"space-y-1.5 ml-1",children:[e.jsxs("li",{className:"flex items-start gap-2",children:[e.jsx(ne,{kind:"available",children:"P: Available"}),e.jsx("span",{children:"Default. The op hasn't said otherwise â assume they'll be there."})]}),e.jsxs("li",{className:"flex items-start gap-2",children:[e.jsx(ne,{kind:"confirmed",children:"P: Confirmed"}),e.jsx("span",{children:"The op has explicitly confirmed for that date."})]}),e.jsxs("li",{className:"flex items-start gap-2",children:[e.jsx(ne,{kind:"unavailable",children:"P: Unavailable"}),e.jsx("span",{children:"The op can't make it. An editor should arrange a substitute or swap."})]}),e.jsxs("li",{className:"flex items-start gap-2",children:[e.jsx(ne,{kind:"swap",children:"P: Swap requested"}),e.jsx("span",{children:"The op proposed trading dates with someone else. Look for the blue Incoming Swap banner on the matched row."})]})]}),e.jsx("h4",{className:"font-mono text-[11px] uppercase tracking-widest text-muted-foreground mt-4 mb-1",children:"What you can do on your own row"}),e.jsxs("ul",{className:"list-disc pl-5 space-y-1.5",children:[e.jsxs("li",{children:[e.jsx("strong",{className:"font-mono uppercase text-xs",children:"Confirm"})," ","â flip your status to Confirmed so editors know you're locked in."]}),e.jsxs("li",{children:[e.jsx("strong",{className:"font-mono uppercase text-xs",children:"Can't make it"})," ","â mark Unavailable. You'll be prompted for an optional reason (illness, travel, etc.)."]}),e.jsxs("li",{children:[e.jsx("strong",{className:"font-mono uppercase text-xs",children:"Request swap"})," ","â pick another upcoming slot and propose a trade. The other op gets an Accept / Decline banner. When accepted, both rows update automatically."]})]}),e.jsx("p",{className:"text-xs text-muted-foreground mt-2",children:"You can only change your own row. Editors (the net manager and preamble editors) can update on behalf of any op."}),e.jsx("h4",{className:"font-mono text-[11px] uppercase tracking-widest text-muted-foreground mt-4 mb-1",children:"Swaps in detail"}),e.jsxs("ol",{className:"list-decimal pl-5 space-y-1.5",children:[e.jsxs("li",{children:["Find your row and click ",e.jsx("em",{children:"Request swap"}),"."]}),e.jsx("li",{children:"Pick the date and role (Primary or Backup) you want to trade into. Cross-role trades (Primary â Backup) are allowed."}),e.jsx("li",{children:"Add an optional note â context helps the other op decide quickly."}),e.jsxs("li",{children:["The other op sees an"," ",e.jsx("span",{className:"font-mono uppercase text-[10px] tracking-widest text-blue-600 dar
1k:text-blue-400",children:"Incoming Swap"})," ","banner with Accept / Decline."]}),e.jsx("li",{children:"On accept, both schedule rows are updated atomically and any stale confirmations reset to Available."}),e.jsxs("li",{children:["You can cancel an outgoing swap any time before it's resolved from your row's ",e.jsx("em",{children:"Outgoing"})," banner."]})]}),e.jsx("h4",{className:"font-mono text-[11px] uppercase tracking-widest text-muted-foreground mt-4 mb-1",children:"Other tips"}),e.jsxs("ul",{className:"list-disc pl-5 space-y-1.5",children:[e.jsxs("li",{children:[e.jsx("strong",{children:"Export PDF"})," â the button at the top of Upcoming downloads a printable copy of the next several weeks. Useful for posting on a club bulletin or sharing in email."]}),e.jsxs("li",{children:[e.jsx("strong",{children:"Gap warnings"})," â if a row is missing a Primary or Backup, a red banner highlights it at the top so editors can fill it in."]}),e.jsxs("li",{children:[e.jsx("strong",{children:"One-time substitutes"})," appear in the schedule like any other entry but are flagged so the rotation generator won't shift the pattern around them."]})]})]}),e.jsxs("section",{className:"border-t border-border/60 pt-5",children:[e.jsxs("h3",{className:"font-display text-base font-semibold flex items-center gap-2 mb-2",children:[e.jsx(Te,{className:"h-4 w-4 text-primary"}),"N/C Availability"]}),e.jsxs("p",{className:"text-muted-foreground mb-3",children:["The N/C Availability pane is where ops flag whether they're willing to take the upcoming"," ",e.jsx("strong",{children:"proposed"})," rotation â ",e.jsx("em",{children:"before"})," an editor clicks Generate. It only lists operators that appear in the current rotation preview."]}),e.jsx("h4",{className:"font-mono text-[11px] uppercase tracking-widest text-muted-foreground mt-4 mb-1",children:"How to use it"}),e.jsxs("ol",{className:"list-decimal pl-5 space-y-1.5",children:[e.jsxs("li",{children:["Find your call sign in the list. You'll see two duty rows â"," ",e.jsx("strong",{children:"Primary"})," and ",e.jsx("strong",{children:"Backup"})," â each with the dates you'd be assigned."]}),e.jsxs("li",{children:["Each duty defaults to"," ",e.jsx("span",{className:"font-mono uppercase tracking-wider text-emerald-600 dark:text-emerald-400",children:"available"}),". If you can cover them, do nothing â silence means yes."]}),e.jsxs("li",{children:["If you can't cover one of them, click"," ",e.jsx("strong",{className:"font-mono uppercase text-xs",children:"Unavailable"})," ",`on that row. Add a short note (e.g. "out of town that month") so the editor doesn't have to chase you.`]}),e.jsx("li",{children:"You can mark Primary unavailable but stay available for Backup (or vice versa) â they're independent."}),e.jsxs("li",{children:["Changed your mind? Click"," ",e.jsx("strong",{className:"font-mono uppercase text-xs",children:"Available"})," ","to flip back."]})]}),e.jsx("h4",{className:"font-mono text-[11px] uppercase tracking-widest text-muted-foreground mt-4 mb-1",children:"Why it matters"}),e.jsxs("ul",{className:"list-disc pl-5 space-y-1.5",children:[e.jsx("li",{children:"Editors can see at a glance who needs a substitute before the rotation gets locked in, instead of scrambling the week of the net."}),e.jsxs("li",{children:["Once Generate Rotation runs, the proposed dates become real schedule rows â and that's where"," ",e.jsx("em",{children:"per-date"})," confirmations and swaps take over (see the N/C Schedule section above)."]})]}),e.jsx("h4",{className:"font-mono text-[11px] uppercase tracking-widest text-muted-foreground mt-4 mb-1",children:"Difference between the two panes"}),e.jsxs("ul",{className:"list-disc pl-5 space-y-1.5",children:[e.jsxs("li",{children:[e.jsx("strong",{children:"N/C Availability"})," â flag your willingness for the ",e.jsx("em",{children:"proposed"})," rotation, by role (Primary / Backup). Used ",e.jsx("em",{children:"before"})," generation."]}),e.jsxs("li",{children:[e.jsx("strong",{children:"N/C Schedule"})," â confirm, decline, or swap specific ",e.jsx("em",{children:"scheduled dates"}),". Used ",e.jsx("em",{children:"after"})," ","generation."]})]})]}),e.jsxs("section",{className:"border-t border-border/60 pt-5",children:[e.jsx("h3",{className:"font-display text-base font-semibold mb-2",children:"Qu
1ick reference"}),e.jsxs("div",{className:"grid sm:grid-cols-2 gap-3",children:[e.jsxs(re,{icon:e.jsx(z,{className:"h-4 w-4 text-emerald-600"}),title:"Confirm a date",children:["Schedule row â ",e.jsx("em",{children:"Confirm"})]}),e.jsxs(re,{icon:e.jsx(V,{className:"h-4 w-4 text-rose-600"}),title:"Decline a date",children:["Schedule row â ",e.jsx("em",{children:"Can't make it"})]}),e.jsxs(re,{icon:e.jsx(le,{className:"h-4 w-4 text-blue-600"}),title:"Trade dates",children:["Schedule row â ",e.jsx("em",{children:"Request swap"})]}),e.jsxs(re,{icon:e.jsx(pe,{className:"h-4 w-4 text-primary"}),title:"Pre-rotation flag",children:["Availability pane â ",e.jsx("em",{children:"Unavailable"})]})]}),e.jsx("p",{className:"text-xs text-muted-foreground mt-4",children:"Stuck or seeing something odd? Use the Feedback button in the header to send a note to the net manager."})]})]})]})]})}function ne({kind:t,children:o}){const c=t==="confirmed"?"bg-emerald-500/15 text-emerald-700 dark:text-emerald-400 border-emerald-500/30":t==="unavailable"?"bg-rose-500/15 text-rose-600 dar
1k:text-rose-400 border-rose-500/30":t==="swap"?"bg-blue-500/15 text-blue-600 dark:text-blue-400 border-blue-500/30":"bg-emerald-500/10 text-emerald-700/80 dark:text-emerald-400/80 border-emerald-500/20";return e.jsx("span",{className:`shrink-0 inline-flex items-center font-mono text-[10px] uppercase tracking-wider px-1.5 py-0.5 rounded border ${c}`,children:o})}function re({icon:t,title:o,children:c}){return e.jsxs("div",{className:"rounded-md border border-border/60 bg-muted/30 p-3",children:[e.jsxs("div",{className:"flex items-center gap-1.5 mb-1",children:[t,e.jsx("p",{className:"font-mono text-[11px] uppercase tracking-widest",children:o})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:c})]})}const v="__none__";function ia(){const{profile:t}=os(),{canEdit:o,manager:c}=cs(),[n,u]=d.useState([]),[r,g]=d.useState([]),[f,h]=d.useState(!0),[x,k]=d.useState(""),[b,A]=d.useState(v),[p,m]=d.useState(v),[y,M]=d.useState(""),[J,xe]=d.useState(!1),[he,fe]=d.useState(!1),[ge,je]=d.useState(!1),[Z,qe]=d.useState("8"),[Ie,ie]=d.useState(null),[oe,be]=d.useState(v),[ce,ye]=d.useState(v),[Ne,ve]=d.useState(""),[we,ke]=d.useState(!1),U=o(t.call),W=t.call.trim().toUpperCase(),{confirmations:Fe,swaps:Ge,reload:ee}=Es(),{rows:ze,refresh:Ve}=$s(),We=(r.some(s=>s.call_sign.toUpperCase()===W)||U)&&!!W,H=d.useCallback(async()=>{h(!0);const[{data:s},{data:a}]=await Promise.all([X.from("net_schedule").select("*").order("scheduled_date",{ascending:!0}),X.from("net_controllers_public").select("call_sign, name, exclude_from_auto_schedule, is_active").order("call_sign",{ascending:!0})]);u(s??[]);const i=(a??[]).filter(l=>l.is_active!==!1);g(i),h(!1)},[]);d.useEffect(()=>{H()},[H]);const D=d.useMemo(()=>{const s=C(new Date,"yyyy-MM-dd");return n.filter(a=>a.scheduled_date>=s)},[n]),_e=d.useMemo(()=>{const s=C(new Date,"yyyy-MM-dd");return n.filter(a=>a.scheduled_date<s).reverse()},[n]),K=s=>r.find(a=>a.call_sign===s),He=async s=>{if(s.preventDefault(),!x){E.error("Pick a date");return}fe(!0);const a=b!==v?K(b):void 0,i=p!==v?K(p):void 0,l=await B({op:"schedule.upsert",data:{scheduled_date:x,primary_call:a?.call_sign??null,primary_name:a?.name??null,backup_call:i?.call_sign??null,backup_name:i?.name??null,notes:y.trim()||null,is_override:J}});fe(!1),l.ok&&(E.success("Schedule entry saved"),k(""),A(v),m(v),M(""),xe(!1),await H())},Ye=s=>{ie(s.id),be(s.primary_call??v),ye(s.backup_call??v),ve(s.notes??""),ke(!!s.is_override)},Ke=async s=>{const a=oe!==v?K(oe):void 0,i=ce!==v?K(ce):void 0;(await B({op:"schedule.upsert",data:{scheduled_date:s.scheduled_date,primary_call:a?.call_sign??null,primary_name:a?.name??null,backup_call:i?.call_sign??null,backup_name:i?.name??null,notes:Ne.trim()||null,is_override:we}})).ok&&(E.success("Updated"),ie(null),await H())},Qe=async s=>{if(!confirm(`Remove the schedule entry for ${s.scheduled_date}?`))return;(await B({op:"schedule.delete",id:s.id})).ok&&(E.success("Removed"),await H())},S=d.useMemo(()=>fs(n,r,Z),[Z,r,n]),[Q,se]=d.useState({});d.useEffect(()=>{se({})},[Z,n.length]);const de=(s,a)=>{se(i=>({...i,[s]:{...i[s],...a}}))},Xe=s=>{se(a=>{const i={...a};return delete i[s],i})},Je=s=>{const a=Q[s.date]??{},i=(_,O)=>{if(_===void 0)return{call:O.call_sign,controller:O};if(_===v)return{call:null,controller:void 0};const N=K(_);return{call:N?.call_sign??null,controller:N}},l=i(a.primary,s.primary),j=i(a.backup,s.backup);return{primary:l,backup:j,skip:!!a.skip}},Ze=async()=>{if(S.error){E.error(S.error);return}if(!S.items.length){E.error("Enter how many weeks to generate");return}je(!0);let s=0,a=0,i=0;for(const l of S.items){if(l.existing){a++;continue}const j=Je(l);if(j.skip){i++;continue}const _=Q[l.date]!==void 0&&(Q[l.date].primary!==void 0||Q[l.date].backup!==void 0);if(!(await B({op:"schedule.upsert",data:{scheduled_date:l.date,primary_call:j.primary.call,primary_name:j.primary.controller?.name??null,backup_call:j.backup.call,backup_name:j.backup.controller?.name??null,is_override:_}},{silent:!0})).ok){E.error(`Failed at ${l.date} â stopping.`);break}s++}je(!1),E.success(`Generated ${s} week${s===1?"":"s"} (${S.N}-week rotation)`+(a?` · skipped ${a} existing`:"")+(i?` · skipped ${i} manually`:"")),se({}),await H()},Ce=d.useMemo(()=>{const s=[];D.forEach(a=>{const i=[];if(a.primary_call||i.push("primary"),a.backup_call||i.push("backup"),i.length){let l=a.scheduled_date;try{l=C($(a.scheduled_date),"EEE, MMM d")}catch{}s.push({key:`missing-${a.id}`,label:l,detail:`Missing ${i.join(" and ")}`})}});for(let a=0;a<D.length-1;a++){const i=$(D[a].scheduled_date),l=$(D[a+1].scheduled_date),j=Math.round((l.getTime()-i.getTime())/864e5);if(j>7){const _=Math.floor(j/7)-1;s.push({key:`gap-${D[a].id}`,label:`${C(i,"MMM d")} â ${C(l,"MMM d")}`,detail:`${_} week${_===1?"":"s"} unscheduled in between`})}}return s},[D]),me=d.useCallback(s=>n.find(a=>a.id===s)?.scheduled_date??null,[n]),es=d.useCallback((s,a)=>{const i=[];for(const l of D)for(const j of["primary","backup"]){if(l.id===s&&j===a)continue;const _=(j==="primary"?l.primary_call:l.backup_call)?.toUpperCase();_&&_!==W&&i.push({schedule_id:l.id,scheduled_date:l.scheduled_date,role:j,call_sign:_,call_name:j==="primary"?l.primary_name:l.backup_name})}return i},[D,W]),ss=C(new Date,"yyyy-MM-dd"),Se=(s,a)=>{const i=(a==="primary"?s.primary_call:s.backup_call)?.toUpperCase();if(!i)return null;const l=Ms(Fe,s.id,a),{incoming:j,outgoing:_}=Ds(Ge,s.id,a),O=i===W,N=U||O;return e.jsxs("div",{className:"space-y-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-1.5",children:[e.jsx(Ps,{role:a,confirmation:l,hasIncomingSwap:j.length>0}),l?.note&&N&&e.jsxs("span",{className:"text-[11px] italic text-muted-foreground",children:['"',l.note,'"']}),l?.note&&!N&&e.jsx("span",{className:"text-[11px] italic text-muted-foreground
1/60",children:"(note hidden)"})]}),O&&e.jsx(As,{slot:{schedule_id:s.id,scheduled_date:s.scheduled_date,role:a,call_sign:i},swappableTargets:es(s.id,a),onChanged:ee}),O&&_.map(L=>e.jsx(Rs,{swap:L,scheduleDateLookup:me,onCanceled:ee},L.id)),O&&j.map(L=>e.jsx(Ae,{swap:L,scheduleDateLookup:me,onResolved:ee},L.id)),!O&&U&&j.map(L=>e.jsx(Ae,{swap:L,scheduleDateLookup:me,onResolved:ee},L.id))]},a)},as=s=>{if(s.scheduled_date<ss)return null;const a=Se(s,"primary"),i=Se(s,"backup");return!a&&!i?null:e.jsxs("div",{className:"mt-3 pt-3 border-t border-border/40 space-y-2.5",children:[a,i]})},Ee=s=>{const a=Ie===s.id,i=(()=>{try{return C($(s.scheduled_date),"EEE, MMM d, yyyy")}catch{return s.scheduled_date}})();return e.jsxs("li",{className:"py-3",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("p",{className:"font-mono text-sm flex items-center gap-2",children:[i,s.is_override&&e.jsx("span",{className:"font-mono text-[10px] uppercase tracking-wider px-1.5 py-0.5 rounded bg-amber-500/15 text-amber-600 dark:text-amber-400 border border-amber-500/30",children:"One-time"})]}),!a&&e.jsxs(e.Fragment,{children:[e.jsxs("p",{className:"text-xs text-muted-foreground mt-1",children:["Primary:"," ",e.jsx("span",{className:"text-foreground font-mono",children:s.primary_call||"â"}),s.primary_name?` · ${s.primary_name}`:""]}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:["Backup:"," ",e.jsx("span",{className:"text-foreground font-mono",children:s.backup_call||"â"}),s.backup_name?` · ${s.backup_name}`:""]}),s.notes&&e.jsx("p",{className:"text-xs text-muted-foreground italic mt-1",children:s.notes}),as(s)]})]}),U&&!a&&e.jsxs("div",{className:"flex gap-2",children:[e.jsx(w,{size:"sm",variant:"secondary",onClick:()=>Ye(s),children:"Edit"}),e.jsx(w,{size:"sm",variant:"ghost",onClick:()=>Qe(s),title:"Remove",children:e.jsx(ks,{className:"h-3.5 w-3.5"})})]})]}),a&&e.jsxs("div",{className:"mt-3 grid gap-3 md:grid-cols-12",children:[e.jsxs("div",{className:"md:col-span-4",children:[e.jsx(R,{className:"text-xs font-mono uppercase text-muted-foreground",children:"Primary"}),e.jsxs(q,{value:oe,onValueChange:be,children:[e.jsx(I,{children:e.jsx(F,{})}),e.jsxs(G,{children:[e.jsx(P,{value:v,children:"None"}),r.map(l=>e.jsxs(P,{value:l.call_sign,children:[l.call_sign," â ",l.name,l.exclude_from_auto_schedule?" · Occasional":""]},l.call_sign))]})]})]}),e.jsxs("div",{className:"md:col-span-4",children:[e.jsx(R,{className:"text-xs font-mono uppercase text-muted-foreground",children:"Backup"}),e.jsxs(q,{value:ce,onValueChange:ye,children:[e.jsx(I,{children:e.jsx(F,{})}),e.jsxs(G,{children:[e.jsx(P,{value:v,children:"None"}),r.map(l=>e.jsxs(P,{value:l.call_sign,children:[l.call_sign," â ",l.name,l.exclude_from_auto_schedule?" · Occasional":""]},l.call_sign))]})]})]}),e.jsxs("div",{className:"md:col-span-4",children:[e.jsx(R,{className:"text-xs font-mono uppercase text-muted-foreground",children:"Notes"}),e.jsx(ae,{value:Ne,onChange:l=>ve(l.target.value),placeholder:"Optional",maxLength:500})]}),e.jsx("div",{className:"md:col-span-12",children:e.jsxs("label",{className:"flex items-start gap-2 text-xs text-muted-foreground cursor-pointer",children:[e.jsx("input",{type:"checkbox",checked:we,onChange:l=>ke(l.target.checked),className:"mt-0.5"}),e.jsxs("span",{children:[e.jsx("span",{className:"font-mono uppercase tracking-wider text-foreground",children:"One-time substitute"})," â ","flag this as a one-off change so it does not affect the rotation pattern."]})]})}),e.jsxs("div",{className:"md:col-span-12 flex gap-2",children:[e.jsxs(w,{size:"sm",onClick:()=>Ke(s),className:"font-mono uppercase",children:[e.jsx(_s,{className:"h-4 w-4 mr-1"}),"Save"]}),e.jsx(w,{size:"sm",variant:"ghost",onClick:()=>ie(null),children:"Cancel"})]})]})]},s.id)};return e.jsxs("div",{className:"min-h-screen",children:[e.jsx(hs,{}),e.jsxs("main",{className:"mx-auto max-w-3xl px-4 py-10",children:[e.jsxs("div",{className:"flex items-start justify-between gap-3 mb-2",children:[e.jsxs("div",{children:[e.jsx("p",{className:"font-mono text-xs uppercase tracking-[0.3em] text-primary mb-3",children:"Rotation"}),e.jsx("h1",{className:"text-3xl sm:text-4xl font-display font-semibold tracking-tight",children:"N/C Schedule"})]}),e.jsx(Ts,{})]}),e.jsxs("p",{className:"text-muted-foreground mb-3",children:["Upcoming primary and backup net control operator assignments.",U?" You may add or edit entries below.":" Contact the net manager to make changes."]}),e.jsxs("p",{className:"text-sm mb-6",children:[e.jsx("a",{href:"/public/schedule",target:"_blank",rel:"noopener noreferrer",className:"text-primary underline underline-offset-2 hover:text-primary/80",children:"View the public schedule page"}),e.jsxs("span",{className:"text-muted-foreground",children:[" ","â shareable, no login required (PDF & calendar download)."]})]}),!f&&Ce.length>0&&e.jsxs(Y,{className:"panel p-5 mb-4 border-destructive/40",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-3",children:[e.jsx(ds,{className:"h-4 w-4 text-destructive"}),e.jsx("h2",{className:"font-mono text-xs uppercase tracking-widest text-destructive",children:"Gap Warnings"})]}),e.jsx("ul",{className:"space-y-2",children:Ce.map(s=>e.jsxs("li",{className:"text-sm",children:[e.jsx("span",{className:"font-mono",children:s.label}),e.jsxs("span",{className:"text-muted-foreground",children:[" â ",s.detail]})]},s.key))})]}),e.jsxs(Y,{className:"panel p-5 mb-4",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2 mb-3",children:[e.jsx("h2",{className:"font-mono text-xs uppercase tracking-widest text-muted-foreground",children:"Upcoming"}
1),e.jsxs(ms,{children:[e.jsx(us,{asChild:!0,children:e.jsxs(w,{size:"sm",variant:"secondary",disabled:f||D.length===0,className:"font-mono uppercase text-xs",title:"Download upcoming schedule",children:[e.jsx(Ns,{className:"h-3.5 w-3.5 mr-1"}),"Export",e.jsx(vs,{className:"h-3.5 w-3.5 ml-1"})]})}),e.jsxs(ps,{align:"end",children:[e.jsx(Me,{onClick:()=>gs(D),children:"PDF (.pdf)"}),e.jsx(Me,{onClick:()=>Ss(D),children:"Excel / Google Sheets (.xlsx)"})]})]})]}),f?e.jsx("p",{className:"text-sm text-muted-foreground",children:"Loadingâ¦"}):D.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"No upcoming entries scheduled."}):e.jsx("ul",{className:"divide-y divide-border/60",children:D.map(Ee)})]}),_e.length>0&&e.jsxs(Y,{className:"panel p-5 mb-6",children:[e.jsx("h2",{className:"font-mono text-xs uppercase tracking-widest text-muted-foreground mb-3",children:"Past"}),e.jsx("ul",{className:"divide-y divide-border/60",children:_e.map(Ee)})]}),U&&e.jsxs(Y,{className:"panel p-5 sm:p-6 mb-6",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-3 flex-wrap",children:[e.jsx(ws,{className:"h-4 w-4 text-primary"}),e.jsx("h2",{className:"font-display text-lg font-semibold",children:"Add / Update Entry"}),e.jsx(De,{kind:"editor"})]}),e.jsxs("p",{className:"text-xs text-muted-foreground mb-4",children:["Editors: ",c," and the preamble editors. Adding a date that already exists will overwrite the existing entry."]}),e.jsxs("form",{onSubmit:He,className:"grid gap-3 md:grid-cols-12",children:[e.jsxs("div",{className:"md:col-span-3",children:[e.jsx(R,{className:"text-xs font-mono uppercase text-muted-foreground",children:"Date"}),e.jsx(ae,{type:"date",value:x,onChange:s=>k(s.target.value)})]}),e.jsxs("div",{className:"md:col-span-3",children:[e.jsx(R,{className:"text-xs font-mono uppercase text-muted-foreground",children:"Primary"}),e.jsxs(q,{value:b,onValueChange:A,children:[e.jsx(I,{children:e.jsx(F,{placeholder:"Primary"})}),e.jsxs(G,{children:[e.jsx(P,{value:v,children:"None"}),r.map(s=>e.jsxs(P,{value:s.call_sign,children:[s.call_sign," â ",s.name,s.exclude_from_auto_schedule?" · Occasional":""]},s.call_sign))]})]})]}),e.jsxs("div",{className:"md:col-span-3",children:[e.jsx(R,{className:"text-xs font-mono uppercase text-muted-foreground",children:"Backup"}),e.jsxs(q,{value:p,onValueChange:m,children:[e.jsx(I,{children:e.jsx(F,{placeholder:"Backup"})}),e.jsxs(G,{children:[e.jsx(P,{value:v,children:"None"}),r.map(s=>e.jsxs(P,{value:s.call_sign,children:[s.call_sign," â ",s.name,s.exclude_from_auto_schedule?" · Occasional":""]},s.call_sign))]})]})]}),e.jsxs("div",{className:"md:col-span-3",children:[e.jsx(R,{className:"text-xs font-mono uppercase text-muted-foreground",children:"Notes"}),e.jsx(ae,{value:y,onChange:s=>M(s.target.value),placeholder:"Optional",maxLength:500})]}),e.jsx("div",{className:"md:col-span-12",children:e.jsxs("label",{className:"flex items-start gap-2 text-xs text-muted-foreground cursor-pointer",children:[e.jsx("input",{type:"checkbox",checked:J,onChange:s=>xe(s.target.checked),className:"mt-0.5"}),e.jsxs("span",{children:[e.jsx("span",{className:"font-mono uppercase tracking-wider text-foreground",children:"One-time substitute"})," â ","flag this as a one-off change so the rotation generator ignores it when continuing the pattern."]})]})}),e.jsx("div",{className:"md:col-span-12",children:e.jsxs(w,{type:"submit",disabled:he||!x,className:"font-mono uppercase",children:[e.jsx(js,{className:"h-4 w-4 mr-1"}),he?"Savingâ¦":"Save Entry"]})})]})]}),U&&e.jsxs(Y,{className:"panel p-5 sm:p-6 mb-6",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-2 flex-wrap",children:[e.jsx(pe,{className:"h-4 w-4 text-primary"}),e.jsx("h2",{className:"font-display text-lg font-semibold",children:"Generate Rotation"}),e.jsx(De,{kind:"editor"})]}),e.jsxs("p",{className:"text-xs text-muted-foreground mb-3",children:["Cycles through the"," ",r.filter(s=>!s.exclude_from_auto_schedule).length," ","regular controller",r.filter(s=>!s.exclude_from_auto_schedule).length===1?"":"s"," ","in alphabetical order, one per week. Operators flagged"," ",e.jsx("span",{className:"text-foreground font-medium",children:"Occasional"})," on the roster are skipped here but can still be picked manually as substitutes. The next primary continues from where the most recent non-override entry left off. One-time substitutes are skipped when reading the rotation position. Existing dates are not overwritten."]}),e.jsxs("div",{className:"flex flex-wrap items-end gap-3",children:[e.jsxs("div",{children:[e.jsx(R,{className:"text-xs font-mono uppercase text-muted-foreground",children:"Weeks"}),e.jsx(ae,{type:"number",min:1,max:52,value:Z,onChange:s=>qe(s.target.value),className:"w-24"})]}),e.jsxs(w,{type:"button",onClick:Ze,disabled:ge,variant:"secondary",className:"font-mono uppercase",children:[e.jsx(pe,{className:"h-4 w-4 mr-1"}),ge?"Generatingâ¦":"Generate"]})]}),e.jsxs("div",{className:"mt-4 rounded-md border border-border/60 bg-muted/30 p-3",children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("p",{className:"font-mono text-[10px] uppercase tracking-widest text-muted-foreground",children:"Preview"}),!S.error&&S.items.length>0&&e.jsxs("p",{className:"font-mono text-[10px] uppercase tracking-widest text-muted-foreground",children:[S.items.filter(s=>!s.existing).length," new"," · ",S.items.filter(s=>s.existing).length," skipped"]})]}),S.error?e.jsx("p",{className:"text-xs text-muted-foreground italic",children:S.error}):S.items.length===0?e.jsx("p",{className:"text-xs text-muted-foreground italic",children:"Enter a number of weeks to preview the rotation."}):e.jsxs(e.Fragment,{children:[e.jsx("p",{className:"mb-2 text-[11px] text-muted-foreground",children:"Adjust Primary / Backup or check Skip on any week before clicking Generate. Edited weeks are saved as one-off overrides so the rotation pattern continues normally."}),e.jsx("ul",{className:"divide-y divide-border/40 max-h-96 overflow-auto",children:S.items.map(s=>{let a=s.date;try{a=C($(s.date),"EEE, MMM d")}catch{}const i=Q[s.date]??{},l=i.primary??s.primary.call_sign,j=i.backup??s.backup.call_sign,_=i.primary!==void 0||i.backup!==void 0||i.skip!==void 0,O=s.existing||i.skip;return e.jsxs("li",{className:"py-2 grid grid-cols-12 gap-2 text-xs items-center "+(O?"opacity-60":""),children:[e.jsx("span",{className:"col-span-3 sm:col-span-2 font-mono",children:a}),e.jsxs("div",{className:"col-span-4 sm:col-span-4 flex items-center gap-1",children:[e.jsx("span",{className:"text-muted-foreground font-mono",children:"P:"}),e.jsxs(q,{value:l,onValueChange:N=>de(s.date,{primary:N}),disabled:s.existing||i.skip,children:[e.jsx(I,{className:"h-7 text-xs font-mono",children:e.jsx(F,{})}),e.jsxs(G,{children:[e.jsx(P,{value:v,children:"â"}),r.map(N=>e.jsx(P,{value:N.call_sign,children:N.call_sign},N.call_sign))]})]})]}),e.jsxs("div",{className:"col-span-4 sm:col-span-4 flex items-center gap-1",children:[e.jsx("span",{className:"text-muted-foreground font-mono",children:"B:"}),e.jsxs(q,{value:j,onValueChange:N=>de(s.date,{backup:N}),disabled:s.existing||i.skip,children:[e.jsx(I,{className:"h-7 text-xs font-mono",children:e.jsx(F,{})}),e.jsxs(G,{children:[e.jsx(P,{value:v,children:"â"}),r.map(N=>e.jsx(P,{value:N.call_sign,children:N.call_sign},N.call_sign))]})]})]}),e.jsx("div",{className:"col-span-1 sm:col-span-2 flex items-center justify-end gap-2",children:s.existing?e.jsx("span",{className:"font-mono text-[10px] uppercase tracking-wider text-muted-foreground",children:"exists"}):e.jsxs(e.Fragment,{children:[e.jsxs("label",{className:"flex items-center gap-1 cursor-pointer text-[10px] uppercase tracking-wider text-muted-foreground",children:[e.jsx("input",{type:"checkbox",className:"h-3 w-3",checked:!!i.skip,onChange:N=>de(s.date,{skip:N.target.checked})}),"Skip"]}
1),_&&e.jsx("button",{type:"button",title:"Reset to auto-rotation default",onClick:()=>Xe(s.date),className:"font-mono text-[10px] uppercase tracking-wider text-primary hover:underline",children:"reset"})]})})]},s.date)})})]})]})]}),We&&e.jsx(Bs,{rotationItems:S.items,availability:ze,myCall:W,isEditor:U,onChanged:Ve}),e.jsx("p",{className:"mt-6 text-sm",children:e.jsx(xs,{to:"/",className:"text-primary underline font-mono uppercase",children:"â Back home"})})]})]})}export{ia 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.