PageSourceSearch

https://8004.ch/assets/AdminHelfer-BH5Ixiid.js

js 8004.ch collected 2026-09-25 07:32:24 UTC 35,676 bytes, 9 lines download raw bytes

1import{j as e,r as x,u as Qe,s as h}from"./index-CLTM18rh.js";import{u as Xe}from"./AdminContext-B2hLlcqc.js";import{N as Ye}from"./NurLesen-BKsmfvXD.js";import{m as et}from"./massenversand-8NVIJTcX.js";import{b as ne}from"./bestaetige-CpNFuPQa.js";import{g as tt,u as Pe,m as Ne}from"./klappzustand-DoGK2Y88.js";import{C as le}from"./chevron-right-D-hIC4R2.js";import"./authFetch-u5HjDcUX.js";function nt({className:c="w-4 h-4"}){return e.jsx("svg",{className:c,fill:"currentColor",viewBox:"0 0 20 20","aria-hidden":!0,children:e.jsx("path",{d:"M7 2a2 2 0 110 4 2 2 0 010-4zm6 0a2 2 0 110 4 2 2 0 010-4zM7 8a2 2 0 110 4 2 2 0 010-4zm6 0a2 2 0 110 4 2 2 0 010-4zm-6 6a2 2 0 110 4 2 2 0 010-4zm6 0a2 2 0 110 4 2 2 0 010-4z"})})}function st(c,a){const[p,g]=x.useState(null),[z,d]=x.useState(null),j=f=>{if(p===null||p===f){g(null),d(null);return}const O=[...c],[v]=O.splice(p,1);O.splice(f,0,v),g(null),d(null),a(O)};return{aktiv:p!==null,props:f=>({draggable:!0,onDragStart:()=>g(f),onDragOver:O=>{O.preventDefault(),d(f)},onDrop:()=>j(f),onDragEnd:()=>{g(null),d(null)}}),klassen:f=>z===f&&p!==null&&p!==f?"bg-red-50 dark:bg-red-950/20":p===f?"opacity-40":""}}function we(c,a){const p=new Set,g=j=>c.filter(f=>a.ohne?.has(f.id)||p.has(f.id)||!j(f)?!1:(p.add(f.id),!0)),z=[],d=()=>z.push({titel:"Vorstand",personen:g(j=>j.isVorstand)});return a.vorstandZuerst&&d(),z.push({titel:"Für diesen Anlass zugesagt",personen:g(j=>a.zugesagt.has(j.id))}),z.push({titel:"Im Portal gemeldet",personen:g(j=>a.ausPortal?.has(j.id)??!1)}),z.push({titel:"Eingeladen, noch offen",personen:g(j=>a.eingeladen.has(j.id))}),a.vorstandZuerst||d(),z.push({titel:"Alle übrigen Mitglieder",personen:g(()=>!0)}),z.filter(j=>j.personen.length>0)}function at({stations:c,onSortiert:a,canEdit:p,render:g}){const z=st(c.map(d=>d.id),a);return e.jsx("div",{className:"flex flex-col gap-4",children:c.map((d,j)=>e.jsx("div",{children:g(d,p?z.props(j):{},z.klassen(j))},d.id))})}function ke({gruppen:c}){return e.jsx(e.Fragment,{children:c.map(a=>e.jsx("optgroup",{label:`${a.titel} (${a.personen.length})`,children:a.personen.map(p=>e.jsxs("option",{value:p.id,children:[p.label,p.isVorstand?" (Vorstand)":""]},p.id))},a.titel))})}const it={aufbau_abbau:"Auf-/Abbau",verpflegung:"Verpflegung",kasse:"Kasse",kinder:"Kinder",transport:"Transport",betreuung:"Stand/Info",reinigung:"Reinigung"},rt={wochenende:"Wochenende",abend:"Abends",tagsueber:"Tagsüber"},Se={planung:"Planung",anfrage_laeuft:"Anfrage läuft",besetzt:"Besetzt",abgeschlossen:"Abgeschlossen"},lt={planung:"bg-zinc-100 text-zinc-600 dark:bg-zinc-800 dark:text-zinc-300",anfrage_laeuft:"bg-amber-100 text-amber-700 dark:bg-amber-900/40 dark:text-amber-400",besetzt:"bg-green-100 text-green-700 dark:bg-green-900/40 dark:text-green-400",abgeschlossen:"bg-zinc-100 text-zinc-500 dark:bg-zinc-800 dark:text-zinc-400"},ye={vorstand:"Nur Vorstand",pool:"Vorstand + Helferpool",oeffentlich:"Alle Mitglieder"},y="px-2.5 py-1.5 rounded-lg border border-zinc-300 dark:border-zinc-600 bg-white dark:bg-zinc-900 text-sm text-zinc-900 dark:text-zinc-100 focus:outline-none focus:ring-2 focus:ring-red-500/40",C="block text-[12px] font-medium text-zinc-500 dark:text-zinc-400 mb-1",Ee=c=>c?new Date(c).toISOString().slice(11,16):"";function $e(c,a){return!c||!a?null:new Date(`${c}T${a}:00`).toISOString()}function bt(){const{permissions:c}=Xe(),a=c.perm_members,p=c.perm_members||c.perm_members_view,[g,z]=x.useState([]),[d,j]=x.useState([]),[f,O]=x.useState([]),[v,D]=x.useState(null),[V,se]=x.useState(!0),[de,w]=x.useState(null),[Ce,X]=x.useState(null),[Ve]=Qe(),F=Ve.get("einsatz"),[q,u]=x.useState(!1),[K,Me]=x.useState([]),[Y,Ae]=x.useState({}),[oe,Be]=x.useState({}),[ce,De]=x.useState({}),[R,ue]=x.useState({}),[me,he]=x.useState(null),[Ie,pe]=x.useState(()=>new Set(tt("helfer:stationen"))),xe=t=>pe(i=>{const r=new Set(i);return r.has(t)?r.delete(t):r.add(t),Ne("helfer:stationen",r),r}),[ge,fe]=Pe("helfer:pool",!1),[be,Le]=x.useState(!1),[ae,Oe]=x.useState({}),[ie,_e]=x.useState({}),S=x.useCallback(async(t=!1)=>{t||se(!0),w(null);const[i,r,b,M,A,T,k,E,W,J,n,o]=await Promise.all([h.from("helper_events").select("id, title, starts_on, event_id, host_person_id, status, audience, notes, helper_stations(id, title, description, responsible_person_id, sort_order, helper_shifts(id, title, starts_at, ends_at, needed, notes, helper_assignments(person_id, status)))").order("starts_on",{ascending:!0,nullsFirst:!1}),h.from("persons").select("id, first_name, last_name, email"),h.from("person_roles").select("person_id").eq("scope","qv"),h.from("events").select("id, title, date").gte("date",new Date().toISOString().slice(0,10)).order("date"),h.from("organizers").select("id").eq("is_self",!0).maybeSingle(),h.from("person_interests").select("person_id").eq("kind","betaetigung").eq("value","veranstaltungen"),h.from("helper_profiles").select("person_id, tasks, time_windows, event_types, max_per_year, notes"),h.from("helper_invitations").select("helper_event_id, person_id, sent_at, declined_at"),h.from("helper_interests").select("event_id, person_id, note").eq("status","gemeldet"),h.from("event_plans").select("id, helper_event_id, event_id").not("helper_event_id","is",null),h.from("event_plan_events").select("plan_id, event_id"),h.from("membership_events").select("person_id, created_at, meta, kind").in("kind",["mail_sent","engagement"]).not("meta->>plan_id","is",null)]);if(i.error){w(i.error.message),se(!1);return}const B=new Set((b.data??[]).map(s=>s.person_id)),m=r.data??[];z(i.data??[]),j(m.map(s=>{const N=`${s.first_name??""} ${s.last_name??""}`.trim();return{id:s.id,label:N||(s.email?`${s.email} (ohne Name)`:"(ohne Name)"),namenlos:!N,isVorstand:B.has(s.id),email:s.email}}).sort((s,N)=>Number(s.namenlos)-Number(N.namenlos)||s.label.localeCompare(N.label,"de")));const I=new Set((T.data??[]).map(s=>s.person_id)),L=new Map((k.data??[]).map(s=>[s.person_id,s]));Me(m.filter(s=>I.has(s.id)).map(s=>{const N=L.get(s.id);return{id:s.id,label:`${s.first_name??""} ${s.last_name??""}`.trim()||"(ohne Name)",email:s.email,hatProfil:L.has(s.id),tasks:N?.tasks??[],time_windows:N?.time_windows??[],event_types:N?.event_types??[],max_per_year:N?.max_per_year??null,notes:N?.notes??null}}).sort((s,N)=>Number(N.hatProfil)-Number(s.hatProfil)||s.label.localeCompare(N.label,"de")));const $={};
1(E.data??[]).forEach(s=>{$[s.helper_event_id]=$[s.helper_event_id]??{},$[s.helper_event_id][s.person_id]={sent_at:s.sent_at,declined_at:s.declined_at}}),Ae($);const l=new Map;for(const s of J.data??[])s.helper_event_id&&l.set(s.helper_event_id,s.id);const P={};for(const s of o.data??[]){const N=s.meta?.plan_id;if(!(!N||!s.person_id))for(const[G,Q]of l){if(Q!==N)continue;P[G]=P[G]??{};const te=P[G][s.person_id];(!te||s.created_at<te)&&(P[G][s.person_id]=s.created_at)}}Be(P);const U=new Map;for(const s of n.data??[])U.set(s.plan_id,[...U.get(s.plan_id)??[],s.event_id]);const _=new Map;for(const s of W.data??[])_.set(s.event_id,[..._.get(s.event_id)??[],s]);const ve={};for(const s of i.data??[]){const N=l.get(s.id),G=new Set([...s.event_id?[s.event_id]:[],...N?U.get(N)??[]:[]]),Q=new Map;for(const te of G)for(const ze of _.get(te)??[])Q.set(ze.person_id,ze);Q.size>0&&(ve[s.id]=[...Q.values()])}De(ve),O(M.data??[]),D(A.data?.id??null),se(!1)},[]);x.useEffect(()=>{S()},[S]);const H=x.useMemo(()=>new Map(d.map(t=>[t.id,t])),[d]);async function qe(){if(!v){w("Kein Veranstalter (QV) gefunden.");return}u(!0);const{data:t,error:i}=await h.from("helper_events").insert({organizer_id:v,title:"Neuer Einsatz",status:"planung",audience:"vorstand"}).select("id").single();if(u(!1),i){w(i.message);return}await S(!0),X(t.id)}async function Z(t,i){u(!0);const{error:r}=await h.from("helper_events").update({...i,updated_at:new Date().toISOString()}).eq("id",t);if(u(!1),r){w(r.message);return}await S(!0)}async function He(t){if(!await ne("Diesen Einsatz mit allen Schichten und Eintragungen löschen?"))return;u(!0);const{error:i}=await h.from("helper_events").delete().eq("id",t);if(u(!1),i){w(i.message);return}X(null),await S(!0)}async function Te(t){u(!0);const i=(g.find(b=>b.id===t)?.helper_stations??[]).length,{error:r}=await h.from("helper_stations").insert({helper_event_id:t,title:"Neue Station",sort_order:i});if(u(!1),r){w(r.message);return}await S(!0)}async function Ke(t,i){u(!0);const r=g.find(k=>k.id===t)?.helper_stations??[],{data:b,error:M}=await h.from("helper_stations").insert({helper_event_id:t,title:`${i.title} (Kopie)`,description:i.description,responsible_person_id:i.responsible_person_id,sort_order:(i.sort_order??r.length)+1}).select("id").single();if(M||!b){u(!1),w(M?.message??"Fehler");return}const A=i.helper_shifts??[];if(A.length>0){const{error:k}=await h.from("helper_shifts").insert(A.map(E=>({helper_event_id:t,station_id:b.id,title:E.title,starts_at:E.starts_at,ends_at:E.ends_at,needed:E.needed,notes:E.notes})));if(k){u(!1),w(k.message);return}}const T=r.filter(k=>(k.sort_order??0)>(i.sort_order??0));for(const k of T)await h.from("helper_stations").update({sort_order:(k.sort_order??0)+1}).eq("id",k.id);u(!1),pe(k=>{const E=new Set(k);return E.add(b.id),Ne("helfer:stationen",E),E}),await S(!0)}async function Ze(t){u(!0);for(const[i,r]of t.entries())await h.from("helper_stations").update({sort_order:i}).eq("id",r);u(!1),await S(!0)}async function re(t,i){u(!0);const{error:r}=await h.from("helper_stations").update(i).eq("id",t);if(u(!1),r){w(r.message);return}await S(!0)}async function Ue(t){if(!await ne("Diese Station mit allen Schichten und Eintragungen löschen?"))return;u(!0);const{error:i}=await h.from("helper_stations").delete().eq("id",t);if(u(!1),i){w(i.message);return}await S(!0)}async function Fe(t,i){u(!0);const{error:r}=await h.from("helper_shifts").insert({station_id:t,helper_event_id:i,title:"Neue Schicht",needed:1});if(u(!1),r){w(r.message);return}await S(!0)}async function ee(t,i){u(!0);const{error:r}=await h.from("helper_shifts").update(i).eq("id",t);if(u(!1),r){w(r.message);return}await S(!0)}async function Ge(t){if(!await ne("Diese Schicht löschen?"))return;u(!0);const{error:i}=await h.from("helper_shifts").delete().eq("id",t);if(u(!1),i){w(i.message);return}await S(!0)}async function Re(t,i){u(!0);const{error:r}=await h.from("helper_assignments").insert({shift_id:t,person_id:i,status:"zugesagt",responded_at:new Date().toISOString()});if(u(!1),r){w(r.message.includes("duplicate")?"Diese Person ist bereits eingetragen.":r.message);return}await S(!0)}async function We(t,i){u(!0);const{error:r}=await h.from("helper_assignments").delete().eq("shift_id",t).eq("person_id",i);if(u(!1),r){w(r.message);return}await S(!0)}async function Je(t){const i=[...R[t]??[]];if(i.length===0)return;const r=i.filter(b=>oe[t]?.[b]).map(b=>H.get(b)?.label??"jemand");if(!(r.length>
10&&!await ne(`${r.length===1?"Diese Person wurde":"Diese Personen wurden"} über den Veranstaltungsplaner schon um Mithilfe für diesen Anlass gebeten:
2
3${r.join(`
4`)}
5
6Trotzdem eine zweite Anfrage schicken?`,{jaLabel:"Trotzdem senden"}))&&et(i.length,"Helfer-Einladung")){u(!0),he(null),w(null);try{const{data:{session:b}}=await h.auth.getSession(),M=await fetch("/api/admin/helper-invite",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${b?.access_token??""}`},body:JSON.stringify({helperEventId:t,personIds:i})}),A=await M.json().catch(()=>({}));if(!M.ok){w(A.error||"Einladung fehlgeschlagen.");return}he(`${A.sent} Einladung${A.sent===1?"":"en"} verschickt${A.skipped?.length?` · ohne E-Mail übersprungen: ${A.skipped.join(", ")}`:""}.`),ue(T=>({...T,[t]:new Set})),await S(!0)}catch{w("Verbindung fehlgeschlagen.")}finally{u(!1)}}}x.useEffect(()=>{!F||V||g.some(t=>t.id===F)&&(X(F),setTimeout(()=>{document.getElementById(`einsatz-${F}`)?.scrollIntoView({behavior:"smooth",block:"center"})},60))},[F,V,g]);function je(t,i){ue(r=>{const b=new Set(r[t]??[]);return b.has(i)?b.delete(i):b.add(i),{...r,[t]:b}})}return p?V?e.jsx("p",{className:"text-sm text-zinc-400",children:"Lade Helfereinsätze…"}):e.jsxs("div",{children:[e.jsx(Ye,{recht:"perm_members"}),e.jsxs("div",{className:"flex flex-wrap items-end justify-between gap-3 mb-4",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold text-zinc-900 dark:text-white",children:"Helfereinsätze"}),e.jsxs("p",{className:"text-sm text-zinc-500 dark:text-zinc-400 mt-0.5",children:[g.length===0?"Noch keine Einsätze":`${g.length} Einsätze`," · Eintragen tun sich die Helfer:innen im Mitgliederportal"]})]}),a&&e.jsx("button",{onClick:qe,disabled:q,className:"px-3.5 py-2 rounded-lg bg-red-600 text-white text-sm font-semibold hover:bg-red-700 disabled:opacity-50",children:"+ Neuer Einsatz"})]}),de&&e.jsx("p",{className:"mb-3 text-sm text-red-600",children:de}),e.jsx(ot,{}),g.length===0&&e.jsx("div",{className:"rounded-xl border border-dashed border-zinc-300 dark:border-zinc-700 p-8 text-center",children:e.jsx("p",{className:"text-sm text-zinc-500 dark:text-zinc-400",children:"Noch kein Einsatz geplant. Lege einen an, ergänze Schichten und stelle ihn dann auf «Anfrage läuft» — dann erscheint er im Portal für die gewählte Zielgruppe."})}),e.jsx("div",{className:"flex flex-col gap-3",children:g.map(t=>{const i=Ce===t.id,r=[...t.helper_stations??[]].sort((n,o)=>n.sort_order-o.sort_order||n.title.localeCompare(o.title,"de")),b=r.flatMap(n=>n.helper_shifts??[]),M=b.reduce((n,o)=>n+(o.needed??0),0),A=b.reduce((n,o)=>n+(o.helper_assignments??[]).filter(B=>B.status==="zugesagt").length,0),T=t.host_person_id?H.get(t.host_person_id):null,k=new Set(b.flatMap(n=>(n.helper_assignments??[]).filter(o=>o.status==="zugesagt").map(o=>o.person_id))),E=new Set(Object.entries(Y[t.id]??{}).filter(([,n])=>!n.declined_at).map(([n])=>n)),W=new Set((ce[t.id]??[]).map(n=>n.person_id)),J=new Set([...E,...W]).size;return e.jsxs("div",{id:`einsatz-${t.id}`,className:`rounded-xl border bg-white dark:bg-zinc-900 overflow-hidden ${t.id===F?"border-red-300 dark:border-red-800 ring-2 ring-red-500/20":"border-zinc-200 dark:border-zinc-800"}`,children:[e.jsxs("button",{onClick:()=>X(i?null:t.id),className:"w-full flex flex-wrap items-center gap-3 px-4 py-3 text-left hover:bg-zinc-50 dark:hover:bg-zinc-800/50",children:[e.jsx("span",{className:"font-semibold text-zinc-900 dark:text-white",children:t.title}),e.jsx("span",{className:`px-2 py-0.5 rounded-full text-[11px] font-bold ${lt[t.status]??""}`,children:Se[t.status]??t.status}),e.jsx("span",{className:"text-[12px] text-zinc-400",children:ye[t.audience]??t.audience}),t.starts_on&&e.jsx("span",{className:"text-sm text-zinc-500 tabular-nums",children:t.starts_on}),T&&e.jsxs("span",{className:"text-[12px] text-zinc-400",children:["Host: ",T.label]}),M===0&&J>0&&e.jsxs("span",{className:"ml-auto text-[12px] font-semibold text-green-700 dark:text-green-400",children:[J," bereit"]}),e.jsxs("span",{className:`${M===0&&J>0?"":"ml-auto"} text-sm font-semibold tabular-nums ${A>=M&&M>0?"text-green-600":"text-zinc-500"}`,children:[A," / ",M," Plätze"]})]}),i&&e.jsxs("div",{className:"border-t border-zinc-200 dark:border-zinc-800 p-4 space-y-5",children:[e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-3",children:[e.jsxs("div",{children:[e.jsx("label",{className:C,children:"Titel"}),e.jsx("input",{className:`${y} w-full`,defaultValue:t.title,disabled:!a,onBlur:n=>n.target.value!==t.title&&Z(t.id,{title:n.target.value})})]}),e.jsxs("div",{children:[e.jsx("label",{className:C,children:"Datum"}),e.jsx("input",{type:"date",className:`${y} w-full`,defaultValue:t.starts_on??"",disabled:!a,onBlur:n=>n.target.value!==(t.starts_on??"")&&Z(t.id,{starts_on:n.target.value||null})})]}),e.jsxs("div",{children:[e.jsx("label",{className:C,children:"Verknüpftes Event (Kalender)"}),e.jsxs("select",{className:`${y} w-full`,value:t.event_id??"",disabled:!a,onChange:n=>{const o=n.target.value||null,B=f.find(m=>m.id===o);Z(t.id,{event_id:o,...B?{starts_on:B.date,...t.title==="Neuer Einsatz"?{title:B.title}:{}}:{}})},children:[e.jsx("option",{value:"",children:"— frei erfasst (kein Event) —"}),t.event_id&&!f.some(n=>n.id===t.event_id)&&e.jsx("option",{value:t.event_id,children:"verknüpfter Anlass (nicht in der Liste, vermutlich vorbei)"}),f.map(n=>e.jsxs("option",{value:n.id,children:[n.date," · ",n.title]},n.id))]})]}),e.jsxs("div",{children:[e.jsx("label",{className:C,children:"Host (zuständig)"}),e.jsxs("select",{className:`${y} w-full`,value:t.host_person_id??"",disabled:!a,onChange:n=>Z(t.id,{host_person_id:n.target.value||null}),children:[e.jsx("option",{value:"",children:"— kein Host —"}),d.filter(n=>n.isVorstand).map(n=>e.jsx("option",{value:n.id,children:n.label},n.id))]})]}),e.jsxs("div",{children:[e.jsx("label",{className:C,children:"Zielgruppe (wer darf sich eintragen)"}),e.jsx("select",{className:`${y}
6 w-full`,value:t.audience,disabled:!a,onChange:n=>Z(t.id,{audience:n.target.value}),children:Object.entries(ye).map(([n,o])=>e.jsx("option",{value:n,children:o},n))})]}),e.jsxs("div",{children:[e.jsx("label",{className:C,children:"Status"}),e.jsx("select",{className:`${y} w-full`,value:t.status,disabled:!a,onChange:n=>Z(t.id,{status:n.target.value}),children:Object.entries(Se).map(([n,o])=>e.jsx("option",{value:n,children:o},n))}),t.status==="planung"&&e.jsx("p",{className:"mt-1 text-[11.5px] text-zinc-400",children:"In «Planung» noch nicht im Portal sichtbar."})]})]}),e.jsxs("div",{children:[e.jsx("label",{className:C,children:"Bemerkungen"}),e.jsx("textarea",{className:`${y} w-full`,rows:2,defaultValue:t.notes??"",disabled:!a,onBlur:n=>n.target.value!==(t.notes??"")&&Z(t.id,{notes:n.target.value||null})})]}),e.jsx(dt,{ausVorstand:Object.entries(Y[t.id]??{}).filter(([,n])=>!n.declined_at).map(([n])=>H.get(n)?.label??"Unbekannt"),abgesagt:Object.entries(Y[t.id]??{}).filter(([,n])=>n.declined_at).map(([n])=>H.get(n)?.label??"Unbekannt"),ausPortal:(ce[t.id]??[]).map(n=>({name:H.get(n.person_id)?.label??"Unbekannt",notiz:n.note})),eingeteilt:k.size}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("h3",{className:"text-sm font-bold text-zinc-900 dark:text-white",children:"Stationen"}),a&&e.jsx("button",{onClick:()=>Te(t.id),disabled:q,className:"text-sm text-red-600 hover:underline font-medium",children:"+ Station"})]}),r.length===0&&e.jsx("p",{className:"text-sm text-zinc-400",children:"Noch keine Station. Lege eine an (z. B. «Kuchen-Buffet»), darin dann die Schichten."}),e.jsx(at,{stations:r,onSortiert:Ze,canEdit:a,render:(n,o,B)=>{const m=n.helper_shifts??[],I=m.reduce((l,P)=>l+(P.needed??0),0),L=m.reduce((l,P)=>l+(P.helper_assignments??[]).filter(U=>U.status==="zugesagt").length,0),$=Ie.has(n.id);return e.jsxs("div",{...a?o:{},className:`rounded-xl border border-zinc-200 dark:border-zinc-700 bg-zinc-50/60 dark:bg-zinc-800/30 transition-colors ${B}`,children:[e.jsxs("div",{className:`flex flex-wrap items-center gap-x-2.5 gap-y-1 px-3.5 py-2.5 cursor-pointer
7                              hover:bg-zinc-100/70 dark:hover:bg-zinc-800/60 rounded-xl`,onClick:()=>xe(n.id),role:"button",tabIndex:0,onKeyDown:l=>{(l.key==="Enter"||l.key===" ")&&(l.preventDefault(),xe(n.id))},children:[a&&e.jsx("span",{className:"shrink-0 text-zinc-300 dark:text-zinc-600 cursor-grab active:cursor-grabbing",title:"Zum Verschieben ziehen",onClick:l=>l.stopPropagation(),children:e.jsx(nt,{className:"w-3.5 h-3.5"})}),e.jsx(le,{"aria-hidden":!0,className:`w-3.5 h-3.5 shrink-0 text-zinc-400 transition-transform ${$?"rotate-90":""}`}),e.jsx("span",{className:"font-semibold text-zinc-900 dark:text-white",children:n.title||"Ohne Namen"}),e.jsx("span",{className:"text-[12.5px] text-zinc-500",children:m.length===1?"1 Schicht":`${m.length} Schichten`}),n.responsible_person_id&&e.jsx("span",{className:"text-[12.5px] text-zinc-400",children:H.get(n.responsible_person_id)?.label??"unbekannt"}),e.jsxs("span",{className:`ml-auto text-sm font-semibold tabular-nums ${L>=I&&I>0?"text-green-600":"text-zinc-500"}`,children:[L," / ",I," Plätze"]})]}),$&&e.jsxs("div",{className:"px-3.5 pb-3.5",children:[e.jsxs("div",{className:"flex flex-wrap items-end gap-2",children:[e.jsxs("div",{className:"flex-1 min-w-[160px]",children:[e.jsx("label",{className:C,children:"Station"}),e.jsx("input",{className:`${y} w-full font-semibold`,defaultValue:n.title,disabled:!a,onBlur:l=>l.target.value!==n.title&&re(n.id,{title:l.target.value})})]}),e.jsxs("div",{className:"w-full sm:w-56",children:[e.jsx("label",{className:C,children:"Verantwortlich (optional)"}),e.jsxs("select",{className:`${y} w-full`,value:n.responsible_person_id??"",disabled:!a,onChange:l=>re(n.id,{responsible_person_id:l.target.value||null}),children:[e.jsx("option",{value:"",children:"— niemand —"}),e.jsx(ke,{gruppen:we(d,{zugesagt:k,eingeladen:E,ausPortal:W,vorstandZuerst:!0})})]})]})]}),e.jsxs("div",{className:"mt-2",children:[e.jsx("label",{className:C,children:"Beschreibung (optional)"}),e.jsx("input",{className:`${y} w-full`,defaultValue:n.description??"",disabled:!a,onBlur:l=>l.target.value!==(n.description??"")&&re(n.id,{description:l.target.value||null})})]}),e.jsxs("div",{className:"mt-3 flex items-center justify-between",children:[e.jsx("h4",{className:"text-[13px] font-semibold text-zinc-700 dark:text-zinc-300",children:"Schichten"}),a&&e.jsx("button",{onClick:()=>Fe(n.id,t.id),disabled:q,className:"text-sm text-red-600 hover:underline font-medium",children:"+ Schicht"})]}),m.length===0&&e.jsx("p",{className:"text-sm text-zinc-400 mt-1",children:"Noch keine Schichten."}),e.jsx("div",{className:"flex flex-col gap-3 mt-2",children:m.map(l=>{const P=(l.helper_assignments??[]).filter(_=>_.status==="zugesagt"),U=P.length>=(l.needed??0);return e.jsxs("div",{className:"rounded-lg border border-zinc-200 dark:border-zinc-700 p-3",children:[e.jsxs("div",{className:"grid grid-cols-2 sm:grid-cols-[1fr_100px_100px_90px_auto] gap-2 items-end",children:[e.jsxs("div",{children:[e.jsx("label",{className:C,children:"Aufgabe"}),e.jsx("input",{className:`${y} w-full`,defaultValue:l.title,disabled:!a,onBlur:_=>_.target.value!==l.title&&ee(l.id,{title:_.target.value})})]}),e.jsxs("div",{children:[e.jsx("label",{className:C,children:"Von"}),e.jsx("input",{type:"time",className:`${y} w-full`,defaultValue:Ee(l.starts_at),disabled:!a||!t.starts_on,onBlur:_=>ee(l.id,{starts_at:$e(t.starts_on,_.target.value)})})]}),e.jsxs("div",{children:[e.jsx("label",{className:C,children:"Bis"}),e.jsx("input",{type:"time",className:`${y} w-full`,defaultValue:Ee(l.ends_at),disabled:!a||!t.starts_on,onBlur:_=>ee(l.id,{ends_at:$e(t.starts_on,_.target.value)})})]}),e.jsxs("div",{children:[e.jsx("label",{className:C,children:"Benötigt"}
7),e.jsx("input",{type:"number",min:1,className:`${y} w-full`,defaultValue:l.needed,disabled:!a,onBlur:_=>ee(l.id,{needed:Math.max(1,Number(_.target.value)||1)})})]}),a&&e.jsx("button",{onClick:()=>Ge(l.id),disabled:q,className:"px-2 py-1.5 text-sm text-zinc-400 hover:text-red-600",children:"Löschen"})]}),!t.starts_on&&e.jsx("p",{className:"mt-1 text-[11.5px] text-amber-600",children:"Zeiten erst erfassbar, wenn der Einsatz ein Datum hat."}),e.jsxs("div",{className:"mt-3",children:[e.jsxs("p",{className:"text-[12px] font-medium text-zinc-500 mb-1.5",children:["Eingetragen: ",P.length," / ",l.needed,U&&e.jsx("span",{className:"ml-1.5 text-green-600 font-semibold",children:"· voll"})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-1.5",children:[P.map(_=>e.jsxs("span",{className:"inline-flex items-center gap-1.5 px-2 py-0.5 rounded-md text-[12.5px] bg-green-50 dark:bg-green-950/30 border border-green-200 dark:border-green-900 text-green-700 dark:text-green-400",children:[H.get(_.person_id)?.label??"(unbekannt)",a&&e.jsx("button",{onClick:()=>We(l.id,_.person_id),disabled:q,className:"text-green-500 hover:text-red-600 leading-none",children:"×"})]},_.person_id)),P.length===0&&e.jsx("span",{className:"text-sm text-zinc-400",children:"Noch niemand."})]}),a&&e.jsx("div",{className:"mt-2",children:e.jsxs("select",{className:`${y} text-xs`,value:"",onChange:_=>{_.target.value&&Re(l.id,_.target.value)},children:[e.jsx("option",{value:"",children:"+ Person von Hand eintragen…"}),e.jsx(ke,{gruppen:we(d,{zugesagt:k,eingeladen:E,ausPortal:W,ohne:new Set(P.map(_=>_.person_id))})})]})})]})]},l.id)})}),a&&e.jsxs("div",{className:"mt-3 flex flex-wrap items-center gap-3",children:[e.jsx("button",{onClick:()=>Ke(t.id,n),disabled:q,className:"text-[12.5px] text-zinc-500 hover:text-red-600 underline underline-offset-2",children:"Station duplizieren"}),e.jsx("button",{onClick:()=>Ue(n.id),disabled:q,className:"text-[12.5px] text-zinc-400 hover:text-red-600",children:"Station löschen"})]})]})]},n.id)}})]}),a&&t.audience!=="vorstand"&&e.jsxs("div",{className:"pt-4 border-t border-zinc-200 dark:border-zinc-800",children:[e.jsxs("div",{onClick:()=>fe(),role:"button",tabIndex:0,onKeyDown:n=>{(n.key==="Enter"||n.key===" ")&&(n.preventDefault(),fe())},className:`flex flex-wrap items-center gap-x-2.5 gap-y-1 -mx-1 px-1 py-1 cursor-pointer rounded-lg
8                          hover:bg-zinc-50 dark:hover:bg-zinc-800/40`,children:[e.jsx(le,{"aria-hidden":!0,className:`w-3.5 h-3.5 shrink-0 text-zinc-400 transition-transform ${ge?"rotate-90":""}`}),e.jsx("h3",{className:"text-sm font-bold text-zinc-900 dark:text-white",children:"Helferpool einladen"}),e.jsxs("span",{className:"text-[12.5px] text-zinc-400",children:[K.length," ",K.length===1?"Person":"Personen"," mit Interesse an Veranstaltungen"]})]}),ge&&e.jsxs(e.Fragment,{children:[e.jsx("p",{className:"text-[12.5px] text-zinc-400 mb-3 mt-2",children:"Wähle aus, wer eine Einladung bekommt. Das Profil zeigt dir, was der Person liegt, gefiltert wird bewusst nicht automatisch. Bernstein markiert ist, wer über den Veranstaltungsplaner schon um Mithilfe gebeten wurde: Eine Einladung von hier wäre die zweite Anfrage zum selben Anlass."}),K.length===0&&(ae[t.id]?.size??0)===0&&e.jsx("p",{className:"text-sm text-zinc-400",children:"Niemand im Helferpool. Über die Suche unten lässt sich trotzdem jemand einladen."}),e.jsxs("label",{className:"mb-2 inline-flex items-center gap-2 text-[12.5px] text-zinc-600 dark:text-zinc-300 cursor-pointer",children:[e.jsx("input",{type:"checkbox",checked:be,className:"accent-red-600 w-3.5 h-3.5",onChange:n=>Le(n.target.checked)}),"Nur mit ausgefülltem Helferprofil",e.jsxs("span",{className:"text-zinc-400",children:["(",K.filter(n=>n.hatProfil).length," von ",K.length,")"]})]}),e.jsx("div",{className:"flex flex-col gap-1.5",children:[...K.filter(n=>!be||n.hatProfil),...[...ae[t.id]??[]].map(n=>{const o=H.get(n);return{id:n,label:o?.label??"(unbekannt)",email:o?.email??null,hatProfil:!1,tasks:[],time_windows:[],event_types:[],max_per_year:null,notes:null}})].map(n=>{const o=Y[t.id]?.[n.id],m=b.some($=>($.helper_assignments??[]).some(l=>l.person_id===n.id&&l.status==="zugesagt"))?"zugesagt":o?.declined_at?"abgesagt":o?"eingeladen":null,I=R[t.id]?.has(n.id)??!1,L=oe[t.id]?.[n.id];return e.jsxs("label",{className:`flex flex-wrap items-center gap-2 rounded-lg border px-3 py-2 cursor-pointer hover:border-zinc-300 ${L&&!o?"border-amber-300 bg-amber-50/60 dark:border-amber-900/60 dark:bg-amber-950/20":"border-zinc-200 dark:border-zinc-700"}`,children:[e.jsx("input",{type:"checkbox",checked:I,disabled:!n.email,onChange:()=>je(t.id,n.id),className:"accent-red-600 w-4 h-4"}),e.jsx("span",{className:"text-sm font-medium text-zinc-800 dark:text-zinc-200",children:n.label}),!n.email&&e.jsx("span",{className:"text-[11px] text-amber-600",children:"keine E-Mail"}),L&&e.jsxs("span",{className:"px-2 py-0.5 rounded-full text-[11px] font-bold bg-amber-100 text-amber-800 dark:bg-amber-950/60 dark:text-amber-300",title:"Über den Veranstaltungsplaner bereits um Mithilfe gebeten. Eine Einladung von hier wäre die zweite Anfrage zum selben Anlass.",children:["im Planer gefragt · ",new Date(L).toLocaleDateString("de-CH",{day:"2-digit",month:"2-digit"})]}),m&&e.jsx("span",{className:`px-2 py-0.5 rounded-full text-[11px] font-bold ${m==="zugesagt"?"bg-green-100 text-green-700":m==="abgesagt"?"bg-zinc-100 text-zinc-500":"bg-amber-100 text-amber-700"}`,children:m}),e.jsxs("span",{className:"ml-auto text-[11.5px] text-zinc-400 text-right",children:[[n.tasks.map($=>it[$]??$).join(", "),n.time_windows.map($=>rt[$]??$).join(", "),n.max_per_year?`max. ${n.max_per_year}
8/Jahr`:""].filter(Boolean).join(" · ")||"kein Helferprofil",n.notes&&e.jsxs("span",{className:"block italic",children:["«",n.notes,"»"]})]})]},n.id)})}),e.jsxs("div",{className:"mt-3",children:[e.jsx("label",{className:C,children:"Weitere Person einladen"}),e.jsx("input",{className:`${y} w-full sm:w-72`,placeholder:"Name eingeben…",value:ie[t.id]??"",onChange:n=>_e(o=>({...o,[t.id]:n.target.value}))}),(ie[t.id]??"").trim().length>=2&&(()=>{const n=ie[t.id].trim().toLowerCase(),o=new Set([...K.map(m=>m.id),...ae[t.id]??[]]),B=d.filter(m=>!o.has(m.id)&&m.label.toLowerCase().includes(n)).slice(0,8);return B.length===0?e.jsx("p",{className:"mt-1.5 text-[12.5px] text-zinc-400",children:"Keine Person gefunden."}):e.jsx("div",{className:"mt-1.5 flex flex-wrap gap-1.5",children:B.map(m=>e.jsxs("button",{onClick:()=>{Oe(I=>{const L=new Set(I[t.id]??[]);return L.add(m.id),{...I,[t.id]:L}}),m.email&&je(t.id,m.id),_e(I=>({...I,[t.id]:""}))},className:"px-2.5 py-1 rounded-lg border border-zinc-200 dark:border-zinc-700 text-[12.5px] text-zinc-700 dark:text-zinc-300 hover:border-red-400 hover:text-red-600",children:["+ ",m.label,m.isVorstand?" (Vorstand)":"",!m.email&&e.jsx("span",{className:"ml-1 text-amber-600",children:"ohne E-Mail"})]},m.id))})})()]}),e.jsxs("div",{className:"mt-3 flex flex-wrap items-center gap-3",children:[e.jsxs("button",{onClick:()=>Je(t.id),disabled:q||(R[t.id]?.size??0)===0,className:"px-3.5 py-2 rounded-lg bg-red-600 text-white text-sm font-semibold hover:bg-red-700 disabled:opacity-50",children:["Einladung senden",(R[t.id]?.size??0)>0?` (${R[t.id].size})`:""]}),me&&e.jsx("span",{className:"text-sm text-green-600",children:me})]})]})]}),a&&t.audience==="vorstand"&&e.jsx("p",{className:"pt-4 border-t border-zinc-200 dark:border-zinc-800 text-[12.5px] text-zinc-400",children:"Zielgruppe ist «Nur Vorstand» — zum Einladen des Helferpools die Zielgruppe auf «Vorstand + Helferpool» stellen."}),a&&e.jsx("div",{className:"pt-2 border-t border-zinc-200 dark:border-zinc-800",children:e.jsx("button",{onClick:()=>He(t.id),disabled:q,className:"text-sm text-zinc-400 hover:text-red-600",children:"Einsatz löschen"})})]})]},t.id)})})]}):e.jsx("p",{className:"text-sm text-zinc-500",children:"Keine Berechtigung."})}function dt({ausVorstand:c,abgesagt:a,ausPortal:p,eingeteilt:g}){if(c.length===0&&p.length===0&&a.length===0)return null;const z="px-2 py-0.5 rounded-md text-[11.5px] border";return e.jsxs("div",{className:"rounded-lg border border-zinc-200 dark:border-zinc-700 p-3",children:[e.jsxs("div",{className:"flex flex-wrap items-baseline justify-between gap-2 mb-2",children:[e.jsx("h3",{className:"text-sm font-bold text-zinc-900 dark:text-white",children:"Bereits gemeldet"}),e.jsxs("span",{className:"text-[11.5px] text-zinc-400",children:[c.length+p.length," bereit",g>0?` · ${g} bereits eingeteilt`:" · noch niemand eingeteilt"]})]}),e.jsxs("div",{className:"space-y-1.5",children:[c.length>0&&e.jsxs("div",{className:"flex flex-wrap items-baseline gap-1.5",children:[e.jsxs("span",{className:"text-[11px] uppercase tracking-wide text-zinc-400 w-[130px] shrink-0 whitespace-nowrap",children:["Vorstand (",c.length,")"]}),c.map(d=>e.jsx("span",{className:`${z} bg-green-600 text-white border-green-700`,children:d},d))]}),p.length>0&&e.jsxs("div",{className:"flex flex-wrap items-baseline gap-1.5",children:[e.jsxs("span",{className:"text-[11px] uppercase tracking-wide text-zinc-400 w-[130px] shrink-0 whitespace-nowrap",children:["Portal (",p.length,")"]}),p.map(d=>e.jsxs("span",{title:d.notiz??void 0,className:`${z} bg-sky-50 dark:bg-sky-950/30 text-sky-800 dark:text-sky-300 border-sky-200 dark:border-sky-900`,children:[d.name,d.notiz?" ·":""]},d.name))]}),a.length>0&&e.jsxs("div",{className:"flex flex-wrap items-baseline gap-1.5",children:[e.jsxs("span",{className:"text-[11px] uppercase tracking-wide text-zinc-400 w-[130px] shrink-0 whitespace-nowrap",children:["Abgesagt (",a.length,")"]}),a.map(d=>e.jsx("span",{className:`${z} bg-zinc-50 dark:bg-zinc-800 text-zinc-400 border-zinc-200 dark:border-zinc-700`,children:d},d))]})]}),e.jsx("p",{className:"mt-2 text-[11.5px] text-zinc-400",children:"Unverbindliche Bereitschaft, noch keine Einteilung. Sobald Posten und Schichten stehen, kannst du diese Leute direkt einteilen."})]})}
8function ot(){const[c,a]=x.useState([]),[p,g]=x.useState(!0),[z,d]=Pe("helfer:meldungen",!1);if(x.useEffect(()=>{(async()=>{const{data:v}=await h.from("helper_interests").select("id, status, note, created_at, events(id, title, date), persons(first_name, last_name, email, phone)").eq("status","gemeldet").order("created_at",{ascending:!1});a(v??[]),g(!1)})()},[]),p||!c.length)return null;const j=new Map;for(const v of c){if(!v.events)continue;const D=j.get(v.events.id)??{titel:v.events.title,datum:v.events.date,leute:[]};D.leute.push(v),j.set(v.events.id,D)}const f=[...j.entries()].sort((v,D)=>v[1].datum.localeCompare(D[1].datum)),O=c.length;return e.jsxs("div",{className:"mb-5 rounded-xl border border-zinc-200 dark:border-zinc-800 overflow-hidden",children:[e.jsxs("div",{onClick:()=>d(),role:"button",tabIndex:0,onKeyDown:v=>{(v.key==="Enter"||v.key===" ")&&(v.preventDefault(),d())},className:`flex flex-wrap items-center gap-x-2.5 gap-y-1 px-4 py-3 cursor-pointer
9          hover:bg-zinc-50 dark:hover:bg-zinc-800/40`,children:[e.jsx(le,{"aria-hidden":!0,className:`w-3.5 h-3.5 shrink-0 text-zinc-400 transition-transform ${z?"rotate-90":""}`}),e.jsx("h2",{className:"text-sm font-semibold text-zinc-900 dark:text-white",children:"Wer hat sich gemeldet"}),e.jsxs("span",{className:"text-[13px] text-zinc-500 dark:text-zinc-400",children:[O===1?"1 Meldung":`${O} Meldungen`,f.length>1?` zu ${f.length} Anlässen`:""]})]}),z&&e.jsxs("div",{className:"px-4 pb-4",children:[e.jsx("p",{className:"text-[13px] text-zinc-500 dark:text-zinc-400",children:"Unverbindliche Meldungen aus dem Mitgliederportal, abgegeben bevor Posten und Schichten stehen. Sobald du den Einsatz planst, kannst du diese Personen direkt anfragen."}),e.jsx("div",{className:"mt-3 space-y-3",children:f.map(([v,D])=>e.jsxs("div",{className:"rounded-lg bg-zinc-50 dark:bg-zinc-900 p-3",children:[e.jsxs("div",{className:"flex flex-wrap items-baseline gap-x-2",children:[e.jsx("span",{className:"text-sm font-semibold text-zinc-900 dark:text-white",children:D.titel}),e.jsx("span",{className:"text-[13px] text-zinc-500",children:new Date(`${D.datum}T12:00:00`).toLocaleDateString("de-CH",{day:"2-digit",month:"long",year:"numeric"})}),e.jsx("span",{className:"ml-auto text-[13px] font-medium text-zinc-700 dark:text-zinc-300",children:D.leute.length===1?"1 Meldung":`${D.leute.length} Meldungen`})]}),e.jsx("ul",{className:"mt-2 space-y-1",children:D.leute.map(V=>e.jsxs("li",{className:"text-[13px] text-zinc-700 dark:text-zinc-300 flex flex-wrap gap-x-2",children:[e.jsx("span",{className:"font-medium",children:[V.persons?.first_name,V.persons?.last_name].filter(Boolean).join(" ")||"ohne Namen"}),V.persons?.email&&e.jsx("span",{className:"text-zinc-400",children:V.persons.email}),V.persons?.phone&&e.jsx("span",{className:"text-zinc-400",children:V.persons.phone}),V.note&&e.jsx("span",{className:"italic text-zinc-500",children:V.note})]},V.id))})]},v))})]})]})}export{bt as AdminHelfer};

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.