PageSourceSearch

https://edia.app/static/js/page-cuFcLwhl.js

js edia.app collected 2026-10-01 15:10:59 UTC 22,928 bytes, 2 lines download raw bytes

1import{r as l,j as e,t as A,H as Ee}from"./index-C_WF_BJq.js";import{m as Re}from"./index-RV5JhC3H.js";import{b as Ae,a as Be}from"./communicationsDateTime-Byo7-GtF.js";import{u as Fe,s as je,A as Ve,a as Pe}from"./audience_facet_filters-B1VK26Be.js";import{s as Ne,p as _e,C as Me}from"./CommunicationConfirmPopup-BfoUoVEO.js";import{C as le}from"./ColumnFilter-D47RXuKy.js";import{S as de}from"./SearchInput-5freF5RO.js";import{U as Te}from"./undo-2-Kh3QC5EQ.js";import{X as Ke}from"./Avatar-DtGDmkuP.js";import{dt as Oe,dn as Ue,du as ze,dv as He,d as qe,c4 as We}from"./DataProviderContext-CBDYCNcF.js";import{a as Qe,L as ve}from"./loader-circle-Ck1hktYW.js";import{P as we}from"./plus-CjQuaDVv.js";import{L as Xe}from"./Link-17SPgqEk.js";import{P as Ye}from"./index-CIwrb30O.js";import{B as Je}from"./Badge-C7v4vPvS.js";import{S as Ze}from"./SlideOver-Bri6ZZkB.js";import{S as et}from"./send-DKdqONAF.js";import{S as tt}from"./sliders-horizontal-DFUjSHjK.js";import{L as st}from"./list-checks-BTfvk8yw.js";import{F as oe}from"./file-up-BLiaSv9F.js";import{T as at}from"./trash-2-B9CykmCo.js";import"./utils-CzBtCSbB.js";import"./funnel-BchonVGp.js";import"./createLucideIcon-07Q-ETyz.js";import"./triangle-alert-C5muH5bc.js";import"./AssignmentAdder-BQZqYLhc.js";import"./ai-Z_mVEYdG.js";import"./assignment-Bb2_O5Dm.js";import"./bluebonnet-5UhW2wPy.js";import"./communications-CPr3N3PG.js";import"./ContactForm-nFJhnAqW.js";import"./curriculum-Cz49gruj.js";import"./district-CMgaN5Nj.js";import"./it_onboarding-Duk6QZuq.js";import"./pd-DscbDIKQ.js";import"./problems-DEq45IZ7.js";import"./sart-CWW28Bvf.js";import"./standards-D-5mjPXc.js";import"./subjects-D-MrSF8L.js";import"./search-Ce6BxiQo.js";import"./SearchBar-Co8iaTuY.js";import"./Icon-DVT53fS0.js";import"./district_scope-FATnlT4N.js";import"./object-geCv8b2G.js";import"./index-DgoKnyni.js";import"./circle-alert--qStYFqi.js";import"./sart-B3jih3T5.js";import"./users-BgQSeBqf.js";import"./tslib.es6-CMwweBXX.js";import"./common-DrIemzIo.js";/* empty css                  */import"./prep_levels-DAO8iQsN.js";import"./arrow-left-DoUYf9FM.js";const Se=25;function nt(u){const i=[u.smsReachable?"Text":null,u.emailReachable?"Email":null].filter(Boolean);return i.length>0?i.join(" + "):"No"}function rt(u){return u.flatMap(i=>i.matchedStudents.map(d=>({studentId:d.id,student:d.name,guardian:i.recipientName,reachable:nt(i),guardianKey:i.recipientKey,siblingCount:i.matchedStudents.length})))}function it({recipients:u,truncated:i,totalStudents:d,totalGuardians:$,removable:_,removedKeys:G,removalTarget:B,onToggleRemoved:h,emptyHint:m}){const[p,ee]=l.useState(""),[v,M]=l.useState("student"),[S,Y]=l.useState("asc"),[x,J]=l.useState({}),L=l.useMemo(()=>rt(u),[u]),F=l.useMemo(()=>{const o=p.trim().toLowerCase();return[...L.filter(y=>o&&!`${y.student} ${y.guardian}`.toLowerCase().includes(o)?!1:Object.entries(x).every(([a,g])=>g.size===0?!0:g.has(String(y[a]??""))))].sort((y,a)=>{const g=String(y[v]??""),K=String(a[v]??""),P=g.localeCompare(K);return S==="asc"?P:-P})},[L,p,x,v,S]),n=F.slice(0,Se),T=Object.values(x).some(o=>o.size>0);function D(o,k){M(o),Y(k)}function V(o,k){J(y=>({...y,[o]:k}))}const I=o=>x[o]??new Set;return e.jsxs("section",{className:"overflow-hidden rounded-xl border border-gray-200",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 px-4 py-3",children:[e.jsxs("p",{className:"text-sm text-gray-600",children:[e.jsx("span",{className:"font-semibold text-gray-900",children:d.toLocaleString()})," ",d===1?"student":"students"," ·"," ",e.jsx("span",{className:"font-semibold text-gray-900",children:$.toLocaleString()})," ",$===1?"guardian":"guardians",G.length>0&&` · ${G.length} removed`]}),u.length>0&&e.jsx(de,{value:p,onChange:ee,placeholder:"Search this list"})]}),u.length===0?e.jsx("p",{className:"border-t border-gray-200 px-4 py-8 text-center text-sm text-gray-500",children:m}):e.jsxs(e.Fragment,{children:[e.jsxs("table",{className:"w-full table-fixed",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"table-header-row",children:[e.jsx(le,{label:"Student",columnKey:"student",data:L,sortKey:v,sortDirection:S,onSort:D,selectedValues:I("student"),onFilterChange:V}),e.jsx(le,{label:"Guardian",columnKey:"guardian",data:L,sortKey:v,sortDirection:S,onSort:D,selectedValues:I("guardian"),onFilterChange:V}),e.jsx(le,{label:"Reachable",columnKey:"reachable",data:L,sortKey:v,sortDirection:S,onSort:D,selectedValues:I("reachable"),onFilterChange:V,className:"w-[124px]"}),_&&e.jsx("th",{className:"table-header w-10"})]})}),e.jsx("tbody",{children:n.map(o=>{const k=B==="student"?o.studentId:o.guardianKey,y=G.includes(k);return e.jsxs("tr",{children:[e.jsx("td",{className:`table-cell truncate ${y?"text-gray-400 line-through":"font-medium text-gray-800"}`,children:o.student}),e.jsxs("td",{className:"table-cell truncate text-gray-600",children:[o.guardian,o.siblingCount>1&&e.jsxs("span",{className:"text-gray-400",children:[" ","· ",o.siblingCount," children"]})]}),e.jsx("td",{className:"table-cell text-xs",children:e.jsx("span",{className:o.reachable==="No"?"text-amber-700":"text-gray-500",children:o.reachable})}),_&&e.jsx("td",{className:"table-cell",children:e.jsx("button",{type:"button",onClick:()=>h(k),"aria-label":y?`Restore ${B==="student"?o.student:o.guardian}`:`Remove ${B==="student"?o.student:o.guardian}`,className:"rounded-lg p-1 text-gray-400 hover:bg-gray-100 hover:text-gray-700",children:y?e.jsx(Te,{className:"h-4 w-4"}):e.jsx(Ke,{className:"h-4 w-4"})})})]},`${o.guardianKey}:${o.studentId}`)})})]}),F.length===0&&e.jsx("p",{className:"px-4 py-6 text-center text-sm text-gray-500",children:"No one matches the current search and filters."}),(F.length>Se||i||T)&&e.jsxs("p",{className:"border-t border-gray-100 px-4 py-2.5 text-xs text-gray-500",children:["Showing ",n.length.toLocaleStr
1ing()," of"," ",(T||p.trim()?F.length:d).toLocaleString()]})]})]})}function lt(u){const i=u.trim().replace(/^0+(?=\d)/,"");return i?/^\d+$/.test(i)?`Grade ${i}`:i:""}function ot({picked:u,onChange:i}){const[d,$]=l.useState(""),{data:_,isLoading:G}=Oe(d),B=new Set(u.map(m=>m.id)),h=_??[];return e.jsxs("div",{className:"space-y-3",children:[e.jsx(de,{value:d,onChange:$,placeholder:"Search students by name or ID",className:"w-full"}),d.trim().length>=2&&e.jsxs("div",{className:"max-h-64 overflow-auto rounded-xl border border-gray-200",children:[G&&e.jsx("p",{className:"px-3 py-4 text-sm text-gray-500",children:"Searching…"}),!G&&h.length===0&&e.jsxs("p",{className:"px-3 py-4 text-sm text-gray-500",children:["No students match “",d.trim(),"”."]}),e.jsx("ul",{className:"divide-y divide-gray-100",children:h.map(m=>{const p=B.has(m.id);return e.jsxs("li",{className:"flex items-center gap-3 px-3 py-2",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("p",{className:"truncate text-sm font-medium text-gray-800",children:m.name}),e.jsx("p",{className:"truncate text-xs text-gray-500",children:[m.school,lt(m.grade)].filter(Boolean).join(" · ")})]}),e.jsx("button",{type:"button",disabled:p,onClick:()=>i([...u,{id:m.id,name:m.name,grade:m.grade,school:m.school}]),className:p?"inline-flex shrink-0 items-center gap-1 rounded-lg px-2 py-1 text-xs font-semibold text-emerald-700":"inline-flex shrink-0 items-center gap-1 rounded-lg border border-gray-200 px-2 py-1 text-xs font-semibold text-gray-700 hover:bg-gray-50",children:p?e.jsxs(e.Fragment,{children:[e.jsx(Qe,{className:"h-3.5 w-3.5"})," Added"]}):e.jsxs(e.Fragment,{children:[e.jsx(we,{className:"h-3.5 w-3.5"})," Add"]})})]},m.id)})})]})]})}const dt=[{value:"rules",label:"Filter by attributes",Icon:tt},{value:"pick",label:"Pick students",Icon:st},{value:"csv",label:"Upload a CSV",Icon:oe}],Ce={"Rule-based":"rules","Hand-picked":"pick","CSV import":"csv"};function ds(){var ge;const{data:u=[]}=Ue(),i=ze(),d=He(),{data:$}=qe(),_=Fe(),G=($==null?void 0:$.timezone)??Re.tz.guess(),{data:B=[]}=We(),h=u,[m,p]=l.useState(null),[ee,v]=l.useState({}),M=(m??h).map(t=>{const s=ee[t.id];return{...t,studentCount:(s==null?void 0:s.students)??t.studentCount,guardianCount:(s==null?void 0:s.guardians)??t.guardianCount,siblingGroups:(s==null?void 0:s.siblingGroups)??t.siblingGroups}}),[S,Y]=l.useState(!1),[x,J]=l.useState(null),[L,F]=l.useState(""),[n,T]=l.useState("rules"),[D,V]=l.useState([]),[I,o]=l.useState(je()),[k,y]=l.useState(""),[a,g]=l.useState(null),[K,P]=l.useState(!1),[U,te]=l.useState("student_id"),[z,se]=l.useState(null),[ke,ce]=l.useState(!1),ue=M.filter(t=>`${t.name} ${t.kind}`.toLowerCase().includes(k.toLowerCase())),[H,q]=l.useState({students:0,guardians:0,siblingGroups:0}),[me,O]=l.useState({recipients:[],truncated:!1}),[he,W]=l.useState([]),E=(a==null?void 0:a.status)==="uploaded"||(a==null?void 0:a.status)==="processing",C=n==="csv"&&U!=="student_id"?"guardians":"students",pe=(t,s)=>`${t.toLocaleString()} ${t===1?s:`${s}s`}`,xe=t=>pe(t,C==="students"?"student":"guardian"),ae=a==null?void 0:a.id,R=M.find(t=>t.id===x),Ge=n==="pick"||n==="csv",Ie=!!R&&Ce[R.kind]===n&&(((ge=R.memberIds)==null?void 0:ge.length)??0)>0,Z=new Set(he.map(t=>C==="guardians"?t.replace(/^guardian:/,""):t));l.useEffect(()=>{p(null)},[h]),l.useEffect(()=>{if(h.length===0)return;let t=!1;return Promise.all(h.map(async s=>{const r=await i.preview(s.id);return[s.id,{students:r.counts.students,guardians:r.counts.guardians,siblingGroups:r.counts.siblingBatches}]})).then(s=>{t||v(Object.fromEntries(s))}).catch(s=>{t||A(s)}),()=>{t=!0}},[i,h]),l.useEffect(()=>{if(!ae||!E)return;let t=!1;const s=window.setInterval(()=>{d.get(ae).then(r=>{t||g(r.import)}).catch(r=>{t||A(r),window.clearInterval(s)})},1500);return()=>{t=!0,window.clearInterval(s)}},[ae,E,d]);const ne=[...new Set([...(R==null?void 0:R.memberIds)??[],...D.map(t=>t.id)])].join(",");l.useEffect(()=>{if(!S||n==="csv")return;const t=ne?ne.split(","):[];if(n==="pick"&&t.length===0){q({students:0,guardians:0,siblingGroups:0}),O({recipients:[],truncated:!1});return}let s=!1;const r=window.setTimeout(()=>{i.previewDefinition({target:"students",schoolIds:[],...n==="pick"?{memberIds:t}:{rules:I.filter(b=>b.values.length>0)}}).then(b=>{s||(q({students:b.counts.students,guardians:b.counts.guardians,siblingGroups:b.counts.siblingBatches}),O({recipients:b.recipients,truncated:b.truncated}))}).catch(b=>{s||A(b)})},400);return()=>{s=!0,window.clearTimeout(r)}},[I,i,n,ne,S]),l.useEffect(()=>{if(!S||!x||n!=="csv")return;let t=!1;return i.preview(x).then(s=>{t||(q({students:s.counts.students,guardians:s.counts.guardians,siblingGroups:s.counts.siblingBatches}),O({recipients:s.recipients,truncated:s.truncated}))}).catch(s=>{t||A(s)}),()=>{t=!0}},[S,x,n,i]);function re(t){var r;const s=t?Ce[t.kind]:"rules";J((t==null?void 0:t.id)??null),F((t==null?void 0:t.name)??""),T(s),V([]),o((t==null?void 0:t.kind)==="Rule-based"?Pe(((r=t.ruleDefinition)==null?void 0:r.rules)??[]):je()
1),q({students:0,guardians:0,siblingGroups:0}),O({recipients:[],truncated:!1}),W([]),g(null),P(!1),te((t==null?void 0:t.target)==="guardians"?"guardian_email":"student_id"),Y(!0)}function Q(){Y(!1),J(null),T("rules"),V([]),O({recipients:[],truncated:!1}),W([]),g(null),P(!1)}async function $e(t){if(t.size>10*1024*1024){A(new Error("CSV exceeds the 10 MB limit"));return}P(!0),g(null),O({recipients:[],truncated:!1}),q({students:0,guardians:0,siblingGroups:0}),W([]);try{const s=t.type||"text/csv",r=await d.create({schoolIds:[],target:C,identifierType:U,fileName:t.name,contentType:s,size:t.size});g(r.import),await d.upload(r.uploadUrl,t);const b=await d.complete(r.import.id);g(b.import)}catch(s){g(r=>r?{...r,status:"failed",error:s instanceof Error?s.message:"CSV upload failed"}:null),A(s)}finally{P(!1)}}async function Le(){var b,be;const t=M.find(w=>w.id===x),s=L.trim()||"Untitled group",r=[...new Set([...(t==null?void 0:t.memberIds)??[],...D.map(w=>w.id)])].filter(w=>!Z.has(w));try{if(n==="csv"&&a){if(a.status!=="ready"&&a.status!=="needs_review")throw new Error("Wait for the CSV import to finish before saving");const c=await d.apply(a.id,{name:s,groupId:t==null?void 0:t.id,allowPartial:a.status==="needs_review"}),j={id:c.group.id,name:s,target:C,kind:"CSV import",studentCount:C==="students"?a.matchedCount:0,guardianCount:C==="guardians"?a.matchedCount:0,siblingGroups:0,updatedAt:c.group.updatedAt};p(f=>{const N=f??h;return t?N.map(ye=>ye.id===j.id?j:ye):[j,...N]}),v(f=>{if(!(j.id in f))return f;const N={...f};return delete N[j.id],N}),Q();return}if(n==="csv"&&t){const c=Z.size>0&&((b=t.memberIds)!=null&&b.length)?(await i.previewDefinition({target:C,schoolIds:[],memberIds:r})).counts:null,j=await i.update(t.id,{name:s,...Z.size>0&&((be=t.memberIds)!=null&&be.length)?{memberIds:r}:{}});p(f=>(f??h).map(N=>N.id===t.id?{...N,name:s,...c?{studentCount:c.students,guardianCount:c.guardians,siblingGroups:c.siblingBatches}:{},updatedAt:j.group.updatedAt}:N)),c&&v(f=>{if(!(t.id in f))return f;const N={...f};return delete N[t.id],N}),Q();return}const w=n==="pick"?{schoolIds:[],name:s,target:"students",kind:"static",memberIds:r}:{schoolIds:[],name:s,target:"students",kind:"rule",rules:I.filter(c=>c.values.length>0)},ie=Z.size>0?(await i.previewDefinition(w)).counts:{students:H.students,guardians:H.guardians,siblingBatches:H.siblingGroups},fe=t?await i.update(t.id,w):await i.create(w),X={id:fe.group.id,name:s,target:"students",kind:n==="pick"?"Hand-picked":"Rule-based",scope:{type:"district"},ruleDefinition:n==="pick"?null:{rules:I.filter(c=>c.values.length>0)},memberIds:n==="pick"?r:[],studentCount:ie.students,guardianCount:ie.guardians,siblingGroups:ie.siblingBatches,updatedAt:fe.group.updatedAt};p(c=>{const j=c??h;return t?j.map(f=>f.id===X.id?X:f):[X,...j]}),v(c=>{if(!(X.id in c))return c;const j={...c};return delete j[X.id],j}),Q()}catch(w){A(w)}}async function De(){if(z){ce(!0);try{await i.delete(z.id),p(t=>(t??h).filter(s=>s.id!==z.id)),se(null)}catch(t){A(t)}finally{ce(!1)}}}return e.jsxs("div",{className:"district2 flex h-full flex-col",children:[e.jsx(Ee,{title:"Communication groups"}),e.jsx("div",{className:"px-6 pb-3 pt-6",children:e.jsx(Ye,{title:"Groups",subtitle:"Reusable groups of students. Messages go to their guardians, with siblings combined into one communication.",actions:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(de,{value:k,onChange:y,placeholder:"Search groups"}),e.jsxs("button",{type:"button",className:"btn btn-md btn-primary shrink-0",onClick:()=>re(),children:[e.jsx(we,{className:"h-4 w-4"})," New group"]})]})})}),e.jsx("div",{className:"flex-1 overflow-auto bg-white",children:e.jsxs("table",{className:"w-full",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"table-header-row",children:[e.jsx("th",{className:"table-header text-left",children:"Name"}),e.jsx("th",{className:"table-header text-left",children:"Type"}),e.jsx("th",{className:"table-header text-right",children:"Students"}),e.jsx("th",{className:"table-header text-right",children:"Guardians"}),e.jsx("th",{className:"table-header text-left",children:"Updated"}),e.jsx("th",{className:"table-header","aria-label":"Actions"})]})}),e.jsxs("tbody",{children:[ue.map(t=>e.jsxs("tr",{className:"table-row cursor-pointer",tabIndex:0,role:"button","aria-label":`Edit ${t.name}`,onClick:()=>re(t),onKeyDown:s=>{(s.key==="Enter"||s.key===" ")&&(s.preventDefault(),re(t))},children:[e.jsx("td",{className:"table-cell font-medium text-[var(--text-primary)]",children:t.name}),e.jsx("td",{className:"table-cell",children:e.jsx(Je,{variant:"neutral",children:t.kind})}),e.jsx("td",{className:"table-cell table-cell-numeric",children:t.studentCount}),e.jsxs("td",{className:"table-cell table-cell-numeric",children:[t.guardianCount,t.siblingGroups>0&&e.jsxs("span",{className:"block whitespace-nowrap text-xs font-normal text-gray-500",children:[pe(t.siblingGroups,"sibling group")," ","combined"]})]}),e.jsx("td",{className:"table-cell whitespace-nowrap text-[var(--text-secondary)]",children:e.jsx("span",{title:Be(t.updatedAt,G),children:Ae(t.updatedAt,G)})}),e.jsx("td",{className:"table-cell",children:e.jsx("div",{className:"flex items-center justify-end whitespace-nowrap",children:e.jsxs(Xe,{href:`/communications/compose?from=groups&group=${encodeURIComponent(t.id)}`,"aria-label":`Compose a message to ${t.name}`,title:"Opens the campaign builder with this group as the audience",onClick:s=>{s.stopPropagation()},className:"inline-flex items-center gap-1.5 rounded-lg px-2.5 py-2 text-xs font-semibold text-blue-600 hover:bg-blue-50",children:[e.jsx(et,{className:"h-3.5 w-3.5"})," Message"]})})})]},t.id)),ue.length===0&&e.jsx("tr",{children:e.jsx("td",{colSpan:6,className:"px-5 py-14 text-center",children:M.length===0?e.jsxs(e.Fragment,{children:[e.jsx("p",{className:"text-body-sm font-medium text-gray-700",children:"No groups yet"}),e.jsx("p",{className:"mt-1 text-body-sm text-gray-500",children:"Create one with New group to reuse an audie
1nce across campaigns."})]}):e.jsx("p",{className:"text-body-sm text-gray-500",children:"No groups match your search."})})})]})]})}),S&&e.jsxs(Ze,{onClose:Q,ariaLabel:"Group builder",header:e.jsx("h2",{className:"text-heading-lg text-gray-950",children:x?"Edit group":"New group"}),children:[e.jsxs("div",{className:"space-y-6 p-6",children:[e.jsxs("label",{className:"block",children:[e.jsx("span",{className:"text-label text-gray-700",children:"Group name"}),e.jsx("input",{value:L,onChange:t=>F(t.target.value),placeholder:"Untitled group",className:"mt-1.5 w-full rounded-lg border border-gray-300 px-3 py-2.5 text-sm outline-none focus:border-blue-500 focus:ring-2 focus:ring-blue-100"})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-label text-gray-700",children:"How do you want to pick students?"}),e.jsx("div",{className:"mt-2 grid grid-cols-3 gap-3",children:dt.map(({value:t,label:s,Icon:r})=>e.jsxs("button",{type:"button","aria-pressed":n===t,onClick:()=>{T(t),g(null),W([]),te("student_id")},className:`flex flex-col items-start gap-2 rounded-xl border p-3 text-left ${n===t?"border-blue-500 bg-blue-50":"border-gray-200 hover:bg-gray-50"}`,children:[e.jsx(r,{className:`h-4 w-4 shrink-0 ${n===t?"text-blue-600":"text-gray-500"}`}),e.jsx("span",{className:`whitespace-nowrap text-sm font-semibold ${n===t?"text-blue-800":"text-gray-800"}`,children:s})]},t))})]}),n==="rules"&&e.jsx(Ve,{facets:I,onChange:o,schoolOptions:B.map(t=>({value:t.id,label:t.name})),valueOptions:_}),n==="pick"&&e.jsx(ot,{picked:D,onChange:V}),n==="csv"&&e.jsxs("div",{className:"space-y-3",children:[e.jsxs("label",{className:"block",children:[e.jsx("span",{className:"text-label text-gray-700",children:"My file identifies people by"}),e.jsxs("select",{value:U,disabled:K||E,onChange:t=>{te(t.target.value),g(null)},className:"mt-1.5 w-full rounded-lg border border-gray-300 bg-white px-3 py-2.5 text-sm",children:[e.jsx("option",{value:"student_id",children:"Student ID"}),e.jsx("option",{value:"guardian_email",children:"Guardian email"}),e.jsx("option",{value:"guardian_phone",children:"Guardian phone"})]}),e.jsxs("span",{className:"mt-1 block text-xs text-gray-500",children:["Upload a CSV with a column named"," ",e.jsx("code",{children:U}),"."," ",C==="students"?"Each row selects a student using an Edia ID, attendance external ID, student number, PowerSchool ID, or Clever SIS ID. The students are not contacted directly; Edia messages their guardians and combines siblings.":`Each row identifies a guardian by ${U==="guardian_email"?"email":"phone number"}. Every child of theirs counts as matched, including any outside this group’s intent.`]})]}),e.jsxs("label",{className:`${Ne} w-fit cursor-pointer`,children:[K?e.jsx(ve,{className:"h-4 w-4 animate-spin"}):e.jsx(oe,{className:"h-4 w-4"}),a?"Replace CSV":`Choose ${C==="students"?"student":"guardian"} CSV`,e.jsx("input",{type:"file",accept:".csv,text/csv",disabled:K||E,className:"sr-only",onChange:t=>{var r;const s=(r=t.target.files)==null?void 0:r[0];s&&$e(s),t.target.value=""}})]}),a&&e.jsxs("div",{className:`rounded-xl border p-4 ${a.status==="failed"?"border-red-200 bg-red-50":a.status==="needs_review"?"border-amber-200 bg-amber-50":"border-emerald-200 bg-emerald-50"}`,children:[e.jsxs("p",{className:"flex items-center gap-2 text-sm font-semibold text-gray-900",children:[E&&e.jsx(ve,{className:"h-4 w-4 animate-spin"}),!E&&e.jsx(oe,{className:"h-4 w-4"}),a.fileName]}),e.jsxs("p",{className:"mt-1 text-xs text-gray-700",children:[a.status==="uploading"&&"Uploading CSV…",E&&`Processing ${a.processedCount.toLocaleString()} of ${a.totalCount.toLocaleString()||"—"} rows…`,a.status==="ready"&&`${xe(a.matchedCount)} matched.`,a.status==="needs_review"&&`${xe(a.matchedCount)} matched; ${a.unmatchedCount.toLocaleString()} unmatched and ${a.ambiguousCount.toLocaleString()} ambiguous. Saving will use matched ${C} only.`,a.status==="failed"&&(a.error||"Import failed.")]}),a.duplicateCount>0&&e.jsxs("p",{className:"mt-1 text-xs text-gray-600",children:[a.duplicateCount.toLocaleString()," duplicate rows were ignored."]}),a.issues.length>0&&e.jsx("ul",{className:"mt-2 max-h-28 overflow-auto text-xs text-gray-600",children:a.issues.slice(0,10).map(t=>e.jsxs("li",{children:["Row ",t.row,": ",t.reason,t.value?` (${t.value})`:""]},`${t.row}-${t.reason}`))})]}),!a&&Ie&&e.jsx("p",{className:"text-xs text-gray-500",children:"Upload a CSV to replace the current recipients, or save to rename this group without changing them."})]}),!(n==="csv"&&a)&&e.jsx(it,{recipients:me.recipients,truncated:me.truncated,totalStudents:H.students,totalGuardians:H.guardians,removable:Ge,removedKeys:he,removalTarget:C==="guardians"?"guardian":"student",onToggleRemoved:t=>W(s=>s.includes(t)?s.filter(r=>r!==t):[...s,t]),emptyHint:n==="rules"?"No one matches yet. Add a filter to see who is included.":n==="pick"?"No students yet. Search above to add them.":"Upload a CSV to see who is included."})]}),e.jsxs("div",{className:"sticky bottom-0 mt-auto flex items-center justify-end gap-2 border-t border-gray-200 bg-white px-6 py-4",children:[R&&e.jsxs("button",{type:"button",onClick:()=>se(R),className:"mr-auto inline-flex items-center gap-1.5 rounded-lg px-2.5 py-2 text-sm font-semibold text-red-600 hover:bg-red-50",children:[e.jsx(at,{className:"h-4 w-4"})," Delete group"]}),e.jsx("button",{type:"button",className:Ne,onClick:Q,children:"Cancel"}),e.jsx("button",{type:"button",className:_e,disabled:K||E||n==="csv"&&!x&&(a==null?void 0:a.status)!=="ready"&&(a==null?void 0:a.status)!=="needs_review"||n==="pick"&&!x&&D.length===0||(a==null?void 0:a.status)==="failed",onClick:()=>void Le(),children:x?"Save changes":"Save group"})]})]}),z&&e.jsx(Me,{title:`Delete “${z.name}”?`,description:"This removes the reusable group. Campaigns that already used it keep their recipient snapshots.",confirmLabel:"Delete group",busy:ke,onCancel:()=>se(null),onConfirm:()=>void De()})]})}export{ds as default};
2//# sourceMappingURL=page-cuFcLwhl.js.map

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.