PageSourceSearch

https://event-flow-copy-53bc8fa7.base44.app/assets/PendingUserAssignments-5r_XsfBI.js

js event-flow-copy-53bc8fa7.base44.app collected 2026-10-03 03:16:46 UTC 12,343 bytes, 1 lines download raw bytes

1import{a as te,r as n,u as D,j as e,t,b as l}from"./index-BTknFgmn.js";import{C as w,b as Q,c as V,a as A}from"./card-CA4X9pcm.js";import{B as h}from"./button-e-SLIh0W.js";import{I as ne}from"./input-octY78VM.js";import{L as c}from"./label-BVyzOqvp.js";import{T as ie}from"./textarea-CA6E-q-4.js";import{B as $}from"./badge-D0GmcwL9.js";import{S,a as P,b as _,c as k,d as o}from"./select-BaKNKXoe.js";import{R as re,a as U}from"./radio-group-CKErj6Vs.js";import{T as le,a as ce,b as K,c as d,d as oe,e as m}from"./table-Db6l31H5.js";import{S as L}from"./shield-check-C2lLj34B.js";import{U as B}from"./user-plus-8010cp5U.js";import{R as de}from"./refresh-ccw-CSy1woLE.js";import{C as O}from"./circle-x-CJdobh-0.js";import{C as me}from"./circle-check-YfwMblj3.js";import{C as pe}from"./clock-CVhNAm5O.js";import{Z as xe}from"./zap-Bo6XDg7W.js";import{T as he}from"./trash-2-BVy2kP_R.js";import{f as z}from"./format-DIjAYaHL.js";import"./index-I7b3yQLw.js";import"./index-BdQq_4o_.js";import"./index-diE-tiei.js";import"./index-CCW-eNe_.js";import"./index-DgkGV3C0.js";import"./index-CJZsa5lM.js";import"./index-DalST0TR.js";import"./index-BBHh-466.js";import"./index-BNyGG0Ms.js";import"./index-Duc6mrUA.js";import"./index-BPJaiOXt.js";import"./index-0OQW4ssD.js";import"./chevron-down-CVFtQbg7.js";import"./check-CjawTMvI.js";import"./chevron-up-PBxzjLmN.js";import"./index-CfI584ZL.js";import"./circle-BoRd6xXF.js";import"./en-US-Bfz1jvxT.js";import"./differenceInCalendarDays-Dc8vopLT.js";import"./getTimezoneOffsetInMilliseconds-ldkhQntb.js";const H=[{value:"Partner",label:"Partner / Affiliate",needsCompany:!1,description:"External referral partner, no company needed"},{value:"ClientProspect",label:"Client Prospect",needsCompany:!1,description:"Sales trial — typically creates their own company"},{value:"VendorManager",label:"Vendor Manager",needsCompany:!1,description:"Runs vendor-centric events"},{value:"Admin",label:"Company Admin",needsCompany:!0,description:"Full admin access to a specific company"},{value:"EventManager",label:"Event Manager",needsCompany:!0,description:"Manages events for a specific company"},{value:"CheckInStaff",label:"Check-In Staff",needsCompany:!0,description:"Day-of staff for a specific company"},{value:"Viewer",label:"Viewer",needsCompany:!0,description:"Read-only access to a company"}],G={pending:{label:"Pending",icon:pe,className:"bg-amber-100 text-amber-800"},claimed:{label:"Claimed",icon:me,className:"bg-green-100 text-green-800"},expired:{label:"Expired",icon:O,className:"bg-slate-100 text-slate-600"},cancelled:{label:"Cancelled",icon:O,className:"bg-red-100 text-red-700"}};function es(){const x=te(),[F,T]=n.useState(""),[u,W]=n.useState("Partner"),[p,j]=n.useState("none"),[g,f]=n.useState(""),[E,M]=n.useState(""),[q,N]=n.useState(!1),[y,Z]=n.useState("pending"),C=D({queryKey:["pendingUserAssignments"],queryFn:async()=>{const s=await l.entities.PendingUserAssignment.list("-created_date",200);return Array.isArray(s)?s:[]}}),I=D({queryKey:["allCompaniesForPendingAssignments"],queryFn:async()=>{const s=await l.entities.Company.list("name",500);return Array.isArray(s)?s:[]}}),R=n.useMemo(()=>{const s=C.data||[];return y==="all"?s:s.filter(a=>a.status===y)},[C.data,y]),i=H.find(s=>s.value===u);n.useEffect(()=>{i!=null&&i.needsCompany?j("existing"):(j("none"),f(""))},[u,i==null?void 0:i.needsCompany]);const X=async s=>{var r;s.preventDefault();const a=F.trim().toLowerCase();if(!a||!a.includes("@")){t.error("Enter a valid email");return}if(p==="existing"&&!g){t.error("Please pick a company");return}N(!0);try{if((await l.entities.PendingUserAssignment.filter({email:a,status:"pending"})).length>0){t.error("A pending assignment already exists for this email. Cancel it first."),N(!1);return}const b=new Date;b.setDate(b.getDate()+90);const se=p==="existing"&&((r=(I.data||[]).find(ae=>ae.id===g))==null?void 0:r.name)||"";await l.entities.PendingUserAssignment.create({email:a,app_role:u,company_id:p==="existing"?g:"",company_name_cached:se,requires_own_company:p==="self_create",notes:E,expires_at:b.toISOString(),status:"pending",created_by_admin_email:(await l.auth.me()).email}),t.success(`Pending assignment created for ${a}`),T(""),M(""),f(""),x.invalidateQueries({queryKey:["pendingUserAssignments"]})}catch(v){console.error(v),t.error(`Failed to create: ${v.message}`)}N(!1)},Y=async s=>{try{const a=await l.functions.invoke("claimPendingUserAssignment",{email:s.email}),r=(a==null?void 0:a.data)||{};r.claimed?t.success(`Applied to ${s.email}`):t.info(r.message||r.reason||"Nothing to apply"),x.invalidateQueries({queryKey:["pendingUserAssignments"]})}catch(a){t.error(`Failed: ${a.message}`)}},J=async s=>{if(confirm(`Cancel pending assignment for ${s.email}?`))try{await l.entities.PendingUserAssignment.update(s.id,{status:"cancelled"}),t.success("Cancelled"),x.invalidateQueries({queryKey:["pendingUserAssignments"]})}catch(a){t.error(`Failed: ${a.message}`)}},ee=async s=>{if(confirm(`Permanently delete this record for ${s.email}? (Claimed records are kept for audit — only delete if necessary.)`))try{await l.entities.PendingUserAssignment.delete(s.id),t.success("Deleted"),x.invalidateQueries({queryKey:["pendingUserAssignments"]})}catch(a){t.error(`Failed: ${a.message}`)}};
1return e.jsxs("div",{className:"max-w-7xl mx-auto space-y-6",children:[e.jsxs("div",{children:[e.jsxs("h1",{className:"text-3xl font-bold flex items-center gap-2",children:[e.jsx(L,{className:"w-7 h-7 text-blue-600"}),"Pending User Assignments"]}),e.jsx("p",{className:"text-slate-600 mt-1",children:"Pre-assign roles to email addresses. When that user signs up (or already exists), the role is applied automatically. Global admin only."})]}),e.jsxs(w,{children:[e.jsx(Q,{children:e.jsxs(V,{className:"flex items-center gap-2 text-lg",children:[e.jsx(B,{className:"w-5 h-5"}),"Create New Pre-Assignment"]})}),e.jsx(A,{children:e.jsxs("form",{onSubmit:X,className:"space-y-4",children:[e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[e.jsxs("div",{children:[e.jsx(c,{htmlFor:"email",children:"Email Address"}),e.jsx(ne,{id:"email",type:"email",value:F,onChange:s=>T(s.target.value),placeholder:"[email protected]",required:!0})]}),e.jsxs("div",{children:[e.jsx(c,{htmlFor:"role",children:"Role to Assign"}),e.jsxs(S,{value:u,onValueChange:W,children:[e.jsx(P,{id:"role",children:e.jsx(_,{})}),e.jsx(k,{children:H.map(s=>e.jsx(o,{value:s.value,children:s.label},s.value))})]}),i&&e.jsx("p",{className:"text-xs text-slate-500 mt-1",children:i.description})]})]}),e.jsxs("div",{children:[e.jsx(c,{children:"Company Assignment"}),e.jsxs(re,{value:p,onValueChange:j,className:"mt-2 space-y-2",children:[e.jsxs("div",{className:"flex items-start gap-2 p-3 border rounded-md",children:[e.jsx(U,{value:"none",id:"cm-none",className:"mt-0.5"}),e.jsxs(c,{htmlFor:"cm-none",className:"font-normal cursor-pointer leading-tight",children:[e.jsx("span",{className:"font-medium block",children:"No company needed"}),e.jsx("span",{className:"text-xs text-slate-500",children:"For Partners / Affiliates — standalone external role."})]})]}),e.jsxs("div",{className:"flex items-start gap-2 p-3 border rounded-md",children:[e.jsx(U,{value:"existing",id:"cm-existing",className:"mt-0.5"}),e.jsxs(c,{htmlFor:"cm-existing",className:"font-normal cursor-pointer leading-tight",children:[e.jsx("span",{className:"font-medium block",children:"Attach to an existing company"}),e.jsx("span",{className:"text-xs text-slate-500",children:"User will be added as a member of the selected company."})]})]}),e.jsxs("div",{className:"flex items-start gap-2 p-3 border rounded-md",children:[e.jsx(U,{value:"self_create",id:"cm-self",className:"mt-0.5"}),e.jsxs(c,{htmlFor:"cm-self",className:"font-normal cursor-pointer leading-tight",children:[e.jsx("span",{className:"font-medium block",children:"User will create their own company"}),e.jsx("span",{className:"text-xs text-slate-500",children:"Role is applied; user is routed to onboarding to create their company."})]})]})]})]}),p==="existing"&&e.jsxs("div",{children:[e.jsx(c,{htmlFor:"company",children:"Select Company"}),e.jsxs(S,{value:g,onValueChange:f,children:[e.jsx(P,{id:"company",children:e.jsx(_,{placeholder:"Pick a company..."})}),e.jsx(k,{children:(I.data||[]).map(s=>e.jsx(o,{value:s.id,children:s.name},s.id))})]})]}),e.jsxs("div",{children:[e.jsx(c,{htmlFor:"notes",children:"Notes (optional)"}),e.jsx(ie,{id:"notes",value:E,onChange:s=>M(s.target.value),placeholder:"Why this pre-assignment? Context for future reference...",rows:2})]}),e.jsx("div",{className:"flex justify-end",children:e.jsxs(h,{type:"submit",disabled:q,children:[e.jsx(B,{className:"w-4 h-4 mr-2"}),q?"Creating...":"Create Pre-Assignment"]})})]})})]}),e.jsxs(w,{children:[e.jsxs(Q,{className:"flex flex-row items-center justify-between",children:[e.jsx(V,{className:"text-lg",children:"Assignments"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(S,{value:y,onValueChange:Z,children:[e.jsx(P,{className:"w-40",children:e.jsx(_,{})}),e.jsxs(k,{children:[e.jsx(o,{value:"pending",children:"Pending"}),e.jsx(o,{value:"claimed",children:"Claimed"}),e.jsx(o,{value:"expired",children:"Expired"}),e.jsx(o,{value:"cancelled",children:"Cancelled"}),e.jsx(o,{value:"all",children:"All"})]})]}),e.jsx(h,{variant:"outline",size:"icon",onClick:()=>x.invalidateQueries({queryKey:["pendingUserAssignments"]}),title:"Refresh",children:e.jsx(de,{className:"w-4 h-4"})})]})]}),e.jsx(A,{children:C.isLoading?e.jsx("p",{className:"text-sm text-slate-500",children:"Loading..."}):R.length===0?e.jsx("p",{className:"text-sm text-slate-500 py-6 text-center",children:"No assignments match this filter."}):e.jsx("div",{className:"overflow-x-auto",children:e.jsxs(le,{children:[e.jsx(ce,{children:e.jsxs(K,{children:[e.jsx(d,{children:"Email"}),e.jsx(d,{children:"Role"}),e.jsx(d,{children:"Company"}),e.jsx(d,{children:"Status"}),e.jsx(d,{children:"Created"}),e.jsx(d,{children:"Expires"}),e.jsx(d,{className:"text-right",children:"Actions"})]})}),e.jsx(oe,{children:R.map(s=>{const a=G[s.status]||G.pending,r=a.icon;return e.jsxs(K,{children:[e.jsx(m,{className:"font-medium",children:s.email}),e.jsx(m,{children:e.jsx($,{variant:"outline",children:s.app_role})}),e.jsx(m,{className:"text-sm",children:s.company_name_cached?s.company_name_cached:s.requires_own_company?e.jsx("span",{className:"text-slate-500 italic",children:"Self-create"}):e.jsx("span",{className:"text-slate-400",children:"—"})}),e.jsx(m,{children:e.jsxs($,{className:a.className,children:[e.jsx(r,{className:"w-3 h-3 mr-1"}),a.label]})}),e.jsx(m,{className:"text-xs text-slate-500",children:s.created_date?z(new Date(s.created_date),"MMM d, yyyy"):"—"}),e.jsx(m,{className:"text-xs text-slate-500",children:s.expires_at?z(new Date(s.expires_at),"MMM d, yyyy"):"—"}),e.jsxs(m,{className:"text-right space-x-1",children:[s.status==="pending"&&e.jsxs(e.Fragment,{children:[e.jsxs(h,{variant:"outline",size:"sm",onClick:()=>Y(s),title:"Try to apply now (if user already exists)",children:[e.jsx(xe,{className:"w-3 h-3 mr-1"}),"Apply Now"]}),e.jsx(h,{variant:"ghost",size:"sm",onClick:()=>J(s),children:"Cancel"})]}),e.jsx(h,{variant:"ghost",size:"icon",className:"text-red-600 hover:text-red-700",onClick:()=>ee(s),title:"Delete",children:e.jsx(he,{className:"w-3.5 h-3.5"})})]})]},s.id)})})]})})})]}),e.jsx(w,{className:"bg-blue-50 border-blue-200",children:e.jsxs(A,{className:"pt-4",children:[e.jsxs("h3",{className:"font-semibold text-blue-900 flex items-center gap-2",children:[e.jsx(L,{className:"w-4 h-4"}),"How it works"]}),e.jsxs("ul",{className:"text-sm text-blue-800 mt-2 space-y-1 list-disc pl-5",children:[e.jsx("li",{children:"When a new user signs up with a pre-assigned email, their role + company is applied automatically (one-time, on user creation only)."}),e.jsxs("li",{children:["If the user already exists, click ",e.jsx("strong",{children:"Apply Now"})," to apply retroactively."]}),e.jsx("li",{children:"Claimed records are kept for audit. Cancel a pending record 
1if you change your mind."}),e.jsx("li",{children:"Assignments expire after 90 days if unclaimed."}),e.jsxs("li",{children:["Platform admin (",e.jsx("code",{children:"User.role='admin'"}),") is intentionally NOT assignable here — keep that manual."]})]})]})})]})}export{es 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.