PageSourceSearch

https://trianglecurling.com/assets/AdminVolunteering-h4A54BJZ.js

js trianglecurling.com collected 2026-10-08 06:00:33 UTC 11,820 bytes, 1 lines download raw bytes

1import{r as s,$ as t,a2 as Y,_ as z,a4 as ee,a5 as K}from"./vendor-C1VgWBuX.js";import{A as te,a as ae}from"./AppPage-xG3wnjLT.js";import{A as re}from"./AppPageControlsRow-DdZvdtUW.js";import{F as se,G as ne,B as E,p as ie,h as j,u as J,m as Q,c as oe,d as le,f as B,b as k}from"./index-5hIAAaYU.js";import{P as de}from"./PageTabs-BxfopgsZ.js";import{S as ce,D as me}from"./SortableList-Bh0A4D-u.js";import{S as q}from"./SortableRow-C3wHGJWP.js";import{I as ue}from"./IncludeArchivedToggle-Dxs1W6b4.js";import{S as ge}from"./SoftDeleteRowActions-B4bVjx1Q.js";import{D as pe}from"./DataTable-BCv0ar_9.js";import{i as U}from"./softDelete-BfE9329i.js";import{V as he,b as xe,p as D,c as fe,d as ye,e as H,a as G,g as W,h as ve,i as _}from"./volunteering-DVv7VtCy.js";import{F as V}from"./FormField-DGai0Kay.js";import{F as be}from"./FormSection-DfTVaiuu.js";import{I as je}from"./InlineStateMessage-BM010uxt.js";import{M as Se}from"./MemberMultiSelect-Dhlmki86.js";import{M as Ce}from"./Modal-72ZFPyar.js";import{V as Ne}from"./VolunteerProgramLocationField-B0gsP5kc.js";import"./dnd-kit-BgaaM9mg.js";import"./FormCheckbox-C0iae7Jb.js";import"./MemberEmail-COOj5TWq.js";function Ae(r){if(r.startDate){const[u,c,i]=r.startDate.split("-").map(Number);return u&&c&&i?new Date(u,c-1,i).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"}):r.startDate}return r.shifts.length>0?"the earliest shift day (source has no start date)":"none"}function ke({sourceProgram:r,onClose:u,onDuplicated:c}){const i=s.useId(),h=s.useId(),m=s.useId(),$=s.useId(),I=s.useId(),{branding:F}=se(),d=ne(F?.clubName),[S,L]=s.useState(!1),[C,x]=s.useState(""),[o,N]=s.useState(""),[f,T]=s.useState(""),[y,M]=s.useState(""),[P,O]=s.useState(he),[w,R]=s.useState([]),b=(r?.shifts.length??0)>0,g=xe(D(r?.signupKind));s.useEffect(()=>{r&&(N(`${r.title} (Copy)`),T(""),M(r.pointOfContact),O(fe(r.location,d)),R(r.managers.map(a=>a.id)),x(""))},[d,r]);const A=()=>{S||u()},e=async a=>{if(a.preventDefault(),!r)return;if(x(""),b&&!f.trim()){x(`Start date is required so ${g.shiftPlural} can be adjusted.`);return}if(P===null){x("Enter a custom location, or choose the club.");return}const n={title:o.trim(),pointOfContact:y.trim(),location:ye(P,d),startDate:f.trim()||null,managerIds:w};L(!0);try{const v=await ie("/volunteering/admin/programs/{id}/duplicate",n,{id:String(r.id)});c(v.id)}catch(v){x(j(v,"Failed to duplicate program"))}finally{L(!1)}};return t.jsx(Ce,{isOpen:r!=null,onClose:A,title:r?`Duplicate ${r.title}`:"Duplicate program",size:"lg",verticalAlign:"start",children:r?t.jsxs("form",{onSubmit:e,className:"space-y-6",children:[t.jsxs("p",{className:"text-sm text-gray-600 dark:text-gray-400",children:["Review the new program details. ",g.roleTab," and ",g.shiftPlural," are copied; sign-ups are not."," ",g.shiftTab," keep the same time of day and move with the new start date."]}),t.jsxs(be,{title:"New program",surface:"panel",children:[t.jsx(V,{label:"Title",htmlFor:i,required:!0,children:t.jsx("input",{id:i,type:"text",required:!0,maxLength:300,value:o,onChange:a=>N(a.target.value),className:"app-input"})}),t.jsx(V,{label:"Start date",htmlFor:h,required:b,optional:!b,helperText:b?`Source starts on ${Ae(r)}. ${g.shiftTab} move by the same number of days.`:`Optional. Copied programs without ${g.shiftPlural} do not need a start date.`,children:t.jsx("input",{id:h,type:"date",required:b,value:f,onChange:a=>T(a.target.value),className:"app-input w-full max-w-xs"})}),t.jsx(V,{label:"Point of contact",htmlFor:m,required:!0,children:t.jsx("input",{id:m,type:"text",required:!0,maxLength:320,value:y,onChange:a=>M(a.target.value),className:"app-input"})}),t.jsx(Ne,{id:$,clubName:d,value:P,onChange:O,optional:!0}),t.jsx(V,{label:"Managers",htmlFor:I,helperText:`Managers can edit this program’s ${g.rolePlural}, ${g.shiftPlural}, and sign-ups.`,children:t.jsx(Se,{inputId:I,selectedIds:w,onChange:R,placeholder:"Search members..."})})]}),C?t.jsx(je,{title:C,tone:"error"}):null,t.jsxs("div",{className:"flex justify-end gap-3",children:[t.jsx(E,{type:"button",variant:"secondary",onClick:A,disabled:S,children:"Cancel"}),t.jsx(E,{type:"submit",disabled:S,children:S?"Duplicating...":"Duplicate program"})]})]}):null})}function Ye(){const r=Y(),u=z(),{member:c}=J(),i=Q(c,"volunteering.manage")||!!c?.isServerAdmin,h=r.pathname.endsWith("/hour-logs"),m=r.pathname.endsWith("/general");return t.jsxs(te,{children:[t.jsx(ae,{title:"Manage sign-ups",description:h?"Review and manage hours logged for time outside scheduled programs.":m?"General sign-ups, descriptions, lists, and times.":"Volunteer programs, descriptions, roles, and shifts."}),t.jsx(de,{items:[{key:"volunteering",label:"Volunteering",isActive:!h&&!m,onClick:()=>u("/admin/volunteering")},{key:"general",label:"General sign-ups",isActive:m,onClick:()=>u("/admin/volunteering/general")}
1,...i?[{key:"hour-logs",label:"Self-reported hours",isActive:h,onClick:()=>u("/admin/volunteering/hour-logs")}]:[]]}),t.jsx(ee,{})]})}function ze(){const r=Y(),u=z(),c=r.pathname.endsWith("/general"),i=c?"general":"volunteering",h=`/admin/signups/new?kind=${i}`,[m,$]=s.useState([]),[I,F]=s.useState(!0),[d,S]=s.useState(!1),[L,C]=s.useState(null),{member:x}=J(),{showAlert:o}=oe(),{confirm:N}=le(),f=Q(x,"volunteering.manage")||!!x?.isServerAdmin,T=!!x?.isServerAdmin,y=()=>{F(!0);const e=d?{includeArchived:"1"}:void 0;k.get("/volunteering/admin/programs",{params:e}).then(a=>$(a.data?.programs||[])).catch(a=>o(j(a,"Failed to load programs"),"error")).finally(()=>F(!1))};s.useEffect(()=>{y()},[d]);const M=async e=>{try{await k.patch(`/volunteering/admin/programs/${e.id}`,{published:!e.published}),o(e.published?"Program unpublished":"Program published","success"),y()}catch(a){o(j(a,"Failed to update program"),"error")}},P=async e=>{if(await N({message:`Archive "${e.title}"? It will be unpublished and hidden from Volunteering & sign-ups but can be restored later.`,title:"Archive program",variant:"danger"}))try{await k.post(`/volunteering/admin/programs/${e.id}/archive`),o("Program archived","success"),y()}catch(n){o(j(n,"Failed to archive program"),"error")}},O=async e=>{if(await N({message:`Restore "${e.title}"? The program will appear in admin lists again. You can publish it when you are ready.`,title:"Restore program",variant:"info"}))try{await k.post(`/volunteering/admin/programs/${e.id}/restore`),o("Program restored","success"),y()}catch(n){o(j(n,"Failed to restore program"),"error")}},w=async e=>{if(await N({message:`Permanently delete "${e.title}"? This removes ${D(e.signupKind)==="general"?"lists, times":"roles, shifts"}, and signups.`,title:"Delete program",variant:"danger"}))try{await k.delete(`/volunteering/admin/programs/${e.id}`),o("Program deleted","success"),y()}catch(n){o(j(n,"Failed to delete program"),"error")}},R=async e=>{const a=m.filter(l=>D(l.signupKind)===i).filter(l=>!e.some(p=>p.id===l.id)).sort(_),n=[...e,...a],v=new Map(n.map((l,p)=>[l.id,p]));$(l=>l.map(p=>v.has(p.id)?{...p,priority:v.get(p.id)}:p));try{await k.post("/volunteering/admin/programs/reorder",{programIds:n.map(l=>l.id),signupKind:i})}catch(l){o(j(l,"Failed to update program order"),"error"),y()}},b=e=>t.jsxs("div",{className:"flex items-center justify-end gap-1",children:[t.jsx("button",{type:"button",onClick:()=>C(e),className:"rounded px-2 py-1 text-xs text-gray-600 hover:bg-gray-100 hover:text-gray-900 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-gray-100",title:"Duplicate",children:"Duplicate"}),U(e.archivedAt)?null:t.jsx("button",{type:"button",onClick:()=>M(e),className:"rounded px-2 py-1 text-xs text-gray-600 hover:bg-gray-100 hover:text-gray-900 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-gray-100",title:e.published?"Unpublish":"Publish",children:e.published?"Unpublish":"Publish"}),t.jsx(ge,{archived:U(e.archivedAt),isServerAdmin:T,onArchive:()=>P(e),onRestore:()=>O(e),onDeletePermanently:()=>w(e)})]}),g=s.useMemo(()=>[{id:"title",header:"Program",cellClassName:"min-w-[14rem]",renderCell:e=>t.jsxs("div",{children:[t.jsx(K,{to:`/admin/volunteering/${e.id}`,className:"font-medium text-primary-teal-link hover:underline",children:e.title}),e.location?t.jsx("div",{className:"text-sm text-gray-500 dark:text-gray-400",children:e.location}):null]})},{id:"date",header:"Date",cellClassName:"text-sm text-gray-600 dark:text-gray-400",renderCell:e=>{const a=H(e);return a?G(a):"—"}},{id:"signups",header:"Sign-ups",align:"right",cellClassName:"text-sm text-gray-700 dark:text-gray-300",renderCell:e=>{const{signedUp:a,needed:n}=W(e);return`${a}/${n}`}},{id:"managers",header:"Managers",renderCell:e=>e.managers.length===0?"—":e.managers.map(a=>a.name).join(", ")}],[]),A=s.useMemo(()=>{const e=m.filter(n=>D(n.signupKind)===i);return[...d?e:e.filter(n=>!ve(n,new Date().toISOString()))].sort(_)},[m,d,i]);return t.jsxs(t.Fragment,{children:[I?null:t.jsx(re,{left:f?t.jsx(ue,{checked:d,onChange:S}):null,right:f?t.jsx(E,{type:"button",onClick:()=>u(h),children:"Create program"}):null}),I?t.jsx(B,{title:"Loading programs..."}):A.length===0?t.jsx(B,{title:d?"No programs match these filters.":m.some(e=>D(e.signupKind)===i)?"No upcoming programs.":c?"No general sign-ups yet.":"No programs yet.",description:!d&&m.some(e=>D(e.signupKind)===i)?"Past programs are hidden. Include archived items to review them.":f?c?"Create a general sign-up to start adding a description, lists, and times.":"Create a volunteer program to start adding a description, roles, and shifts.":"You are not a manager of any programs in this list.",action:f&&!d?t.jsx(K,{to:h,children:t.jsx(E,{type:"button",children:"Create program"})}):void 0}):f?t.jsxs("div",{className:"space-y-3",children:[t.jsx("p",{className:"text-sm text-gray-600 dark:text-gray-400",children:"Drag programs to change the order they appear on Volunteering & sign-ups and the member dashboard."}),t.jsx(ce,{items:A,getId:e=>e.id,getItemLabel:e=>e.title,itemNoun:"program",onReorder:e=>{R(e)},renderItem:({item:e,isDragging:a,isOverlay:n,dragHandle:v})=>{const l=H(e),{signedUp:p,needed:X}=W(e);return t.jsx(q,{isDragging:a,isOverlay:n,className:"border-gray-200 px-3 py-3 dark:border-gray-700",children:t.jsxs("div",{className:"flex items-start justify-between gap-4",children:[t.jsxs("div",{className:"flex min-w-0 items-start gap-3",children:[v,t.jsxs("div",{className:"min-w-0 space-y-1",children:[t.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[t.jsx(K,{to:`/admin/volunteering/${e.id}`,className:"font-medium text-primary-teal-link hover:underline",children:e.title}),e.published?null:t.jsx("span",{className:"rounded-full bg-gray-100 px-2 py-0.5 text-[11px] font-medium text-gray-600 dark:bg-gray-800 dark:text-gray-300",children:"Unpublished"}),U(e.archivedAt)?t.jsx("span",{className:"rounded-full bg-gray-100 px-2 py-0.5 text-[11px] font-medium text-gray-600 dark:bg-gray-800 dark:text-gray-300",children:"Archived"}):null]}),e.location?t.jsx("div",{className:"text-sm text-gray-500 dark:text-gray-400",children:e.location}):null,t.jsxs("div",{className:"text-sm text-gray-600 dark:text-gray-400",children:[l?G(l):c?"N
1o times yet":"No shifts yet"," · ",p,"/",X," sign-ups",e.managers.length>0?` · ${e.managers.map(Z=>Z.name).join(", ")}`:""]})]})]}),t.jsx("div",{className:"shrink-0",children:b(e)})]})})},renderOverlay:e=>t.jsx(q,{isDragging:!0,isOverlay:!0,className:"px-3 py-3",children:t.jsxs("div",{className:"flex items-center gap-3",children:[t.jsx(me,{label:`Reorder ${e.title}`,disabled:!0}),t.jsx("div",{className:"font-medium",children:e.title})]})})})]}):t.jsx(pe,{rows:A,rowKey:e=>e.id,columns:g}),t.jsx(ke,{sourceProgram:L,onClose:()=>C(null),onDuplicated:e=>{C(null),o("Program duplicated","success"),u(`/admin/volunteering/${e}`)}})]})}export{ze as AdminVolunteeringPrograms,Ye 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.