1import{c as I,r as p,s as L,j as e,L as w,d as R,X as G,i as W}from"./index-IZnvRumJ.js";import{u as X,A as K,a as J,b as Q,c as Y,C as Z,L as ee}from"./AppLayout-cVkycFLS.js";import{C as b,a as N,b as _,c as k,d as j}from"./card-BWWzAZHh.js";import{B as m}from"./button-DcP8iMA9.js";import{L as te}from"./LPSetupChecklist-DxC5cJNm.js";import{B as $}from"./badge-CDTGuZL7.js";import{U as se}from"./users-HfDtNntb.js";import{D as ae}from"./dollar-sign-CpgVierP.js";import{C as re}from"./clock-CgINlRZu.js";import{T as O}from"./triangle-alert-B8sOFBAg.js";import{C as ie}from"./circle-x-Bkg0PfRg.js";import{E as z}from"./external-link-1LE5Lgze.js";import{C as ne}from"./check-C2pnSUS4.js";import{A as F}from"./arrow-right-C8S3duny.js";import{F as oe}from"./file-text-CZEMuyyH.js";import{S as le}from"./send-MRCX-zBf.js";import{E as ce}from"./eye-BaRUKt7b.js";import{T as de}from"./thumbs-up-ILZjmBn8.js";import{C as E}from"./circle-check-CJPteXk5.js";import{C as me}from"./credit-card-Dge_IzRx.js";import{M as pe}from"./mail-Rp6evAGI.js";import{F as ue}from"./file-pen-line-DkW7k01H.js";import{C as q}from"./circle-plus-HJRNrV0j.js";import{b as he}from"./sheet-zYE83Wug.js";import{G as xe}from"./graduation-cap-25AkShwK.js";import"./input-OGCcGVWJ.js";import"./skeleton-D7D6JDZR.js";import"./mysteryShopperBrand-BYkn7pdw.js";import"./mysterycallai-logo-dark-BFNFGS3B.js";import"./useTier-BULoQlR6.js";import"./dropdown-menu-DqOrHu2j.js";import"./index-BmRzOyoq.js";import"./index-MH1WVYsB.js";import"./index-BlZBv0Jc.js";import"./chevron-right-QiugxkLR.js";import"./chevron-down-1nMbKwc_.js";import"./chart-column-CsqJFWcn.js";import"./bot-BQdRaamy.js";import"./target-tsid7M2N.js";import"./swords-CyoFjmFq.js";import"./calculator-Pwff5vj0.js";import"./phone-call-Dm3n_iYk.js";import"./useQuery-DHnKGTyB.js";import"./lpInvoke-Ds_Z-Vno.js";import"./shield-ebKOM8r4.js";import"./building-2-TavQYcI3.js";import"./crown-CGzwbtTd.js";import"./search-9X0la83E.js";import"./trending-up-DZRNf4zr.js";import"./globe-CwLKkDOx.js";import"./lightbulb-uxg2Rvra.js";import"./palette-D2KBmLK0.js";import"./layout-dashboard-D4Xc7vFm.js";import"./book-open-C7ggllaI.js";import"./circle-help-LlvxE_IR.js";import"./alert-dialog-BrhGOoeP.js";import"./dialog-RI8CE1mU.js";import"./label-CoGXWevP.js";import"./select-Ds0eJjSi.js";import"./index-DyIwh2Qx.js";import"./chevron-up-CcQezlK8.js";import"./plus-GBlIdfW8.js";import"./types-C-jxggw2.js";import"./publicUrl-bjBORCqm.js";import"./progress-C5fUdYfo.js";import"./rocket-CGVlk8C7.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 ge=I("RefreshCcw",[["path",{d:"M21 12a9 9 0 0 0-9-9 9.75 9.75 0 0 0-6.74 2.74L3 8",key:"14sxne"}],["path",{d:"M3 3v5h5",key:"1xhq8a"}],["path",{d:"M3 12a9 9 0 0 0 9 9 9.75 9.75 0 0 0 6.74-2.74L21 16",key:"1hlbsb"}],["path",{d:"M16 16h5v5",key:"ccwih5"}]]);function D(a,c="usd"){return new Intl.NumberFormat("en-US",{style:"currency",currency:c.toUpperCase(),maximumFractionDigits:0}).format(a/100)}function B(a){return Math.floor((Date.now()-new Date(a).getTime())/864e5)}function fe({agencyId:a}){const[c,v]=p.useState(!0),[d,g]=p.useState([]),[u,C]=p.useState([]),[A,T]=p.useState(0),h=X(a);p.useEffect(()=>{if(!a)return;let t=!1;return v(!0),(async()=>{const s=new Date(Date.now()-2592e6).toISOString(),[l,n]=await Promise.all([L.from("lp_proposals").select("id, business_name, customer_name, customer_email, status, total_setup_cents, total_recurring_cents, recurring_interval, currency, sent_at, paid_at, created_at, public_token").eq("agency_id",a).order("created_at",{ascending:!1}).limit(500),L.from("lp_proposal_events").select("id, proposal_id, event_type, event_data, created_at").eq("agency_id",a).in("event_type",["payment_failed","checkout_error"]).gte("created_at",s).order("created_at",{ascending:!1}).limit(50)]);t||(g(l.data||[]),C(n.data||[]),v(!1))})(),()=>{t=!0}},[a,A]);const f=p.useMemo(()=>u.filter(t=>{var s;return!((s=t.event_data)!=null&&s.resolved_at)}),[u]),r=p.useMemo(()=>{const t=d.filter(i=>i.status==="paid"),s=t.reduce((i,y)=>y.recurring_interval==="month"?i+(y.total_recurring_cents||0):y.recurring_interval==="year"?i+Math.round((y.total_recurring_cents||0)/12):i,0),l=t.reduce((i,y)=>i+(y.total_setup_cents||0),0),n=d.filter(i=>i.status==="draft"),o=d.filter(i=>i.status==="sent"),x=d.filter(i=>i.status==="viewed"),P=d.filter(i=>i.status==="accepted"),M=d.filter(i=>["sent","viewed","accepted"].includes(i.status)),H=M.filter(i=>i.sent_at&&B(i.sent_at)>7);return{paidCount:t.length,mrrCents:s,oneTimeCents:l,drafts:n,sent:o,viewed:x,accepted:P,awaiting:M,stale:H,failures:f}},[d,f]);async function U(t){const s=u.find(o=>o.id===t);if(!s)return;const l={...s.event_data||{},resolved_at:new Date().toISOString()};C(o=>o.map(x=>x.id===t?{...x,event_data:l}:x));const{error:n}=await L.from("lp_proposal_events").update({event_data:l}).eq("id",t);n?(R.error("Could not mark as resolved"),T(o=>o+1)):R.success("Marked as resolved")}if(!a)return null;const S=({icon:t,label:s,value:l,sub:n,tone:o="default"})=>e.jsx(b,{className:o==="danger"?"border-destructive/40":o==="warning"?"border-amber-500/40":"border-border",children:e.jsx(j,{className:"p-4",children:e.jsxs("div",{className:"flex items-start justify-between",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-xs uppercase tracking-wide text-muted-foreground",children:s}),e.jsx("div",{className:"text-2xl font-bold mt-1",children:l}),n&&e.jsx("div",{className:"text-xs text-muted-foreground mt-1",children:n})]}),e.jsx("div",{className:`p-2 rounded-md ${o==="danger"?"bg-destructive/10 text-destructive":o==="warning"?"bg-amber-500/10 text-amber-600":"bg-primary/10 text-primary"}`,children:e.jsx(t,{className:"h-5 w-5"})})]})})}),V=[{key:"stripe",ok:h.stripeConnected?h.webhookActive:null,label:h.stripeConnected?h.webhookActive?"Stripe + webhook":"Str
6ipe webhook down":"Stripe not connected",icon:me,to:"/dashboard/localproposal/settings"},{key:"email",ok:h.emailVerified,label:h.emailVerified?"Sending domain verified":"Sending domain not verified",icon:pe,to:"/dashboard/localproposal/settings"},{key:"payment",ok:h.paymentMethodConfigured,label:h.paymentMethodConfigured?`Payment method: ${h.paymentMethod}`:"Payment method incomplete",icon:E,to:"/dashboard/localproposal/settings"}];return e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"grid gap-3 sm:grid-cols-2 lg:grid-cols-4",children:[e.jsx(S,{icon:se,label:"Paying customers",value:c?"â¦":r.paidCount,sub:r.paidCount>0?`${D(r.oneTimeCents)} one-time collected`:"None yet"}),e.jsx(S,{icon:ae,label:"Recurring MRR",value:c?"â¦":D(r.mrrCents),sub:"Normalized from monthly + yearly"}),e.jsx(S,{icon:re,label:"Awaiting action",value:c?"â¦":r.awaiting.length,sub:r.accepted.length?`${r.accepted.length} accepted · awaiting payment`:r.stale.length?`${r.stale.length} over 7 days old`:"Sent · viewed · accepted",tone:r.accepted.length||r.stale.length?"warning":"default"}),e.jsx(S,{icon:O,label:"Failed payments (30d)",value:c?"â¦":f.length,sub:f.length?"Click card below to review":"None",tone:f.length?"danger":"default"})]}),f.length>0&&e.jsxs(b,{id:"failed-payments",className:"border-destructive/40",children:[e.jsxs(N,{className:"pb-3",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(ie,{className:"h-4 w-4 text-destructive"}),e.jsx(_,{className:"text-base text-destructive",children:"Failed payments â last 30 days"})]}),e.jsx(k,{children:"A prospect tried to pay and Stripe rejected the card, or the checkout crashed before we could redirect. Reach out and offer a fresh link, then mark it resolved."})]}),e.jsx(j,{className:"space-y-2",children:f.slice(0,10).map(t=>{var n,o;const s=d.find(x=>x.id===t.proposal_id),l=String(((n=t.event_data)==null?void 0:n.message)||((o=t.event_data)==null?void 0:o.stage)||t.event_type).slice(0,120);return e.jsxs("div",{className:"flex items-start justify-between gap-3 rounded-md border border-destructive/20 bg-destructive/5 p-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"text-sm font-medium truncate",children:[(s==null?void 0:s.customer_name)||(s==null?void 0:s.business_name)||"Unknown prospect",(s==null?void 0:s.customer_email)&&e.jsxs("span",{className:"text-muted-foreground font-normal",children:[" · ",s.customer_email]})]}),e.jsxs("div",{className:"text-xs text-muted-foreground mt-0.5",children:[e.jsx($,{variant:"outline",className:"mr-2 text-[10px]",children:t.event_type}),l," · ",new Date(t.created_at).toLocaleString()]})]}),e.jsxs("div",{className:"flex items-center gap-2 shrink-0",children:[(s==null?void 0:s.public_token)&&e.jsx(m,{asChild:!0,size:"sm",variant:"outline",children:e.jsxs("a",{href:`https://lclproposal.com/p/${s.public_token}`,target:"_blank",rel:"noreferrer",children:[e.jsx(z,{className:"h-3.5 w-3.5 mr-1"})," Open"]})}),e.jsxs(m,{size:"sm",variant:"ghost",onClick:()=>U(t.id),className:"text-emerald-600 hover:text-emerald-700 hover:bg-emerald-500/10",children:[e.jsx(ne,{className:"h-3.5 w-3.5 mr-1"})," Resolve"]})]})]},t.id)})})]}),e.jsxs(b,{children:[e.jsx(N,{className:"pb-3",children:e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx(_,{className:"text-base",children:"Proposal pipeline"}),e.jsx(k,{children:"Where every proposal stands right now."})]}),e.jsx(m,{asChild:!0,size:"sm",variant:"outline",className:"gap-1",children:e.jsxs(w,{to:"/dashboard/localproposal/proposals",children:["View proposals ",e.jsx(F,{className:"h-3.5 w-3.5"})]})})]})}),e.jsx(j,{children:e.jsx("div",{className:"grid gap-2 sm:grid-cols-3 lg:grid-cols-5",children:[{label:"Drafts",value:r.drafts.length,icon:oe,tone:"muted"},{label:"Sent",value:r.sent.length,icon:le,tone:"muted"},{label:"Viewed",value:r.viewed.length,icon:ce,tone:"muted"},{label:"Accepted · awaiting payment",value:r.accepted.length,icon:de,tone:r.accepted.length?"warning":"muted"},{label:"Paid",value:r.paidCount,icon:E,tone:r.paidCount?"good":"muted"}].map(t=>
6{const s=t.icon,l=t.tone==="warning"?"border-amber-500/40 bg-amber-500/5":t.tone==="good"?"border-emerald-500/40 bg-emerald-500/5":"border-border";return e.jsxs("div",{className:`rounded-md border p-3 ${l}`,children:[e.jsxs("div",{className:"flex items-center gap-2 text-xs uppercase tracking-wide text-muted-foreground",children:[e.jsx(s,{className:"h-3.5 w-3.5"})," ",t.label]}),e.jsx("div",{className:"text-2xl font-bold mt-1",children:c?"â¦":t.value})]},t.label)})})})]}),r.awaiting.length>0&&e.jsxs(b,{children:[e.jsx(N,{className:"pb-3",children:e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx(_,{className:"text-base",children:"Awaiting your attention"}),e.jsx(k,{children:"Sent, viewed, or accepted but not paid yet. Accepted means the prospect signed off â nudge them to complete payment."})]}),e.jsx(m,{asChild:!0,size:"sm",variant:"ghost",className:"gap-1",children:e.jsxs(w,{to:"/dashboard/localproposal/proposals",children:["All proposals ",e.jsx(F,{className:"h-3.5 w-3.5"})]})})]})}),e.jsx(j,{className:"space-y-2",children:r.awaiting.slice(0,8).map(t=>{const s=t.sent_at?B(t.sent_at):0,l=s>7,n=t.status==="accepted",o=n?"default":t.status==="viewed"?"secondary":"outline",x=n||l?"border-amber-500/40 bg-amber-500/5":"",P=n?"accepted · awaiting payment":t.status;return e.jsxs("div",{className:`flex items-center justify-between gap-3 rounded-md border p-3 ${x}`,children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"text-sm font-medium truncate",children:[t.customer_name||t.business_name,e.jsxs("span",{className:"text-muted-foreground font-normal",children:[" · ",D((t.total_setup_cents||0)+(t.total_recurring_cents||0),t.currency)]})]}),e.jsxs("div",{className:"text-xs text-muted-foreground mt-0.5",children:[e.jsx($,{variant:o,className:"mr-2 text-[10px]",children:P}),t.sent_at?`${s}d since sent`:"Not sent yet"]})]}),e.jsxs("div",{className:"flex items-center gap-2 shrink-0",children:[n&&t.public_token&&e.jsx(m,{asChild:!0,size:"sm",variant:"outline",children:e.jsxs("a",{href:`https://lclproposal.com/p/${t.public_token}`,target:"_blank",rel:"noreferrer",children:[e.jsx(z,{className:"h-3.5 w-3.5 mr-1"})," Payment link"]})}),e.jsx(m,{asChild:!0,size:"sm",variant:"outline",children:e.jsx(w,{to:"/dashboard/localproposal/proposals",children:"Manage"})})]})]},t.id)})})]}),e.jsxs(b,{children:[e.jsx(N,{className:"pb-3",children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(_,{className:"text-base",children:"System health"}),e.jsx(k,{children:"Live status of the rails your proposals depen
6d on."})]}),e.jsxs(m,{variant:"ghost",size:"sm",onClick:()=>T(t=>t+1),className:"gap-1",children:[e.jsx(ge,{className:"h-3.5 w-3.5"})," Refresh"]})]})}),e.jsx(j,{className:"flex flex-wrap gap-2",children:V.map(t=>{const s=t.icon,l=t.ok===!0,n=t.ok===!1||t.ok===null;return e.jsxs(w,{to:t.to,className:`inline-flex items-center gap-2 rounded-md border px-3 py-1.5 text-xs font-medium transition-colors hover:opacity-90 ${l?"border-emerald-500/40 bg-emerald-500/10 text-emerald-600":"border-amber-500/40 bg-amber-500/10 text-amber-600"}`,children:[e.jsx(s,{className:"h-3.5 w-3.5"}),t.label,n&&e.jsx("span",{className:"opacity-70",children:"â Fix"})]},t.key)})})]})]})}function be({agencyId:a}){const[c,v]=p.useState(0),[d,g]=p.useState(null);if(p.useEffect(()=>{if(!a)return;g(localStorage.getItem(`lp-fail-banner-dismissed-${a}`));const C=new Date(Date.now()-7*864e5).toISOString();L.from("lp_proposal_events").select("id",{count:"exact",head:!0}).eq("agency_id",a).in("event_type",["payment_failed","checkout_error"]).gte("created_at",C).then(({count:A})=>v(A||0))},[a]),!a||c===0)return null;const u=`${a}-${c}`;return d===u?null:e.jsxs(K,{variant:"destructive",className:"border-2",children:[e.jsx(O,{className:"h-5 w-5"}),e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{className:"flex-1",children:[e.jsxs(J,{className:"text-base font-bold",children:["ð¨ ",c," payment",c===1?"":"s"," failed in the last 7 days"]}),e.jsxs(Q,{className:"mt-1 space-y-2",children:[e.jsx("p",{className:"text-sm",children:"A prospect tried to pay you and Stripe rejected the card or the checkout crashed. Review the failures below and send a fresh link before they go cold."}),e.jsx(m,{size:"sm",variant:"outline",asChild:!0,children:e.jsx("a",{href:"#failed-payments",children:"Review failures"})})]})]}),e.jsx(m,{variant:"ghost",size:"icon",className:"shrink-0 h-7 w-7",onClick:()=>{localStorage.setItem(`lp-fail-banner-dismissed-${a}`,u),g(u)},children:e.jsx(G,{className:"h-4 w-4"})})]})]})}function Dt(){const{agencyId:a}=W(),c=[{title:"New Proposal",description:"Look up a business and generate an AI draft.",to:"/dashboard/localproposal/new",icon:q},{title:"Proposals",description:"Track drafts, sent, viewed, and paid proposals.",to:"/dashboard/localproposal/proposals",icon:Z},{title:"Package Templates",description:"Reusable service bundles the wizard can drop in.",to:"/dashboard/localproposal/templates",icon:ee},{title:"Settings & Stripe",description:"Connect your Stripe and configure the hosted brand.",to:"/dashboard/localproposal/settings",icon:he},{title:"Training",description:"How to run high-close proposals with LocalProposal.",to:"/dashboard/localproposal/training",icon:xe}];return e.jsx(Y,{userRole:"agency_admin",pageTitle:"LocalProposal",pageDescription:"AI-drafted proposals your customers accept and pay â on your brand, your payment rail (Stripe, external link, or offline).",onAgencyCreated:()=>{},children:e.jsxs("div",{className:"space-y-6",children:[e.jsx(be,{agencyId:a??null}),e.jsxs(b,{className:"border-primary/30 bg-gradient-card",children:[e.jsx(N,{children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"p-3 rounded-lg bg-primary/10",children:e.jsx(ue,{className:"h-6 w-6 text-primary"})}),e.jsxs("div",{children:[e.jsx(_,{children:"Welcome to LocalProposal"}),e.jsx(k,{children:"Turn a business lookup into a branded, hosted proposal your customer can accept and pay in one click."})]})]})}),e.jsx(j,{children:e.jsx(m,{asChild:!0,size:"lg",children:e.jsxs(w,{to:"/dashboard/localproposal/new",children:[e.jsx(q,{className:"mr-2 h-4 w-4"}),"Start a new proposal"]})})})]}),e.jsx(te,{agencyId:a??null}),e.jsx("div",{id:"failed-payments",children:e.jsx(fe,{agencyId:a??null})}),e.jsx("div",{className:"grid gap-4 sm:grid-cols-2 lg:grid-cols-3",children:c.map(({title:v,description:d,to:g,icon:u})=>e.jsxs(b,{className:"hover:border-primary/50 transition-colors",children:[e.jsxs(N,{className:"pb-3",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(u,{className:"h-5 w-5 text-primary"}),e.jsx(_,{className:"text-base",children:v})]}),e.jsx(k,{children:d})]}),e.jsx(j,{children:e.jsx(m,{asChild:!0,variant:"outline",size:"sm",children:e.jsx(w,{to:g,children:"Open"})})})]},g))})]})})}export{Dt 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.