PageSourceSearch

https://www.agencycompass360.com/assets/BulkQuotes-Dhkb4Bal.js

js agencycompass360.com collected 2026-10-09 22:01:24 UTC 16,363 bytes, 7 lines download raw bytes

1import{aE as be,j as e,u as qe,E as Ce,aa as ke,r as x,e as i,w as F,G as Se,f as M,C as p,a as j,b as f,c as y,o as se,bf as te,q as O,p as D,X as ae,L as I,bd as re,I as ne,h as U,B as k,v as le,k as Qe,s as m}from"./index-cOhCav0w.js";import{u as Te,I as Pe}from"./IndependentBlocked-CBmOClsH.js";import{P as Ae}from"./progress-D8aLLPbX.js";import{T as Fe,a as Me,b as V,c as $}from"./tabs-P4VDsRm8.js";import{T as ce,a as ie,b as v,c as n,d as oe,e as r}from"./table-BTGfwxKO.js";import{S as de,a as ue,b as me,c as xe,d as B}from"./select-CMpsylWz.js";import{A as z,a as W}from"./alert-DUBH8R6T.js";import{W as De}from"./wallet-DKJLwrR_.js";import{C as he}from"./car-HiJeHKwU.js";import{U as pe}from"./upload-rOf0qmpW.js";import{H as Ie}from"./history-60sJG3ST.js";import{D as je}from"./download-DIpaFUHi.js";import{A as Ue}from"./arrow-up-right-DS5R6nBg.js";import{C as Ve}from"./circle-check-B4Trbc87.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 $e=be("ArrowDownRight",[["path",{d:"m7 7 10 10",key:"1fmybs"}],["path",{d:"M17 7v10H7",key:"6fjiku"}]]);function Be(){const[b]=qe(),l=Ce(),{agencyId:a,isLoading:fe}=ke(),[K,G]=x.useState("50"),[q,J]=x.useState(null),[h,X]=x.useState(0),[C,ye]=x.useState("home"),[g,ge]=x.useState("csv_only"),[E,Y]=x.useState(!1);x.useEffect(()=>{const s=b.get("deposit"),t=b.get("amount");s==="success"&&t?(i.success(`Successfully added $${(parseInt(t)/100).toFixed(2)} to your wallet!`),l.invalidateQueries({queryKey:["tenant-wallet"]}),l.invalidateQueries({queryKey:["wallet-transactions"]}),window.history.replaceState({},"","/dashboard/bulk-quotes")):s==="cancelled"&&(i.info("Deposit cancelled"),window.history.replaceState({},"","/dashboard/bulk-quotes"))},[b,l]);const{data:N,isLoading:Ne}=F({queryKey:["tenant-wallet",a],queryFn:async()=>{if(!a)return null;const{data:s,error:t}=await m.from("tenant_wallets").select("*").eq("agency_id",a).maybeSingle();if(t)throw t;return s},enabled:!!a}),{data:u}=F({queryKey:["bulk-quote-pricing"],queryFn:async()=>{const{data:s,error:t}=await m.from("bulk_quote_pricing").select("*").eq("is_active",!0);if(t)throw t;return(s==null?void 0:s.reduce((c,d)=>(c[d.quote_type]=d.price_cents,c),{}))||{home:100,auto:100}}}),{data:Z=[]}=F({queryKey:["wallet-transactions",a],queryFn:async()=>{if(!a)return[];const{data:s,error:t}=await m.from("wallet_transactions").select("*").eq("agency_id",a).order("created_at",{ascending:!1}).limit(50);if(t)throw t;return s||[]},enabled:!!a}),{data:ee=[]}=F({queryKey:["bulk-quote-jobs",a],queryFn:async()=>{if(!a)return[];const{data:s,error:t}=await m.from("bulk_quote_jobs").select("*").eq("agency_id",a).order("created_at",{ascending:!1}).limit(20);if(t)throw t;return s||[]},enabled:!!a}),H=Se({mutationFn:async s=>{const{data:t,error:c}=await m.functions.invoke("create-wallet-deposit",{body:{amount_cents:s}});if(c)throw c;return t},onSuccess:s=>{s.url&&(window.location.href=s.url)},onError:s=>{i.error(s.message)}}),_e=()=>{const s=parseFloat(K);if(isNaN(s)||s<5){i.error("Minimum deposit is $5.00");return}H.mutate(Math.round(s*100))},we=x.useCallback(s=>{var d;const t=(d=s.target.files)==null?void 0:d[0];if(!t)return;if(!t.name.endsWith(".csv")){i.error("Please upload a CSV file");return}J(t);const c=new FileReader;c.onload=T=>{var w;const P=((w=T.target)==null?void 0:w.result).split(`
7`).filter(A=>A.trim());X(Math.max(0,P.length-1))},c.readAsText(t)},[]),ve=async()=>{if(!q||!a)return;const s=(u==null?void 0:u[C])||100,t=h*s,c=(N==null?void 0:N.balance_cents)||0;if(t>c){i.error(`Insufficient balance. Need $${(t/100).toFixed(2)}, have $${(c/100).toFixed(2)}`);return}Y(!0);try{const d=await q.text(),{data:T,error:R}=await m.from("bulk_quote_jobs").insert({agency_id:a,status:"pending",total_customers:h,cost_cents:t,quote_type:C,output_mode:g,create_records:g==="csv_and_records",price_per_quote_cents:s}).select("id").single();if(R)throw R;const{error:P}=await m.rpc("deduct_wallet_balance",{p_agency_id:a,p_amount_cents:t,p_description:`Bulk ${C} quotes - ${h} customers`,p_bulk_quote_job_id:T.id});if(P)throw P;i.info(`Processing ${h} quotes... This may take several minutes.`),m.functions.invoke("process-bulk-quotes",{body:{job_id:T.id,csv_content:d,agency_id:a,output_mode:g,create_records:g==="csv_and_records"}}).then(w=>
7{var A;w.error?i.error("Quote processing failed: "+w.error.message):(i.success(`Bulk quotes completed! ${((A=w.data)==null?void 0:A.total_quoted)||0} of ${h} quoted.`),l.invalidateQueries({queryKey:["bulk-quote-jobs"]}),l.invalidateQueries({queryKey:["tenant-wallet"]}),l.invalidateQueries({queryKey:["wallet-transactions"]}))}),l.invalidateQueries({queryKey:["bulk-quote-jobs"]}),l.invalidateQueries({queryKey:["tenant-wallet"]}),l.invalidateQueries({queryKey:["wallet-transactions"]}),J(null),X(0)}catch(d){i.error(d instanceof Error?d.message:"Failed to start processing")}finally{Y(!1)}},o=s=>new Intl.NumberFormat("en-US",{style:"currency",currency:"USD"}).format(s/100);if(fe||Ne)return e.jsx("div",{className:"flex items-center justify-center h-96",children:e.jsx(M,{className:"h-8 w-8 animate-spin text-muted-foreground"})});const _=(N==null?void 0:N.balance_cents)||0,S=(u==null?void 0:u.home)||100,L=(u==null?void 0:u.auto)||100,Q=h*(C==="home"?S:L);return e.jsxs("div",{className:"space-y-6 p-6",children:[e.jsx("div",{className:"flex items-center justify-between",children:e.jsxs("div",{children:[e.jsx("h1",{className:"text-3xl font-bold",children:"Bulk Quotes"}),e.jsx("p",{className:"text-muted-foreground",children:"Upload customer lists and get competitive quotes"})]})}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-4",children:[e.jsxs(p,{className:"bg-gradient-to-br from-primary/10 to-primary/5",children:[e.jsxs(j,{className:"flex flex-row items-center justify-between pb-2",children:[e.jsx(f,{className:"text-sm font-medium",children:"Available Balance"}),e.jsx(De,{className:"h-4 w-4 text-primary"})]}),e.jsxs(y,{children:[e.jsx("div",{className:"text-3xl font-bold",children:o(_)}),e.jsxs("p",{className:"text-xs text-muted-foreground mt-1",children:["~",Math.floor(_/S)," home quotes"]})]})]}),e.jsxs(p,{children:[e.jsx(j,{className:"flex flex-row items-center justify-between pb-2",children:e.jsxs(f,{className:"text-sm font-medium flex items-center gap-2",children:[e.jsx(se,{className:"h-4 w-4"}),"Home Quote Price"]})}),e.jsxs(y,{children:[e.jsx("div",{className:"text-2xl font-bold",children:o(S)}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"per quote"})]})]}),e.jsxs(p,{children:[e.jsx(j,{className:"flex flex-row items-center justify-between pb-2",children:e.jsxs(f,{className:"text-sm font-medium flex items-center gap-2",children:[e.jsx(he,{className:"h-4 w-4"}),"Auto Quote Price"]})}),e.jsxs(y,{children:[e.jsx("div",{className:"text-2xl font-bold",children:o(L)}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"per quote"})]})]})]}),e.jsxs(Fe,{defaultValue:"upload",className:"space-y-4",children:[e.jsxs(Me,{children:[e.jsxs(V,{value:"upload",className:"gap-2",children:[e.jsx(pe,{className:"h-4 w-4"}),"Upload Quotes"]}),e.jsxs(V,{value:"fund",className:"gap-2",children:[e.jsx(te,{className:"h-4 w-4"}),"Add Funds"]}),e.jsxs(V,{value:"history",className:"gap-2",children:[e.jsx(Ie,{className:"h-4 w-4"}),"History"]}),e.jsxs(V,{value:"jobs",className:"gap-2",children:[e.jsx(O,{className:"h-4 w-4"}),"Quote Jobs"]})]}),e.jsx($,{value:"upload",children:e.jsxs(p,{children:[e.jsxs(j,{children:[e.jsx(f,{children:"Upload Customer CSV"}),e.jsx(D,{children:"Upload a CSV file with customer data to generate bulk quotes"})]}),e.jsxs(y,{className:"space-y-4",children:[_<100&&e.jsxs(z,{variant:"destructive",children:[e.jsx(ae,{className:"h-4 w-4"}),e.jsx(W,{children:"Insufficient balance. Please add funds before uploading quotes."})]}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(I,{children:"Quote Type"}),e.jsxs(de,{value:C,onValueChange:s=>ye(s),children:[e.jsx(ue,{children:e.jsx(me,{})}),e.jsxs(xe,{children:[e.jsx(B,{value:"home",children:e.jsxs("span",{className:"flex items-center gap-2",children:[e.jsx(se,{className:"h-4 w-4"}),"Home Insurance (",o(S),"/quote)"]})}),e.jsx(B,{value:"auto",children:e.jsxs("span",{className:"flex items-center gap-2",children:[e.jsx(he,{className:"h-4 w-4"}),"Auto Insurance (",o(L),"/quote)"]})})]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(I,{children:"Output Mode"}),e.jsxs(de,{value:g,onValueChange:s=>ge(s),children:[e.jsx(ue,{children:e.jsx(me,{})}),e.jsxs(xe,{children:[e.jsx(B,{value:"csv_only",children:e.jsxs("span",{className:"flex items-center gap-2",children:[e.jsx(O,{className:"h-4 w-4"}),"CSV Export Only"]})}),e.jsx(B,{value:"csv_and_records",children:e.jsxs("span",{className:"flex items-center gap-2",children:[e.jsx(re,{className:"h-4 w-4"}),"CSV + Create Leads & Clients"]})})]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(I,{children:"CSV File"}),e.jsx(ne,{type:"file",accept:".csv",onChange:we,className:"cursor-pointer"})]})]}),q&&e.jsxs("div",{className:"p-4 bg-muted rounded-lg",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(O,{className:"h-5 w-5 text-primary"}),e.jsx("span",{className:"font-medium",children:q.name})]}),e.jsxs(U,{variant:"secondary",children:[h," customers"]})]}),e.jsxs("div",{className:"mt-3 flex items-center justify-between text-sm",children:[e.jsx("span",{className:"text-muted-foreground",children:"Estimated cost:"}),e.jsx("span",{className:"font-semibold",children:o(Q)})]}),Q>_&&e.jsxs(z,{variant:"destructive",className:"mt-3",children:[e.jsx(ae,{className:"h-4 w-4"}),e.jsxs(W,{children:["Insufficient balance. You need ",o(Q-_)," more."]})]})]}),e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsxs(k,{onClick:ve,disabled:!q||Q>_||E,className:"gap-2",children:[E?e.jsx(M,{className:"h-4 w-4 animate-spin"}):e.jsx(pe,{className:"h-4 w-4"}),E?"Submitting...":"Process Quotes"]}),e.jsx(k,{variant:"outline",className:"gap-2",asChild:!0,children:e.jsxs("a",{href:"/templates/bulk-quote-template.csv",download:!0,children:[e.jsx(je,{className:"h-4 w-4"}),"Download Template"]})})]}),g==="csv_and_records"&&e.jsxs(z,{children:[e.jsx(re,{className:"h-4 w-4"}),e.jsxs(W,{children:["Records mode will create a ",e.jsx("strong",{children:"Client"})," and ",e.jsx("strong",{children:"Lead"})," for each row under your tenant, with all quotes saved to the CRM."]})]}),e.jsxs("div",{className:"border rounded-lg p-4 space-y-3",children:[e.jsx("h4",{className:"font-medium",children:"CSV Columns (flexible — missing data auto-filled via property lookup):"}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{children:[e.jsx("span",{className:"text-sm font-medium text-primary",children:"Required:"}),e.jsx("code",{className:"text-xs bg-muted p-2 rounded block mt-1",children:"first_name, last_name, address, city, state, zip"})]}),e.jsxs("div",{children:[e.jsx("span",{className:"text-sm font-medium text-muted-foreground",children:"Optional (auto-filled if missing):"}),e.jsx("code",{className:"text-xs bg-muted p-2 rounded block mt-1",children:"email, phone, year_built, sqft, construction_type, roof_year, roof_type, roof_shape, stories, dwelling_coverage, date_of_birth"})]}),e.jsxs("div",{children:[e.jsx("span",{className:"text-sm font-medium text-accent",children:"Output columns added:"}),e.jsx("code",{className:"text-xs bg-muted p-2 rounded block mt-1",children:"flood_zone, cheapest_home_carrier, cheapest_home_premium, cheapest_flood_carrier, cheapest_flood_premium, all_home_carriers"})]})]})]})]})]})}),e.jsx($,{value:"fund",children:e.jsxs(p,{children:[e.jsxs(j,{children:[e.jsx(f,{children:"Add Funds to Wallet"}),e.jsx(D,{children:"Pre-load your wallet to run bulk quotes"})]}),e.jsxs(y,{className:"space-y-4",children:[e.jsx("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-2",children:[25,50,100,250].map(s=>e.jsxs(k,{variant:K===s.toString()?"default":"outline",onClick:()=>G(s.toString()),children:["$",s]},s))}),e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsxs("div",{className:"flex-1 space-y-2",children:[e.jsx(I,{children:"Custom Amount"}),e.jsxs("div",{className:"relative",children:[e.jsx("span",{className:"absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground",children:"$"}),e.jsx(ne,{type:"number",min:"5",step:"1",value:K,onChange:s=>G(s.target.value),className:"pl-7"})]})]}),e.jsxs(k,{onClick:_e,disabled:H.isPending,size:"lg",className:"gap-2 mt-6",children:[H.isPending?e.jsx(M,{className:"h-4 w-4 animate-spin"}):e.jsx(te,{className:"h-4 w-4"}),"Pay with Card"]})]}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Payments are processed securely via Stripe. Funds are added instantly upon payment."})]})]})}),e.jsx($,{value:"history",children:e.jsxs(p,{children:[e.jsxs(j,{children:[e.jsx(f,{children:"Transaction History"}),e.jsx(D,{children:"View all deposits and charges"})]}),e.jsx(y,{children:e.jsxs(ce,{children:[e.jsx(ie,{children:e.jsxs(v,{children:[e.jsx(n,{children:"Date"}),e.jsx(n,{children:"Type"}),e.jsx(n,{children:"Description"}),e.jsx(n,{className:"text-right",children:"Amount"}),e.jsx(n,{className:"text-right",children:"Balance"})]})}),e.jsx(oe,{children:Z.length===0?e.jsx(v,{children:e.jsx(r,{colSpan:5,className:"text-center text-muted-foreground py-8",children:"No transactions yet"})}):Z.map(s=>e.jsxs(v,{children:[e.jsx(r,{children:le(new Date(s.created_at),"MMM d, yyyy h:mm a")}),e.jsx(r,{children:e.jsxs(U,{variant:s.transaction_type==="deposit"?"default":"secondary",children:[s.transaction_type==="deposit"?e.jsx($e,{className:"h-3 w-3 mr-1"}):e.jsx(Ue,{className:"h-3 w-3 mr-1"}),s.transaction_type]})}),e.jsx(r,{children:s.description}),e.jsxs(r,{className:`text-right font-medium ${s.amount_cents>=0?"text-green-600":"text-red-600"}`,children:[s.amount_cents>=0?"+":"",o(s.amount_cents)]}),e.jsx(r,{className:"text-right",children:o(s.balance_after_cents)})]},s.id))})]})})]})}),e.jsx($,{value:"jobs",children:e.jsxs(p,{children:[e.jsxs(j,{children:[e.jsx(f,{children:"Quote Jobs"}),e.jsx(D,{children:"View status of your bulk quote processing jobs"})]}),e.jsx(y,{children:e.jsxs(ce,{children:[e.jsx(ie,{children:e.jsxs(v,{children:[e.jsx(n,{children:"Date"}),e.jsx(n,{children:"Status"}),e.jsx(n,{children:"Type"}),e.jsx(n,{children:"Mode"}),e.jsx(n,{className:"text-right",children:"Customers"}),e.jsx(n,{className:"text-right",children:"Cost"}),e.jsx(n,{children:"Actions"})]})}),e.jsx(oe,{children:ee.length===0?e.jsx(v,{children:e.jsx(r,{colSpan:7,className:"text-center text-muted-foreground py-8",children:"No quote jobs yet. Upload a CSV to get started."})}):ee.map(s=>e.jsxs(v,{children:[e.jsx(r,{children:le(new Date(s.created_at),"MMM d, yyyy")}),e.jsx(r,{children:e.jsxs(U,{variant:s.status==="completed"?"default":s.status==="processing"?"secondary":s.status==="failed"?"destructive":"outline",children:[s.status==="completed"&&e.jsx(Ve,{className:"h-3 w-3 mr-1"}),s.status==="processing"&&e.jsx(M,{className:"h-3 w-3 mr-1 animate-spin"}),s.status==="pending"&&e.jsx(Qe,{className:"h-3 w-3 mr-1"}),s.status]})}),e.jsx(r,{className:"capitalize",children:s.quote_type||"home"}),e.jsx(r,{children:e.jsx(U,{variant:s.create_records?"default":"outline",className:"text-xs",children:s.create_records?"CSV + Records":"CSV Only"})}),e.jsxs(r,{className:"text-right",children:[s.processed_customers," / ",s.total_customers]}),e.jsx(r,{className:"text-right",children:o(s.cost_cents)}),e.jsxs(r,{children:[s.status==="completed"&&s.output_file_path&&e.jsxs(k,{variant:"ghost",size:"sm",className:"gap-1",onClick:async()=>{const{data:t}=await m.storage.from("documents").createSignedUrl(s.output_file_path,3600);t!=null&&t.signedUrl?window.open(t.signedUrl,"_blank"):i.error("Failed to generate download link")},children:[e.jsx(je,{className:"h-3 w-3"}),"Download"]}),s.status==="processing"&&e.jsx(Ae,{value:s.processed_customers/s.total_customers*100,className:"w-20"})]})]},s.id))})]})})]})})]})]})}function ss(b){const{blocked:l}=Te();return l?e.jsx(Pe,{what:"Bulk quoting"}):e.jsx(Be,{...b})}export{ss 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.