PageSourceSearch

https://snapfind.ai/assets/AdminUsers-fp-NS21R.js

js snapfind.ai collected 2026-10-05 12:39:18 UTC 22,856 bytes, 27 lines download raw bytes

1import{h as X,u as He,V as Ke,r as a,s as ie,j as e,aj as Ye,B as r,X as Je,T as Xe,I as N,Y as Ze,ai as be,ah as Se}from"./index-DbZOmY8Y.js";import{L as es}from"./LoadError-DQcxPpYj.js";import{u as ss}from"./useAdminData-Du5BQDbA.js";import{B as b}from"./badge-Duxj7S1s.js";import{C as fe}from"./checkbox-gqJ6TDpO.js";import{L as j}from"./label-DUx495TQ.js";import{S as ts,a as as,b as ns,c as is,d as rs}from"./select-AVkWMApv.js";import{D as B,a as I,b as M,c as P,d as z,e as q}from"./dialog-Bf-zf-5c.js";import{D as ls,a as cs,E as ds,b as os,c as w,d as ms}from"./dropdown-menu-ChJhTsy9.js";import{T as hs}from"./textarea-B0R2DRFO.js";import{M as ne}from"./mail-CcoqCoOL.js";import{P as xs}from"./pencil-B5SLSdqC.js";import{S as ps}from"./scan-line-BBwGbxAk.js";import{R as us}from"./rotate-ccw-Y82jRGw8.js";import{S as we}from"./shield-check-B7MakMTU.js";import{S as gs}from"./send-Bvqcsxoa.js";import{C as js}from"./clock-DaSzOV0p.js";import"./readAllPages-DqUz4X8x.js";import"./check-DAXJTmxG.js";/**
2 * @license lucide-react v0.462.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 ve=X("Ban",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m4.9 4.9 14.2 14.2",key:"1m5liu"}]]);/**
7 * @license lucide-react v0.462.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 ys=X("KeyRound",[["path",{d:"M2.586 17.414A2 2 0 0 0 2 18.828V21a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h1a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h.172a2 2 0 0 0 1.414-.586l.814-.814a6.5 6.5 0 1 0-4-4z",key:"1s6t7t"}],["circle",{cx:"16.5",cy:"7.5",r:".5",fill:"currentColor",key:"w0ekpg"}]]);/**
12 * @license lucide-react v0.462.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 fs=X("UserCheck",[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",key:"1yyitq"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}],["polyline",{points:"16 11 18 13 22 9",key:"1pwet4"}]]);/**
17 * @license lucide-react v0.462.0 - ISC
18 *
19 * This source code is licensed under the ISC license.
20 * See the LICENSE file in the root directory of this source tree.
21 */const ws=X("UserX",[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",key:"1yyitq"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}],["line",{x1:"17",x2:"22",y1:"8",y2:"13",key:"3nzzx3"}],["line",{x1:"22",x2:"17",y1:"8",y2:"13",key:"1swrse"}]]);async function S(k,l,Z){const{data:{session:v}}=await ie.auth.getSession();if(!(v!=null&&v.access_token))throw new Error("Not authenticated");const C=await fetch(`${Se}/functions/v1/admin-user-actions`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${v.access_token}`,apikey:be},body:JSON.stringify({action:k,user_id:l,...Z})}),x=await C.json();if(!C.ok)throw new Error(x.error||`Action failed (${C.status})`);return x}const Ne=[{label:"Custom",subject:"",body:""},{label:"Re-engagement",subject:"We miss you on SnapFind!",body:`It's been a while since you last catalogued items on SnapFind. Your inventory is waiting for you — snap a quick photo and we'll handle the rest.
22
23If you have any questions or need help getting started again, just reply to this email.`},{label:"Welcome back",subject:"Welcome back to SnapFind",body:`Great to see you back on SnapFind! We've made some improvements since your last visit.
24
25Feel free to explore and let us know if there's anything we can help with.`},{label:"New feature",subject:"New on SnapFind",body:`We've just launched a new feature that we think you'll love.
26
27Check it out next time you open the app. As always, we'd love your feedback.`}],zs=()=>{var he,xe,pe,ue,ge,je,ye;const{user:k}=He(),{participants:l,items:Z,loading:v,error:C,refetch:x}=ss(),{toast:n}=Ke(),[R,Q]=a.useState({open:!1,participant:null}),[E,O]=a.useState({open:!1,participant:null}),[D,V]=a.useState({open:!1,participant:null}),[i,W]=a.useState({open:!1,participant:null,action:"suspend"}),[m,U]=a.useState({open:!1,recipients:[]}),[y,_]=a.useState(new Set),[G,re]=a.useState(""),[le,ce]=a.useState(""),[ee,de]=a.useState(50),[se,T]=a.useState(""),[H,K]=a.useState(""),[A,Y]=a.useState(""),[ke,te]=a.useState("Custom"),[h,d]=a.use
27State(!1),[c,$]=a.useState(null),[oe,Ce]=a.useState([]),[Ee,De]=a.useState(!0),ae=a.useCallback(async()=>{const{data:s,error:t}=await ie.from("email_log").select("*").order("created_at",{ascending:!1}).limit(50);!t&&s&&Ce(s),De(!1)},[]);a.useEffect(()=>{ae()},[ae]);const Ue=l.length,_e=l.filter(s=>s.status!=="suspended").length,me=l.filter(s=>s.status==="suspended").length,Te=async()=>{if(R.participant){d(!0);try{await S("update_user",R.participant.id,{name:G,assigned_area:le}),n({title:"User updated",description:`${G} has been updated.`}),Q({open:!1,participant:null}),x()}catch(s){n({title:"Error",description:s.message,variant:"destructive"})}finally{d(!1)}}},Ae=async()=>{if(!i.participant)return;d(!0);const s=i.action==="suspend"?"suspend_user":"unsuspend_user";try{await S(s,i.participant.id),n({title:i.action==="suspend"?"User suspended":"User unsuspended",description:`${i.participant.name} has been ${i.action==="suspend"?"suspended":"reactivated"}.`}),W({open:!1,participant:null,action:"suspend"}),x()}catch(t){n({title:"Error",description:t.message,variant:"destructive"})}finally{d(!1)}},$e=async()=>{if(!(!D.participant||se!=="DELETE")){d(!0);try{await S("delete_user",D.participant.id),n({title:"User deleted",description:`${D.participant.name} and all their data have been permanently deleted.`}),V({open:!1,participant:null}),T(""),x()}catch(s){n({title:"Error",description:s.message,variant:"destructive"})}finally{d(!1)}}},Le=async s=>{try{await S("reset_password",s.id),n({title:"Password reset sent",description:`Reset email sent to ${s.email}`})}catch(t){n({title:"Error",description:t.message,variant:"destructive"})}},Fe=async()=>{if(E.participant){d(!0);try{await S("update_quota",E.participant.id,{scan_quota:ee}),n({title:"Quota updated",description:`Scan quota set to ${ee}`}),O({open:!1,participant:null}),x()}catch(s){n({title:"Error",description:s.message,variant:"destructive"})}finally{d(!1)}}},Be=async s=>{try{await S("reset_scans",s.id),n({title:"Scans reset",description:`${s.name}'s scan count reset to 0.`}),x()}catch(t){n({title:"Error",description:t.message,variant:"destructive"})}},Ie=async()=>{const s=m.recipients;if(s.length===0||!H.trim()||!A.trim())return;d(!0);const{data:{session:t}}=await ie.auth.getSession();if(!(t!=null&&t.access_token)){n({title:"Error",description:"Not authenticated",variant:"destructive"}),d(!1);return}const o={"Content-Type":"application/json",Authorization:`Bearer ${t.access_token}`,apikey:be},p=[];$({current:0,total:s.length,failures:[]});for(let u=0;u<s.length;u++){const g=s[u],L=(g.name||"").split(" ")[0]||g.name||"",F=A.replace(/\{\{firstName\}\}/g,L);$({current:u+1,total:s.length,failures:[...p]});try{const J=await fetch(`${Se}/functions/v1/send-user-email`,{method:"POST",headers:o,body:JSON.stringify({to:g.email,toName:g.name||void 0,subject:H,body:F})}),Ge=await J.json();if(!J.ok)throw new Error(Ge.error||`${J.status}`)}catch{p.push(g.email)}}$(null),d(!1);const f=s.length-p.length;p.length===0?n({title:"All emails sent",description:`Sent ${f} email${f!==1?"s":""} successfully.`}):n({title:`Sent ${f}/${s.length}`,description:`Failed: ${p.join(", ")}`,variant:"destructive"}),U({open:!1,recipients:[]}),_(new Set),ae()},Me=s=>{re(s.name||""),ce(s.assigned_area||""),Q({open:!0,participant:s})},Pe=s=>{de(s.scan_quota??50),O({open:!0,participant:s})},ze=s=>{const t=s.status==="suspended"?"unsuspend":"suspend";W({open:!0,participant:s,action:t})},qe=s=>{T(""),V({open:!0,participant:s})},Re=s=>{K(""),Y(""),te("Custom"),$(null),U({open:!0,recipients:[{id:s.id,name:s.name||"",email:s.email}]})},Qe=()=>{const s=l.filter(t=>y.has(t.id)).map(t=>({id:t.id,name:t.name||"",email:t.email}));s.length!==0&&(K(""),Y(""),te("Custom"),$(null),U({open:!0,recipients:s}))},Oe=s=>{_(t=>{const o=new Set(t);return o.has(s)?o.delete(s):o.add(s),o})},Ve=()=>{y.size===l.length?_(new Set):_(new Set(l.map(s=>s.id)))},We=s=>{te(s);const t=Ne.find(o=>o.label===s);t&&(K(t.subject),Y(t.body))};return v?e.jsx("div",{className:"flex justify-center items-center py-20",children:e.jsx("div",{className:"animate-spin rounded-full h-10 w-10 border-b-2 border-blue-600"})}):C?e.jsx(es,{subject:"Admin data",onRetry:x}):e.jsxs("div",{className:"sf-page space-y-6",children:[e.jsxs("div",{children:[e.jsxs("h1",{className:"text-2xl font-bold text-gray-900 flex items-center gap-2",children:[e.jsx(Ye,{className:"w-7 h-7 text-blue-500"}),"User Management"]}),e.jsxs("p",{className:"text-gray-500 mt-1",children:[Ue," total ·"," ",e.jsxs("span",{className:"text-green-600",children:[_e," active"]}),me>0&&e.jsxs(e.Fragment,{children:[" · ",e.jsxs("span",{className:"text-red-500",children:[me," suspended"]})]})]})]}),y.size>0&&e.jsxs("div",{className:"flex items-center justify-between bg-blue-50 border border-blue-200 rounded-lg px-4 py-2",children:[e.jsxs("div",{className:"flex items-center gap-2 text-sm text-blue-800",children:[e.jsxs("span",{className:"font-medium",children:[y.size," user",y.size!==1?"s":""," selected"]}),e.jsxs(r,{variant:"ghost",size:"sm",className:"h-6 px-2 text-blue-600",onClick:()=>
27_(new Set),children:[e.jsx(Je,{className:"w-3 h-3 mr-1"}),"Clear"]})]}),e.jsxs(r,{size:"sm",onClick:Qe,children:[e.jsx(ne,{className:"w-4 h-4 mr-2"}),"Email Selected"]})]}),e.jsx("div",{className:"bg-white rounded-lg shadow-sm border",children:e.jsx("div",{className:"overflow-x-auto",children:l.length>0?e.jsxs("table",{className:"min-w-full divide-y divide-gray-200",children:[e.jsx("thead",{className:"bg-gray-50",children:e.jsxs("tr",{children:[e.jsx("th",{className:"px-3 py-3 text-left",children:e.jsx(fe,{"aria-label":"Select all users",checked:l.length>0&&y.size===l.length,onCheckedChange:Ve})}),e.jsx("th",{className:"px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider",children:"User"}),e.jsx("th",{className:"px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider",children:"Status"}),e.jsx("th",{className:"px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider",children:"Items"}),e.jsx("th",{className:"px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider",children:"Scans"}),e.jsx("th",{className:"px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider",children:"AI Assisted"}),e.jsx("th",{className:"px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider",children:"Joined"}),e.jsx("th",{className:"px-4 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider",children:"Actions"})]})}),e.jsx("tbody",{className:"bg-white divide-y divide-gray-200",children:l.map(s=>{const t=Z.filter(F=>F.participant_id===s.id),o=t.filter(F=>F.ai_confidence_score!==null),p=s.id===(k==null?void 0:k.id),f=s.status==="suspended",u=s.scan_quota??50,g=s.scans_used??0,L=u>0?Math.round(g/u*100):0;return e.jsxs("tr",{className:`hover:bg-gray-50 ${f?"opacity-60":""}`,children:[e.jsx("td",{className:"px-3 py-3 whitespace-nowrap",children:e.jsx(fe,{"aria-label":`Select ${s.name||s.email}`,checked:y.has(s.id),onCheckedChange:()=>Oe(s.id)})}),e.jsx("td",{className:"px-4 py-3 whitespace-nowrap",children:e.jsxs("div",{children:[e.jsxs("div",{className:"font-medium text-gray-900 flex items-center gap-1.5",children:[s.name||"Unnamed",p&&e.jsx(b,{variant:"outline",className:"text-[10px] px-1 py-0",children:"You"})]}),e.jsx("div",{className:"text-xs text-gray-500",children:s.email}),s.assigned_area&&e.jsx("div",{className:"text-xs text-gray-400",children:s.assigned_area})]})}),e.jsx("td",{className:"px-4 py-3 whitespace-nowrap",children:f?e.jsxs(b,{variant:"destructive",className:"text-xs",children:[e.jsx(ws,{className:"w-3 h-3 mr-1"}),"Suspended"]}):e.jsxs(b,{className:"bg-green-100 text-green-800 hover:bg-green-100 text-xs",children:[e.jsx(fs,{className:"w-3 h-3 mr-1"}),"Active"]})}),e.jsx("td",{className:"px-4 py-3 whitespace-nowrap",children:e.jsx(b,{variant:"outline",children:t.length})}),e.jsx("td",{className:"px-4 py-3 whitespace-nowrap",children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"w-14 bg-gray-200 rounded-full h-1.5",children:e.jsx("div",{className:`h-1.5 rounded-full ${L>=90?"bg-red-500":L>=70?"bg-yellow-500":"bg-blue-500"}`,style:{width:`${Math.min(L,100)}%`}})}),e.jsxs("span",{className:"text-xs text-gray-500",children:[g,"/",u]})]})}),e.jsx("td",{className:"px-4 py-3 whitespace-nowrap",children:o.length>0?e.jsxs(b,{variant:"secondary",children:[o.length,"/",t.length]}):e.jsx("span",{className:"text-gray-400 text-xs",children:"-"})}),e.jsx("td",{className:"px-4 py-3 whitespace-nowrap text-sm text-gray-500",children:new Date(s.created_at).toLocaleDateString("en-GB",{day:"numeric",month:"short",year:"numeric"})}),e.jsx("td",{className:"px-4 py-3 whitespace-nowrap text-right",children:e.jsxs(ls,{children:[e.jsx(cs,{asChild:!0,children:e.jsx(r,{variant:"ghost",size:"sm",className:"h-8 w-8 p-0","aria-label":`Actions for ${s.name||s.email}`,children:e.jsx(ds,{className:"h-4 w-4"})})}),e.jsxs(os,{align:"end",children:[e.jsxs(w,{onClick:()=>Me(s),children:[e.jsx(xs,{className:"w-4 h-4 mr-2"}),"Edit User"]}),e.jsxs(w,{onClick:()=>Pe(s),children:[e.jsx(ps,{className:"w-4 h-4 mr-2"}
27),"Update Scan Quota"]}),e.jsxs(w,{onClick:()=>Be(s),children:[e.jsx(us,{className:"w-4 h-4 mr-2"}),"Reset Scan Count"]}),e.jsxs(w,{onClick:()=>Le(s),children:[e.jsx(ys,{className:"w-4 h-4 mr-2"}),"Send Password Reset"]}),e.jsxs(w,{onClick:()=>Re(s),children:[e.jsx(ne,{className:"w-4 h-4 mr-2"}),"Send Email"]}),e.jsx(ms,{}),!p&&e.jsxs(e.Fragment,{children:[e.jsx(w,{onClick:()=>ze(s),children:f?e.jsxs(e.Fragment,{children:[e.jsx(we,{className:"w-4 h-4 mr-2 text-green-600"}),e.jsx("span",{className:"text-green-600",children:"Unsuspend User"})]}):e.jsxs(e.Fragment,{children:[e.jsx(ve,{className:"w-4 h-4 mr-2 text-orange-600"}),e.jsx("span",{className:"text-orange-600",children:"Suspend User"})]})}),e.jsxs(w,{onClick:()=>qe(s),children:[e.jsx(Xe,{className:"w-4 h-4 mr-2 text-red-600"}),e.jsx("span",{className:"text-red-600",children:"Delete User"})]})]})]})]})})]},s.id)})})]}):e.jsx("div",{className:"p-6 text-center text-gray-500",children:"No users registered yet"})})}),e.jsxs("div",{children:[e.jsxs("h2",{className:"text-lg font-semibold text-gray-900 flex items-center gap-2 mb-3",children:[e.jsx(gs,{className:"w-5 h-5 text-blue-500"}),"Sent Emails"]}),e.jsx("div",{className:"bg-white rounded-lg shadow-sm border",children:e.jsx("div",{className:"overflow-x-auto",children:Ee?e.jsx("div",{className:"p-6 text-center text-gray-400",children:"Loading email history..."}):oe.length>0?e.jsxs("table",{className:"min-w-full divide-y divide-gray-200",children:[e.jsx("thead",{className:"bg-gray-50",children:e.jsxs("tr",{children:[e.jsx("th",{className:"px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider",children:"Date"}),e.jsx("th",{className:"px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider",children:"To"}),e.jsx("th",{className:"px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider",children:"Subject"}),e.jsx("th",{className:"px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider",children:"Status"})]})}),e.jsx("tbody",{className:"bg-white divide-y divide-gray-200",children:oe.map(s=>e.jsxs("tr",{className:"hover:bg-gray-50",children:[e.jsx("td",{className:"px-4 py-3 whitespace-nowrap text-sm text-gray-500",children:e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx(js,{className:"w-3.5 h-3.5 text-gray-400"}),new Date(s.created_at).toLocaleDateString("en-GB",{day:"numeric",month:"short"})," ",new Date(s.created_at).toLocaleTimeString("en-GB",{hour:"2-digit",minute:"2-digit"})]})}),e.jsx("td",{className:"px-4 py-3 whitespace-nowrap",children:e.jsxs("div",{children:[e.jsx("div",{className:"text-sm font-medium text-gray-900",children:s.recipient_name||"—"}),e.jsx("div",{className:"text-xs text-gray-500",children:s.sent_to})]})}),e.jsxs("td",{className:"px-4 py-3",children:[e.jsx("div",{className:"text-sm text-gray-900 max-w-xs truncate",children:s.subject}),s.body_preview&&e.jsx("div",{className:"text-xs text-gray-400 max-w-xs truncate",children:s.body_preview})]}),e.jsx("td",{className:"px-4 py-3 whitespace-nowrap",children:e.jsx(b,{className:"bg-green-100 text-green-800 hover:bg-green-100 text-xs",children:s.status})})]},s.id))})]}):e.jsx("div",{className:"p-6 text-center text-gray-500",children:"No emails sent yet"})})})]}),e.jsx(B,{open:R.open,onOpenChange:s=>!s&&Q({open:!1,participant:null}),children:e.jsxs(I,{children:[e.jsxs(M,{children:[e.jsx(P,{children:"Edit User"}),e.jsxs(z,{children:["Update details for ",((he=R.participant)==null?void 0:he.name)||"this user","."]})]}),e.jsxs("div",{className:"space-y-4 py-2",children:[e.jsxs("div",{children:[e.jsx(j,{htmlFor:"edit-name",children:"Display Name"}),e.jsx(N,{id:"edit-name",value:G,onChange:s=>re(s.target.value)})]}),e.jsxs("div",{children:[e.jsx(j,{htmlFor:"edit-area",children:"Assigned Area"}),e.jsx(N,{id:"edit-area",value:le,onChange:s=>ce(s.target.value),placeholder:"e.g. Kitchen, Garage"})]})]}),e.jsxs(q,{children:[e.jsx(r,{variant:"outline",onClick:()=>Q({open:!1,participant:null}),children:"Cancel"}),e.jsx(r,{onClick:Te,disabled:h||!G.trim(),children:h?"Saving...":"Save Changes"})]})]})}),e.jsx(B,{open:E.open,onOpenChange:s=>!s&&O({open:!1,participant:null}),children:e.jsxs(I,{children:[e.jsxs(M,{children:[e.jsx(P,{children:"Update Scan Quota"}),e.jsxs(z,{children:["Set the maximum number of AI scans for ",((xe=E.participant)==null?void 0:xe.name)||"this user",". Currently used: ",((pe=E.participant)==null?void 0:pe.scans_used)??0," scans."]})]}),e.jsxs("div",{className:"py-2",children:[e.jsx(j,{htmlFor:"scan-quota",children:"Scan Quota"}),e.jsx(N,{id:"scan-quota",type:"number",min:0,value:ee,onChange:s=>de(parseInt(s.target.value)||0)})]}),e.jsxs(q,{children:[e.jsx(r,{variant:"outline",onClick:()=>O({open:!1,participant:null}),children:"Cancel"}),e.jsx(r,{onClick:Fe,disabled:h,children:h?"Updating...":"Update Quota"})]})]})}),e.jsx(B,{open:i.open,onOpenChange:s=>!s&&W({open:!1,participant:null,action:"suspend"}),children:e.jsxs(I,{children:[e.jsxs(M,{children:[e.jsx(P,{className:"flex items-center gap-2",children:i.action==="suspend"?e.jsxs(e.Fragment,{children:[e.jsx(ve,{className:"w-5 h-5 text-orange-600"})," Suspend User"]}):e.jsxs(e.Fragment,{children:[e.jsx(we,{className:"w-5 h-5 text-green-600"})," Unsuspend User"]})}),e.jsx(z,{children:i.action==="suspend"?`This will prevent ${(ue=i.participant)==null?void 0:ue.name} from signing in. Their data will be preserved.`:`This will allow ${(ge=i.participant)==null?void 0:ge.name} to sign in again.`})]}),e.jsxs(q,{children:[e.jsx(r,{variant:"outline",onClick:()=>W({open:!1,participant:null,action:"suspend"}),children:"Cancel"}),e.jsx(r,{variant:i.action==="suspend"?"destructive":"default",onClick:Ae,disabled:h,children:h?"Processing...":i.action==="suspend"?"Suspend User":"Unsuspend User"})]})]})}),e.jsx(B,{open:D.open,onOpenChange:s=>{s||(V({open:!1,participant:null}),T(""))},children:e.jsxs(I,{children:[e.jsxs(M,{children:[e.jsxs(P,{className:"flex items-center gap-2 text-red-600",children:[e.jsx(Ze,{className:"w-5 h-5"}),"Delete User Permanently"]}),e.jsxs(z,{children:["This will permanently delete ",e.jsx("strong",{children:(je=D.participant)==null?void 0:je.name})," and all their data (items, boxes, analytics). This action cannot be undone."]})]}),e.jsxs("div",{className:"py-2",children:[e.jsx(j,{htmlFor:"delete-confirm",children:"Type DELETE to confirm"}),e.jsx(N,{id:"delete-confirm",value:se,onChange:s=>T(s.target.value),placeholder:"DELETE",className:"mt-1"})]}),e.jsxs(q,{children:[e.jsx(r,{variant:"outline",onClick:()=>{V({open:!1,participant:null}),T("")},children:"Cancel"}),e.jsx(r,{variant:"destructive",onClick:$e,disabled:h||se!=="DELETE",children:h?"Deleting...":"Delete User"})]})]})}),e.jsx(B,{open:m.open,onOpenChange:s=>{!s&&!c&&U({open:!1,recipients:[]})},children:e.jsxs(I,{className:"sm:max-w-lg",children:[e.jsxs(M,{children:[e.jsxs(P,{className:"flex items-center gap-2",children:[e.jsx(ne,{className:"w-5 h-5 text-blue-500"}),m.recipients.length===1?"Send Email":`Email ${m.recipients.length} Users`]}),e.jsx(z,{children:c?`Sending ${c.current}/${c.total}...`:"From [email protected] · replies go to [email protected]"})]}),c?e.jsxs("div",{className:"py-6 space-y-3",children:[e.jsx("div",{className:"w-full bg-gray-200 rounded-full h-2",children:e.jsx("div",{className:"bg-blue-500 h-2 rounded-full transition-all",style:{width:`${Math.round(c.current/c.total*100)}%`}})}),e.jsxs("p",{className:"text-sm text-gray-500 text-center",children:["Sending ",c.current," of ",c.total,"...",c.failures.length>0&&e.jsxs("span",{className:"text-red-500",children:[" (",c.failures.length," failed)"]})]})]}):e.jsxs("div",{className:"space-y-4 py-2",children:[e.jsxs("div",{children:[e.jsx(j,{htmlFor:"email-to",children:"To"}),m.recipients.length===1?e.jsx(N,{id:"email-to",value:((ye=m.recipients[0])==null?void 0:ye.email)||"",disabled:!0,className:"bg-gray-50 text-gray-500"}):e.jsx("div",{className:"text-sm bg-gray-50 border rounded-md px-3 py-2 text-gray-600",children:m.recipients.map(s=>s.name||s.email).join(", ")})]}),e.jsxs("div",{children:[e.jsx(j,{children:"Template"}),e.jsxs(ts,{value:ke,onValueChange:We,children:[e.jsx(as,{children:e.jsx(ns,{})}),e.jsx(is,{children:Ne.map(s=>e.jsx(rs,{value:s.label,children:s.label},s.label))})]})]}),e.jsxs("div",{children:[e.jsx(j,{htmlFor:"email-subject",children:"Subject"}),e.jsx(N,{id:"email-subject",value:H,onChange:s=>K(s.target.value),placeholder:"e.g. Quick update from SnapFind"})]}),e.jsxs("div",{children:[e.jsx(j,{htmlFor:"email-body",children:"Message"}),e.jsx(hs,{id:"email-body",value:A,onChange:s=>Y(s.target.value),placeholder:"Write your message here...",rows:6,className:"resize-y"}),e.jsxs("p",{className:"text-xs text-gray-400 mt-1",children:[A.length," chars",m.recipients.length>1&&e.jsxs("span",{className:"ml-2",children:["· Use ",e.jsx("code",{className:"bg-gray-100 px-1 rounded",children:"{{firstName}}"})," to personalize"]})]})]})]}),!c&&e.jsxs(q,{children:[e.jsx(r,{variant:"outline",onClick:()=>U({open:!1,recipients:[]}),children:"Cancel"}),e.jsx(r,{onClick:Ie,disabled:h||!H.trim()||!A.trim(),children:h?"Sending...":m.recipients.length===1?"Send Email":`Send to ${m.recipients.length} Users`})]})]})})]})};export{zs as default};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.