PageSourceSearch

https://taxease360.ai/assets/StaffSignatureRequests-DZG3HEYv.js

js taxease360.ai collected 2026-10-05 14:26:17 UTC 19,243 bytes, 6 lines download raw bytes

1import{a4 as X,r as d,j as e,a7 as G,F as J,w as P,I as O,a1 as Q,a5 as Z,t as se,q as I,p,L as ae,D as ie,C as ee,E as U,e as ne,ac as L,ag as le}from"./index-CfXbMZ_V.js";import{P as de}from"./PortalHeader-BREe-gcq.js";import{n as re}from"./notifications-9caIblD9.js";import{P as B}from"./DocumentPreviewer-DCJvCjIY.js";import{D as oe,a as ce,b as me,c as xe,d as ge}from"./dialog-D3H816yE.js";import{T as pe}from"./textarea-D5CbgVJ9.js";import{C as ue}from"./circle-check-big-9H_erV8K.js";import{C as he}from"./circle-x-DL4QWNIP.js";import{C as fe}from"./clock-DmU1_sat.js";import{R as K}from"./rotate-cw-CPY9HMVJ.js";import{A as be}from"./archive-restore-C_Z0fNFm.js";import"./chevron-left-BFeklwt6.js";import"./download-oHmw96Dk.js";function ye({request:a,open:k,onOpenChange:u,onSent:f}){const{toast:C}=X(),[v,N]=d.useState(!0),[S,x]=d.useState(!0),[r,D]=d.useState(!1),[_,b]=d.useState([]),[E,R]=d.useState(""),[$,c]=d.useState(""),[w,T]=d.useState(!1);if(d.useEffect(()=>{k&&a&&(N(!0),x(!0),D(!1),b([]),R(`Signed & completed: ${a.title||a.document_name||"Document"}`),c(`Hi,
2
3Please find attached the signed and completed copy of "${a.title||a.document_name||"document"}". This is the final version signed by all required recipients.
4
5Kind regards,
6${a.accountant_name||"your accountant"}`))},[k,a]),!a)return null;const H=Array.isArray(a.recipients)?a.recipients:[],M=()=>b(n=>[...n,{name:"",email:""}]),A=(n,m)=>b(g=>g.map((h,t)=>t===n?{...h,...m}:h)),F=n=>b(m=>m.filter((g,h)=>h!==n)),z=async()=>{var m,g,h,t;const n=_.filter(s=>{var i;return(i=s.email)==null?void 0:i.trim()});if(!v&&!S&&!r&&n.length===0){C({title:"Select at least one recipient",variant:"destructive"});return}T(!0);try{const s=await p.functions.invoke("emailSignedDocToParties",{token:a.token,to_client:v,to_all_signatories:S,to_accountant:r,additional_recipients:n,subject:E,message:$}),i=((m=s.data)==null?void 0:m.sent_count)??0,o=((g=s.data)==null?void 0:g.failed_count)??0;C({title:i>0?`Sent to ${i} recipient${i===1?"":"s"}`:"Nothing sent",description:o>0?`${o} delivery failed.`:"Completed signed document delivered.",variant:o>0?"destructive":"default"}),f==null||f(),u(!1)}catch(s){C({title:"Failed to send",description:((t=(h=s==null?void 0:s.response)==null?void 0:h.data)==null?void 0:t.error)||(s==null?void 0:s.message),variant:"destructive"})}finally{T(!1)}};return e.jsx(oe,{open:k,onOpenChange:n=>!n&&!w&&u(n),children:e.jsxs(ce,{className:"bg-card border-border text-foreground max-w-md",children:[e.jsx(me,{children:e.jsxs(xe,{className:"flex items-center gap-2",children:[e.jsx(G,{size:18,className:"text-emerald-600"}),"Email signed & completed document"]})}),e.jsxs("div",{className:"flex items-center gap-2 bg-emerald-50 border border-emerald-100 rounded-lg p-2.5 text-xs text-emerald-800",children:[e.jsx(J,{size:14,className:"shrink-0"}),e.jsxs("span",{className:"truncate",children:[a.title||a.document_name," — final signed version"]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(P,{children:"Send to"}),e.jsxs("label",{className:"flex items-center gap-2 text-sm",children:[e.jsx("input",{type:"checkbox",checked:v,onChange:n=>N(n.target.checked),className:"w-4 h-4"}),e.jsxs("span",{children:["Primary client ",e.jsxs("span",{className:"text-gray-500",children:["(",a.client_email||"no email",")"]})]})]}),H.length>1&&e.jsxs("label",{className:"flex items-center gap-2 text-sm",children:[e.jsx("input",{type:"checkbox",checked:S,onChange:n=>x(n.target.checked),className:"w-4 h-4"}),e.jsxs("span",{children:["All signatories (",H.length,")"]})]}),e.jsxs("label",{className:"flex items-center gap-2 text-sm",children:[e.jsx("input",{type:"checkbox",checked:r,onChange:n=>D(n.target.checked),className:"w-4 h-4"}),e.jsxs("span",{children:["Me / accountant ",e.jsxs("span",{className:"text-gray-500",children:["(",a.accountant_email||"",")"]})]})]}),_.map((n,m)=>e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(O,{value:n.name,onChange:g=>A(m,{name:g.target.value}),placeholder:"Name",className:"text-xs flex-1"}),e.jsx(O,{value:n.email,onChange:g=>A(m,{email:g.target.value}),placeholder:"Email",className:"text-xs flex-1"}),e.jsx("button",{onClick:()=>F(m),className:"text-rose-500 p-1","aria-label":"Remove recipient",children:e.jsx(Q,{size:14})})]},m)),e.jsxs("button",{onClick:M,className:"inline-flex items-center gap-1 text-xs font-medium text-emerald-700 bg-emerald-50 rounded-lg px-2.5 py-1.5",children:[e.jsx(Z,{size:13})," Add another recipient"]})]}),e.jsxs("div",{children:[e.jsx(P,{children:"Subject"}),e.jsx(O,{value:E,onChange:n=>R(n.target.value),className:"mt-1"})]}),e.jsxs("div",{children:[e.jsx(P,{children:"Message"}),e.jsx(pe,{value:$,onChange:n=>c(n.target.value),rows:4,className:"mt-1"})]}),e.jsx(ge,{className:"flex-col gap-2 sm:flex-col",children:e.jsxs(se,{onClick:z,disabled:w,className:"w-full bg-emerald-700 hover:bg-emerald-800 text-white",children:[w?e.jsx(I,{size:14,className:"animate-spin mr-1"}):e.jsx(ue,{size:14,className:"mr-1"}),w?"Sending…":"Send completed document"]})})]})})}const V={pending:{icon:fe,color:"text-amber-600",bg:"bg-amber-50",label:"Awaiting signature"},signed:{icon:ee,color:"text-emerald-600",bg:"bg-emerald-50",label:"Signed"},declined:{icon:he,color:"text-rose-600",bg:"bg-rose-50",label:"Declined"}},W={not_sent:{label:"Not sent",color:"text-gray-400"},sent:{label:"Sent",color:"text-amber-600"},viewed:{label:"Viewed",color:"text-blue-600"},signed:{label:"Signed",color:"text-emerald-600"},declined:{label:"Declined",color:"text-rose-600"},expired:{label:"Expired",color:"text-gray-500"},completed:{label:"Completed",color:"text-emerald-600"}};
6function Ee(){const[a,k]=d.useState(null),[u,f]=d.useState([]),[C,v]=d.useState(!0),[N,S]=d.useState("All"),[x,r]=d.useState(null),[D,_]=d.useState(null),[b,E]=d.useState(!1),[R,$]=d.useState(null),{toast:c}=X(),w=async(t,s)=>{r(t.id+"_"+s.id);try{const i=`${window.location.origin}/sign/${t.token}?rt=${s.token}`,j=`<div style="font-family:Arial,sans-serif;max-width:560px;margin:0 auto;color:#1f2937"><div style="background:linear-gradient(90deg,#1d4ed8,#06b6d4);padding:24px;border-radius:12px 12px 0 0;text-align:center"><h1 style="color:#fff;margin:0;font-size:22px">TaxEase360</h1><p style="color:#dbeafe;margin:4px 0 0;font-size:13px">A reminder to sign</p></div><div style="padding:24px;border:1px solid #e5e7eb;border-top:none;border-radius:0 0 12px 12px"><p style="margin:0 0 12px">${`Hi ${s.name||"there"},`}</p><p style="margin:0 0 12px">This is a friendly reminder that <strong>${(a==null?void 0:a.full_name)||"your accountant"}</strong> is waiting for you to sign <strong>${t.title}</strong>.</p><a href="${i}" style="display:inline-block;background:#1d4ed8;color:#fff;text-decoration:none;padding:14px 28px;border-radius:10px;font-weight:bold;font-size:15px">Review &amp; Sign Document</a><p style="margin:16px 0 0;font-size:12px;color:#9ca3af">If the button doesn't work, copy this link: ${i}</p></div></div>`;await p.functions.invoke("sendExternalEmail",{to:s.email,subject:`Reminder: ${t.title} is waiting for your signature`,from_name:(a==null?void 0:a.full_name)||"TaxEase360",html:j}),await p.entities.SignatureRequest.update(t.id,{reminder_sent_at:new Date().toISOString()}),c({title:`Reminder sent to ${s.name||s.email}`})}catch(i){c({title:"Failed to resend",description:i.message,variant:"destructive"})}finally{r(null)}},T=async t=>{r(t.id);try{const s=`${window.location.origin}/sign/${t.token}`,o=`<div style="font-family:Arial,sans-serif;max-width:560px;margin:0 auto;color:#1f2937"><div style="background:linear-gradient(90deg,#1d4ed8,#06b6d4);padding:24px;border-radius:12px 12px 0 0;text-align:center"><h1 style="color:#fff;margin:0;font-size:22px">TaxEase360</h1><p style="color:#dbeafe;margin:4px 0 0;font-size:13px">A reminder to sign</p></div><div style="padding:24px;border:1px solid #e5e7eb;border-top:none;border-radius:0 0 12px 12px"><p style="margin:0 0 12px">${t.client_name?`Hi ${t.client_name},`:"Hello,"}</p><p style="margin:0 0 12px">This is a friendly reminder that <strong>${(a==null?void 0:a.full_name)||"your accountant"}</strong> is waiting for you to sign <strong>${t.title}</strong>.</p><a href="${s}" style="display:inline-block;background:#1d4ed8;color:#fff;text-decoration:none;padding:14px 28px;border-radius:10px;font-weight:bold;font-size:15px">Review &amp; Sign Document</a><p style="margin:16px 0 0;font-size:12px;color:#9ca3af">If the button doesn't work, copy this link: ${s}</p></div></div>`;await p.functions.invoke("sendExternalEmail",{to:t.client_email,subject:`Reminder: ${t.title} is waiting for your signature`,from_name:(a==null?void 0:a.full_name)||"TaxEase360",html:o}),await p.entities.SignatureRequest.update(t.id,{reminder_sent_at:new Date().toISOString()}),await re({target_email:t.client_email,actor_name:a==null?void 0:a.full_name,type:"signature_requested",title:`Reminder: ${t.title}`,body:"Your accountant has resent a document for your signature.",client_id:t.client_id,send_email:!1,audience:"client"}),c({title:"Reminder sent to client"})}catch(s){c({title:"Failed to resend",description:s.message,variant:"destructive"})}finally{r(null)}},H=async t=>{r(t.id);try{const s=new Date().toISOString();await p.entities.SignatureRequest.update(t.id,{revoked:!0,expires_at:s}),f(i=>i.map(o=>o.id===t.id?{...o,revoked:!0,expires_at:s}:o)),c({title:"Request revoked",description:"Recipients can no longer sign this document."})}catch(s){c({title:"Failed to revoke",description:s.message,variant:"destructive"})}finally{r(null)}},M=async t=>{r(t.id);try{await p.entities.SignatureRequest.delete(t.id),f(s=>s.filter(i=>i.id!==t.id)),_(null),c({title:"Request cancelled"})}catch(s){c({title:"Failed to cancel",description:s.message,variant:"destructive"})}finally{r(null)}},A=async t=>{r(t.id);try{await p.entities.SignatureRequest.update(t.id,{archived:!0}),f(s=>s.map(i=>i.id===t.id?{...i,archived:!0}:i)),c({title:"Archived"})}catch(s){c({title:"Failed to archive",description:s.message,variant:"destructive"})}finally{r(null)}},F=async t=>{r(t.id);try{await p.entities.SignatureRequest.update(t.id,{archived:!1}),f(s=>s.map(i=>i.id===t.id?{...i,archived:!1}:i))}catch(s){c({title:"Failed to restore",description:s.message,variant:"destructive"})}finally{r(null)}},z=d.useCallback(async()=>{v(!0);try{const t=await p.auth.me();k(t);const s=await p.entities.SignatureRequest.filter({accountant_email:t.email},"-requested_date",300);f(s)}finally{v(!1)}},[]);d.useEffect(()=>{z()},[z]);const n=d.useMemo(()=>{const t=new Map;return u.forEach(s=>{s.client_id&&!t.has(s.client_id)&&t.set(s.client_id,s.client_name||s.client_id)}),Array.from(t.entries()).map(([s,i])=>({id:s,name:i}))},[u]),m=N==="All"?u:u.filter(t=>t.client_id===N),g=u.filter(t=>t.archived).length,h=b?m:m.filter(t=>!t.archived);return e.jsxs("div",{className:"space-y-5 pb-10",children:[e.jsx(de,{title:"Signature Requests",subtitle:"Documents sent to clients and recipients for signing",backTo:"/staff"}),e.jsxs(ae,{to:"/staff/signatures/new",className:"flex items-center justify-center gap-2 bg-emerald-700 text-white rounded-xl p-3 active:scale-95 transition-transform",children:[e.jsx(Z,{size:16})," ",e.jsx("span",{className:"text-sm font-semibold",children:"New signature request"})]}),u.length>0&&e.jsxs(e.Fragment,{children:[e.jsxs("select",{value:N,onChange:t=>S(t.target.value),className:"w-full bg-white border border-gray-200 rounded-xl px-3 py-2.5 text-sm text-gray-800",style:{minHeight:44},children:[e.jsx("option",{value:"All",children:"All clients"}),n.map(t=>e.jsx("option",{value:t.id,children:t.name},t.id))]}),g>0&&e.jsx("button",{onClick:()=>E(t=>
6!t),className:"self-start text-xs font-medium text-slate-500",children:b?"← Hide archived":`Show archived (${g})`})]}),C?e.jsx("div",{className:"flex justify-center py-16",children:e.jsx(I,{className:"text-gray-400 animate-spin"})}):u.length===0?e.jsxs("div",{className:"flex flex-col items-center gap-3 py-12 text-center",children:[e.jsx("div",{className:"w-14 h-14 rounded-full bg-gray-100 flex items-center justify-center",children:e.jsx(ie,{size:26,className:"text-gray-400"})}),e.jsx("p",{className:"text-sm font-semibold text-gray-800",children:"No requests yet"}),e.jsx("p",{className:"text-xs text-gray-500",children:"Upload a document and send it to one or more recipients to sign."})]}):h.length===0?e.jsx("div",{className:"text-center py-12 text-gray-500",children:e.jsx("p",{className:"text-sm",children:b?"No archived requests":"No requests for this client"})}):e.jsx("div",{className:"space-y-2",children:h.map(t=>{const s=V[t.status]||V.pending,i=s.icon,o=Array.isArray(t.recipients)?t.recipients:[],j=o.length>0,te=o.filter(l=>l.status==="signed"||l.status==="completed").length,Y=t.status==="signed";return e.jsxs("div",{className:"bg-white border border-gray-100 rounded-xl p-4",children:[e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx("div",{className:`w-10 h-10 rounded-lg flex items-center justify-center shrink-0 ${s.bg}`,children:e.jsx(i,{size:18,className:s.color})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"text-sm font-semibold text-gray-900 truncate",children:t.title}),e.jsx("p",{className:"text-xs text-gray-500 truncate",children:t.client_name}),e.jsxs("p",{className:"text-xs text-gray-400 mt-0.5",children:["Sent ",t.requested_date?U(t.requested_date).format("D MMM YYYY"):"—",t.signed_at?` • Completed ${U(t.signed_at).format("D MMM YYYY")}`:"",j&&` • ${te}/${o.length} signed`,t.revoked?" • Revoked":t.expires_at?` • Expires ${U(t.expires_at).format("D MMM YYYY")}`:""]})]})]}),j&&e.jsxs("div",{className:"mt-3 pt-3 border-t border-gray-50 space-y-1.5",children:[e.jsxs("p",{className:"text-[11px] font-medium text-gray-500 flex items-center gap-1",children:[e.jsx(ne,{size:12})," Recipients ",t.signing_order==="sequential"?"(sequential)":""]}),o.map((l,y)=>{const q=W[l.status]||W.not_sent;return e.jsxs("div",{className:"flex items-center gap-2 text-xs",children:[e.jsx("span",{className:`w-5 h-5 rounded-full flex items-center justify-center text-[10px] font-bold ${l.status==="signed"||l.status==="completed"?"bg-emerald-600 text-white":l.status==="declined"?"bg-rose-500 text-white":"bg-gray-200 text-gray-500"}`,children:y+1}),e.jsxs("span",{className:"flex-1 min-w-0 truncate text-gray-700",children:[l.name,l.role&&l.role!=="Client"?` · ${l.role}`:""]}),e.jsx("span",{className:`text-[10px] font-medium ${q.color}`,children:q.label}),l.status==="sent"||l.status==="viewed"?e.jsx("button",{onClick:()=>w(t,l),disabled:x===t.id+"_"+l.id,className:"ml-1 text-emerald-700 disabled:opacity-50 p-1","aria-label":`Resend to ${l.name}`,children:x===t.id+"_"+l.id?e.jsx(I,{size:12,className:"animate-spin"}):e.jsx(K,{size:12})}):null]},l.id)})]}),t.status==="signed"&&t.field_values&&!j&&e.jsx("div",{className:"mt-3 pt-3 border-t border-gray-50 flex flex-wrap gap-3",children:Object.entries(t.field_values).slice(0,3).map(([l,y])=>typeof y=="string"&&(y.startsWith("data:image")||y.match(/^https?:\/\/.+\.(png|jpg|jpeg|webp)/i)||y.includes("/file_uploads/"))?e.jsx("img",{src:y,alt:"signature",className:"h-10 bg-white border border-gray-100 rounded object-contain"},l):e.jsx("span",{className:"text-xs text-gray-700 bg-gray-50 px-2 py-1 rounded",children:String(y)},l))}),t.status==="signed"&&t.signed_document_url&&e.jsxs("div",{className:"mt-3 pt-3 border-t border-gray-50",children:[e.jsxs("p",{className:"text-xs font-medium text-emerald-700 mb-2 flex items-center gap-1.5",children:[e.jsx(ee,{size:13})," Signed document"]}),e.jsx(B,{url:t.signed_document_url,name:`${t.document_name||t.title||"Document"} (signed)`,thumbClassName:"w-full h-32"})]}),t.document_url&&e.jsxs("div",{className:"mt-3 pt-3 border-t border-gray-50",children:[e.jsxs("p",{className:"text-xs font-medium text-gray-500 mb-2 flex items-center gap-1.5",children:[e.jsx(J,{size:13})," Document sent"]}),e.jsx(B,{url:t.document_url,name:t.document_name||t.title||"Document",thumbClassName:"w-full h-32"})]}),t.decline_reason&&t.status==="declined"&&e.jsxs("p",{className:"mt-2 text-xs text-rose-600",children:["Reason: ",t.decline_reason]}),t.archived?e.jsxs("div",{className:"mt-3 pt-3 border-t border-gray-50 flex items-center gap-2",children:[e.jsx("span",{className:"text-xs text-gray-400 flex-1",children:"Archived"}),e.jsxs("button",{onClick:()=>F(t),disabled:x===t.id,className:"flex items-center justify-center gap-1.5 text-xs font-semibold text-slate-600 bg-slate-100 rounded-lg px-3 py-2 disabled:opacity-50",style:{minHeight:36},children:[e.jsx(be,{size:14})," Restore"]})]}):t.revoked?e.jsxs("div",{className:"mt-3 pt-3 border-t border-gray-50 flex items-center gap-2",children:[e.jsx("span",{className:"text-xs text-amber-700 flex-1",children:"Revoked — recipients can no longer sign"}),e.jsxs("button",{onClick:()=>A(t),disabled:x===t.id,className:"flex items-center justify-center gap-1.5 text-xs font-semibold text-slate-500 bg-slate-50 rounded-lg px-3 py-2 disabled:opacity-50",style:{minHeight:36},children:[e.jsx(L,{size:14})," Archive"]})]}):t.status==="pending"&&D===t.id?e.jsxs("div",{className:"mt-3 pt-3 border-t border-gray-50 flex gap-2",children:[e.jsx("span",{className:"text-xs text-gray-500 self-center flex-1",children:"Delete this request?"}),e.jsx("button",{onClick:()=>M(t),disabled:x===t.id,className:"text-xs font-semibold text-white bg-rose-600 rounded-lg px-3 py-2 disabled:opacity-50",style:{minHeight:36},children:"Delete"}),e.jsx("button",{onClick:()=>_(null),className:"text-xs font-semibold text-gray-600 bg-gray-100 rounded-lg px-3 py-2",style:{minHeight:36},children:"Keep"})]}):e.jsxs("div",{className:"mt-3 pt-3 border-t border-gray-50 flex flex-wrap gap-2",children:[Y&&e.jsxs("button",{onClick:()=>$(t),className:"flex-1 flex items-center justify-center gap-1.5 text-xs font-semibold text-white bg-emerald-700 rounded-lg py-2",style:{minHeight:36},children:[e.jsx(G,{size:14})," Email signed & completed"]}),!Y&&e.jsxs(e.Fragment,{children:[!j&&e.jsxs("button",{onClick:()=>T(t),disabled:x===t.id,className:"flex-1 flex items-center justify-center gap-1.5 text-xs font-semibold text-emerald-700 bg-emerald-50 rounded-lg py-2 disabled:opacity-50",style:{minHeight:36},children:[e.jsx(K,{size:14})," ",x===t.id?"Sending…":"Resend"]}),e.jsxs("button",{onClick:()=>H(t),disabled:x===t.id,className:"flex items-center justify-center gap-1.5 text-xs font-semibold text-amber-700 bg-amber-50 rounded-lg px-3 py-2 disabled:opacity-50",style:{minHeight:36},children:[x===t.id?e.jsx(I,{size:14,className:"animate-spin"}):e.jsx(le,{size:14})," Revoke"]}),e.jsxs("button",{onClick:()=>_(t.id),className:"flex items-center justify-center gap-1.5 text-xs font-semibold text-rose-600 bg-rose-50 rounded-lg px-3 py-2",style:{minHeight:36},children:[e.jsx(Q,{size:14})," Cancel"]})]}),e.jsxs("button",{onClick:()=>A(t),disabled:x===t.id,className:`flex items-center justify-center gap-1.5 text-xs font-semibold text-slate-500 bg-slate-50 rounded-lg px-3 py-2 disabled:opacity-50 ${Y||!j?"":"flex-1"}`,style:{minHeight:36},children:[e.jsx(L,{size:14})," Archive"]})]})]},t.id)})}),e.jsx(ye,{request:R,open:!!R,onOpenChange:t=>!t&&$(null),onSent:z})]})}
6export{Ee 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.