1import{h as e,r as s,j as a,_ as t,B as n,a5 as l,aG as r,P as o,a6 as i,bf as c,bl as d,aP as m,a3 as x,I as u,a8 as h,a9 as p,aa as j,ab as g,T as f,X as b,s as v,d as y,i as N,L as w,$ as _,q as C}from"./index--fmOKDlP.js";import{S,a as k,b as A,c as B,d as P}from"./select-BBq4ylW6.js";import{f as $}from"./formatCurrency-B_rgjc7Z.js";import{S as L}from"./scan-Ffi3H6Cf.js";import{a as M,Z as z,o as R,s as D,l as E,_ as W}from"./schemas-CpBdNpBU.js";import"./pdf-DgJZEHwN.js";import"./index-DE3j0vFP.js";import"./chevron-up-DSVr7d2p.js";const G="#F97316",I="#10B981",O="#F59E0B",U="#EF4444",F=["Basic","Starter","Pro","Agency"],T=R({business_name:D().trim().min(1,"Required").max(120),owner_name:D().trim().max(120).optional().or(E("")),phone:D().trim().max(20).optional().or(E("")),whatsapp:D().trim().max(20).optional().or(E("")),email:D().trim().email("Invalid email").max(255).optional().or(E("")),category:D().trim().max(80).optional().or(E("")),gbp_url:D().trim().max(500).optional().or(E("")),city:D().trim().max(80).optional().or(E("")),area:D().trim().max(80).optional().or(E("")),plan:W(F),monthly_fee:M(z,void 0).min(0).max(1e7),notes:D().trim().max(1e3).optional().or(E(""))});const q={business_name:"",owner_name:"",phone:"",whatsapp:"",email:"",category:"",gbp_url:"",city:"",area:"",plan:"Basic",monthly_fee:2999,notes:""};function Z(e){return e?new Date(e).toLocaleDateString("en-IN",{day:"2-digit",month:"short",year:"numeric",timeZone:"Asia/Kolkata"}):"â"}function H(e){return e>=75?I:e>=50?O:U}function V(){const{user:N}=e(),[w,_]=s.useState([]),[C,M]=s.useState(!0),[z,R]=s.useState(!1),[D,E]=s.useState(""),[W,O]=s.useState(q),[U,V]=s.useState(!1),X=async()=>{if(!N)return;M(!0);const{data:e,error:s}=await v.from("clients").select("*").eq("user_id",N.id).order("created_at",{ascending:!1});s&&y.error(s.message),_(e||[]),M(!1)};s.useEffect(()=>{X()},[N?.id]);const se=s.useMemo(()=>{const e=D.trim().toLowerCase();return e?w.filter(s=>s.business_name.toLowerCase().includes(e)||(s.owner_name||"").toLowerCase().includes(e)||(s.city||"").toLowerCase().includes(e)):w},[w,D]),ae=s.useMemo(()=>{const e=w.filter(e=>e.is_active),s=e.reduce((e,s)=>e+Number(s.monthly_fee||0),0),a=w.length?Math.round(w.reduce((e,s)=>e+(s.gbp_score||0),0)/w.length):0,t=new Date;t.setDate(1),t.setHours(0,0,0,0);const n=w.filter(e=>e.last_scan_at&&new Date(e.last_scan_at)>=t).length;return{total:w.length,active:e.length,revenue:s,avgScore:a,scansThisMonth:n}},[w]),te=async e=>{window.location.href=`/audit?business=${encodeURIComponent(e.business_name)}`,y.info("Opening Audit Engine for a verified scan...")},ne=e=>{const s=(e.whatsapp||e.phone||"").replace(/\D/g,"");if(!s)return void y.error("No WhatsApp number on file");const a=encodeURIComponent(`Hi ${e.owner_name||e.business_name}, this is a quick update on your Google Business Profile from MapRanker.`);window.open(`https://wa.me/${s}?text=${a}`,"_blank","noopener")};return a.jsx(t,{children:a.jsxs("div",{className:"p-6 space-y-6",children:[a.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[a.jsxs("div",{children:[a.jsx("h1",{className:"text-3xl font-bold text-foreground",children:"Client Manager"}),a.jsx("p",{className:"text-sm text-muted-foreground",children:"Manage all your agency clients in one place"})]}),a.jsxs("div",{className:"flex gap-2",children:[a.jsxs(n,{variant:"outline",size:"sm",onClick:()=>{if(!w.length)return void y.error("No clients to export");const e=[["Business","Owner","Phone","WhatsApp","Email","City","Plan","Monthly Fee","GBP Score","Status","Last Scan","Next Due"],...w.map(e=>[e.business_name,e.owner_name||"",e.phone||"",e.whatsapp||"",e.email||"",e.city||"",e.plan,e.monthly_fee,e.gbp_score||0,e.payment_status,Z(e.last_scan_at),Z(e.next_due_at)])].map(e=>e.map(e=>`"${String(e).replace(/"/g,'""')}"`).join(",")).join("\n"),s=new Blob([e],{type:"text/csv;charset=utf-8"}),a=URL.createObjectURL(s),t=document.createElement("a");t.href=a,t.download=`clients-${Date.now()}.csv`,t.click(),URL.revokeObjectURL(a)},children:[a.jsx(l,{className:"h-4 w-4"})," Export CSV"]}),a.jsxs(n,{variant:"outline",size:"sm",onClick:async()=>{N&&w.length&&(y.info(`Redirecting to Audit Engine for ${w.length} clientsâ¦`),window.location.href="/audit")},children:[a.jsx(L,{className:"h-4 w-4"})," Bulk Scan"]}),a.jsxs(n,{variant:"outline",size:"sm",onClick:()=>{const e=w.filter(e=>e.whatsapp||e.phone).length;y.success(`Opening WhatsApp Web â ${e} contacts ready`),window.open("https://web.whatsapp.com/","_blank","noopener")},children:[a.jsx(r,{className:"h-4 w-4"})," Bulk WhatsApp"]}),a.jsxs(n,{onClick:()=>R(!0),style:{background:G,color:"#fff"},children:[a.jsx(o,{className:"h-4 w-4"})," Add New Client"]})]})]}
1),a.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-5 gap-4",children:[a.jsx(J,{icon:a.jsx(i,{size:18}),label:"Total Clients",value:String(ae.total)}),a.jsx(J,{icon:a.jsx(c,{size:18}),label:"Active",value:String(ae.active),color:I}),a.jsx(J,{icon:a.jsx(d,{size:18}),label:"Monthly Revenue",value:$(ae.revenue),color:G}),a.jsx(J,{icon:a.jsx(m,{size:18}),label:"Avg GBP Score",value:`${ae.avgScore}/100`,color:H(ae.avgScore)}),a.jsx(J,{icon:a.jsx(L,{size:18}),label:"Scans This Month",value:String(ae.scansThisMonth)})]}),a.jsxs("div",{className:"relative max-w-md",children:[a.jsx(x,{className:"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground"}),a.jsx(u,{placeholder:"Search by business, owner, or cityâ¦",value:D,onChange:e=>E(e.target.value),className:"pl-9"})]}),C?a.jsx("div",{className:"text-sm text-muted-foreground",children:"Loading clientsâ¦"}):0===se.length?a.jsx(Y,{onAdd:()=>R(!0)}):a.jsx("div",{className:"grid sm:grid-cols-2 lg:grid-cols-3 gap-4",children:se.map(e=>a.jsx(Q,{c:e,onScan:te,onWhatsApp:ne},e.id))}),a.jsx(ee,{clients:w}),a.jsx(h,{open:z,onOpenChange:R,children:a.jsxs(p,{className:"max-w-2xl max-h-[90vh] overflow-y-auto",children:[a.jsx(j,{children:a.jsx(g,{children:"Add New Client"})}),a.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-3",children:[a.jsx(K,{label:"Business Name *",children:a.jsx(u,{value:W.business_name,onChange:e=>O({...W,business_name:e.target.value})})}),a.jsx(K,{label:"Owner Name",children:a.jsx(u,{value:W.owner_name,onChange:e=>O({...W,owner_name:e.target.value})})}),a.jsx(K,{label:"Phone",children:a.jsx(u,{value:W.phone,onChange:e=>O({...W,phone:e.target.value})})}),a.jsx(K,{label:"WhatsApp",children:a.jsx(u,{value:W.whatsapp,onChange:e=>O({...W,whatsapp:e.target.value})})}),a.jsx(K,{label:"Email",children:a.jsx(u,{type:"email",value:W.email,onChange:e=>O({...W,email:e.target.value})})}),a.jsx(K,{label:"Business Category",children:a.jsx(u,{value:W.category,onChange:e=>O({...W,category:e.target.value})})}),a.jsx(K,{label:"GBP URL",full:!0,children:a.jsx(u,{value:W.gbp_url,onChange:e=>O({...W,gbp_url:e.target.value})})}),a.jsx(K,{label:"City",children:a.jsx(u,{value:W.city,onChange:e=>O({...W,city:e.target.value})})}),a.jsx(K,{label:"Area",children:a.jsx(u,{value:W.area,onChange:e=>O({...W,area:e.target.value})})}),a.jsx(K,{label:"Current Plan",children:a.jsxs(S,{value:W.plan,onValueChange:e=>O({...W,plan:e}),children:[a.jsx(k,{children:a.jsx(A,{})}),a.jsx(B,{children:F.map(e=>a.jsx(P,{value:e,children:e},e))})]})}),a.jsx(K,{label:"Monthly Fee (â¹)",children:a.jsx(u,{type:"number",value:String(W.monthly_fee??""),onChange:e=>O({...W,monthly_fee:Number(e.target.value)})})}),a.jsx(K,{label:"Notes",full:!0,children:a.jsx(f,{rows:3,value:W.notes,onChange:e=>O({...W,notes:e.target.value})})})]}),a.jsxs("div",{className:"flex justify-end gap-2 mt-2",children:[a.jsxs(n,{variant:"outline",onClick:()=>R(!1),children:[a.jsx(b,{className:"h-4 w-4"})," Cancel"]}),a.jsx(n,{onClick:async()=>{if(!N)return;const e=T.safeParse(W);if(!e.success)return void y.error(e.error.issues[0]?.message||"Invalid input");V(!0);const s=e.data,{error:a}=await v.from("clients").insert({user_id:N.id,business_name:s.business_name,owner_name:s.owner_name||null,phone:s.phone||null,whatsapp:s.whatsapp||null,email:s.email||null,category:s.category||null,gbp_url:s.gbp_url||null,city:s.city||null,area:s.area||null,plan:s.plan,monthly_fee:s.monthly_fee,notes:s.notes||null});V(!1),a?y.error(a.message):(y.success("Client added"),R(!1),O(q),X())},disabled:U,style:{background:G,color:"#fff"},children:U?"Savingâ¦":"Save Client"})]})]})})]})})}function K({label:e,full:s,children:t}){return a.jsxs("div",{className:s?"md:col-span-2":"",children:[a.jsx(N,{className:"text-xs text-muted-foreground",children:e}),a.jsx("div",{className:"mt-1",children:t})]})}function J({icon:e,label:s,value:t,color:n}){return a.jsxs("div",{className:"rounded-2xl border border-border/60 bg-card p-4",children:[a.jsxs("div",{className:"flex items-center gap-2 text-xs text-muted-foreground",children:[a.jsx("span",{style:{color:n||void 0},children:e}),s]}),a.jsx("div",{className:"mt-2 text-2xl font-bold",style:{color:n||void 0},children:t})]})}function Q({c:e,onScan:s,onWhatsApp:t}){return a.jsxs("div",{className:"rounded-2xl border border-border/60 bg-card p-5 flex flex-col gap-3",children:[a.jsxs("div",{className:"flex items-start justify-between",children:[a.jsxs("div",{children:[a.jsx(w,{to:`/client-manager/${e.id}`,className:"font-semibold text-foreground hover:text-orange-400",children:e.business_name}),a.jsx("p",{className:"text-xs text-muted-foreground mt-0.5",children:[e.area,e.city].filter(
1Boolean).join(", ")||"â"})]}),a.jsx("span",{className:"px-2 py-0.5 rounded-full text-[10px] font-semibold",style:{background:e.is_active?`${I}20`:`${U}20`,color:e.is_active?I:U},children:e.is_active?"Active":"Inactive"})]}),a.jsxs("div",{className:"grid grid-cols-2 gap-2 text-xs",children:[a.jsx(X,{label:"Plan",value:e.plan}),a.jsx(X,{label:"GBP Score",value:`${e.gbp_score??0}/100`,color:H(e.gbp_score??0)}),a.jsx(X,{label:"Monthly",value:$(Number(e.monthly_fee||0))}),a.jsx(X,{label:"Last Scan",value:Z(e.last_scan_at)})]}),a.jsxs("div",{className:"flex gap-2 pt-2 border-t border-border/40",children:[a.jsxs(n,{size:"sm",variant:"outline",className:"flex-1",onClick:()=>s(e),children:[a.jsx(L,{className:"h-3.5 w-3.5"})," Scan"]}),a.jsx(n,{size:"sm",variant:"outline",className:"flex-1",asChild:!0,children:a.jsxs(w,{to:`/client-manager/${e.id}`,children:[a.jsx(_,{className:"h-3.5 w-3.5"})," Report"]})}),a.jsxs(n,{size:"sm",variant:"outline",className:"flex-1",onClick:()=>t(e),style:{borderColor:"#25D366",color:"#25D366"},children:[a.jsx(C,{className:"h-3.5 w-3.5"})," WhatsApp"]})]})]})}function X({label:e,value:s,color:t}){return a.jsxs("div",{className:"rounded-lg bg-muted/30 px-2.5 py-1.5",children:[a.jsx("div",{className:"text-[10px] uppercase tracking-wide text-muted-foreground",children:e}),a.jsx("div",{className:"font-semibold text-sm",style:{color:t||void 0},children:s})]})}function Y({onAdd:e}){return a.jsxs("div",{className:"rounded-2xl border border-dashed border-border bg-card/40 p-10 text-center",children:[a.jsx(i,{className:"mx-auto h-10 w-10 text-muted-foreground"}),a.jsx("h3",{className:"mt-3 font-semibold",children:"No clients yet"}),a.jsx("p",{className:"text-sm text-muted-foreground",children:"Add your first client to start tracking their Google Business Profile."}),a.jsxs(n,{onClick:e,className:"mt-4",style:{background:G,color:"#fff"},children:[a.jsx(o,{className:"h-4 w-4"})," Add New Client"]})]})}function ee({clients:e}){return e.length?a.jsxs("div",{className:"rounded-2xl border border-border/60 bg-card overflow-hidden",children:[a.jsxs("div",{className:"px-5 py-4 border-b border-border/40",children:[a.jsx("h2",{className:"font-semibold",children:"Payment Tracker"}),a.jsx("p",{className:"text-xs text-muted-foreground",children:"Monthly billing status across all clients"})]}),a.jsx("div",{className:"overflow-x-auto",children:a.jsxs("table",{className:"w-full text-sm",children:[a.jsx("thead",{className:"bg-muted/20 text-muted-foreground text-xs uppercase",children:a.jsxs("tr",{children:[a.jsx("th",{className:"text-left px-4 py-2",children:"Client"}),a.jsx("th",{className:"text-left px-4 py-2",children:"Plan"}),a.jsx("th",{className:"text-right px-4 py-2",children:"Monthly Fee"}),a.jsx("th",{className:"text-left px-4 py-2",children:"Last Payment"}),a.jsx("th",{className:"text-left px-4 py-2",children:"Next Due"}),a.jsx("th",{className:"text-left px-4 py-2",children:"Status"})]})}),a.jsx("tbody",{children:e.map(e=>{const s="paid"===(t=e.payment_status)?I:"overdue"===t?U:O;var t;return a.jsxs("tr",{className:"border-t border-border/40",children:[a.jsx("td",{className:"px-4 py-2 font-medium",children:e.business_name}),a.jsx("td",{className:"px-4 py-2 text-muted-foreground",children:e.plan}),a.jsx("td",{className:"px-4 py-2 text-right",children:$(Number(e.monthly_fee||0))}),a.jsx("td",{className:"px-4 py-2 text-muted-foreground",children:Z(e.last_payment_at)}),a.jsx("td",{className:"px-4 py-2 text-muted-foreground",children:Z(e.next_due_at)}),a.jsx("td",{className:"px-4 py-2",children:a.jsx("span",{className:"px-2 py-0.5 rounded-full text-[10px] font-semibold capitalize",style:{background:`${s}20`,color:s},children:e.payment_status})})]},e.id)})})]})})]}):null}export{V 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.