1import{j as e,r as o}from"./index-aWHYV2P8.js";import{e as ot,f as Qe,g as $e,h as Ie,U as Is,c as Ds,d as Ls}from"./m4hMark-4bQO_nXa.js";import{M as Ft,a as Se,b as Ut,k as Bs,s as Ae,J as Os,o as qs,l as Fs,d as Us,f as Be,g as Oe,m as Hs,u as Ht,e as Ks}from"./App-DGJhB_Lc.js";import{d as Gs,_ as Ws,v as jt,T as Ys}from"./pageMeta-OBeqI8bG.js";import{u as Qs,a as Kt,b as Gt,c as Vs,i as zs,d as Js,e as Xs,f as Zs,C as Wt,g as ea,h as ta,j as sa,r as aa,P as Yt,k as na,l as ia,m as ra,n as oa,o as la,I as da}from"./parentLessonReportEmail-DEBMfxjm.js";import{s as re}from"./supabaseClient-Bga8xEX7.js";import{u as Ve,a as Qt,b as ca,e as ma,c as ua,E as Vt,d as pa,h as Nt,f as ha,g as xa,i as fa,j as ba,k as ga}from"./useCommunications-DWlT-C0n.js";import{r as ie,s as _a,b as zt,a as Jt,M as Xt,c as ya,d as va,t as Ze,n as Zt}from"./emailTemplates-BPJGXi5m.js";import{F as es,a as ts}from"./FormModal-DitLZvK5.js";import{c as ne,e as at,p as ge,f as pe,h as et}from"./formClasses-BohnxhWn.js";import{S as ja}from"./save-BenS5hNQ.js";import{C as Ye}from"./circle-check-Cx-WixrN.js";import{R as Na}from"./rotate-ccw-A9HP6-2S.js";import{S as Re}from"./send-DCz_ij0i.js";import{M as ss}from"./music-CqJsKz-O.js";import{G as as,g as wa}from"./attendanceDate-DE7Ar6Gc.js";import{T as ns}from"./trash-2-CVILWCx9.js";import{u as is}from"./useStudents-Dkn2iFcr.js";import{u as Sa}from"./useRegistrations-DEqnQTyV.js";import{u as ka}from"./useWaivers-tPZWSUFq.js";import{u as Ca}from"./useStudentSchoolHistory-D3A17vmI.js";import{l as Ta}from"./leadTeacherAssignment-DbDISFVE.js";import{B as wt}from"./authRoutes-YPIBnK90.js";import{A as St}from"./arrow-left-Lz9psQY7.js";import{C as Ea}from"./check-CdjTL8KO.js";import{u as $a}from"./useLessonLiveRoster-Cw0EcUGJ.js";import{g as Pa,u as Aa,a as Ra,p as Ma,f as kt,b as Ia}from"./useLessonReports-DxMA5XAe.js";import{u as Da}from"./useAccessibleGroups-B-0q2JLN.js";import{F as Ct}from"./FormNativeSelect--the3wZE.js";import{E as La}from"./eye-C-AqnwR1.js";import{c as nt,e as rs,d as os,f as ve,a as Ba,b as Oa}from"./emailMessageFormat-lmF3EA1t.js";import{C as qa}from"./chevron-left-NmOW2AJn.js";import{C as ls}from"./chevron-right-Cu_m1HCA.js";import{S as Fa}from"./settings-2-Dm7ZZtbX.js";import{P as Ua}from"./template-BymKwmnO.js";import{a as Ha}from"./AdminPageHeader-CuWcCitP.js";import{F as Ka}from"./flask-conical-CkJK_nH3.js";import{E as Ga}from"./ellipsis-iFtgfaAa.js";import"./lessonLiveSubmitReport-5YeLwPpt.js";import"./queryClient-CMzOD_mj.js";/** 2 * @license lucide-react v1.17.0 - ISC 3 * 4 * This source code is licensed under the ISC license. 5 * See the LICENSE file in the root directory of this source tree. 6 */const Wa=[["path",{d:"M10.268 21a2 2 0 0 0 3.464 0",key:"vwvbt9"}],["path",{d:"M22 8c0-2.3-.8-4.3-2-6",key:"5bb3ad"}],["path",{d:"M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326",key:"11g9vi"}],["path",{d:"M4 2C2.8 3.7 2 5.7 2 8",key:"tap9e0"}]],ds=ot("bell-ring",Wa);/** 7 * @license lucide-react v1.17.0 - ISC 8 * 9 * This source code is licensed under the ISC license. 10 * See the LICENSE file in the root directory of this source tree. 11 */const Ya=[["path",{d:"M19.414 14.414C21 12.828 22 11.5 22 9.5a5.5 5.5 0 0 0-9.591-3.676.6.6 0 0 1-.818.001A5.5 5.5 0 0 0 2 9.5c0 2.3 1.5 4 3 5.5l5.535 5.362a2 2 0 0 0 2.879.052 2.12 2.12 0 0 0-.004-3 2.124 2.124 0 1 0 3-3 2.124 2.124 0 0 0 3.004 0 2 2 0 0 0 0-2.828l-1.881-1.882a2.41 2.41 0 0 0-3.409 0l-1.71 1.71a2 2 0 0 1-2.828 0 2 2 0 0 1 0-2.828l2.823-2.762",key:"17lmqv"}]],cs=ot("heart-handshake",Ya);/** 12 * @license lucide-react v1.17.0 - ISC 13 * 14 * This source code is licensed under the ISC license. 15 * See the LICENSE file in the root directory of this source tree. 16 */const Qa=[["path",{d:"M22 13V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v12c0 1.1.9 2 2 2h9",key:"1j9vog"}],["path",{d:"m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7",key:"1ocrg3"}],["path",{d:"m17 17 4 4",key:"1b3523"}],["path",{d:"m21 17-4 4",key:"uinynz"}]],ms=ot("mail-x",Qa);function Va(t){return Qe({queryKey:["communication_outbox",t],refetchInterval:15e3,queryFn:async()=>{const{data:s,error:a}=await re.rpc("communication_outbox",{p_search:t.search,p_category:t.category,p_
16school:t.school,p_group:t.group,p_status:t.status,p_session:t.session,p_page:t.page,p_size:30});if(a)throw new Error(a.message);return s}})}function za(){const t=$e();return Ie({mutationFn:async({row:s,action:a})=>{const{data:i,error:l}=s.source==="draft"?await re.rpc("recover_parent_draft",{p_id:s.id}):await re.rpc("recover_outbox_automation",{p_id:s.id,p_action:a});if(l)throw new Error(l.message.includes("reconciliation")?"This attempt needs delivery reconciliation before it can be retried. It may already have been sent.":l.message.includes("expired")?"This notice is out of date. Dismiss it instead of retrying.":l.message);return i},onSettled:()=>{t.invalidateQueries({queryKey:["communication_outbox"]})}})}const Ja=["automation_events","awaiting_approval"];function Xa(){const t=$e();return Ie({mutationFn:async({eventId:s,action:a})=>{const{data:i,error:l}=await re.functions.invoke("review_automation_event",{body:{event_id:s,action:a}});if(l)throw new Error(l.message);if((i==null?void 0:i.ok)!==!0)throw new Error(String((i==null?void 0:i.error)??"review_failed"));return i},onSettled:()=>{t.invalidateQueries({queryKey:Ja}),t.invalidateQueries({queryKey:["communication_outbox"]}),t.invalidateQueries({queryKey:["email_messages"]})}})}function Za({row:t,template:s,loading:a,busy:i,onApprove:l}){var d,_;const r=t.data.payload??{},c={...typeof r.merge_data=="object"&&r.merge_data!==null?r.merge_data:{},email_signature:Jt()},x=typeof r.to_name=="string"?r.to_name:void 0,m=t.source==="draft",g=m?!!((d=t.data.subject_rendered)!=null&&d.trim()&&((_=t.data.body_html_rendered)!=null&&_.trim())):!!(s!=null&&s.is_active&&s.subject.trim()&&s.body_html.trim()),w=!m&&a,u=m?t.data.subject_rendered??"":g?ie(s.subject,c,{toName:x}):"",j=m?t.data.body_html_rendered??"":g?ie(s.body_html,c,{html:!0,toName:x}):"",v=t.data.template_key,h=m||["parent_lesson_report","parent_end_of_term","parent_end_of_term_reenroll","parent_beginning_of_term"].includes(v)?"letter":_a(v);return e.jsxs("section",{"aria-label":"Email preview",className:"min-w-0 rounded-lg bg-[var(--m4h-tint-soft)] p-3 sm:p-4 md:col-span-2",children:[w?e.jsx("p",{role:"status",className:"m-0 text-sm",children:"Loading email previewâ¦"}):g?e.jsxs(e.Fragment,{children:[e.jsxs("p",{className:"m-0 break-all text-xs text-[var(--m4h-ink-muted)]",children:["To: ",t.recipient]}),e.jsx("h3",{className:"m-0 mt-1 break-words text-sm font-medium",children:u}),e.jsx("p",{className:"mb-3 mt-1 text-xs text-[var(--m4h-ink-faint)]",children:m?"Saved lesson report. Approval makes it ready for you to send.":"Current template with this emailâs details. Approval queues the email for sending."}),e.jsx("iframe",{title:"Email content",sandbox:"",className:"block h-[28rem] w-full rounded-lg border-0 bg-white",srcDoc:zt(j,h,v)})]}):e.jsx("p",{role:"alert",className:"m-0 text-sm text-red-800",children:m?"This draft has no saved email content yet. Open Review to prepare it before approval.":"The active email template could not be loaded. Approval is unavailable until the preview is ready."}),t.status==="review"&&e.jsx("button",{type:"button",disabled:w||!g||i,onClick:l,className:"mt-3 min-h-11 rounded-lg border-0 bg-black px-4 py-2 text-sm text-white hover:bg-black/80 focus-visible:outline focus-visible:outline-2 focus-visible:outline-[var(--m4h-brand-purple)] disabled:opacity-40",children:i?"Workingâ¦":m?"Approve":"Approve & send"})]})}function Tt(t){return t.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function Et(t){const s=[];let a=!1;for(const i of t.split(/\r?\n/)){const l=i.trim();if(!l){a&&(s.push("</ul>"),a=!1);continue}const r=l.match(/^[â¢*-]\s*(.+)$/);if(r){a||(s.push("<ul>"),a=!0),s.push(`<li>${Tt(r[1]??"")}</li>`);continue}a&&(s.push("</ul>"),a=!1),s.push(`<p>${Tt(l)}</p>`)}return a&&s.push("</ul>"),s.join(` 17`)}function en(t){const s=t.lastIndexOf(Xt);return s===-1?{content:t,hadSignature:!1}:{content:t.slice(0,s).replace(/\s+$/,""),hadSignature:!0}}function tn(t,s){if(!s)return{html:Et(t),text:t};const a=t.replace(/\s+$/,"");return{html:`${Et(a)} 18${ya}`,text:`${a} 19 20${Xt}`}}function sn({draft:t,template:s,onClose:a,onApproved:i}){const l=Qs(),r=Kt(),c=Gt(),x=Vs(),m=t.status==="ready_for_review",g=t.status==="approved",w=zs(t),u=!!t.body_html_rendered,j=o.useMemo(()=>en(t.body_text_rendered??""),[t.body_text_rendered]),[v,h]=o.use
20State(t.merge_data),[d,_]=o.useState(t.subject_rendered??""),[S,T]=o.useState(j.content),[E,A]=o.useState(null),I=u&&S!==j.content,f=o.useMemo(()=>u?d:s?ie(s.subject,v):t.subject_rendered??"",[u,d,s,v,t.subject_rendered]),C=o.useMemo(()=>u?I?tn(S,j.hadSignature):{html:t.body_html_rendered??"",text:t.body_text_rendered??""}:{html:s?ie(s.body_html,v,{html:!0}):"",text:t.body_text_rendered??""},[u,I,S,j.hadSignature,t.body_html_rendered,t.body_text_rendered,s,v]),B=C.html,P=JSON.stringify(v)!==JSON.stringify(t.merge_data)||u&&d!==(t.subject_rendered??"")||I,K=l.isPending||r.isPending||c.isPending||x.isPending,R=l.error??r.error??c.error??x.error,N=R instanceof Error?R.message:null;function oe(){return{id:t.id,version:t.updated_at,mergeData:v,subjectRendered:f,bodyHtmlRendered:C.html,bodyTextRendered:C.text}}function le(){return{...t,merge_data:v,subject_rendered:f,body_html_rendered:u?C.html:t.body_html_rendered,body_text_rendered:u?C.text:t.body_text_rendered}}function Y(){!m||!P||(A(null),l.mutate(oe(),{onSuccess:()=>A("Saved.")}))}function W(){if(!m)return;A(null);const D=(Q=t)=>c.mutate([Q],{onSuccess:()=>{A("Approved â content is locked and the draft can now be sent."),i==null||i()}});P||!u?l.mutate(oe(),{onSuccess:D}):D()}function M(){g&&(A(null),x.mutate([t],{onSuccess:()=>A("Returned to review â the draft can be edited again.")}))}function de(){w&&(A(null),r.mutate(le(),{onSuccess:D=>{D.duplicate?A("Skipped â this family was already emailed for this class."):D.skipped?A(D.skipped==="suppressed"?"Not sent â this address is on the Do not email list.":`Not sent: ${D.skipped}.`):a()}}))}return e.jsxs(es,{icon:Ft,iconClassName:"bg-black",onClose:a,size:"xl",subtitle:`${t.recipient_name??t.recipient_email} · ${t.merge_data.student_name??""}`.trim(),title:"Review parent email",titleId:"outbox-review-title",children:[e.jsxs(ts,{className:"font-geist min-h-0 flex-1 space-y-4 overflow-y-auto p-6",children:[e.jsx("p",{className:"m-0 rounded-lg border border-[var(--m4h-line)] bg-[var(--m4h-tint)] px-3 py-2 text-sm font-medium text-[var(--m4h-ink)]",children:Js(t)}),!s&&!u?e.jsx("p",{className:"m-0 rounded-lg border border-amber-200 bg-amber-50 px-3 py-3 text-sm font-medium text-amber-800",children:"The parent lesson report template is unavailable, so this draft cannot be previewed or sent."}):e.jsxs(e.Fragment,{children:[u?e.jsxs(e.Fragment,{children:[e.jsxs("label",{className:ne,children:["Subject",e.jsx("input",{className:"mt-1 w-full rounded-lg border border-stone-200 bg-white px-3 py-2 text-sm text-stone-900 focus:border-indigo-500 focus:outline-none focus:ring-2 focus:ring-indigo-100 disabled:bg-stone-50",disabled:!m,onChange:D=>{_(D.target.value),A(null)},value:d})]}),e.jsxs("label",{className:ne,children:["Body",e.jsx("textarea",{className:`${at} mt-1 min-h-72`,disabled:!m,onChange:D=>{T(D.target.value),A(null)},value:S}),g?e.jsx("span",{className:"mt-1 block text-xs text-stone-500",children:"This draft is approved and its content is locked. Unapprove it to edit."}):m?j.hadSignature?e.jsx("span",{className:"mt-1 block text-xs text-stone-500",children:"The Music 4 Humans signature is added automatically and isn't editable here."}):null:e.jsxs("span",{className:"mt-1 block text-xs text-stone-500",children:["This draft is ",t.status.replace(/_/g," ")," and can no longer be edited."]})]})]}):e.jsxs("label",{className:ne,children:["Class summary",e.jsx("textarea",{className:`${at} mt-1 min-h-24`,disabled:!m,onChange:D=>{const Q=D.target.value;h(V=>({...V,class_summary:Q})),A(null)},value:v.class_summary??""}),g?e.jsx("span",{className:"mt-1 block text-xs text-stone-500",children:"This draft is approved and its content is locked. Unapprove it to edit."}):m?null:e.jsxs("span",{className:"mt-1 block text-xs text-stone-500",children:["This draft is ",t.status.replace(/_/g," ")," and can no longer be edited."]})]}),e.jsxs("section",{className:"rounded-lg border border-stone-200 bg-white p-3","aria-label":"Email preview",children:[e.jsx("p",{className:"m-0 text-xs font-semibold uppercase tracking-wide text-stone-500",children:"Subject"}),e.jsx("p",{className:"m-0 mt-1 rounded-lg bg-stone-50 px-3 py-2 text-sm font-medium text-stone-900",children:f||"No subject"}),e.jsx("p",{className:"m-0 mt-4 text-xs font-semibold uppercase tracking-wide text-stone-500",children:"Body"}),e.jsx("iframe",{className:"mt-2 h-80 w-full rounded-lg border border-stone-200 bg-white",sandbox:"",srcDoc:B,title:"Parent email preview"})]}),E?e.jsx("p",{className:"m-0 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm font-medium text-amber-800",children:E}):null,N?e.jsx("p",{className:"m-0 text-sm font-medium text-rose-700",children:N}):null]})]}),e.jsxs("div",{className:"flex shrink-0 flex-wrap items-center justify-end gap-3 border-t border-stone-200 bg-stone-50/80 px-6 py-4",children:[e.jsx("button",{className:`${Se} min-w-[5.5rem]`,disabled:K,onClick:a,type:"button",children:"Close"}),m?e.jsxs("button",{className:Se,disabled:!P||K,onClick:Y,type:"button",children:[e.jsx(ja,{"aria-hidden":"true",className:"h-4 w-4"}),l.isPending?"Saving...":"Save"]}):null,m?e.jsxs("button",{className:`${ge} !bg-black !text-white !shadow-none`,disabled:!s&&!u||K,onClick:W,type:"button",children:[e.jsx(Ye,{"aria-hidden":"true",className:"h-4 w-4"}),c.isPending?"Approving...":"Approve"]}):null,g?e.jsxs("button",{className:Se,disabled:K,onClick:M,type:"button",children:[e.jsx(Na,{"aria-hidden":"true",className:"h-4 w-4"}),x.isPending?"Unapproving...":"Unapprove"]}):null,w?e.jsxs("button",{className:`${ge} !bg-black !text-white !shadow-none`,disabled:!s&&!u||K,onClick:de,type:"button",children:[e.jsx(Re,{"aria-hidden":"true",className:"h-4 w-4"}),r.isPending?"Sending...":"Send email"]}):null]})]})}const $t=new Set(["recurring_charge_receipt","admin_lesson_upgrade_receipt","admin_lesson_schedule_change_receipt"]);function an(t){const s=t.data??void 0;if((t.category??(s==null?void 0:s.category)??null)==="private_lesson")return!0;const i=(s==null?void 0:s.template_key)??null,l=(s==null?void 0:s.event_type)??null;return!!(i!=null&&i.startsWith("private_lesson_")||l!=null&&l.startsWith("private_lesson_")||l&&$t.has(l)||i&&$t.has(i))}function nn(t){var r;if(!an(t))return{isPrivateLesson:!1,primary:t.school_name??"Unassigned school",secondary:t.group_name??"Unassigned group"};const s=((r=t.data)==null?void 0:r.payload)??null,a=(s==null?void 0:s.merge_data)??null,i=(a==null?void 0:a.instrument)??(s==null?void 0:s.instrument)??null,l=(a==null?void 0:a.teacher_name)??(a==null?void 0:a.teacher_first_name)??((s==null?void 0:s.recipient_type)==="teacher"?(s==null?void 0:s.to_name)??null:null);return!i&&!l?{isPrivateLesson:!0,primary:"Private lesson",secondary:null}:{isPrivateLesson:!0,primary:i??null,secondary:l??null}}const X="min-h-11 rounded-lg border border-solid border-[var(--m4h-line)] bg-white px-3 py-2 text-sm text-[var(--m4h-ink)] transition-colors hover:bg-[var(--m4h-tint)] focu
20s-visible:outline focus-visible:outline-2 focus-visible:outline-[var(--m4h-brand-purple)] disabled:opacity-40",tt=`${X} !border-black !bg-black !text-white hover:!bg-black/80`,Pt={review:"Needs review",approved:"Approved",pending:"Queued",processing:"Sending",paused:"Paused",failed:"Failed",sent:"Sent",skipped:"Not sent"},At=["Registrations","Lesson reports","Bookings","Payments","Teacher updates","Family updates","Admin alerts"];function rn({search:t,lessonSessionIdFilter:s}){var ce,fe,be,je;const[a,i]=o.useState(""),[l,r]=o.useState(""),[c,x]=o.useState(""),[m,g]=o.useState("attention"),[w,u]=o.useState(0),[j,v]=o.useState(null),[h,d]=o.useState(null),[_,S]=o.useState(null),T=Va({search:t,category:a,school:l,group:c,status:m,session:s??"",page:w}),E=Ve(),A=Kt(),I=Xa(),f=za(),C=$e(),B=Gt(),P=Xs(),K=Zs(),[R,N]=o.useState([]),[oe,le]=o.useState(!1),Y=A.isPending||I.isPending||f.isPending||B.isPending||P.isPending||K.isPending||oe,W=((ce=T.data)==null?void 0:ce.rows)??[],M=((fe=T.data)==null?void 0:fe.total)??0,de=W.find(b=>b.id===j),D=W.filter(b=>R.includes(b.id));o.useEffect(()=>N([]),[t,a,l,c,m,w]);async function Q(b){const p=D.filter(k=>k.source==="draft").map(k=>k.data);if(p.length&&!((b==="send"||b==="delete")&&!window.confirm(`${b==="send"?"Send":"Delete"} ${p.length} selected parent emails?`))){le(!0),d(null);try{if(b==="approve"&&(await B.mutateAsync(p),g("approved")),b==="delete"&&await K.mutateAsync(p.map(k=>k.id)),b==="regenerate"&&(await P.mutateAsync(p.map(q=>q.id))).some(q=>!q.ok))throw new Error("Some drafts could not be regenerated. Review them individually.");if(b==="send"){let k=0,q=0,O=0;for(const[z,Z]of p.entries()){z>0&&await new Promise(ee=>window.setTimeout(ee,Wt));try{(await A.mutateAsync(Z)).skipped?q++:k++}catch{O++}}d(`${k} accepted · ${q} not sent · ${O} unconfirmed. Check each status before retrying.`)}else d("Selected drafts updated.")}catch(k){d(k instanceof Error?k.message:"The action could not be completed.")}finally{le(!1),N([]),C.invalidateQueries({queryKey:["communication_outbox"]})}}}o.useEffect(()=>u(0),[t,a,l,c,m,s]),o.useEffect(()=>{T.data&&w>0&&w*30>=M&&u(Math.max(0,Math.ceil(M/30)-1))},[T.data,w,M]);async function V(b,p){d(null);try{if(b.source==="draft"&&p==="approve")await B.mutateAsync([b.data]),g("approved"),d("Approved. The email is ready for you to send.");else if(p==="send"||p==="retry"&&b.source==="draft"&&b.reserved){const k=await A.mutateAsync(b.data);d(k.skipped==="suppressed"?"Not sent: this address is on the Do not email list.":k.skipped?`Not sent: ${k.skipped}.`:"Email accepted by the sending service.")}else if(b.status==="failed"||b.source==="draft"&&b.status==="skipped"){const k=await f.mutateAsync({row:b,action:p==="dism
20iss"?"dismiss":"retry"});d(k==="sent"?"Reconciled with the existing sent email.":k==="skipped"?"Dismissed without sending.":"Returned to review. Check the content before approving.")}else await I.mutateAsync({eventId:b.id,action:p==="dismiss"?"dismiss":"approve"}),d(p==="dismiss"?"Dismissed without sending.":"Approved and queued. Delivery status will update here.")}catch(k){d(k instanceof Error?k.message:"The action could not be completed.")}finally{C.invalidateQueries({queryKey:["communication_outbox"]})}}function xe(b,p,k,q){return e.jsxs("label",{className:"grid gap-2 text-xs text-[var(--m4h-ink-muted)]",children:[b,e.jsxs("select",{"aria-label":b,value:p,onChange:O=>k(O.target.value),className:"h-11 min-w-0 rounded-xl border border-solid border-[var(--m4h-line)] bg-white px-3 text-sm text-[var(--m4h-ink)] focus:outline-[var(--m4h-brand-purple)]",children:[e.jsxs("option",{value:"",children:["All ",b.toLowerCase()]}),q.map(O=>e.jsx("option",{value:O.id,children:O.name},O.id))]})]})}return e.jsxs("section",{className:"space-y-6","aria-label":"Communications outbox",children:[e.jsxs("header",{className:"pt-4",children:[e.jsx("p",{className:"m-0 font-mono text-[11px] uppercase tracking-[.1em] text-[var(--m4h-ink-faint)]",children:"Delivery desk"}),e.jsx("h2",{className:"m-0 mt-2 text-2xl font-semibold tracking-tight text-[var(--m4h-ink)]",children:"Every email, in one place"}),e.jsx("p",{className:"m-0 mt-2 max-w-xl text-sm leading-6 text-[var(--m4h-ink-muted)]",children:"Review lesson reports, approve notices, and follow each message through delivery."})]}),e.jsx("nav",{className:"flex flex-wrap gap-2","aria-label":"Email categories",children:["",...At].map(b=>e.jsx("button",{type:"button","aria-pressed":a===b,className:`${a===b?tt:X} !rounded-full shrink-0 whitespace-nowrap`,onClick:()=>i(b),children:b||"All categories"},b))}),e.jsxs("div",{className:"grid gap-4 rounded-2xl bg-[var(--m4h-tint)] p-5 sm:grid-cols-3",children:[xe("Schools",l,b=>{r(b),x("")},[...((be=T.data)==null?void 0:be.schools)??[],{id:"unassigned",name:"Unassigned"}]),xe("Groups",c,x,[...((je=T.data)==null?void 0:je.groups)??[],{id:"unassigned",name:"Unassigned"}]),xe("Statuses",m,g,[{id:"attention",name:"Needs attention"},...Object.entries(Pt).map(([b,p])=>({id:b,name:p}))])]}),s&&e.jsx("p",{className:"text-sm text-[var(--m4h-ink-muted)]",children:"Showing one lesson report."}),h&&e.jsx("p",{role:"status",className:"rounded-xl bg-[var(--m4h-tint)] p-4 text-sm text-[var(--m4h-ink)]",children:h}),T.error?e.jsxs("div",{role:"alert",className:"text-sm text-red-700",children:["Could not load the outbox. ",T.error.message," ",e.jsx("button",{className:X,onClick:()=>void T.refetch(),children:"Try again"})]}):T.isLoading?e.jsx("div",{className:"animate-pulse space-y-3","aria-label":"Loading outbox",children:[0,1,2].map(b=>e.jsx("div",{className:"h-20 rounded-xl bg-[var(--m4h-tint)]"},b))}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("p",{className:"m-0 text-sm tabular-nums text-[var(--m4h-ink-muted)]",children:[M," matching ",M===1?"email":"emails",M>0?` · ${w*30+1}â${Math.min((w+1)*30,M)}`:""]}),e.jsx("button",{className:X,disabled:T.isFetching,onClick:()=>void T.refetch(),children:"Refresh"})]}),W.length===0?e.jsxs("div",{className:"rounded-2xl bg-[var(--m4h-tint-soft)] px-6 py-12",children:[e.jsx("p",{className:"m-0 text-lg font-medium",children:"No emails in this view"}),e.jsx("p",{className:"mt-2 text-sm text-[var(--m4h-ink-muted)]",children:"Try another status or clear your school and group filters."}),e.jsx("button",{className:X,onClick:()=>{i(""),r(""),x(""),g("")},children:"Show all statuses and categories"})]}):e.jsxs("div",{className:"space-y-8",children:[D.length>0&&e.jsxs("div",{className:"flex flex-wrap items-center gap-2 rounded-xl bg-[var(--m4h-tint)] p-4",children:[e.jsxs("span",{className:"mr-2 text-sm",children:[D.length," selected on this page"]}),e.jsx("button",{className:X,disabled:Y||D.some(b=>b.status!=="review"||!b.data.body_html_rendered),onClick:()=>void Q("approve"),children:"Approve selected"}),e.jsx("button",{className:tt,disabled:Y||D.some(b=>b.status!=="approved"),onClick:()=>void Q("send"),children:"Send selected"}),e.jsx("button",{className:X,disabled:Y||D.some(b=>b.status!=="review"),onClick:()=>void Q("regenerate"),children:"Regenerate"}),e.jsx("button",{className:X,disabled:Y||D.some(b=>b.reserved||!["review","approved"].includes(b.status)),onClick:()=>void Q("delete"),children:"Delete drafts"})]}),At.filter(b=>W.some(p=>p.category===b)).map(b=>e.jsxs("section",{"aria-label":b,children:[e.jsx("p",{className:"mb-2 font-mono text-[11px] uppercase tracking-[.1em] text-[var(--m4h-ink-faint)]",children:b}),e.jsx("div",{className:"overflow-hidden rounded-xl border border-solid border-[var(--m4h-line)] bg-white",children:W.filter(p=>p.category===b).map(p=>{var k;return e.jsx(o.Fragment,{children:e.jsxs("article",{className:"grid gap-x-3 gap-y-2 border-0 border-t border-solid border-[var(--m4h-line)] px-3 py-3 first:border-t-0 transition-colors hover:bg-[var(--m4h-tint-soft)] md:grid-cols-[minmax(0,1fr)_auto] md:px-4",children:[e.jsxs("div",{className:"relative grid min-w-0 items-center gap-x-4 gap-y-1 pl-9 lg:grid-cols-[minmax(0,.85fr)_minmax(0,1.3fr)_minmax(0,1fr)_auto]",children:[p.source==="draft"&&["review","approved"].includes(p.status)&&e.jsxs("label",{className:"absolute -left-2 top-0 lg:top-1/2 lg:-translate-y-1/2 flex h-11 w-11 cursor-pointer items-center justify-center",children:[e.jsx("input",{"aria-label":`Select ${p.subject}`,type:"checkbox",disabled:Y,checked:R.includes(p.id),onChange:q=>N(O=>q.target.checked?[...O,p.id]:O.filter(z=>z!==p.id))}),e.jsx("span",{className:"sr-only",children:"Select draft"})]}),e.jsx("p",{className:"m-0 min-w-0 break-all text-[13px] leading-5 text-[var(--m4h-ink-muted)]",children:p.recipient||"Recipient unavailable"}),e.jsx("h3",{className:"m-0 min-w-0 break-words text-sm font-medium leading-5",children:p.subject}),(()=>{const q=nn(p);return e.jsxs("p",{className:"m-0 min-w-0 text-xs leading-5 text-[var(--m4h-ink-faint)]",children:[e.jsx("span",{className:"block",children:q.primary??""}),q.secondary&&e.jsx("span",{className:"block",children:q.secondary})]})})(),e.jsxs("div",{className:"flex flex-wrap items-center gap-x-2 gap-y-1 lg:flex-col lg:items-end",children:[e.jsx("span",{className:`whitespace-nowrap rounded-full px-2 py-0.5 text-xs ${p.status==="failed"?"bg-red-50 text-red-800":"bg-[var(--m4h-tint)] text-[var(--m4h-ink-muted)]"}`,children:Pt[p.status]??p.status}),e.jsx("time",{className:"whitespace-nowrap text-xs text-[var(--m4h-ink-faint)]",dateTime:p.created_at,children:new Date(p.created_at).toLocaleDateString()})]}),p.error&&e.jsx("p",{className:"m-0 mt-1 text-xs text-[var(--m4h-ink-muted)] lg:col-span-4",children:p.error.replace(/_/g," ")}),p.reconciliation_required&&e.jsx("p",{className:"m-0 text-sm text-red-800 lg:col-span-4",children:"Delivery needs reconciliation before another attempt."})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2 pl-9 md:max-w-64 md:justify-end md:pl-0 [&>button]:md:min-h-8 [&>button]:md:py-1 [&>button]:md:text-xs",children:[p.source==="draft"&&e.jsx("button",{className:X,disabled:Y,onClick:()=>v(p.id),children:p.status==="review"?"Review":"View email"}),e.jsx("button",{className:X,"aria-expanded":_===p.id,onClick:()=>S(_===p.id?null:p.id),children:_===p.id?"Close preview":"Preview"}),p.source==="draft"&&p.status==="approved"&&e.jsx("button",{className:tt,disabled:Y,onClick:()=>void V(p,"send"),children:"Send"}),p.source==="automation"&&p.status==="review"&&e.jsx(e.Fragment,{children:e.jsx("button",{className:X,disabled:Y,onClick:()=>void V(p,"dismiss"),children:"Dismiss"})}),(p.status==="failed"||p.source==="draft"&&p.status==="skipped")&&e.jsx("button",{className:X,disabled:Y||p.reconciliation_required,onClick:()=>void V(p,"retry"),children:p.reserved?"Retry original email":"Return to review"}),p.source==="automation"&&p.status==="failed"&&e.jsx("button",{className:X,disabled:Y,onClick:()=>void V(p,"dismiss"),children:"Dismiss"})]}),_===p.id&&e.jsx(Za,{row:p,template:(k=E.data)==null?void 0:k.find(q=>q.key===p.data.template_key),loading:E.isLoading,busy:Y,onApprove:()=>void V(p,"approve")})]})},p.id)})})]},b))]}),e.jsxs("div",{className:"flex justify-end gap-2",children:[e.jsx("button",{className:X,disabled:w===0,onClick:()=>u(b=>b-1),children:"Previous"}),e.jsx("button",{className:X,disabled:(w+1)*30>=M,onClick:()=>u(b=>b+1),children:"Next"})]})]}),de&&e.jsx(sn,{draft:de.data,template:(E.data??[]).find(b=>b.key===de.data.template_key)??null,onClose:()=>v(null),onApproved:()=>{v(null),g("approved"),d("Approved. The email is ready for you to send.")}},de.id)]})}const lt=["notification_settings"],on="id, notification_type, scope_type, scope_id, mode, config, updated_by, updated_at, created_at";async function ln(){const{data:t,error:s}=await re.from("notification_settings").select(on).order("notification_type",{ascending:!0}).order("scope_type",{ascending:!0});if(s)throw new Error(s.message);return t??[]}function dn(){return Qe({queryKey:lt,queryFn:ln})}
20function cn(){const t=$e();return Ie({mutationFn:async s=>{var r;const{data:a,error:i}=await re.auth.getUser();if(i)throw new Error(i.message);const{error:l}=await re.from("notification_settings").upsert({notification_type:s.notification_type,scope_type:s.scope_type,scope_id:s.scope_id,mode:s.mode,config:s.config??{},updated_by:((r=a.user)==null?void 0:r.id)??null},{onConflict:"notification_type,scope_type,scope_id"});if(l)throw new Error(l.message)},onSuccess:()=>void t.invalidateQueries({queryKey:lt})})}function mn(){const t=$e();return Ie({mutationFn:async s=>{const{error:a}=await re.from("notification_settings").delete().eq("id",s);if(a)throw new Error(a.message)},onSuccess:()=>void t.invalidateQueries({queryKey:lt})})}const st=[{value:"teacher_prep_reminder",label:"Teacher prep reminder",description:"Upcoming-class prep notifications for assigned teachers."},{value:"teacher_pay_review",label:"Teacher pay review",description:"Teacher reminders to review ready pay summaries."},{value:"teacher_missing_log",label:"Teacher missing log",description:"Digest-style reminders for missing attendance or teaching logs."},{value:"teacher_schedule_change",label:"Teacher schedule change",description:"Teacher notices for substitute or material schedule changes."},{value:"teacher_group_assignment",label:"Teacher group assignment",description:"Notice to a teacher when an admin assigns them to an ongoing class."},{value:"teacher_holiday_notice",label:"Teacher holiday notice",description:"Digest of upcoming school closures affecting a teacher's classes. Honors Global and Teacher scope only."},{value:"group_cancellation",label:"Group cancellation family notices",description:"Household notices to enrolled families and pending registrants when a class is cancelled. Generated only by the cancel action itself; Manual holds each email in the Outbox for approval."},{value:"parent_closure_notice",label:"Family closure notices",description:"Household digests when upcoming closures or a cancelled class session affect enrolled families. Forward-looking only; same-day closures qualify immediately, and teacher-triggered notices always hold for approval."},{value:"registration_next_steps",label:"Registration next steps",description:"Payment and waiver instructions after a family registers. Manual holds each email in the Outbox for approval; Auto sends it on submit."},{value:"registration_received",label:"Registration confirmation",description:"Tells a family their registration was received. Off by default so it is not stacked with next-steps. Manual holds for approval; Auto sends on submit."},{value:"private_lesson_booking_request_teacher",label:"New booking request (teacher)",description:"Tells the teacher a family requested lessons with them."},{value:"private_lesson_booking_request_pending_student",label:"Booking request sent (family)",description:"Confirms to the family that their request reached the teacher."},{value:"private_lesson_booking_confirmed_student",label:"Booking confirmed (family)",description:"Lesson details once the teacher accepts."},{value:"private_lesson_booking_confirmed_teacher",label:"Booking confirmed (teacher)",description:"The teacher's copy of a confirmed booking."},{value:"private_lesson_booking_declined_student",label:"Request declined (family)",description:"Sent when a teacher declines a request."},{value:"private_lesson_reminder",label:"Lesson reminder (family)",description:"Reminder before an upcoming lesson."},{value:"private_lesson_teacher_reminder",label:"Lesson reminder (teacher)",description:"Reminder to the teacher before an upcoming lesson."},{value:"private_lesson_reschedule_approved_student",label:"Reschedule approved (family)",description:"The new time, once a reschedule is approved."},{value:"private_lesson_reschedule_approved_teacher",label:"Reschedule approved (teacher)",description:"The teacher's copy of an approved reschedule."},{value:"private_lesson_weekly_time_changed_student",label:"Weekly time changed (family)",description:"Confirms a family's new weekly lesson time."},{value:"private_lesson_weekly_time_changed_teacher",label:"Weekly time changed (teacher)",description:"Tells the teacher a family moved their weekly time."},{value:"private_lesson_cancelled_by_student_confirmation",label:"Cancellation confirmed (family)",description:"Confirms a lesson the family cancelled."},{value:"private_lesson_cancelled_by_student_teacher",label:"Family cancelled (teacher)",description:"Tells the teacher a family cancelled a lesson."},{value:"private_lesson_cancelled_by_teacher_student",label:"Teacher cancelled (family)",description:"Tells the family their teacher cancelled a lesson."},{value:"private_lesson_cancelled_teacher_confirmation",label:"Cancellation confirmed (teacher)",description:"Confirms a lesson the teacher cancelled."},{value:"private_lesson_subscription_invoice",label:"Upcoming payment (family)",description:"Heads-up before the monthly charge."},{value:"private_lesson_message_received",label:"New message from a teacher (family)",description:"Tells a family a teacher wrote to them. At most one every 30 minutes per conversation until they read it."},{value:"private_lesson_message_received_teacher",label:"New message from a fam
20ily (teacher)",description:"Tells a teacher a family wrote to them. At most one every 30 minutes per conversation until they read it."},{value:"admin_message_needs_review",label:"Message held for review (admin)",description:"Tells message reviewers that screening held a message, marked urgent for a possible safety disclosure."},{value:"recurring_charge_receipt",label:"Monthly lesson receipt (family)",description:"Receipt after each monthly charge: every lesson, credits applied, total paid."},{value:"private_lesson_subscription_renewed",label:"Subscription renewed (family)",description:"Confirmation when a subscription renews."},{value:"private_lesson_payment_declined_student",label:"Payment declined (family)",description:"Asks the family to update their card after a declined charge."},{value:"private_lesson_payment_declined_admin",label:"Payment declined (admin)",description:"Your copy when a family's charge is declined."},{value:"admin_lesson_upgrade_receipt",label:"Lesson upgrade confirmation (family)",description:"Confirmation and receipt when you upgrade a student's lesson length."},{value:"admin_lesson_schedule_change_receipt",label:"Day or time change receipt (family)",description:"Receipt when you move a student to a new lesson day and it changes what they pay: the extra charge, or the credits added."},{value:"private_lesson_upgrade_teacher",label:"Lesson upgraded (teacher)",description:"Tells the teacher a student moved to longer lessons."},{value:"private_lesson_subscription_cancelled_student",label:"Subscription cancelled (family)",description:"Confirms a cancelled subscription to the family."},{value:"private_lesson_subscription_cancelled_teacher",label:"Subscription cancelled (teacher)",description:"Tells the teacher a subscription ended."},{value:"private_lesson_review_request",label:"Review your teacher (family)",description:"Invites the family to leave a review."},{value:"match_request_matches_ready",label:"Your teachers are ready (family)",description:"Within minutes of a family asking to be matched: their teachers, and a link back to them."},{value:"match_request_teacher_intro",label:"A teacher wrote to you (family)",description:"Sends a matched teacherâs hello to the family, with a button to book with them."},{value:"match_request_family_reminder",label:"Your teachers are still ready (family)",description:"One day after a matching request, if nothing is booked."},{value:"match_request_family_last_call",label:"Can we help you choose? (family)",description:"Three days after a matching request, if nothing is booked. The last one."},{value:"match_request_teacher_nudge",label:"A family is looking (teacher)",description:"An hour after a matching request with no booking, to the first three matched teachers."},{value:"admin_recurring_billing_summary",label:"Monthly billing summary (admin)",description:"Your summary after each monthly billing run."},{value:"admin_payment_recovery_stuck",label:"Payment recovery stuck (admin)",description:"Alerts you when a declined payment stays unresolved."},{value:"admin_upgrade_payment_stuck",label:"Upgrade payment stuck (admin)",description:"Alerts you when a lesson-upgrade payment needs attention."}],Rt=new Set(["teacher_prep_reminder","teacher_pay_review","teacher_missing_log","teacher_schedule_change","teacher_group_assignment","teacher_holiday_notice"]),Mt=new Set(["private_lesson_message_received","private_lesson_message_received_teacher","admin_message_needs_review","private_lesson_booking_request_teacher","private_lesson_booking_request_pending_student","private_lesson_booking_confirmed_student","private_lesson_booking_confirmed_teacher","private_lesson_booking_declined_student","private_lesson_reminder","private_lesson_teacher_reminder","private_lesson_reschedule_approved_student","private_lesson_reschedule_approved_teacher","private_lesson_weekly_time_changed_student","private_lesson_weekly_time_changed_teacher","private_lesson_cancelled_by_student_confirmation","private_lesson_cancelled_by_student_teacher","private_lesson_cancelled_by_teacher_student","private_lesson_cancelled_teacher_confirmation","private_lesson_subscription_invoice","recurring_charge_receipt","private_lesson_subscription_renewed","private_lesson_payment_declined_student","private_lesson_payment_declined_admin","admin_lesson_upgrade_receipt","admin_lesson_schedule_change_receipt","private_lesson_upgrade_teacher","private_lesson_subscription_cancelled_student","private_lesson_subscription_cancelled_teacher","private_lesson_review_request","match_request_matches_ready","match_request_teacher_intro","match_request_family_reminder","match_request_family_last_call","match_request_teacher_nudge","admin_recurring_billing_summary","admin_payment_recovery_stuck","admin_upgrade_payment_stuck"]),un=[{id:"teachers",title:"Teachers",subtitle:"Notifications and emails sent to instructors and staff.",automated:st.filter(t=>Rt.has(t.value)),informational:[{value:"teacher_invite",label:"Teacher invite & welcome",behavior:"Transactional · Sends immediately",description:"Invite link (or welcome note) when an admin adds a teacher account."},{value:"pay_packet_document",label:"Pay packet documents",behavior:"Human controlled · Admin sends",description:"Pay packet PDFs, sent explicitly from the Pay page."},{value:"public_teacher_contact",label:"Family â teacher contact relay",behavior:"Transactional · Sends immediately",description:"Relays a family's message from the public progress page to the teacher, with reply-to set to the family. The teacher's address is never exposed."},{value:"password_reset",label:"Password reset",behavior:"Transactional · Sends on request",description:"Reset links for staff accounts. The email body is deliberately never stored."}]},{id:"private_lessons",title:"Private lessons",subtitle:"Notifications for one-on-one lesson families and their teachers.",automated:st.filter(t=>
20Mt.has(t.value)),informational:[{value:"private_lesson_student_welcome",label:"Welcome (family)",behavior:"Transactional · Sends immediately",description:"Sent when a family's private-lesson account is created."},{value:"private_lesson_consultation_auto_reply",label:"Enquiry auto-reply",behavior:"Transactional · Sends immediately",description:"Auto-reply to a public enquiry."},{value:"private_lesson_booking_abandoned_student",label:"Finish your booking",behavior:"Transactional · Sends immediately",description:"Nudge when a checkout is left unfinished."},{value:"private_lesson_reschedule_request_teacher",label:"Reschedule request (teacher)",behavior:"Transactional · Sends immediately",description:"A family's reschedule request, to the teacher."},{value:"private_lesson_reschedule_pending_student",label:"Reschedule sent (family)",behavior:"Transactional · Sends immediately",description:"Confirms a reschedule request was sent."},{value:"private_lesson_reschedule_pending_teacher",label:"Reschedule sent (teacher)",behavior:"Transactional · Sends immediately",description:"The teacher's copy of a pending reschedule."},{value:"private_lesson_reschedule_declined_student",label:"Reschedule declined (family)",behavior:"Transactional · Sends immediately",description:"Sent when a reschedule is declined."},{value:"private_lesson_reschedule_declined_teacher",label:"Reschedule declined (teacher)",behavior:"Transactional · Sends immediately",description:"The teacher's copy of a declined reschedule."},{value:"private_lesson_refund_confirmation",label:"Refund confirmation",behavior:"Human controlled · Admin issues refund",description:"Sent when you record a refund."},{value:"enrollment_spot_payment_required",label:"Spot confirmation / payment required",behavior:"Transactional · Sends immediately",description:"Holds a spot pending payment."}]},{id:"parents",title:"Parents & Families",subtitle:"Notifications and emails sent to parents and guardians.",automated:st.filter(t=>!Rt.has(t.value)&&!Mt.has(t.value)),informational:[{value:"enrollment_confirmed",label:"Enrollment confirmed",behavior:"Transactional · Sends after you confirm enrollment",description:"Welcome + class logistics, sent when an admin confirms a registration."},{value:"waiver_signed_confirmation",label:"Waiver signed confirmation",behavior:"Transactional · Sends immediately",description:"Confirmation with the signed PDF attached when a family completes a waiver. Admins can re-send it."},{value:"waiver_email_verification_code",label:"Waiver verification code",behavior:"Transactional · Sends on request",description:"The email verification code used during waiver signing."},{value:"parent_lesson_report",label:"Parent lesson report",behavior:"Human controlled · Requires approval + Send",description:"Drafts are generated per lesson report, must be approved in the Outbox, and only send when an admin sends them. Never automatic."}]}],pn={teachers:as,private_lessons:ss,parents:cs},hn=[{value:"off",label:"Off"},{value:"manual",label:"Manual"},{value:"auto",label:"Auto"}],xn=[{term:"Auto",definition:"sends automatically",tone:"mode"},{term:"Manual",definition:"generates and holds for approval",tone:"mode"},{term:"Off",definition:"suppresses that configurable automation",tone:"mode"},{term:"Transactional",definition:"triggered by a specific action; not controlled here",tone:"static"},{term:"Human-controlled",definition:"requires an explicit admin send",tone:"static"}];function It(t,s=!1){return t==="off"&&s?"OFF (default)":t==="off"?"OFF":t==="manual"?"MANUAL":"AUTO"}function fn(t,s){return t.find(a=>a.notification_type===s&&a.scope_type==="global"&&a.scope_id===null)??null}function bn(t){return t.filter(s=>s.scope_type!=="global")}function gn(t){return t.nextMode===t.currentMode?{action:"noop"}:t.nextMode==="auto"&&t.autoConfirmationFor!==t.notificationType?{action:"request_auto_confirmation",notificationType:t.notificationType}:{action:"upsert",input:{notification_type:t.notificationType,scope_type:"global",scope_id:null,mode:t.nextMode,config:t.currentConfig??{}}}}function _n(t){return t.startsWith("Human controlled")?"border-indigo-200 bg-indigo-50 text-indigo-700":"border-stone-200 bg-stone-100 text-stone-600"}function yn({rows:t,isLoading:s=!1,errorMessage:a=null,upsertPending:i=!1,deletePending:l=!1,onUpsert:r,onDelete:c}){const[x,m]=o.useState(null),g=o.useMemo(()=>bn(t),[t]);function w(d,_,S){const T=(_==null?void 0:_.mode)??"off",E=gn({notificationType:d,currentMode:T,nextMode:S,
20currentConfig:_==null?void 0:_.config,autoConfirmationFor:x});if(E.action==="request_auto_confirmation"){m(E.notificationType);return}m(null),E.action==="upsert"&&r(E.input)}function u(d,_){m(null),r({notification_type:d,scope_type:"global",scope_id:null,mode:"auto",config:(_==null?void 0:_.config)??{}})}if(s)return e.jsx("section",{className:"rounded-xl border border-stone-200 bg-white p-5 shadow-sm","aria-busy":"true",children:e.jsx("p",{className:"m-0 text-sm text-stone-600",children:"Loading automation settings..."})});function j(d){const _=fn(t,d.value),S=(_==null?void 0:_.mode)??"off",T=!_,E=x===d.value;return e.jsxs("div",{className:"px-5 py-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-x-6 gap-y-3",children:[e.jsxs("div",{className:"min-w-0 flex-1 basis-64",children:[e.jsxs("p",{className:"m-0 flex flex-wrap items-center gap-2 text-sm font-medium text-stone-900",children:[d.label,T?e.jsx("span",{className:"text-[11px] font-medium uppercase tracking-wide text-stone-400",children:It(S,T)}):null]}),e.jsx("p",{className:"m-0 mt-0.5 text-sm leading-5 text-stone-500",children:d.description})]}),e.jsx("div",{"aria-label":`${d.label} mode`,className:"inline-flex shrink-0 rounded-lg bg-stone-100 p-0.5",role:"group",children:hn.map(A=>e.jsx("button",{className:`appearance-none rounded-md border-0 px-3 py-1.5 text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 ${S===A.value?"bg-white text-stone-900 shadow-sm ring-1 ring-stone-200":"bg-transparent text-stone-500 hover:text-stone-900"}`,disabled:i,onClick:()=>w(d.value,_,A.value),type:"button",children:A.label},A.value))})]}),E?e.jsxs("div",{className:"mt-3 rounded-lg border border-amber-300 bg-amber-50 p-3",children:[e.jsxs("div",{className:"flex gap-2",children:[e.jsx(Bs,{"aria-hidden":"true",className:"mt-0.5 h-4 w-4 shrink-0 text-amber-700"}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("p",{className:"m-0 text-sm font-semibold text-amber-950",children:"Confirm automatic mode"}),e.jsx("p",{className:"m-0 mt-1 text-sm leading-5 text-amber-900",children:"AUTO means this notification sends automatically, without the Outbox approval step Manual provides."})]})]}),e.jsxs("div",{className:"mt-3 flex flex-wrap gap-2",children:[e.jsx("button",{className:`${Ae} bg-amber-100 text-amber-950 ring-amber-300 hover:bg-amber-200`,disabled:i,onClick:()=>u(d.value,_),type:"button",children:"Confirm auto mode"}),e.jsx("button",{className:Ae,disabled:i,onClick:()=>m(null),type:"button",children:"Cancel"})]})]}):null]},d.value)}function v(d){return e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-x-6 gap-y-2 px-5 py-4",children:[e.jsxs("div",{className:"min-w-0 flex-1 basis-64",children:[e.jsx("p",{className:"m-0 text-sm font-medium text-stone-900",children:d.label}),e.jsx("p",{className:"m-0 mt-0.5 text-sm leading-5 text-stone-500",children:d.description})]}),e.jsx("span",{className:`inline-flex shrink-0 whitespace-nowrap rounded-md border px-2.5 py-1 text-xs font-medium ${_n(d.behavior)}`,children:d.behavior})]},d.value)}function h(d,_){return e.jsxs("div",{children:[e.jsx("h3",{className:"m-0 mb-2 text-[11px] font-semibold uppercase tracking-widest text-stone-400",children:d}),e.jsx("div",{className:"divide-y divide-stone-100 overflow-hidden rounded-xl border border-stone-200 bg-white",children:_})]})}return e.jsxs("section",{className:"space-y-10",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-2.5",children:[e.jsx(ds,{"aria-hidden":"true",className:"h-5 w-5 text-indigo-600"}),e.jsx("h2",{className:"m-0 text-xl font-semibold tracking-tight text-stone-950",children:"Email Automations"})]}),e.jsx("p",{className:"m-0 mt-1 text-sm text-stone-600",children:"Control how teacher and family notifications are generated, reviewed, and sent."}),e.jsx("dl",{className:"m-0 mt-4 flex flex-wrap gap-x-6 gap-y-2 rounded-xl border border-stone-200 bg-stone-50/70 px-5 py-3.5",children:xn.map(d=>e.jsxs("div",{className:"flex items-baseline gap-1.5 text-sm",children:[e.jsx("dt",{className:`m-0 font-semibold ${d.tone==="mode"?"text-stone-900":"text-stone-700"}`,children:d.term}),e.jsx("dd",{className:"m-0 text-stone-500",children:d.definition})]},d.term))}),a?e.jsx("p",{className:"m-0 mt-4 text-sm font-medium text-rose-700",role:"alert",children:a}):null]}),un.map(d=>{const _=pn[d.id];return e.jsxs("section",{"aria-labelledby":`email-section-${d.id}`,className:"space-y-5",children:[e.jsxs("div",{className:"flex items-center gap-3.5 rounded-xl border border-stone-200 bg-stone-100/70 px-5 py-4",children:[e.jsx("span",{className:"flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-indigo-100 text-indigo-700",children:e.jsx(_,{"aria-hidden":"true",className:"h-5 w-5"})}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("h2",{className:"m-0 text-lg font-semibold tracking-tight text-stone-950",id:`email-section-${d.id}`,children:d.title}),e.jsx("p",{className:"m-0 mt-0.5 text-sm text-stone-600",children:d.subtitle})]})]}),d.automated.length>0?h("Automated notifications",d.automated.map(j)):null,d.informational.length>0?h("Transactional & human-controlled",d.informational.map(v)):null]},d.id)}),e.jsx("p",{className:"m-0 rounded-lg bg-stone-50 px-4 py-3 text-xs leading-5 text-stone-500",children:"Admin-only mail is not listed above: bounce/complaint alerts and registration/waiver submission notices go to the admin address automatically, and Compose, Test Send, and Re-send are always explicit admin actions. All of it appears in Sent."}),e.jsxs("section",{className:"rounded-xl border border-stone-200 bg-white p-5 shadow-sm",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"m-0 text-base font-semibold text-stone-950",children:"Scoped overrides"}),e.jsx("p",{className:"m-0 mt-1 text-sm text-stone-600",children:"Existing school, group, template, and teacher overrides are read-only here."})]}),e.jsxs("span",{className:"text-xs font-medium text-stone-500",children:[g.length," override",g.length===1?"":"s"]})]}),g.length===0?e.jsx("p",{className:"m-0 mt-4 rounded-lg bg-stone-50 px-4 py-3 text-sm text-stone-600",children:"No scoped overrides yet."}):e.jsx("div",{className:"mt-4 overflow-hidden rounded-lg border border-stone-200",children:e.jsxs("table",{className:"min-w-full divide-y divide-stone-200 text-sm",children:[e.jsx("thead",{className:"bg-stone-50 text-left text-xs font-semibold uppercase tracking-wide text-stone-500",children:e.jsxs("tr",{children:[e.jsx("th",{className:"px-4 py-3",children:"Notification"}),e.jsx("th",{className:"px-4 py-3",children:"Scope"}),e.jsx("th",{className:"px-4 py-3",children:"Mode"}),e.jsx("th",{className:"px-4 py-3 text-right",children:"Remove"})]})}),e.jsx("tbody",{className:"divide-y divide-stone-200 bg-white",children:g.map(d=>e.jsxs("tr",{children:[e.jsx("td",{className:"px-4 py-3 font-medium text-stone-900",children:d.notification_type}),e.jsxs("td",{className:"px-4 py-3 text-stone-600",children:[e.jsx("span",{className:"font-medium text-stone-800",children:d.scope_type}),e.jsx("span",{className:"ml-2 break-all font-mono text-xs text-stone-500",children:d.scope_id})]}),e.jsx("td",{className:"px-4 py-3 text-stone-700",children:It(d.mode)}),e.jsx("td",{className:"px-4 py-3 text-right",children:d.id?e.jsx("button",{"aria-label":`Delete ${d.notification_type} ${d.scope_type} override`,className:Ut,disabled:l,onClick:()=>c(d.id),type:"button",children:e.jsx(ns,{"aria-hidden":"true",className:"h-4 w-4"})}):null})]},d.id??`${d.notification_type}-${d.scope_type}-${d.scope_id}`))})]})})]})]})}function vn(){const t=dn(),s=cn(),a=mn();return e.jsx(yn,{rows:t.data??[],isLoading:t.isLoading,errorMessage:t.error?t.error.message:null,upsertPending:s.isPending,deletePending:a.isPending,onUpsert:i=>s.mutate(i),onDelete:i=>a.mutate(i)})}const dt=["email_suppressions"];function us(){return Qe({queryKey:dt,queryFn:async()=>{const{data:t,error:s}=await re.from("email_suppressions").select("id, email, scope, reason, note, created_at").order("created_at",{ascending:!1}).limit(2e3);if(s)throw new Error(s.message);return t??[]}})}
20function jn(){const t=$e();return Ie({mutationFn:async({email:s,scope:a,note:i})=>{const l=s.trim().toLowerCase();if(!l)throw new Error("Enter an email address.");const{error:r}=await re.from("email_suppressions").insert({email:l,scope:a,reason:"manual",note:(i==null?void 0:i.trim())||null});if(r)throw new Error(r.message)},onSuccess:()=>void t.invalidateQueries({queryKey:dt})})}function Nn(){const t=$e();return Ie({mutationFn:async s=>{const{error:a}=await re.from("email_suppressions").delete().eq("id",s);if(a)throw new Error(a.message)},onSuccess:()=>void t.invalidateQueries({queryKey:dt})})}function wn(){const{data:t,isLoading:s,error:a}=us(),i=jn(),l=Nn(),[r,c]=o.useState(""),[x,m]=o.useState("promotional"),[g,w]=o.useState(""),u=a instanceof Error?a.message:null,j=i.error instanceof Error?i.error.message:null;function v(h){h.preventDefault(),!(!r.trim()||i.isPending)&&i.mutate({email:r,scope:x,note:g||null},{onSuccess:()=>{c(""),w(""),m("promotional")}})}return e.jsxs("section",{"aria-label":"Do not email",className:"mx-auto max-w-3xl space-y-5",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-2.5",children:[e.jsx(ms,{"aria-hidden":"true",className:"h-5 w-5 text-indigo-600"}),e.jsx("h2",{className:"m-0 text-xl font-semibold tracking-tight text-stone-950",children:"Do not email"})]}),e.jsx("p",{className:"m-0 mt-1 text-sm text-stone-600",children:"Every send checks this list server-side â Compose, automations, and re-sends alike. Compose shows excluded addresses rather than silently skipping them."})]}),e.jsxs("form",{className:"flex flex-wrap items-end gap-3 rounded-xl border border-stone-200 bg-white px-4 py-3.5",onSubmit:v,children:[e.jsxs("label",{className:"min-w-0 flex-1 basis-56 text-xs font-medium text-stone-700",children:["Email address",e.jsx("input",{className:`${pe} mt-1`,onChange:h=>c(h.target.value),placeholder:"[email protected]",type:"email",value:r})]}),e.jsxs("label",{className:"min-w-0 flex-1 basis-56 text-xs font-medium text-stone-700",children:["Note ",e.jsx("span",{className:"font-normal text-stone-500",children:"(optional)"}),e.jsx("input",{className:`${pe} mt-1`,onChange:h=>w(h.target.value),placeholder:"e.g. requested no email 8/18",value:g})]}),e.jsxs("fieldset",{className:"m-0 w-full border-0 p-0",children:[e.jsx("legend",{className:"sr-only",children:"What to stop"}),e.jsx("div",{className:"flex flex-wrap gap-x-6 gap-y-2",children:[{value:"promotional",label:"Promotional emails only",description:"Stops news, registration announcements, and re-enrollment outreach."},{value:"all",label:"All non-essential emails",description:"Stops promotional and n
20ormal program communications. Account/security messages may still be delivered."}].map(h=>e.jsxs("label",{className:"flex items-start gap-2 text-sm",children:[e.jsx("input",{checked:x===h.value,className:"mt-1 h-4 w-4 border-stone-300 text-indigo-600 focus:ring-indigo-500",name:"suppression-scope",onChange:()=>m(h.value),type:"radio"}),e.jsxs("span",{className:"min-w-0",children:[e.jsx("span",{className:"block font-medium text-stone-900",children:h.label}),e.jsx("span",{className:"block text-xs leading-5 text-stone-500",children:h.description})]})]},h.value))})]}),e.jsx("button",{className:ge,disabled:!r.trim()||i.isPending,type:"submit",children:i.isPending?"Adding...":"Add to list"}),j?e.jsx("p",{className:"m-0 w-full text-sm font-medium text-rose-700",children:j}):null]}),u?e.jsx("p",{className:"m-0 rounded-lg bg-rose-50 px-3 py-2 text-sm font-medium text-rose-700",children:u}):null,s?e.jsx("p",{className:"m-0 text-sm text-stone-500",children:"Loading..."}):null,(t??[]).length===0&&!s&&!u?e.jsx("p",{className:"m-0 rounded-lg bg-stone-50 px-4 py-3 text-sm text-stone-600",children:"No suppressed addresses."}):(t??[]).length>0?e.jsx("ul",{className:"m-0 list-none divide-y divide-stone-100 overflow-hidden rounded-xl border border-stone-200 bg-white p-0",role:"list",children:(t??[]).map(h=>e.jsxs("li",{className:"flex items-center gap-4 px-4 py-3",children:[e.jsxs("span",{className:"min-w-0 flex-1",children:[e.jsx("span",{className:"block truncate text-sm font-medium text-stone-900",children:h.email}),e.jsxs("span",{className:"block truncate text-xs text-stone-500",children:[h.reason==="unsubscribe"?"Unsubscribed":h.reason==="hard_bounce"?"Address bounced":h.reason==="complaint"?"Spam complaint":"Marked by admin",h.note?` · ${h.note}`:""]})]}),e.jsx("span",{className:`shrink-0 rounded-md border px-2 py-0.5 text-[11px] font-medium ${h.scope==="all"?"border-rose-200 bg-rose-50 text-rose-700":"border-stone-200 bg-stone-100 text-stone-600"}`,children:h.scope==="all"?"All non-essential":"Promotional only"}),e.jsx("button",{"aria-label":`Remove ${h.email} from the do-not-email list`,className:Ut,disabled:l.isPending,onClick:()=>l.mutate(h.id),type:"button",children:e.jsx(ns,{"aria-hidden":"true",className:"h-4 w-4"})})]},h.id))}):null]})}function Sn(t){if(!/^\d{4}-\d{2}-\d{2}$/.test(t))return null;const[s,a,i]=t.split("-").map(Number),l=new Date(Date.UTC(s,a-1,i));return[l.getUTCFullYear(),String(l.getUTCMonth()+1).padStart(2,"0"),String(l.getUTCDate()).padStart(2,"0")].join("-")===t?l:null}function kn(t){const s=Sn(t);if(!s)return"neutral";const a=s.getUTCMonth()+1;return a===8||a===9?"fall":a===1||a===2?"spring":"neutral"}function Cn(t){const s=t.trim().replace(/\/+$/,"");return s?`${s}/register`:"/register"}function Tn(t,s=""){const a=s.trim()||"your school";return t==="fall"?{opening:"I hope youâre doing well and that you and the family had a wonderful summer! I canât believe another school year is already here.",inviteLead:`Weâre so excited to be back at ${a} for another year of music, and weâd absolutely love to have `,inviteTail:" join us!",aheadLead:"We have another fun year ahead of us, and it would be great to have ",aheadTail:" making music with us again!",close:"Hope weâll get to make music together again soon!"}:t==="spring"?{opening:"Happy New Year! I hope you and the family had a wonderful winter break.",inviteLead:`Weâre back at ${a} for a fresh semester of music â new songs, new ideas, and weâd love to have `,inviteTail:" with us!",aheadLead:"If youâd like ",aheadTail:" to jump back in, it would be so good to make more music together.",close:"Hereâs to more music â hope to see you soon!"}:{opening:"I hope youâre doing well!",inviteLead:`Weâre excited to be back at ${a} for another semester of music, and weâd love to have `,inviteTail:" join us!",aheadLead:"We have another fun semester ahead of us, and it would be great to have ",aheadTail:" making music with us again!",close:"Hope weâll get to make music together again soon!"}}const ps=[{id:"audience",label:"Audience"},{id:"message",label:"Message"},{id:"review",label:"Review & Send"}];function En(t,s){const a=ps.map(r=>r.id),i=a.indexOf(t),l=a.indexOf(s);return i===l?"current":i<l?"complete":"upcoming"}function $n(t){return t>0}function Pn(t){return t.mode==="template"?!!t.templateKey:t.subject.trim().length>0&&t.bodyText.trim().length>0}function An(t){const s=new Map;for(const a of t){const i=a.school_id??`name:${a.school_name}`;s.has(i)||s.set(i,{id:i,name:a.school_name})}return[...s.values()].sort((a,i)=>a.name.localeCompare(i.name))}function it(t,s){return t.filter(a=>(a.school_id??`name:${a.school_name}`)===s).sort((a,i)=>a.name.localeCompare(i.name))}const qe="all";function hs(t,s){return!(t.status==="cancelled"||t.is_archived||t.end_date&&t.end_date<s)}const Rn=new Set(["active","inactive","completed"]);function Dt(t){if(t.scope==="pending")return[];const s=new Map(t.groups.filter(r=>(r.school_id??`name:${r.school_name}`)===t.schoolKey).map(r=>[r.id,r])),a=new Map(t.students.map(r=>[r.id,r])),i=new Map;for(const r of t.enrollments){const c=s.get(r.group_id);if(!c||!Rn.has(r.status)||t.groupId!==qe&&r.group_id!==t.groupId)continue;const x=a.get(r.student_id);if(!x||x.active===!1||x.synthetic===!0)continue;const m=i.get(r.student_id)??{current:null,last:null,historyGroupName:null};r.status==="active"&&hs(c,t.today)&&(m.current={groupId:c.id,groupName:c.name});const g=r.enrollment_start??"";(!m.last||g>=m.last.sortKey)&&(m.last={groupId:c.id,groupName:c.name,sortKey:g}),i.set(r.student_id,m)}if(t.groupId===qe&&t.history)for(const r of t.history){if(r.school_id!==t.schoolKey||i.has(r.student_id))continue;const c=a.get(r.student_id);!c||c.active===!1||c.synthetic===!0||i.set(r.student_id,{current:null,last:null,historyGroupName:r.group_name})}const l=[];for(const[r,c]of i){const x=a.get(r),m=c.current?"current":"past";if(t.scope==="current"&&m!=="current"||t.scope==="past"&&m!=="past")continue;const g=c.current??c.last;g?l.push({student:x,groupId:g.groupId,groupName:g.groupName,enrollment:m}):l.push({student:x,groupId:null,groupName:c.historyGroupName,enrollment:"past"})}return l.sort((r,c)=>`${r.student.first_name} ${r.student.last_name}`.localeCompare(`${c.student.first_name} ${c.student.last_name}`))}function xs(t){return Array.isArray(t)?t[0]??null:t??null}function Mn(t){var s;return((s=xs(t.group))==null?void 0:s.name)??null}function Lt(t){return t.submissions.filter(s=>{var l;if(s.status!=="pending")return!1;const a=((l=xs(s.school))==null?void 0:l.school_name)??null;return!(!(s.school_id===t.schoolKey||a!=null&&`name:${a}`===t.schoolKey)||t.groupId!==qe&&s.group_id!==t.groupId)}).map(s=>({submission:s,groupName:Mn(s)})).sort((s,a)=>`${s.submission.student_first_name} ${s.submission.student_last_name}`.localeCompare(`${a.submission.student_first_name} ${a.submission.student_last_name}`))}function we(t,s){return t?t==="all"?!0:s==="promotional":!1}function In(t){return t.audienceKind==="families"&&t.enrollmentScope==="past"?{purpose:"promotional",forcedPromotional:!0,needsChoice:!1}:t.messageMode==="template"&&t.templatePurpose?{purpose:t.templatePurpose==="promotional"?"promotional":"transactional",forcedPromotional:!1,needsChoice:!1}:{purpose:t.chosenPurpose,forcedPromotional:!1,needsChoice:!0}}function Dn(t,s,a){const i=[];let l=0;for(const r of t){const c=s.get(r.email.trim().toLowerCase());we(c,a)?l+=1:i.push(r)}return{allowed:i,suppressedCount:l}}function Ln(t,s,a){const i=On(t,s);return a>0?`${i} · ${a} opted out excluded`:i}function Bn(t){if(!t.schoolKey&&!t.groupId)return null;const s=t.groupId?new Set([t.groupId]):new Set(it(t.groups,t.schoolKey).map(i=>i.id)),a=new Set;for(const i of t.edges)!i.active||i.archived||s.has(i.group_id)&&a.add(i.teacher_user_id
20);return a}function Me(t,s,a){return`${t} ${t===1?s:a??`${s}s`}`}function On(t,s){return`${Me(t,"student")} selected · ${Me(s,"family","families")}`}function qn(t){return t.kind==="teachers"?`Sending to ${Me(t.teacherCount,"teacher")}${t.groupName?` in ${t.groupName}`:""}`:`Sending to ${Me(t.studentCount,"student")}${t.groupName?` in ${t.groupName}`:""}`}function Fn(t,s){return t==="teachers"?`Send to ${Me(s,"teacher")}`:`Send to ${Me(s,"family","families")}`}function Un(t){return t.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function fs(t){return t.trim().split(/\n{2,}/).map(s=>`<p>${Un(s).replace(/\n/g,"<br />")}</p>`).join(` 21`)}const Hn=new Set(["email","name","recipient_name","parent_name","parent_first_name","student_name","student_first_name","student_last_name","teacher_name","teacher_first_name","teacher_last_name","group_name"]),Kn=new Set(["email_signature","prep_checklist_html"]);function Bt(t){const s=t==null?void 0:t.trim().match(/^(\d{1,2}):(\d{2})/);if(!s)return null;const a=Number(s[1]),i=s[2];if(!Number.isFinite(a)||a>23)return null;const l=a>=12?"PM":"AM";return`${a%12===0?12:a%12}:${i} ${l}`}function Gn(t){var c;if(!t)return"";const s=((c=t.day_of_week)==null?void 0:c.trim())||null,a=Bt(t.start_time),i=Bt(t.end_time),l=a&&i?`${a} â ${i}`:a,r=[s,l].filter(Boolean).join(", ");return r?`Schedule: ${r}`:""}function Wn(t){var r;const s=(r=t==null?void 0:t.start_date)==null?void 0:r.trim(),a=s==null?void 0:s.match(/^(\d{4})-(\d{2})-(\d{2})$/);if(!a)return"";const i=new Date(Date.UTC(Number(a[1]),Number(a[2])-1,Number(a[3]),12));return Number.isNaN(i.getTime())?"":`Starts: ${i.toLocaleDateString("en-US",{timeZone:"UTC",month:"long",day:"numeric",year:"numeric"})}`}function he(t){return typeof t=="string"&&t.trim().length>0?t.trim():null}function Yn(t,s){return t&&s?` for ${t} at ${s}`:t?` for ${t}`:s?` at ${s}`:""}function rt(t){const s=he(t);if(!s)return null;try{const a=new URL(s);return a.protocol!=="http:"&&a.protocol!=="https:"?null:s}catch{return null}}const Qn=/^[a-z0-9][a-z0-9-]*[a-z0-9]$/;function Vn(t,s){var l;const a=((l=he(t))==null?void 0:l.replace(/\/+$/,""))??null,i=he(s);return!a||!i||!Qn.test(i)?null:rt(`${a}/waivers/${i}`)}function zn(t){if(!t)return null;const s=he(t.first_name),a=he(t.last_name);return s&&a?`${s} ${a}`:he(t.name)||s||a}const Jn=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;function Xn(t){var c;const s=he(t.name),a=(c=he(t.email))!=null&&c.includes("@")?he(t.email):null,i=he(t.phone),l=i&&!Jn.test(i)?i:null;if(!s&&!a&&!l)return"";const r=[a,l].filter(Boolean).join(" · ");return s&&r?`Your teacher is ${s} â ${r}.`:s?`Your teacher is ${s}.`:`Your teacher: ${r}.`}function Zn(t){var S,T,E,A,I,f,C,B;const s=t.group,a=((s==null?void 0:s.school_name)||t.schoolName||"").trim(),i=((S=t.origin)==null?void 0:S.trim())||"https://app.music4humans.com",l=((T=s==null?void 0:s.start_date)==null?void 0:T.trim())||((E=t.today)==null?void 0:E.trim())||"",r=Tn(kn(l),a),c={email_signature:Jt(),registration_url:Cn(i),seasonal_opening:r.opening,seasonal_invite_lead:r.inviteLead,seasonal_invite_tail:r.inviteTail,seasonal_ahead_lead:r.aheadLead,seasonal_ahead_tail:r.aheadTail,seasonal_close:r.close};a&&(c.school_name=a,c.location_name=a,c.location_line=`Location: ${a}`);const x=(s==null?void 0:s.name.trim())||null,m=Yn(x,a||null);m&&(c.class_context=m);const g=zn(t.teacher),w=Xn({name:g,email:(A=t.teacher)==null?void 0:A.email,phone:(I=t.teacher)==null?void 0:I.phone});g&&(c.teacher_name=g),w&&(c.teacher_line=w);const u=Vn(i,(f=t.waiver)==null?void 0:f.slug);if(u&&(c.waiver_url=u,c.waiver_line=`Please sign the waiver here: ${u}`),!s)return c;c.class_name=s.name;const j=((C=s.program_name)==null?void 0:C.trim())||s.name.trim();j&&(c.program_name=j,(B=s.program_name)!=null&&B.trim()&&(c.program_line=`Program: ${s.program_name.trim()}`));const v=typeof s.max_capacity=="number"&&Number.isFinite(s.max_capacity)?Math.floor(s.max_capacity):null;v!=null&&v>0&&(c.capacity=String(v));const h=rt(s.parent_payment_url)??he(s.parent_payment_url);if(h){c.payment_url=h;const P=rt(h);P&&(c.payment_line=`Please complete payment here: ${P}`)}const d=Gn(s);d&&(c.schedule_line=d);const _=Wn(s);return _&&(c.start_line=_),c}function ei(t,s,a){const i=t??[],l=u=>u.slice().sort((j,v)=>v.updated_at.localeCompare(j.updated_at))[0]??null,r=u=>u.status!=="archived",c=s?i.filter(u=>u.group_id===s&&r(u)):[],x=a?i.filter(u=>u.school_id===a&&u.group_id==null&&r(u)):[],m=c.length>0?c:x,g=m.filter(u=>u.status==="active"),w=l(g.length>
210?g:m);return w?{name:w.name,slug:w.slug}:null}function ti(t,s){const a=[],i=[],l=[];for(const r of t)Hn.has(r)?a.push(r):Kn.has(r)||r in s?i.push(r):l.push(r);return{recipient:a,context:i,manual:l}}function si(t,s){return t.filter(a=>!(s[a]??"").trim())}function ai(t,s){return t.kind==="template"?{templateKey:t.templateKey,mergeData:{...t.commonValues,...s.mergeData},...t.purpose?{purpose:t.purpose}:{}}:{subject:ie(t.subject,s.mergeData),html:ie(fs(t.bodyText),s.mergeData,{html:!0}),purpose:t.purpose}}function ni(t){return new Promise(s=>{window.setTimeout(s,t)})}function ii(){const t=Qt(),[s,a]=o.useState(!1),[i,l]=o.useState(null),[r,c]=o.useState(null),x=o.useCallback(()=>{c(null),t.reset()},[t]),m=o.useCallback(async({recipients:g,message:w})=>{const u=g,j=u.length,v=[];let h=0,d=0,_=0;a(!0),c(null),l({current:0,total:j});try{for(let T=0;T<j;T+=1){const E=u[T];l({current:T+1,total:j});try{(await t.mutateAsync({to:E.email,toName:E.name,...ai(w,E),recipientType:E.metadata.recipientType,recipientId:E.metadata.recipientId,relatedEntityType:E.metadata.relatedEntityType,relatedEntityId:E.metadata.relatedEntityId})).skipped?d+=1:h+=1}catch(A){_+=1;const I=A instanceof Error?A.message:String(A);v.push(`${E.email}: ${I}`)}T<j-1&&await ni(Wt)}}finally{a(!1),l(null)}const S={attempted:j,sent:h,skipped:d,failed:_,errors:v};return c(S),S},[t]);return{sending:s,progress:i,summary:r,isPending:t.isPending,send:m,reset:x}}async function ri(){const{data:t,error:s}=await re.from("enrollments").select("student_id, group_id, status, enrollment_start").limit(1e4);if(s)throw new Error(s.message);return t??[]}function oi(){return Qe({queryKey:["enrollments","history"],queryFn:ri})}function bs(t){return[t.first_name,t.last_name].filter(Boolean).join(" ").trim()}function gs(t){return t.name??([t.first_name,t.last_name].filter(Boolean).join(" ").trim()||t.email)}function li(t){if(!t.parent_email)return null;const s=bs(t),a=t.parent_name.trim()||`${s} family`;return{id:`parent:${t.id}`,type:"parent",email:t.parent_email,name:a,label:`${a} (${s})`,groupName:t.group_name,studentName:s,metadata:{recipientType:"parent",recipientId:t.id,relatedEntityType:"student",relatedEntityId:t.id},mergeData:{email:t.parent_email,group_name:t.group_name,name:a,parent_name:a,parent_first_name:Zt(t.parent_name),recipient_name:a,student_first_name:t.first_name,student_last_name:t.last_name,student_name:s}}}function di(t){const s=gs(t);return{id:`teacher:${t.id}`,type:"teacher",email:t.email,name:s,label:s,metadata:{recipientType:"teacher",recipientId:t.id,relatedEntityType:"teacher",relatedEntityId:t.id},mergeData:{email:t.email,name:s,recipient_name:s,teacher_first_name:t.first_name??"",teacher_last_name:t.last_name??"",teacher_name:s}}}function ci(t){const s=t.submission;if(!s.parent_email)return null;const a=`${s.student_first_name} ${s.student_last_name}`.trim(),i=s.parent_name.trim()||`${a} family`;return{id:`pending:${s.id}`,type:"parent",email:s.parent_email,name:i,label:`${i} (${a})`,groupName:t.groupName,studentName:a,metadata:{recipientType:"parent",recipientId:s.id,relatedEntityType:"registration_submission",relatedEntityId:s.id},mergeData:{email:s.parent_email,group_name:t.groupName??"",name:i,parent_name:i,parent_first_name:Zt(s.parent_name),recipient_name:i,student_first_name:s.student_first_name,student_last_name:s.student_last_name,student_name:a}}}function Ot(t,s){return t.includes(s)?t.filter(a=>a!==s):[...t,s]}function mi({current:t}){return e.jsx("ol",{className:"m-0 flex flex-wrap items-center gap-x-3 gap-y-1 p-0 text-xs font-semibold uppercase tracking-widest",children:ps.map((s,a)=>{const i=En(s.id,t);return e.jsxs("li",{className:"flex items-center gap-3",children:[a>0?e.jsx("span",{"aria-hidden":"true",className:"h-px w-6 bg-stone-200"}):null,e.jsxs("span",{"aria-current":i==="current"?"step":void 0,className:`flex items-center gap-1.5 ${i==="current"?"text-indigo-700":i==="complete"?"text-stone-600":"text-stone-400"}`,children:[i==="complete"?e.jsx(Ea,{"aria-hidden":"true",className:"h-3.5 w-3.5"}):null,i==="current"?e.jsx("span",{"aria-hidden":"true",className:"h-1.5 w-1.5 rounded-full bg-indigo-600"}):null,s.label]})]},s.id)})})}function ui({search:t}
21){var _t,yt;const[s,a]=o.useState("audience"),[i,l]=o.useState("families"),[r,c]=o.useState(""),[x,m]=o.useState(""),[g,w]=o.useState([]),[u,j]=o.useState(""),[v,h]=o.useState(""),[d,_]=o.useState([]),[S,T]=o.useState("template"),[E,A]=o.useState(null),[I,f]=o.useState(""),[C,B]=o.useState(""),[P,K]=o.useState(""),[R,N]=o.useState({}),[oe,le]=o.useState(""),[Y,W]=o.useState(!1),[M,de]=o.useState("current"),{data:D}=Ve(),{data:Q}=is(),{data:V}=Os(),{data:xe}=qs(),{data:ce}=Fs(),{data:fe}=oi(),{data:be}=Ca(),{data:je}=us(),{data:b}=Sa({enabled:i==="families"}),{data:p}=ka(),k=ii(),q=wa(),O=o.useMemo(()=>new Map((je??[]).map(n=>[n.email,n.scope])),[je]),z=i==="families"&&M==="past"?"promotional":"transactional",Z=o.useMemo(()=>(xe??[]).filter(n=>!Us(n)),[xe]),ee=o.useMemo(()=>(xe??[]).filter(n=>n.status!=="cancelled"),[xe]),_e=o.useMemo(()=>An(ee),[ee]),ze=o.useMemo(()=>r?it(ee,r):[],[ee,r]),H=o.useMemo(()=>x!==qe?ee.find(n=>n.id===x)??null:null,[ee,x]),ke=o.useMemo(()=>r&&x?Dt({students:Q??[],enrollments:fe??[],groups:ee,history:be??[],schoolKey:r,groupId:x,scope:M,today:q}):[],[Q,fe,be,ee,r,x,M,q]),Ce=o.useMemo(()=>M==="pending"&&r&&x?Lt({submissions:b??[],schoolKey:r,groupId:x}):[],[M,b,r,x]),me=o.useMemo(()=>M==="pending"?Ce.map(n=>({student:{id:n.submission.id,first_name:n.submission.student_first_name,last_name:n.submission.student_last_name,parent_email:n.submission.parent_email,parent_name:n.submission.parent_name},groupId:n.submission.group_id,groupName:n.groupName,enrollment:"pending"})):ke,[M,Ce,ke]),ye=o.useMemo(()=>me.filter(n=>{var $;return!!n.student.parent_email&&!we(O.get((($=n.student.parent_email)==null?void 0:$.trim().toLowerCase())??""),z)}),[me,O,z]),Fe=o.useMemo(()=>me.filter(n=>{var $;return!!n.student.parent_email&&we(O.get((($=n.student.parent_email)==null?void 0:$.trim().toLowerCase())??""),z)}).length,[me,O,z]),y=o.useMemo(()=>u?it(Z,u):Z,[Z,u]),F=o.useMemo(()=>Bn({edges:(ce??[]).map(n=>({teacher_user_id:n.teacher_user_id,group_id:n.group_id,active:n.active,archived:n.archived})),groups:Z,schoolKey:u||null,groupId:v||null}),[ce,Z,u,v]),te=o.useMemo(()=>(V??[]).filter(n=>n.active!==!1&&n.email).filter(n=>F?F.has(n.id):!0),[V,F]),Ue=o.useMemo(()=>i==="teachers"?te.filter(n=>d.includes(n.id)).map(di):M==="pending"?Ce.filter(n=>{var $;return g.includes(n.submission.id)&&!!n.submission.parent_email&&!we(O.get((($=n.submission.parent_email)==null?void 0:$.trim().toLowerCase())??""),z)}).map(n=>ci(n)).filter(n=>n!==null):ke.filter(n=>{var $;return g.includes(n.student.id)&&!!n.student.parent_email&&!we(O.get((($=n.student.parent_email)==null?void 0:$.trim().toLowerCase())??""),z)}).map(n=>li(n.student)).filter(n=>n!==null),[i,te,d,M,Ce,ke,g,O,z]),De=o.useMemo(()=>i==="families"?ye.filter(n=>g.includes(n.student.id)).length:0,[i,ye,g]),Te=o.useMemo(()=>(D??[]).filter(n=>n.is_active),[D]),L=o.useMemo(()=>Te.find(n=>n.key===I)??null,[Te,I]),ct=o.useMemo(()=>L?va(`${L.subject} 22${L.body_html}
22`):[],[L]),Le=o.useMemo(()=>In({audienceKind:i,enrollmentScope:M,messageMode:S,templatePurpose:S==="template"?(L==null?void 0:L.purpose)??null:null,chosenPurpose:E}),[i,M,S,L,E]),Ne=Le.purpose,Pe=o.useMemo(()=>Dn(Ue,O,Ne??z),[Ue,O,Ne,z]),mt=o.useMemo(()=>ea(Pe.allowed,{mergeStudentNames:!0}),[Pe.allowed]),G=mt.recipients,ut=o.useMemo(()=>{const n=i==="families"?H:Z.find($=>$.id===v)??null;return n?{name:n.name,school_name:n.school_name,program_name:n.program_name,day_of_week:n.day_of_week,start_time:n.start_time,end_time:n.end_time,start_date:n.start_date,max_capacity:n.max_capacity,parent_payment_url:n.parent_payment_url}:null},[i,H,Z,v]),pt=o.useMemo(()=>{var ae;const n=i==="families"?H:Z.find(Ee=>Ee.id===v)??null;if(!n)return null;const $=((ae=Ta(ce??[],n.id))==null?void 0:ae.teacher_user_id)??n.teacher_user_id;if(!$)return null;const U=(V??[]).find(Ee=>Ee.user_id===$||Ee.id===$);return U?{first_name:U.first_name,last_name:U.last_name,name:U.name,email:U.email,phone:U.phone}:null},[i,H,Z,v,ce,V]),ht=o.useMemo(()=>ei(p,(H==null?void 0:H.id)??null,(H==null?void 0:H.school_id)??null),[p,H]),He=o.useMemo(()=>{var U;const n=(H==null?void 0:H.school_name)??((U=_e.find(ae=>ae.id===r))==null?void 0:U.name)??null,$=typeof window>"u"?"https://app.music4humans.com":window.location.origin;return Zn({group:ut,schoolName:n,today:q,origin:$,teacher:pt,waiver:ht})},[ut,pt,ht,r,_e,H,q]),ue=o.useMemo(()=>ti(ct,He),[ct,He]),Je=o.useMemo(()=>S==="template"?si(ue.manual,R):[],[S,ue.manual,R]),Ke=o.useMemo(()=>({...He,...R}),[He,R]),se=o.useMemo(()=>G.find(n=>n.id===oe)??G[0]??null,[oe,G]),Ge=o.useMemo(()=>ta(Ke,se),[Ke,se]),Ss=o.useMemo(()=>S==="template"?L?ie(L.subject,Ge):"":ie(C,(se==null?void 0:se.mergeData)??{}),[S,L,Ge,C,se]),ks=o.useMemo(()=>S==="template"?L?ie(L.body_html,Ge,{html:!0}):"":ie(fs(P),(se==null?void 0:se.mergeData)??{},{html:!0}),[S,L,Ge,P,se]),Cs=o.useMemo(()=>S==="template"?{kind:"template",templateKey:(L==null?void 0:L.key)??"",commonValues:Ke,purpose:Le.forcedPromotional?"promotional":L!=null&&L.purpose?null:Ne}:{kind:"blank",subject:C,bodyText:P,purpose:Ne??"promotional"},[S,L,Ke,C,P,Le,Ne]),We=Ne?Je.length>0?`Fill in ${Je.map(n=>Ze(n)).join(", ")} before sending.`:sa({mode:S,templateKey:(L==null?void 0:L.key)??null,subject:C,bodyText:P,recipientCount:G.length,batchConfirmed:Y,isPending:k.sending||k.isPending}):"Choose what kind of message this is.";o.useEffect(()=>{N(n=>{const $={};for(const U of ue.manual)$[U]=n[U]??"";return $})},[ue.manual]),o.useEffect(()=>{var n;G.some($=>$.id===oe)||le(((n=G[0])==null?void 0:n.id)??"")},[oe,G]),o.useEffect(()=>{W(!1),k.reset()},[i,x,M,g,d,I,S,C,P]),o.useEffect(()=>{var n;I&&Te.some($=>$.key===I)||f(((n=Te[0])==null?void 0:n.key)??"")},[Te,I]);function xt(n,$){return!r||!n?[]:$==="pending"?Lt({submissions:b??[],schoolKey:r,groupId:n}).filter(U=>{var ae;return!!U.submission.parent_email&&!we(O.get(((ae=U.submission.parent_email)==null?void 0:ae.trim().toLowerCase())??""),"transactional")}).map(U=>U.submission.id):Dt({students:Q??[],enrollments:fe??[],groups:ee,history:be??[],schoolKey:r,groupId:n,scope:$,today:q}).filter(U=>{var ae;return!!U.student.parent_email&&!we(O.get(((ae=U.student.parent_email)==null?void 0:ae.trim().toLowerCase())??""),$==="past"?"promotional":"transactional")}).map(U=>U.student.id)}function Ts(n){c(n),m(""),w([])}function Es(n){m(n),w(xt(n,M))}function $s(n){de(n),w(xt(x,n))}async function Ps(){We||(await k.send({recipients:G,message:Cs}),W(!1))}const ft=Ln(De,G.length,Fe),As=M==="past"?"Past students":M==="pending"?"Pending signups":M==="all"?"Current & past students":"Current students",Rs=qn({kind:i,studentCount:De,teacherCount:G.length,groupName:i==="families"?(H==null?void 0:H.name)??null:((_t=Z.find(n=>n.id===v))==null?void 0:_t.name)??null}),bt=ye.length>0&&ye.every(n=>g.includes(n.student.id)),gt=te.length>0&&te.every(n=>d.includes(n.id));return e.jsxs("section",{"aria-label":"Compose email",className:"mx-auto max-w-5xl space-y-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"m-0 text-xl font-semibold tracking-tight text-stone-950",children:"Compose Email"}),e.jsx("p",{className:"m-0 mt-1 text-sm text-stone-600",children:"Create and send a one-time message."}),e.jsx("div",{className:"mt-4",children:e.jsx(mi,{current:s})})]}),s==="audience"?e.jsxs("div",{className:"space-y-5",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"m-0 text-base font-semibold text-stone-950",children:"Audience"}),e.jsx("p",{className:"m-0 mt-0.5 text-sm text-stone-600",children:"Choose who should receive this message."})]}),e.jsx("div",{className:"flex flex-wrap gap-2",role:"group","aria-label":"Audience type",children:[{value:"families",label:"Families"},{value:"teachers",label:"Teachers"}].map(n=>e.jsx("button",{"aria-pressed":i===n.value,className:i===n.value?Be:Oe,onClick:()=>l(n.value),type:"button",children:n.label},n.value))}),i==="families"?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsxs("label",{className:ne,children:["School",e.jsxs("select",{className:`${pe} mt-1`,onChange:n=>Ts(n.target.value),value:r,children:[e.jsx("option",{value:"",children:"Select a school"}),_e.map(n=>e.jsx("option",{value:n.id,children:n.name},n.id))]})]}),e.jsxs("label",{className:ne,children:["Group",e.jsxs("select",{className:`${pe} mt-1`,disabled:!r,onChange:n=>Es(n.target.value),value:x,children:[e.jsx("option",{value:"",children:r?"Select a group":"Choose a school first"}),r?e.jsx("option",{value:qe,children:"All groups at this school"}):null,ze.map(n=>e.jsxs("option",{value:n.id,children:[n.name,hs(n,q)?"":" (ended)"]},n.id))]})]})]}),r?e.jsxs("div",{className:"flex flex-wrap items-center gap-2",role:"group","aria-label":"Enrollment scope",children:[[{value:"current",label:"Current students"},{value:"pending",label:"Pending"},{value:"past",label:"Past students"},{value:"all",label:"Everyone"}].map(n=>e.jsx("button",{"aria-pressed":M===n.value,className:M===n.value?Be:Oe,onClick:()=>$s(n.value),type:"button",children:n.label},n.value)),M==="pending"?e.jsx("span",{className:"text-xs text-stone-500",children:"Pending = signed up through the registration form, awaiting approval."}):M!=="current"?e.jsx("span",{className:"text-xs text-stone-500",children:"Past = a real prior enrollment here, not currently in a running group."}):null]}):null,x?e.jsxs("div",{className:"overflow-hidden rounded-xl border border-stone-200 bg-white",children:[e.jsxs("label",{className:"flex items-center gap-2.5 border-b border-stone-100 bg-stone-50/70 px-4 py-2.5 text-xs font-semibold uppercase tracking-wide text-stone-600",children:[e.jsx("input",{checked:bt,className:"h-4 w-4 roun
22ded border-stone-300 text-indigo-600 focus:ring-indigo-500",disabled:ye.length===0,onChange:()=>w(bt?[]:ye.map(n=>n.student.id)),type:"checkbox"}),"Select all students",e.jsxs("span",{className:"ml-auto font-medium normal-case tracking-normal text-stone-500",children:[me.length," student",me.length===1?"":"s"]})]}),me.length===0?e.jsx("p",{className:"m-0 px-4 py-6 text-center text-sm text-stone-500",children:M==="pending"?"No pending signups match this scope.":M==="past"?"No past students match this scope.":"No active students are enrolled in this scope."}):e.jsx("ul",{className:"m-0 max-h-80 list-none divide-y divide-stone-100 overflow-y-auto p-0",children:me.map(n=>{var vt;const $=n.student,U=((vt=$.parent_email)==null?void 0:vt.trim().toLowerCase())??"",ae=O.get(U),Ee=!!$.parent_email&&we(ae,z),Xe=!!$.parent_email&&!Ee;return e.jsx("li",{children:e.jsxs("label",{className:`flex items-start gap-2.5 px-4 py-2.5 text-sm ${Xe?"":"opacity-60"}`,children:[e.jsx("input",{checked:Xe&&g.includes($.id),className:"mt-0.5 h-4 w-4 rounded border-stone-300 text-indigo-600 focus:ring-indigo-500",disabled:!Xe,onChange:()=>w(Ms=>Ot(Ms,$.id)),type:"checkbox"}),e.jsxs("span",{className:"min-w-0 flex-1",children:[e.jsx("span",{className:"block font-medium text-stone-900",children:bs($)}),e.jsx("span",{className:"block truncate text-xs text-stone-500",children:$.parent_email?Ee?`Parent: ${$.parent_name.trim()||"â"} · ${ae==="all"?"Do not contact â excluded":"Opted out of promotional email â excluded"}`:`Parent: ${$.parent_name.trim()||"â"} · ${$.parent_email}`:"No parent email on file â cannot be emailed"}),e.jsx("span",{className:"mt-0.5 block truncate text-xs text-stone-400",children:n.groupName??(n.enrollment==="pending"?"No group chosen on the signup":"Previous group unavailable")})]}),e.jsx("span",{className:`mt-0.5 shrink-0 rounded-md border px-1.5 py-0.5 text-[11px] font-medium ${n.enrollment==="current"?"border-stone-200 bg-stone-100 text-stone-600":n.enrollment==="pending"?"border-sky-200 bg-sky-50 text-sky-800":"border-amber-200 bg-amber-50 text-amber-800"}`,children:n.enrollment==="current"?"Current":n.enrollment==="pending"?"Pending":"Past"})]})},$.id)})}),e.jsx("p",{className:"m-0 border-t border-stone-100 bg-stone-50/70 px-4 py-2 text-center text-xs font-medium text-stone-600",children:ft})]}):null]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsxs("label",{className:ne,children:["School ",e.jsx("span",{className:"font-normal text-stone-500",children:"(optional)"}),e.jsxs("select",{className:`${pe} mt-1`,onChange:n=>{j(n.target.value),h("")},value:u,children:[e.jsx("option",{value:"",children:"All schools"}),_e.map(n=>e.jsx("option",{value:n.id,children:n.name},n.id))]})]}),e.jsxs("label",{className:ne,children:["Group ",e.jsx("span",{className:"font-normal text-stone-500",children:"(optional)"}),e.jsxs("select",{className:`${pe} mt-1`,onChange:n=>h(n.target.value),value:v,children:[e.jsx("option",{value:"",children:"All groups"}),y.map(n=>e.jsx("option",{value:n.id,children:n.name},n.id))]})]})]}),e.jsxs("div",{className:"overflow-hidden rounded-xl border border-stone-200 bg-white",children:[e.jsxs("label",{className:"flex items-center gap-2.5 border-b border-stone-100 bg-stone-50/70 px-4 py-2.5 text-xs font-semibold uppercase tracking-wide text-stone-600",children:[e.jsx("input",{checked:gt,className:"h-4 w-4 rounded border-stone-300 text-indigo-600 focus:ring-indigo-500",disabled:te.length===0,onChange:()=>_(gt?[]:te.map(n=>n.id)),type:"checkbox"}),"Select all teachers",e.jsxs("span",{className:"ml-auto font-medium normal-case tracking-normal text-stone-500",children:[te.length," teacher",te.length===1?"":"s"]})]}),te.length===0?e.jsx("p",{className:"m-0 px-4 py-6 text-center text-sm text-stone-500",children:"No active teachers match this scope."}):e.jsx("ul",{className:"m-0 max-h-80 list-none divide-y divide-stone-100 overflow-y-auto p-0",children:te.map(n=>e.jsx("li",{children:e.jsxs("label",{className:"flex items-start gap-2.5 px-4 py-2.5 text-sm",children:[e.jsx("input",{checked:d.includes(n.id
22),className:"mt-0.5 h-4 w-4 rounded border-stone-300 text-indigo-600 focus:ring-indigo-500",onChange:()=>_($=>Ot($,n.id)),type:"checkbox"}),e.jsxs("span",{className:"min-w-0",children:[e.jsx("span",{className:"block font-medium text-stone-900",children:gs(n)}),e.jsx("span",{className:"block truncate text-xs text-stone-500",children:n.email})]})]})},n.id))}),e.jsxs("p",{className:"m-0 border-t border-stone-100 bg-stone-50/70 px-4 py-2 text-center text-xs font-medium text-stone-600",children:[G.length," teacher",G.length===1?"":"s"," selected",Pe.suppressedCount>0?` · ${Pe.suppressedCount} opted out excluded`:""]})]})]}),mt.duplicateCount>0?e.jsx("p",{className:"m-0 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm font-medium text-amber-800",children:"Siblings sharing a parent email are combined â the family receives one copy naming every selected child."}):null,e.jsx("div",{className:"flex justify-end",children:e.jsxs("button",{className:ge,disabled:!$n(G.length),onClick:()=>a("message"),type:"button",children:["Continue to Message",e.jsx(wt,{"aria-hidden":"true",className:"h-4 w-4"})]})})]}):null,s==="message"?e.jsxs("div",{className:"space-y-5",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"m-0 text-base font-semibold text-stone-950",children:"Message"}),e.jsx("p",{className:"m-0 mt-0.5 text-sm text-stone-600",children:"Write the message you want to send."}),e.jsxs("p",{className:"m-0 mt-2 flex items-center gap-1.5 text-xs font-medium text-stone-500",children:[e.jsx(Is,{"aria-hidden":"true",className:"h-3.5 w-3.5"}),Rs]})]}),e.jsx("div",{className:"flex flex-wrap gap-2",role:"group","aria-label":"Message source",children:[{value:"template",label:"Use a template"},{value:"blank",label:"Start from blank"}].map(n=>e.jsx("button",{"aria-pressed":S===n.value,className:S===n.value?Be:Oe,onClick:()=>T(n.value),type:"button",children:n.label},n.value))}),Le.forcedPromotional?e.jsx("p",{className:"m-0 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900",children:"This message goes to families without a current enrollment, so it counts as promotional â families who opted out of promotional email are excluded automatically."}):Le.needsChoice?e.jsxs("fieldset",{className:"m-0 rounded-xl border border-stone-200 bg-stone-50/70 p-4",children:[e.jsx("legend",{className:"px-1 text-sm font-medium text-stone-900",children:"What kind of message is this?"}),e.jsx("div",{className:"mt-2 space-y-2",children:[{value:"transactional",label:"Class or program information",description:"Important information related to classes, schedules, enrollment, or an existing program relationship."},{value:"promotional",label:"News, invitations or promotions",description:"Registration announcements, re-enrollment outreach, new programs, and optional marketing."}].map(n=>e.jsxs("label",{className:"flex items-start gap-2.5 text-sm",children:[e.jsx("input",{checked:E===n.value,className:"mt-1 h-4 w-4 border-stone-300 text-indigo-600 focus:ring-indigo-500",name:"compose-message-purpose",onChange:()=>A(n.value),type:"radio"}),e.jsxs("span",{className:"min-w-0",children:[e.jsx("span",{className:"block font-medium text-stone-900",children:n.label}),e.jsx("span",{className:"block text-xs leading-5 text-stone-500",children:n.description})]})]},n.value))})]}):null,S==="template"?e.jsxs("div",{className:"space-y-4",children:[e.jsxs("label",{className:ne,children:["Template",e.jsxs("select",{className:`${pe} mt-1`,onChange:n=>f(n.target.value),value:I,children:[Te.length===0?e.jsx("option",{value:"",children:"No active templates"}):null,Te.map(n=>e.jsx("option",{value:n.key,children:n.name},n.id))]})]}),ue.recipient.length>0||ue.context.length>0?e.jsxs("p",{className:"m-0 rounded-lg bg-stone-50 px-3 py-2 text-xs leading-5 text-stone-500",children:["Filled automatically:"," ",[...ue.context,...ue.recipient].map(n=>Ze(n)).join(", "),ue.recipient.length>0?" â recipient fields personalize per family, listing every selected child.":"."]}):null,ue.manual.length>0?e.jsxs("div",{className:"rounded-xl border border-stone-200 bg-stone-50/70 px-4 py-3",children:[e.jsx("p",{className:"m-0 text-sm font-medium text-stone-900",children:"This template needs from you"}),e.jsx("p",{className:"m-0 mt-0.5 text-xs text-stone-500",children:"These fields aren't known to the app â what you type here is exactly what sends."}),e.jsx("div",{className:"mt-3 grid gap-3 sm:grid-cols-2",children:ue.manual.map(n=>e.jsxs("label",{className:"text-xs font-medium text-stone-700",children:[e.jsx("span",{className:"block",children:Ze(n)}),e.jsx("input",{className:`${pe} mt-1`,onChange:$=>N(U=>({...U,[n]:$.target.value})),placeholder:"Required",value:R[n]??""})]},n))})]}):null]}):e.jsxs("div",{className:"space-y-4",children:[e.jsxs("label",{className:ne,children:["Subject",e.jsx("input",{className:`${pe} mt-1`,onChange:n=>B(n.target.value),placeholder:"Enter subject line...",value:C})]}),e.jsxs("label",{className:ne,children:["Message",e.jsx("textarea",{className:`${at} mt-1 min-h-64`,onChange:n=>K(n.target.value),placeholder:"Write your message here...",value:P}),e.jsxs("span",{className:"mt-1 block text-xs font-normal text-stone-500",children:["Blank lines start a new paragraph. Personalize with"," ",i==="families"?"variables like {{parent_name}}, {{student_name}}, and {{group_name}}":"variables like {{teacher_name}}","â they fill in per recipient. The branded Music 4 Humans wrapper is added automatically."]})]})]}),e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("button",{className:Se,onClick:()=>a("audience"),type:"button",children:[e.jsx(St,{"aria-hidden":"true",className:"h-4 w-4"}),"Audience"]}),e.jsxs("button",{className:ge,disabled:!Pn({mode:S,templateKey:(L==null?void 0:L.key)??null,subject:C,bodyText:P})||Je.length>0||!Ne,onClick:()=>a("review"),type:"button",children:["Continue to Review",e.jsx(wt,{"aria-hidden":"true",className:"h-4 w-4"})]})]})]}
22):null,s==="review"?e.jsxs("div",{className:"space-y-5",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"m-0 text-base font-semibold text-stone-950",children:"Review & Send"}),e.jsx("p",{className:"m-0 mt-0.5 text-sm text-stone-600",children:"Check everything before sending."})]}),e.jsxs("div",{className:"divide-y divide-stone-100 overflow-hidden rounded-xl border border-stone-200 bg-white",children:[e.jsxs("div",{className:"flex items-center gap-4 px-4 py-3",children:[e.jsx("span",{className:"w-20 shrink-0 text-[11px] font-semibold uppercase tracking-widest text-stone-400",children:"Audience"}),e.jsx("span",{className:"min-w-0 flex-1 truncate text-sm text-stone-900",children:i==="families"?`${ft} · ${As} · ${H?`${H.name} · ${H.school_name}`:`All groups · ${((yt=_e.find(n=>n.id===r))==null?void 0:yt.name)??""}`}`:`${G.length} teacher${G.length===1?"":"s"} selected${Pe.suppressedCount>0?` · ${Pe.suppressedCount} opted out excluded`:""}`}),e.jsx("button",{className:Ae,onClick:()=>a("audience"),type:"button",children:"Edit"})]}),e.jsxs("div",{className:"flex items-center gap-4 px-4 py-3",children:[e.jsx("span",{className:"w-20 shrink-0 text-[11px] font-semibold uppercase tracking-widest text-stone-400",children:"Message"}),e.jsxs("span",{className:"min-w-0 flex-1 truncate text-sm text-stone-900",children:[S==="template"?`Template: ${(L==null?void 0:L.name)??"â"}`:`Subject: ${C||"â"}`,Ne==="promotional"?" · News & promotions (opted-out families excluded)":" · Class & program information"]}),e.jsx("button",{className:Ae,onClick:()=>a("message"),type:"button",children:"Edit"})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"mb-2 flex flex-wrap items-center justify-between gap-2",children:[e.jsx("p",{className:"m-0 text-[11px] font-semibold uppercase tracking-widest text-stone-400",children:"Email preview"}),G.length>1?e.jsxs("label",{className:"text-xs font-medium text-stone-600",children:["Preview recipient"," ",e.jsx("select",{className:"ml-1 rounded-md border border-stone-200 bg-white px-2 py-1 text-xs",onChange:n=>le(n.target.value),value:(se==null?void 0:se.id)??"",children:G.map(n=>e.jsx("option",{value:n.id,children:n.studentName?`${n.name} · ${n.studentName}`:`${n.name} · ${n.email}`},n.id))})]}):null]}),e.jsxs("div",{className:"mx-auto w-full max-w-2xl overflow-hidden rounded-xl border border-stone-200 bg-white",children:[e.jsx("p",{className:"m-0 border-b border-stone-100 bg-stone-50/70 px-4 py-2.5 text-sm font-medium text-stone-900",children:Ss||"No subject"}),e.jsx("iframe",{className:"h-[30rem] w-full border-0 bg-white",sandbox:"",srcDoc:zt(ks),title:"Composed email preview"})]})]}),G.length>1?e.jsxs("label",{className:"flex items-start gap-2 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm font-medium text-amber-900",children:[e.jsx("input",{checked:Y,className:"mt-1 h-4 w-4 rounded border-amber-300 text-amber-600 focus:ring-amber-500",onChange:n=>W(n.target.checked),type:"checkbox"}),"I confirm sending this email to ",G.length," ",i==="families"?"families":"teachers","."]}):null,k.progress?e.jsxs("p",{className:"m-0 text-sm text-stone-600",children:["Sending ",k.progress.current," of ",k.progress.total,"..."]}):We&&!k.summary?e.jsx("p",{className:"m-0 text-sm text-stone-500",children:We}):null,k.summary?e.jsxs("div",{className:`rounded-lg border px-3 py-2 text-sm ${k.summary.failed>0?"border-rose-200 bg-rose-50 text-rose-700":k.summary.skipped>0?"border-amber-200 bg-amber-50 text-amber-800":"border-emerald-200 bg-emerald-50 text-emerald-700"}`,children:[e.jsxs("div",{className:"flex items-center gap-2 font-semibold",children:[e.jsx(Ye,{"aria-hidden":"true",className:"h-4 w-4"}),k.summary.attempted," attempted · ",k.summary.sent," sent · ",k.summary.skipped," skipped · ",k.summary.failed," failed"]}),k.summary.errors.length>0?e.jsx("ul",{className:"m-0 mt-2 list-disc pl-5 text-xs",children:k.summary.errors.slice(0,3).map(n=>e.jsx("li",{children:n},n))}):null]}):null,e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("button",{className:Se,onClick:()=>a("message"),type:"button",children:[e.jsx(St,{"aria-hidden":"true",className:"h-4 w-4"}),"Message"]}),e.jsxs("button",{className:ge,disabled:k.sending||!!We,onClick:()=>void Ps(),type:"button",children:[e.jsx(Re,{"aria-hidden":"true",className:"h-4 w-4"}),k.sending?"Sending...":Fn(i,G.length)]})]})]}):null]})}const _s="templates";function pi(t){return t==="templates"||t==="compose"||t==="sent"||t==="outbox"||t==="test_send"||t==="automations"||t==="do_not_email"?t:null}function hi(t){return pi(t)??_s}function xi(t,s){if(t!=="outbox")return null;const a=s==null?void 0:s.trim();return a||null}function fi(t,s){const a=new URLSearchParams(t);return s===_s?a.delete("tab"):a.set("tab",s),s!=="outbox"&&a.delete("lessonSessionId"),a}const bi="Test email rendering. Select a session, student, and preview the rendered email. Test sends go only to the test recipient email you enter. No real parent emails are involved.";function gi(t){var l,r;const s=_i(t.classDate),a=((l=t.groupName)==null?void 0:l.trim())||"Group",i=((r=t.lessonTitle)==null?void 0:r.trim())||"Lesson";return`${a} · ${s} · ${i}`}function _i(t){const[s,a,i]=t.split("-").map(Number);return!s||!a||!i?t:new Date(s,a-1,i).toLocaleDateString(void 0,{month:"short",day:"numeric",year:"numeric"})}function ys(t){return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t.trim())}function yi(t,s){return t.map(a=>{var x;const i=s.get(a.student_id),l=[a.first_name,a.last_name].filter(
22Boolean).join(" ").trim()||`Student ${a.student_id.slice(0,8)}`,r=((x=i==null?void 0:i.parent_email)==null?void 0:x.trim())||null,c=r?"":" (no parent email on file)";return{studentId:a.student_id,label:`${l}${c}`,parentEmail:r}})}function vi(t){if(t.template.key!==Yt||!t.template.is_active)return null;const a=new Map(Pa(t.badgeOutcomes).map(r=>[r.studentId,r])).get(t.student.studentId)??{practiced:[],awarded:[]},i=t.session.teacherName.trim().split(/\s+/)[0]??"",l={...ia(t.session,t.blockRows),...na(t.student,a,t.blockRows,{classSummary:t.session.classSummary,teacherFirstName:i,otherStudentFirstNames:[]})};return{templateKey:t.template.key,mergeData:l,subject:ie(t.template.subject,l),bodyHtml:ie(t.template.body_html,l,{html:!0})}}function ji({sessionId:t,studentId:s,testRecipient:a,preview:i,sendConfirmed:l,isPending:r}){return r?"Sending is already in progress.":t?s?ys(a)?i?l?null:"Confirm this test send before continuing.":"Generate a preview before sending.":"Enter a valid test recipient email.":"Select a student to preview.":"Select a submitted lesson report session."}function Ni(t){return{to:t.testRecipient.trim(),templateKey:t.templateKey,mergeData:t.mergeData,recipientType:"admin",recipientId:null,relatedEntityType:"lesson_session",relatedEntityId:t.lessonSessionId}}function vs(t,s){const a=t.trim().toLowerCase();if(!a)return!1;const i=(s==null?void 0:s.trim().toLowerCase())??"";return!i||a!==i}function js(t){return t&&aa(t)==="stored"?t:null}function wi(t){return{subject:t.subject_rendered??"",bodyHtml:t.body_html_rendered??""}}function Si(t,s){let a=null;for(const i of t)s&&!s.has(i.lesson_session_id)||js(i)&&(!a||(i.generated_at??"")>(a.generated_at??""))&&(a=i);return a}function ki(t){const s=wi(t.draft);return{to:t.testRecipient.trim(),subject:s.subject,html:s.bodyHtml,recipient_type:"admin",related_entity_type:"lesson_session",related_entity_id:t.lessonSessionId}}function Ci({sessionId:t,studentId:s,storedDraft:a,testRecipient:i,sendConfirmed:l,isPending:r}){return r?"Sending is already in progress.":t?s?a?ys(i)?vs(i,a.recipient_email)?l?null:"Confirm this test send before continuing.":"Test sends must not use the real parent email. Enter a different test recipient.":"Enter a valid test recipient email.":"No reviewed parent email draft is available for this student.":"Select a student to preview.":"Select a submitted lesson report session."}function Ti(t){const[s,a,i]=t.split("-").map(Number);return!s||!a||!i?t:new Date(s,a-1,i).toLocaleDateString(void 0,{weekday:"long",month:"long",day:"numeric",year:"numeric"})}function Ei(){var me,ye,Fe;const{user:t}=Gs(),{data:s,isLoading:a,error:i}=Aa(),{data:l}=Ve(),{data:r}=is(),{data:c}=Hs(),x=Da(),m=Qt(),g=ca(),[w,u]=o.useState("parent"),[j,v]=o.useState(""),[h,d]=o.useState(""),[_,S]=o.useState(""),[T,E]=o.useState(null),[A,I]=o.useState(!1),[f,C]=o.useState(null),[B,P]=o.useState(null),K=Ra(j||void 0),R=((me=K.data)==null?void 0:me.session)??null,N=((ye=K.data)==null?void 0:ye.blocks)??[],oe=((Fe=K.data)==null?void 0:Fe.badgeOutcomes)??[],le=ra(j||void 0),Y=o.useMemo(()=>{const y=new Map;for(const F of le.data??[])y.has(F.student_id)||y.set(F.student_id,F);return y},[le.data]),W=h?js(Y.get(h)??null):null,M=oa(),de=o.useMemo(()=>new Set((s??[]).map(y=>y.sessionId)),[s]),D=o.useMemo(()=>Si(M.data??[],de),[M.data,de]),Q=$a((R==null?void 0:R.group_id)??null,(R==null?void 0:R.class_date)??null,(R==null?void 0:R.attendance_session_id)??null,!!R),V=o.useMemo(()=>(l??[]).find(y=>y.key===Yt&&y.is_active)??null,[l]),xe=o.useMemo(()=>new Map((x.data??[]).map(y=>[y.id,y.name])),[x.data]),ce=o.useMemo(()=>new Map((r??[]).map(y=>[y.id,y])),[r]),fe=o.useMemo(()=>yi(Q.data??[],ce),[Q.data,ce]),be=o.useMemo(()=>fe.find(y=>y.studentId===h)??null,[fe,h]),je=o.useMemo(()=>new Map((c??[]).map(y=>[y.id,y])),[c]);o.useEffect(()=>{var F;if(_.trim())return;const y=(F=t==null?void 0:t.email)==null?void 0:F.trim();y&&S(y)},[_,t==null?void 0:t.email]);const b=o.useRef(!1),p=o.useRef(null);o.useEffect(()=>{b.current||w==="parent"&&(j||!M.data||a||(b.current=!0,D&&(p.current=D.student_id,v(D.lesson_session_id))))},[M.data,a,D,j,w]),o.useEffect(()=>{E(null),I(!1),C(null),P(null),m.reset(),g.reset()},[w,j,h,_]),o.useEffect(()=>{const y=p.current;y?(p.current=null,d(y)):d("")},[j]);const k=i instanceof Error?i.message:null,q=K.error instanceof Error?K.error.message:null,O=Ci({sessionId:j||null,studentId:h||null,storedDraft:W,testRecipient:_,sendConfirmed:A,isPending:g.isPending});async function z(){if(!(!R||!W||O)){P(null),C(null);try{const y=await g.mutateAsync(ki({testRecipient:_,lessonSessionId:R.id,draft:W}));C(y.skipped?`Logged as skipped (${y.skipped}). No delivery without a configured provider.`:`Test copy of the reviewed draft sent to ${_.trim()}.`),I(!1)}catch(y){P(y instanceof Error?y.message:"Test send failed.")}}}function Z(){if(!h)return null;const y=(Q.data??[]).find(te=>te.student_id===h),F=ce.get(h);return y?{studentId:h,firstName:y.first_name??(F==null?void 0:F.first_name)??null,lastName:y.last_name??(F==null?void 0:F.last_name)??null,parentName:(F==null?void 0:F.parent_name)??null,parentEmail:(F==null?void 0:F.parent_email)??null}:null}function ee(){if(P(null),C(null),m.reset(),!R||!V){P("Select a session and ensure the parent lesson report template is active.");return}const y=Z();if(!y){P("Select a student to preview.");return}const F=Ma(R.lesson_snapshot),te=F.groupName??xe.get(R.group_id)??"class",Ue=kt(je,R.submitted_by_user_id)??kt(je,R.lead_teacher_user_id
22)??"Your Music 4 Humans team",De=vi({session:{sessionId:R.id,classDateLabel:Ti(R.class_date),classDateIso:R.class_date,groupName:te,lessonTitle:F.lessonTitle,classSummary:R.class_summary??"",teacherName:Ue},blockRows:Ia(N),badgeOutcomes:oe,student:y,template:V});if(!De){P("The parent lesson report template is not available.");return}E(De)}const _e=ji({sessionId:j||null,studentId:h||null,testRecipient:_,preview:T,sendConfirmed:A,isPending:m.isPending});async function ze(){if(!(!R||!T||_e)){if(!vs(_,be==null?void 0:be.parentEmail)){P("Test sends must not use the real parent email. Enter a different test recipient.");return}P(null),C(null);try{const y=await m.mutateAsync(Ni({testRecipient:_,lessonSessionId:R.id,templateKey:T.templateKey,mergeData:T.mergeData}));C(y.skipped?`Logged as skipped (${y.skipped}). No delivery without a configured provider.`:`Template test email sent to ${_.trim()}.`),I(!1)}catch(y){P(y instanceof Error?y.message:"Test send failed.")}}}const H="rounded-lg px-3 py-1.5 text-sm font-semibold transition",ke="bg-indigo-600 text-white shadow-sm",Ce="bg-white text-stone-600 hover:bg-stone-50 border border-stone-200";return e.jsxs("section",{className:"space-y-4","aria-label":"Parent email test send",children:[e.jsx("p",{className:"m-0 rounded-lg border border-amber-200 bg-amber-50 px-4 py-3 text-sm font-medium text-amber-900",children:bi}),e.jsxs("div",{className:"flex flex-wrap gap-2",role:"group","aria-label":"Test send mode",children:[e.jsx("button",{className:`${H} ${w==="parent"?ke:Ce}`,"data-testid":"test-send-mode-parent",onClick:()=>u("parent"),type:"button",children:"Parent email (reviewed draft)"}),e.jsx("button",{className:`${H} ${w==="template"?ke:Ce}`,"data-testid":"test-send-mode-template",onClick:()=>u("template"),type:"button",children:"Template test"})]}),e.jsx("p",{className:`m-0 ${et}`,children:w==="parent"?"Sends a safe copy of the actual reviewed draft body parents would receive for this class.":"Checks the parent_lesson_report template rendering and deliverability â not the AI reviewed body."}),e.jsxs("div",{className:"rounded-xl border border-stone-200 bg-white p-5 shadow-sm",children:[e.jsxs("div",{className:"grid gap-4 lg:grid-cols-2",children:[e.jsxs("label",{className:ne,children:["Session",e.jsxs(Ct,{className:"mt-1",onChange:y=>v(y.target.value),value:j,children:[e.jsx("option",{value:"",children:"Select a submitted lesson report"}),(s??[]).map(y=>e.jsx("option",{value:y.sessionId,children:gi(y)},y.sessionId))]})]}),e.jsxs("label",{className:ne,children:["Student",e.jsxs(Ct,{className:"mt-1",disabled:!j||Q.isLoading,onChange:y=>d(y.target.value),value:h,children:[e.jsx("option",{value:"",children:j?"Select a student":"Choose a session first"}),fe.map(y=>e.jsx("option",{value:y.studentId,children:y.label},y.studentId))]})]}),e.jsxs("label",{className:`${ne} lg:col-span-2`,children:["Test recipient email",e.jsx("input",{className:`${pe} mt-1`,onChange:y=>S(y.target.value),placeholder:"[email protected]",type:"email",value:_}),e.jsx("span",{className:`${et} mt-1 block`,children:"Defaults to your admin email. Test sends never use the student's parent email."})]})]}),a?e.jsx("p",{className:"m-0 mt-4 text-sm text-stone-500",children:"Loading submitted lesson reports..."}):null,k?e.jsx("p",{className:"m-0 mt-4 text-sm font-medium text-rose-700",children:k}):null,q?e.jsx("p",{className:"m-0 mt-4 text-sm font-medium text-rose-700",children:q}):null,B?e.jsx("p",{className:"m-0 mt-4 text-sm font-medium text-rose-700",children:B}):null,w==="template"?e.jsx("div",{className:"mt-4 flex flex-wrap gap-2",children:e.jsxs("button",{className:Ae,disabled:!j||!h||!V,onClick:ee,type:"button",children:[e.jsx(La,{"aria-hidden":"true",className:"h-4 w-4"}),"Generate template preview"]})}):null]}),w==="parent"?M.isLoading&&!j?e.jsx("p",{className:"m-0 rounded-lg border border-stone-200 bg-stone-50 px-3 py-3 text-sm text-stone-600",children:"Finding the most recent reviewed draftâ¦"}):!j||!h?D?null:e.jsxs("p",{className:"m-0 rounded-lg border border-amber-200 bg-amber-50 px-3 py-3 text-sm font-medium text-amber-800","data-testid":"parent-test-no-draft-global",children:["No reviewed parent email drafts are available yet. A draft appears here once a lesson report is submitted and AI generation succeeds. Use ",e.jsx("strong",{children:"Template test"})," to check template rendering and deliverability in the meantime."]}):le.isLoading?e.jsx("p",{className:"m-0 rounded-lg border border-stone-200 bg-stone-50 px-3 py-3 text-sm text-stone-600",children:"Loading the reviewed draft for this studentâ¦"}):W?e.jsxs("div",{className:"rounded-xl border border-stone-200 bg-white p-5 shadow-sm",children:[e.jsx("h2",{className:"m-0 text-base font-semibold text-stone-950",children:"Reviewed draft preview"}),e.jsx("p",{className:"m-0 mt-1 rounded-lg border border-indigo-200 bg-indigo-50 px-3 py-2 text-sm font-medium text-indigo-900","data-testid":"parent-test-provenance",children:la(W)==="AI-generated"?"AI-generated reviewed draft â this is the exact body parents would receive, and the exact body test-sent below.":"Reviewed draft â this is the exact body parents would receive, and the exact body test-sent below."}),e.jsxs("div",{className:"mt-4 space-y-4",children:[e.jsxs("div",{children:[e.jsx("p",{className:"m-0 text-xs font-semibold uppercase tracking-wide text-stone-500",children:"Subject"}),e.jsx("p",{className:"m-0 mt-1 rounded-lg bg-stone-50 px-3 py-2 text-sm font-medium text-stone-900","data-testid":"parent-test-subject",children:W.subject_rendered||"No subject"})]}),e.jsxs("div",{children:[e.jsx("p",{className:"m-0 text-xs font-semibold uppercase tracking-wide text-stone-500",children:"Body"}),e.jsx("iframe",{className:"mt-2 h-96 w-full rounded-lg border border-stone-200 bg-white",sandbox:"",srcDoc:W.body_html_rendered??"",title:"Reviewed parent draft preview"})]})]}),e.jsxs("label",{className:"mt-4 flex items-start gap-2 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm font-medium text-amber-900",children:[e.jsx("input",{checked:A,className:"mt-1 h-4 w-4 roun
22ded border-amber-300 text-amber-600 focus:ring-amber-500",onChange:y=>I(y.target.checked),type:"checkbox"}),"I confirm sending this reviewed draft only to ",_.trim()||"the test recipient","."]}),e.jsxs("div",{className:"mt-4 flex flex-wrap items-center justify-between gap-3",children:[e.jsx("span",{className:"min-w-0 text-sm text-stone-600",children:O??`Ready to send test copy to ${_.trim()}.`}),e.jsxs("button",{className:ge,"data-testid":"parent-test-send",disabled:!!O,onClick:()=>void z(),type:"button",children:[e.jsx(Re,{"aria-hidden":"true",className:"h-4 w-4"}),g.isPending?"Sending...":"Send test copy"]})]}),f?e.jsx("div",{className:"mt-4 rounded-lg border border-emerald-200 bg-emerald-50 px-3 py-2 text-sm font-medium text-emerald-700",children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Ye,{"aria-hidden":"true",className:"h-4 w-4"}),f]})}):null]}):e.jsxs("p",{className:"m-0 rounded-lg border border-amber-200 bg-amber-50 px-3 py-3 text-sm font-medium text-amber-800","data-testid":"parent-test-no-draft",children:["No reviewed parent email draft with a rendered body is available for this student yet. It appears once the lesson report is submitted and AI generation succeeds. Use ",e.jsx("strong",{children:"Template test"})," to check the template rendering and deliverability instead."]}):null,w==="template"&&T?e.jsxs("div",{className:"rounded-xl border border-stone-200 bg-white p-5 shadow-sm",children:[e.jsx("h2",{className:"m-0 text-base font-semibold text-stone-950",children:"Template preview"}),e.jsxs("p",{className:`m-0 mt-1 ${et}`,children:["Template test â rendered with the ",e.jsx("code",{children:"parent_lesson_report"})," template and merge data. This checks template rendering/deliverability, not the AI reviewed body parents receive."]}),e.jsxs("div",{className:"mt-4 space-y-4",children:[e.jsxs("div",{children:[e.jsx("p",{className:"m-0 text-xs font-semibold uppercase tracking-wide text-stone-500",children:"Subject"}),e.jsx("p",{className:"m-0 mt-1 rounded-lg bg-stone-50 px-3 py-2 text-sm font-medium text-stone-900",children:T.subject||"No subject"})]}),e.jsxs("div",{children:[e.jsx("p",{className:"m-0 text-xs font-semibold uppercase tracking-wide text-stone-500",children:"Body"}),e.jsx("iframe",{className:"mt-2 h-96 w-full rounded-lg border border-stone-200 bg-white",sandbox:"",srcDoc:T.bodyHtml,title:"Parent template test preview"})]})]}),e.jsxs("label",{className:"mt-4 flex items-start gap-2 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm font-medium text-amber-900",children:[e.jsx("input",{checked:A,className:"mt-1 h-4 w-4 rounded border-amber-300 text-amber-600 focus:ring-amber-500",onChange:y=>I(y.target.checked),type:"checkbox"}),"I confirm sending this template test only to ",_.trim()||"the test recipient","."]}),e.jsxs("div",{className:"mt-4 flex flex-wrap items-center justify-between gap-3",children:[e.jsx("span",{className:"min-w-0 text-sm text-stone-600",children:_e??`Ready to send template test to ${_.trim()}.`}),e.jsxs("button",{className:ge,"data-testid":"template-test-send",disabled:!!_e,onClick:()=>void ze(),type:"button",children:[e.jsx(Re,{"aria-hidden":"true",className:"h-4 w-4"}),m.isPending?"Sending...":"Send template test"]})]}),f?e.jsx("div",{className:"mt-4 rounded-lg border border-emerald-200 bg-emerald-50 px-3 py-2 text-sm font-medium text-emerald-700",children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Ye,{"aria-hidden":"true",className:"h-4 w-4"}),f]})}):null]}):null,w==="template"&&!V?e.jsxs("p",{className:"m-0 rounded-lg border border-amber-200 bg-amber-50 px-3 py-3 text-sm font-medium text-amber-800",children:["The ",e.jsx("code",{children:"parent_lesson_report"})," template must be active before the Template test can render previews."]}):null]})}function Ns(t){var s;return(s=t.bodyHtmlRendered)!=null&&s.trim()?t.status==="sent"||t.status==="failed"||t.status==="skipped":!1}function $i(t){var s;return t.status==="queued"?"This message is still queued.":(s=t.bodyHtmlRendered)!=null&&s.trim()?Ns(t)?null:"This message cannot be resent.":"No stored body for this message â only emails sent after body persistence can be resent."}
22const Pi=["all","sent","failed","skipped","queued"];function J({label:t,value:s}){return e.jsxs("div",{children:[e.jsx("p",{className:"m-0 text-xs font-semibold uppercase tracking-wide text-stone-500",children:t}),e.jsx("p",{className:"m-0 mt-0.5 break-words text-sm text-stone-900",children:s!=null&&s.trim()?s:"â"})]})}function ws({message:t}){const s=os(t);return e.jsx("span",{className:`inline-flex rounded-md border px-2 py-0.5 text-xs font-semibold ${Oa(s)}`,children:Ba(s)})}function Ai({message:t,onClose:s}){const{data:a,isLoading:i}=xa(t.id),{data:l,isLoading:r}=fa(t.id),c=ba(),[x,m]=o.useState(null),{data:g,isLoading:w,error:u}=ga(t.id),j=u instanceof Error?u.message:null,v=(l==null?void 0:l.status)??t.status,h=(l==null?void 0:l.hasStoredBody)??!1,d=Ns({status:v,bodyHtmlRendered:h?"stored":null}),_=r?null:$i({status:v,bodyHtmlRendered:h?"stored":null}),S=c.error instanceof Error?c.error.message:null;function T(){const E=(l==null?void 0:l.toEmail)||t.to_email;window.confirm(`Send this email again to ${E}?`)&&(m(null),c.mutate(t.id,{onSuccess:A=>{if(A.skipped){m(`Logged, but not delivered â ${A.skipped}.`);return}m("Resent. A new row will appear in Sent.")}}))}return e.jsxs(es,{icon:Ft,iconClassName:"bg-gradient-to-br from-indigo-500 to-violet-600",onClose:s,size:"xl",subtitle:t.to_email,title:t.subject_rendered??"No subject",titleId:"sent-email-detail-title",children:[e.jsxs(ts,{className:"min-h-0 flex-1 space-y-4 overflow-y-auto p-6",children:[e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsx(J,{label:"Recipient",value:t.to_name??t.to_email}),e.jsx(J,{label:"Email",value:t.to_email}),e.jsxs("div",{children:[e.jsx("p",{className:"m-0 text-xs font-semibold uppercase tracking-wide text-stone-500",children:"Status"}),e.jsxs("div",{className:"mt-1 flex flex-col items-start gap-1",children:[e.jsx("span",{className:`inline-flex rounded-md border px-2 py-0.5 text-xs font-semibold capitalize ${rs(t.status)}`,children:t.status}),e.jsx(ws,{message:t})]})]}),e.jsx(J,{label:"Category",value:nt(t.category)}),e.jsx(J,{label:"Template",value:t.template_key??"Raw send"}),e.jsx(J,{label:"Trigger",value:t.trigger_source}),e.jsx(J,{label:"Recipient type",value:t.recipient_type}),e.jsx(J,{label:"Related entity",value:t.related_entity_type}),e.jsx(J,{label:"Provider id",value:t.provider_id}),e.jsx(J,{label:"Created",value:ve(t.created_at)}),e.jsx(J,{label:"Sent",value:ve(t.sent_at)}),e.jsx(J,{label:"Delivered",value:ve(t.delivered_at)}),e.jsx(J,{label:"Bounced",value:ve(t.bounced_at)}),e.jsx(J,{label:"Complained",value:ve(t.complained_at)}),e.jsx(J,{label:"Bounce kind",value:t.bounce_kind}),e.jsx(J,{label:"Last provider event",value:t.last_provider_event}),e.jsx(J,{label:"Last provider event at",value:ve(t.last_provider_event_at)})]}),t.error?e.jsxs("div",{children:[e.jsx("p",{className:"m-0 text-xs font-semibold uppercase tracking-wide text-stone-500",children:"Error"}),e.jsx("p",{className:"m-0 mt-1 rounded-lg border border-rose-200 bg-rose-50 px-3 py-2 text-sm font-medium text-rose-700",children:t.error})]}):null,e.jsxs("section",{children:[e.jsx("p",{className:"m-0 text-xs font-semibold uppercase tracking-wide text-stone-500",children:"Delivery timeline"}),j?e.jsx("p",{className:"m-0 mt-2 rounded-lg border border-rose-200 bg-rose-50 px-3 py-2 text-sm font-medium text-rose-700",children:j}):w?e.jsx("p",{className:"m-0 mt-2 text-sm text-stone-500",children:"Loading delivery eventsâ¦"}):g&&g.length>0?e.jsx("ol",{className:"m-0 mt-2 list-none space-y-2 p-0",children:g.map(E=>e.jsxs("li",{className:"rounded-lg border border-stone-200 bg-stone-50 px-3 py-2",children:[e.jsx("div",{className:"text-sm font-medium text-stone-900",children:E.event_type}),e.jsx("div",{className:"text-xs text-stone-500",children:ve(E.received_at)})]},E.id))}):e.jsx("p",{className:"m-0 mt-2 rounded-lg border border-stone-200 bg-stone-50 px-3 py-3 text-sm text-stone-500",children:"No provider delivery events have been logged for this email yet."})]}),e.jsxs("div",{children:[e.jsx("p",{className:"m-0 text-xs font-semibold uppercase tracking-wide text-stone-500",children:"Body"}),i?e.jsx("p",{className:"m-0 mt-2 text-sm text-stone-500",children:"Loading bodyâ¦"}):a?e.jsx("iframe",{className:"mt-2 h-96 w-full rounded-lg border border-stone-200 bg-white",sandbox:"",srcDoc:a,title:"Sent email body"}):e.jsx("p",{className:"m-0 mt-2 rounded-lg border border-stone-200 bg-stone-50 px-3 py-3 text-sm text-stone-500",children:"No stored body for this message. Newer sends keep the exact HTML that was delivered; older rows may only retain a body when linked to a parent lesson-report draft."})]})]}),e.jsxs("div",{className:"flex shrink-0 flex-wrap items-center justify-between gap-3 border-t border-stone-200 bg-stone-50/80 px-6 py-4",children:[e.jsx("div",{className:"min-w-0 flex-1",children:S?e.jsx("p",{className:"m-0 text-sm font-medium text-rose-700",role:"alert",children:S}):x?e.jsx("p",{className:"m-0 text-sm font-medium text-emerald-700",role:"status",children:x}):_?e.jsx("p",{className:"m-0 text-xs text-stone-500",children:_}):e.jsx("p",{className:"m-0 text-xs text-stone-500",children:"Resend delivers the exact stored body to the same recipient."})}),e.jsxs("div",{className:"flex shrink-0 gap-3",children:[e.jsx("button",{className:Se,disabled:c.isPending,onClick:s,type:"button",children:"Close"}),e.jsxs("button",{className:ge,disabled:!d||c.isPending||r,onClick:T,type:"button",children:[e.jsx(Re,{"aria-hidden":"true",className:"h-4 w-4"}),c.isPending?"Resendingâ¦":"Resend"]})]})]})]})}function Ri({search:t}
22){const[s,a]=o.useState("all"),[i,l]=o.useState("all"),[r,c]=o.useState("all"),[x,m]=o.useState(""),[g,w]=o.useState(""),[u,j]=o.useState(1),[v,h]=o.useState(null),d=o.useMemo(()=>({search:t,status:s,category:i,recipientType:r,from:x,to:g}),[t,s,i,r,x,g]),_=ma(d);o.useEffect(()=>{j(1)},[_]);const{data:S,isLoading:T,isFetching:E,error:A}=ua(d,u),I=(S==null?void 0:S.rows)??[],f=(S==null?void 0:S.total)??0,C=ha(f),B=A instanceof Error?A.message:null,P=o.useMemo(()=>I.find(N=>N.id===v)??null,[I,v]);function K(){a("all"),l("all"),c("all"),m(""),w("")}const R=`${pe} h-9 py-0`;return e.jsxs("section",{className:"space-y-4","aria-label":"Sent emails",children:[e.jsxs("div",{className:"flex flex-wrap items-end gap-3 rounded-xl border border-stone-200 bg-white px-4 py-3 shadow-sm",children:[e.jsxs("label",{className:"text-xs font-medium text-stone-600",children:["Status",e.jsx("select",{className:`${R} mt-1`,onChange:N=>a(N.target.value),value:s,children:Pi.map(N=>e.jsx("option",{value:N,children:N==="all"?"All statuses":N.charAt(0).toUpperCase()+N.slice(1)},N))})]}),e.jsxs("label",{className:"text-xs font-medium text-stone-600",children:["Category",e.jsxs("select",{className:`${R} mt-1`,onChange:N=>l(N.target.value),value:i,children:[e.jsx("option",{value:"all",children:"All categories"}),Vt.map(N=>e.jsx("option",{value:N,children:nt(N)},N))]})]}),e.jsxs("label",{className:"text-xs font-medium text-stone-600",children:["Recipient",e.jsxs("select",{className:`${R} mt-1`,onChange:N=>c(N.target.value),value:r,children:[e.jsx("option",{value:"all",children:"All recipients"}),pa.map(N=>e.jsx("option",{value:N,children:N.charAt(0).toUpperCase()+N.slice(1)},N))]})]}),e.jsxs("label",{className:"text-xs font-medium text-stone-600",children:["From",e.jsx("input",{className:`${R} mt-1`,onChange:N=>m(N.target.value),type:"date",value:x})]}),e.jsxs("label",{className:"text-xs font-medium text-stone-600",children:["To",e.jsx("input",{className:`${R} mt-1`,onChange:N=>w(N.target.value),type:"date",value:g})]}),Nt(d)?e.jsx("button",{className:Ae,onClick:K,type:"button",children:"Clear filters"}):null,e.jsx("span",{className:"ml-auto text-xs text-stone-500",children:E?"Loadingâ¦":`${f} message${f===1?"":"s"}`})]}),e.jsxs("div",{className:"rounded-xl border border-stone-200 bg-white shadow-sm",children:[B?e.jsx("p",{className:"m-0 p-4 text-sm font-medium text-rose-700",children:B}):null,T?e.jsx("p",{className:"m-0 p-4 text-sm text-stone-500",children:"Loading sent emails..."}):null,!T&&I.length===0?e.jsx("p",{className:"m-0 p-8 text-center text-sm text-stone-500",children:Nt(d)?"No emails match these filters.":"No emails have been sent yet."}):null,I.length>0?e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"min-w-full divide-y divide-stone-100 text-sm",children:[e.jsx("thead",{className:"bg-stone-50 text-left text-xs font-semibold uppercase tracking-wide text-stone-500",children:e.jsxs("tr",{children:[e.jsx("th",{className:"px-4 py-3",children:"Recipient"}),e.jsx("th",{className:"px-4 py-3",children:"Subject"}),e.jsx("th",{className:"px-4 py-3",children:"Category/template"}),e.jsx("th",{className:"px-4 py-3",children:"Status"}),e.jsx("th",{className:"px-4 py-3",children:"Trigger"}),e.jsx("th",{className:"px-4 py-3",children:"Created / sent"})]})}),e.jsx("tbody",{className:"divide-y divide-stone-100",children:I.map(N=>e.jsxs("tr",{className:"cursor-pointer align-top hover:bg-stone-50",onClick:()=>h(N.id),children:[e.jsxs("td",{className:"px-4 py-3",children:[e.jsx("div",{className:"font-medium text-stone-900",children:N.to_name??N.to_email}),e.jsx("div",{className:"text-xs text-stone-500",children:N.to_email})]}),e.jsx("td",{className:"max-w-xs px-4 py-3",children:e.jsx("span",{className:"text-indigo-700 underline-offset-2 hover:underline",children:N.subject_rendered??"No subject"})}),e.jsxs("td",{className:"px-4 py-3",children:[e.jsx("div",{className:"text-stone-700",children:nt(N.category)}),e.jsx("div",{className:"text-xs text-stone-500",children:N.template_key??"Raw send"})]}),e.jsx("td",{className:"px-4 py-3",children:e.jsxs("div",{className:"flex flex-col items-start gap-1",children:[e.jsx("span",{className:`inline-flex rounded-md border px-2 py-0.5 text-xs font-semibold capitalize ${rs(N.status)}`,children:N.status}),os(N)!=="none"?e.jsx(ws,{message:N}):null]})}),e.jsx("td",{className:"px-4 py-3 capitalize text-stone-700",children:N.trigger_source}),e.jsxs("td",{className:"whitespace-nowrap px-4 py-3 text-stone-700",children:[e.jsx("div",{children:ve(N.created_at)}),e.jsx("div",{className:"text-xs text-stone-500",children:ve(N.sent_at)})]})]},N.id))})]})}):null,f>0?e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3 border-t border-stone-100 px-4 py-3",children:[e.jsxs("span",{className:"text-xs text-stone-500",children:["Page ",Math.min(u,C)," of ",C," · ",f," total"]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs("button",{className:Se,disabled:u<=1||E,onClick:()=>j(N=>Math.max(1,N-1)),type:"button",children:[e.jsx(qa,{"aria-hidden":"true",className:"h-4 w-4"})," Prev"]}),e.jsxs("button",{className:Se,disabled:u>=C||E,onClick:()=>j(N=>Math.min(C,N+1)),type:"button",children:["Next ",e.jsx(ls,{"aria-hidden":"true",className:"h-4 w-4"})]})]})]}):null]}),P?e.jsx(Ai,{message:P,onClose:()=>h(null)}):null]})}const Mi={teacher_prep_reminder:"teachers",teacher_missing_log:"teachers",teacher_schedule_change:"teachers",teacher_group_assignment:"teachers",teacher_holiday_notice:"teachers",teacher_reminder:"teachers",teacher_invite:"teachers",teacher_added:"teachers",pay_ready_notice:"teachers",pay_packet_document:"teachers",registration_received:"parents",registration_next_steps:"parents",enrollment_spot_payment_required:"parents",enrollment_confirmed:"parents",parent_lesson_report:"parents",parent_client_update:"parents",waiver_signed_confirmation:"parents",waiver_email_verification_code:"parents",group_cancellation:"parents",group_cancellation_registration:"parents",parent_closure_notice:"parents",admin_bounce_alert:"admin",admin_notice:"admin",password_reset:"admin"},Ii={private_lesson:"private_lessons",teacher:"teachers",pay:"teachers",parent_client:"parents",registration:"parents",waiver:"parents",admin:"admin",system:"admin"};function Di(t){return t.key.startsWith("private_lesson_")?"private_lessons":Mi[t.key]??Ii[t.category??""]??"admin"}const Li={teacher_prep_reminder:"Reminds a teacher to prepare for an upcoming class.",teacher_pay_review:"Lets a teacher know their pay summary is ready to review.",pay_ready_notice:"Lets a teacher know their pay summary is ready to review.",teacher_missing_log:"Reminds a teacher about classes still missing attendance or a teaching log.",teacher_schedule_change:"Tells a teacher about a change to a class they're scheduled to teach.",teacher_group_assignment:"Welcomes a teacher to a class they've been assigned, with schedule and school details.",teacher_holiday_notice:"Gives teachers a heads-up about upcoming school
22closures that affect their classes.",teacher_reminder:"A general reminder you can send to teachers from Compose.",teacher_invite:"Invites a new teacher to set up their Music 4 Humans account.",teacher_added:"Welcomes a teacher whose account was set up for them.",pay_packet_document:"Delivers a teacher's pay packet PDF.",registration_received:"Confirms to a family that their registration was received.",registration_next_steps:"That group's payment link and waiver, sent after a family registers â before you confirm enrollment.",enrollment_spot_payment_required:"Asks unpaid families to complete tuition so a limited-capacity class spot is confirmed. Choose this from Compose when a class is at or near capacity â it never sends on its own.",enrollment_confirmed:"Welcomes a family after you confirm enrollment, with class details.",parent_lesson_report:"The class report families receive after a lesson, once approved and sent.",parent_client_update:"A general update you can send to families from Compose.",waiver_signed_confirmation:"Confirms a completed waiver and includes the signed copy.",waiver_email_verification_code:"The one-time code a family uses to verify their email while signing a waiver.",group_cancellation:"Lets enrolled families know their class has been cancelled.",group_cancellation_registration:"Lets families with a pending registration know the class was cancelled before it started.",parent_closure_notice:"Tells families when class won't meet â holidays, closures, or a cancelled session.",admin_bounce_alert:"Alerts you when an email to a family or teacher bounces or is marked as spam.",admin_notice:"A general notice you can send from Compose.",password_reset:"Sends a one-time password reset link when someone requests access to their account."};function Bi(t){var i;const s=((i=t.description)==null?void 0:i.trim())??"",a=s&&!/^ported from brevo/i.test(s)?s:"";return Li[t.key]??(a||t.subject)}function Oi(t){const s={private_lessons:[],teachers:[],parents:[],admin:[]};for(const a of t)s[Di(a)].push(a);return s}function qi({template:t,onOpen:s}){return e.jsx("li",{children:e.jsxs("button",{className:"group flex w-full items-center gap-4 border-0 bg-transparent px-5 py-3 text-left transition-colors hover:bg-stone-50",onClick:s,type:"button",children:[e.jsxs("span",{className:"min-w-0 flex-1",children:[e.jsxs("span",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("span",{className:"truncate text-sm font-medium text-stone-900",children:t.name}),t.is_active?null:e.jsx("span",{className:"rounded-md border border-stone-200 bg-stone-100 px-1.5 py-0.5 text-[11px] font-medium text-stone-500",children:"Inactive"})]}),e.jsx("span",{className:"mt-0.5 block truncate text-sm leading-5 text-stone-500",children:Bi(t)})]}),e.jsxs("span",{className:"flex shrink-0 items-center gap-1 text-xs font-medium text-stone-400 transition-colors group-hover:text-indigo-700",children:["Preview",e.jsx(ls,{"aria-hidden":"true",className:"h-4 w-4"})]})]})})}function Fi({search:t}){const s=Ds(),{effectiveCapabilities:a}=Ht(),i=Vt.some(u=>Ws(a,u)),{data:l,isLoading:r,error:c}=Ve(),x=o.useMemo(()=>{const u=t,j=(l??[]).filter(v=>u?[v.key,v.name,v.category,v.subject,v.description].filter(Boolean).some(h=>String(h).toLowerCase().includes(u)):!0);return Oi(j)},[l,t]),m=c instanceof Error?c.message:null,g=!r&&x.private_lessons.length===0&&x.teachers.length===0&&x.parents.length===0&&x.admin.length===0,w=[{id:"private_lessons",title:"Private Lessons",subtitle:"Bookings, payments, reschedules and cancellations for private lessons â to families and teachers.",icon:ss,templates:x.private_lessons},{id:"teachers",title:"Teachers",subtitle:"Email templates sent to instructors and staff.",icon:as,templates:x.teachers},{id:"parents",title:"Parents & Families",subtitle:"Email templates sent to parents and guardians.",icon:cs,templates:x.parents},{id:"admin",title:"System & Admin",subtitle:"Internal operational emails and account messages.",icon:Fa,templates:x.admin}];return e.jsxs("section",{"aria-label":"Email templates",className:"space-y-6",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"m-0 text-xl font-semibold tracking-tight text-stone-950",children:"Email Templates"}),e.jsx("p",{className:"m-0 mt-1 text-sm text-stone-600",children:"Manage the messages sent to teachers, parents, and families."})]}),i?e.jsxs("button",{className:ge,onClick:()=>s("/communications/templates/new"),type:"button",children:[e.jsx(Ua,{"aria-hidden":"true",className:"h-4 w-4"}),"New template"]}):null]}),m?e.jsx("p",{className:"m-0 rounded-lg bg-rose-50 px-3 py-2 text-sm font-medium text-rose-700",children:m}):null,r?e.jsx("p",{className:"m-0 text-sm text-stone-500",children:"Loading templates..."}):null,g?e.jsx("p",{className:"m-0 text-sm text-stone-500",children:"No templates match your search."}):null,w.map(u=>{if(u.templates.length===0)return null;const j=u.icon;return e.jsxs("section",{"aria-labelledby":`templates-section-${u.id}`,children:[e.jsxs("div",{className:"flex items-center gap-3.5 rounded-xl border border-indigo-100 bg-indigo-50/70 px-5 py-3.5",children:[e.jsx("span",{className:"flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-indigo-100 text-indigo-700",children:e.jsx(j,{"aria-hidden":"true",className:"h-5 w-5"})}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("h2",{className:"m-0 text-lg font-semibold tracking-tight text-stone-950",id:`templates-section-${u.id}`,children:u.title}),e.jsx("p",{className:"m-0 text-sm text-stone-600",children:u.subtitle})]})]}),e.jsx("ul",{className:"m-0 mt-2.5 list-none divide-y divide-stone-100 overflow-hidden rounded-xl border border-stone-200 bg-white p-0",role:"list",children:u.templates.map(v=>e.jsx(qi,{onOpen:()=>s(`/communications/templates/${v.id}`),template:v},v.id))})]},u.id)})]})}const Ui=[{value:"templates",label:"Templates"},{value:"compose",label:"Compose",icon:Re},{value:"outbox",label:"Outbox",icon:da},{value:"sent",label:"Sent"}
22],Hi=[{value:"test_send",label:"Test Send",icon:Ka},{value:"automations",label:"Automations",icon:ds},{value:"do_not_email",label:"Do not email",icon:ms}],Ki=new Set(["templates","sent","outbox"]),qt={templates:"Search templates",sent:"Search sent emails",outbox:"Search outbox emails",compose:"",test_send:"",automations:"",do_not_email:""};function Pr(){var I;const{effectiveIsAdmin:t,can:s}=Ht(),a=o.useCallback(f=>f==="compose"?s(jt.communicationsSend):f==="outbox"?s(jt.communicationsOutbox):f==="test_send"||f==="automations"||f==="do_not_email"?t:!0,[s,t]),i=Ui.filter(f=>a(f.value)),l=Hi.filter(f=>a(f.value)),[r,c]=Ls(),x=hi(r.get("tab")),m=a(x)?x:((I=i[0])==null?void 0:I.value)??"templates",g=xi(m,r.get("lessonSessionId")),[w,u]=o.useState(""),[j,v]=o.useState(""),[h,d]=o.useState(!1),_=o.useRef(null),S=l.some(f=>f.value===m),T=[...i.map(f=>f.value),...l.map(f=>f.value)];function E(f){d(!1),c(C=>fi(C,f),{replace:!0})}function A(f){const C=T.indexOf(m);if(C<0)return;const B=T.length-1;let P=C;if(f.key==="ArrowRight")P=C===B?0:C+1;else if(f.key==="ArrowLeft")P=C===0?B:C-1;else if(f.key==="Home")P=0;else if(f.key==="End")P=B;else return;f.preventDefault();const K=T[P];E(K),requestAnimationFrame(()=>{var R;return(R=document.getElementById(`comm-tab-${K}`))==null?void 0:R.focus()})}return o.useEffect(()=>{const f=window.setTimeout(()=>v(w.trim().toLowerCase()),250);return()=>window.clearTimeout(f)},[w]),o.useEffect(()=>{if(!h)return;function f(B){var P;(P=_.current)!=null&&P.contains(B.target)||d(!1)}function C(B){B.key==="Escape"&&d(!1)}return document.addEventListener("mousedown",f),document.addEventListener("keydown",C),()=>{document.removeEventListener("mousedown",f),document.removeEventListener("keydown",C)}},[h]),e.jsxs("main",{className:`${Ha} font-geist communications-studio`,children:[e.jsxs("header",{className:"flex flex-wrap items-end justify-between gap-6 py-4",children:[e.jsxs("div",{children:[e.jsx("p",{className:"m-0 font-mono text-[11px] uppercase tracking-[.1em] text-[var(--m4h-ink-faint)]",children:"Operations"}),e.jsx("h1",{id:"communications-title",className:"m-0 mt-2 text-2xl sm:text-[32px] font-semibold leading-tight tracking-[-.03em]",children:"Communications"}),e.jsx("p",{className:"m-0 mt-2 text-sm text-[var(--m4h-ink-muted)]",children:"Create, review, and follow your schoolâs emails."})]}),Ki.has(m)&&e.jsxs("div",{className:"relative w-full sm:w-72",children:[e.jsx(Ks,{"aria-hidden":"true",className:"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-[var(--m4h-ink-faint)]"}),e.jsx("input",{"aria-label":qt[m],className:"h-11 w-full rounded-xl border border-solid border-[var(--m4h-line)] bg-white pl-9 pr-3 text-sm focus:outline-[var(--m4h-brand-purple)]",onChange:f=>u(f.target.value),placeholder:qt[m],type:"search",value:w})]})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",role:"tablist","aria-label":"Communications",onKeyDown:A,children:[i.map(({value:f,label:C,icon:B})=>{const P=m===f;return e.jsxs("button",{"aria-controls":`comm-panel-${f}`,"aria-selected":P,className:P?Be:Oe,id:`comm-tab-${f}`,onClick:()=>E(f),role:"tab",tabIndex:P?0:-1,type:"button",children:[B?e.jsx(B,{"aria-hidden":"true",className:"h-4 w-4"}):null,C]},f)}),l.length>0?e.jsxs("div",{className:"relative",ref:_,children:[e.jsxs("button",{"aria-expanded":h,"aria-haspopup":"menu",className:`${S?Be:Oe} gap-1.5`,onClick:()=>d(f=>!f),type:"button",children:[e.jsx(Ga,{"aria-hidden":"true",className:"h-4 w-4"}),"More",e.jsx(Ys,{"aria-hidden":"true",className:"h-3.5 w-3.5"})]}),h?e.jsx("div",{className:"absolute left-0 z-30 mt-2 min-w-[11rem] overflow-hidden rounded-lg border border-stone-200 bg-white py-1 shadow-lg",role:"menu",children:l.map(({value:f,label:C,icon:B})=>e.jsxs("button",{"aria-controls":`comm-panel-${f}`,className:`flex w-full items-center gap-2 border-0 bg-transparent px-3 py-2 text-left text-sm ${m===f?"bg-indigo-50 font-medium text-indigo-700":"text-stone-700 hover:bg-stone-50"}`,id:`comm-tab-${f}`,onClick:()=>E(f),role:"menuitem",type:"button",children:[e.jsx(B,{"aria-hidden":"true",className:"h-4 w-4"}),C]},f))}):null]}):null]}
22),e.jsx("div",{"aria-labelledby":"comm-tab-templates",hidden:m!=="templates",id:"comm-panel-templates",role:"tabpanel",children:e.jsx(Fi,{search:j})}),a("compose")?e.jsx("div",{"aria-labelledby":"comm-tab-compose",hidden:m!=="compose",id:"comm-panel-compose",role:"tabpanel",children:e.jsx(ui,{search:j})}):null,m==="outbox"?e.jsx("div",{"aria-labelledby":"comm-tab-outbox",className:"space-y-5",id:"comm-panel-outbox",role:"tabpanel",children:e.jsx(rn,{lessonSessionIdFilter:g,search:j})}):m==="test_send"?e.jsx("div",{"aria-labelledby":"comm-tab-test_send",id:"comm-panel-test_send",role:"tabpanel",children:e.jsx(Ei,{})}):m==="sent"?e.jsx("div",{"aria-labelledby":"comm-tab-sent",id:"comm-panel-sent",role:"tabpanel",children:e.jsx(Ri,{search:j})}):m==="automations"?e.jsx("div",{"aria-labelledby":"comm-tab-automations",id:"comm-panel-automations",role:"tabpanel",children:e.jsx(vn,{})}):m==="do_not_email"?e.jsx("div",{"aria-labelledby":"comm-tab-do_not_email",id:"comm-panel-do_not_email",role:"tabpanel",children:e.jsx(wn,{})}):null]})}export{Pr as CommunicationsPage};
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.