1import{z as je,r as l,d as k,g as y,j as e,B as w,I as R,f as Q,K as Z,Q as Ne,V as ve,X as _e,Y as ye,D as J,F as ee,G as se,H as te,Z as ae,$ as ne}from"./index-FWKSGZPO.js";import{C as ie,c as oe}from"./card-DTQVPU97.js";import{b as re,a as we}from"./format-BNqEDbeN.js";import{p as be,T as ke}from"./TablePagination-Cl4E4vlh.js";import{P as le}from"./pencil-BFL_pWo_.js";import"./select-CNpOZwnZ.js";import"./index-BdQq_4o_.js";const V=o=>new Intl.NumberFormat("pt-BR",{style:"currency",currency:"BRL"}).format(o||0),M=o=>(o||"").replace(/\D+/g,""),Ce=o=>{let c=M(o);return c.length>=12&&c.startsWith("55")&&(c=c.slice(2)),c.length>=10?c.slice(0,2)+c.slice(-8):""};function Le(){const o=je(),c=(o==null?void 0:o.isAdmin)===!0,S=(o==null?void 0:o.orgId)??null,u=(o==null?void 0:o.orgSlug)??null,h=!!S&&!(o!=null&&o.isAdmin),[p,$]=l.useState([]),[B,ce]=l.useState(new Map),[G,W]=l.useState(!0),[P,me]=l.useState(""),[q,H]=l.useState(null),[j,L]=l.useState(null),[m,D]=l.useState(null),[N,T]=l.useState({name:"",email:"",phone:""}),[z,A]=l.useState(!1),[O,X]=l.useState(1),[F,de]=l.useState(50),I=l.useCallback(async()=>{W(!0);let s=k.from("bookings").select("id,customer_name,customer_email,customer_phone,total_amount,status,start_date,end_date,created_at,source").order("created_at",{ascending:!1}).limit(1e3);S&&(s=s.eq("organization_id",S)),h&&u&&(s=s.eq("source",u));const{data:x,error:g}=await s;g&&y.error("Erro ao carregar clientes",{description:g.message});const d=x||[],b=Array.from(new Set(d.filter(t=>!t.customer_name&&t.customer_phone).map(t=>M(t.customer_phone))));if(b.length){const{data:t}
1=await k.from("whatsapp_conversations").select("phone,display_name").in("phone",b),a=new Map;(t||[]).forEach(i=>{i.display_name&&a.set(M(i.phone),i.display_name)});for(const i of d)if(!i.customer_name&&i.customer_phone){const _=a.get(M(i.customer_phone));_&&(i.customer_name=_)}}$(d);const C=d.map(t=>t.id),v=new Map;if(C.length){for(let a=0;a<C.length;a+=200){const i=C.slice(a,a+200),{data:_,error:r}=await k.from("payments").select("booking_id,amount,status").in("booking_id",i).eq("status","approved");if(r){y.error("Erro ao carregar pagamentos",{description:r.message});break}(_||[]).forEach(E=>{v.set(E.booking_id,(v.get(E.booking_id)||0)+Number(E.amount||0))})}for(const a of d)!v.has(a.id)&&a.status==="confirmed"&&v.set(a.id,Number(a.total_amount||0))}ce(v),W(!1)},[S,u,h]);l.useEffect(()=>{I()},[I]);const f=l.useMemo(()=>{const s=new Map,x=t=>{let a=t;for(;s.get(a)!==a;)a=s.get(a);return s.set(t,a),a},g=t=>{s.has(t)||s.set(t,t)},d=(t,a)=>{g(t),g(a);const i=x(t),_=x(a);i!==_&&s.set(_,i)},b=t=>{const a=(t.customer_email||"").trim().toLowerCase(),i=Ce(t.customer_phone);return[a&&`e:${a}`,i&&`t:${i}`].filter(Boolean)};for(const t of p){const a=b(t);a.forEach(g),a.length===2&&d(a[0],a[1])}const C=new Map;for(const t of p){const a=b(t);if(!a.length)continue;const i=x(a[0]),_=t.customer_email?"email":"phone",r=C.get(i)||{key:i,keyKind:_,name:"",email:t.customer_email||"",phone:t.customer_phone||"",count:0,total:0,last:t.created_at,bookingIds:[],names:[],emails:[]};r.count+=1,r.total+=B.get(t.id)||0,t.created_at>r.last&&(r.last=t.created_at),!r.name&&t.customer_name&&(r.name=t.customer_name),!r.email&&t.customer_email&&(r.email=t.customer_email),!r.phone&&t.customer_phone&&(r.phone=t.customer_phone);const E=(t.customer_name||"").trim();E&&!r.names.some(ge=>ge.toLowerCase()===E.toLowerCase())&&r.names.push(E);const U=(t.customer_email||"").trim().toLowerCase();U&&!r.emails.includes(U)&&r.emails.push(U),r.bookingIds.push(t.id),C.set(i,r)}let v=[...C.values()].sort((t,a)=>a.total-t.total);if(P){const t=P.toLowerCase(),a=M(P);v=v.filter(i=>i.name.toLowerCase().includes(t)||i.email.toLowerCase().includes(t)||a&&M(i.phone).includes(a))}return v},[p,P,B]),K=l.useMemo(()=>f.filter(s=>s.phone&&(s.names.length>1||s.emails.length>1)),[f]),ue=async s=>{const x=window.prompt("Nome principal",s.name);if(!x)return;const g=window.prompt("E-mail principal",s.emails[0]||s.email);if(!g)return;const{data:d,error:b}=await k.rpc("admin_unify_customer",{p_phone:s.phone,p_name:x,p_email:g});if(b)return y.error("Não foi possÃvel unificar",{description:b.message});y.success(`Unificado: ${(d==null?void 0:d.bookings)??0} reservas, ${(d==null?void 0:d.accountsMerged)??0} contas juntadas`),I()};l.useEffect(()=>{X(1)},[P,F]);const he=l.useMemo(()=>be(f,O,F),[f,O,F]),n=l.useMemo(()=>f.find(s=>s.key===q)||null,[f,q]),xe=l.useMemo(()=>n?p.filter(s=>n.bookingIds.includes(s.id)):[],[n,p]),Y=s=>{L(s),T({name:s.name||"",email:s.email||"",phone:s.phone||""})}
1,pe=async()=>{if(!j)return;const s=N.name.trim(),x=N.email.trim().toLowerCase(),g=N.phone.trim();if(x&&!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(x)){y.error("Email inválido");return}A(!0);const{error:d}=await k.from("bookings").update({customer_name:s||null,customer_email:x||null,customer_phone:g||null}).in("id",j.bookingIds);if(A(!1),d){y.error("Falha ao salvar",{description:d.message});return}y.success(`Cliente atualizado (${j.count} reserva${j.count>1?"s":""})`),L(null),await I()},fe=async()=>{if(!m)return;A(!0);const{error:s}=await k.from("bookings").delete().in("id",m.bookingIds);if(A(!1),s){y.error("Falha ao excluir",{description:s.message});return}y.success(`${m.count} reserva${m.count>1?"s":""} excluÃda${m.count>1?"s":""}`),D(null),H(null),await I()};return e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsx("h1",{className:"text-2xl font-bold",children:"Clientes"}),e.jsxs("span",{className:"text-xs text-muted-foreground",children:[f.length," contato",f.length===1?"":"s"]})]}),c&&K.length>0&&e.jsx(ie,{children:e.jsxs(oe,{className:"space-y-2 p-4 text-sm",children:[e.jsxs("p",{className:"font-semibold",children:["PossÃveis duplicados (",K.length,")"]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:'Mesmo telefone com nomes ou e-mails diferentes. "Unificar" deixa todas as reservas com o nome e o e-mail principais e junta as contas.'}),K.slice(0,30).map(s=>e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2 border-t pt-2",children:[e.jsxs("div",{children:[e.jsx("div",{className:"font-medium",children:s.phone}),e.jsxs("div",{className:"text-xs text-muted-foreground",children:["Nomes: ",s.names.join(" / ")]}),e.jsxs("div",{className:"text-xs text-muted-foreground",children:["E-mails: ",s.emails.join(" / ")||"-"]})]}),e.jsx(w,{size:"sm",variant:"outline",onClick:()=>ue(s),children:"Unificar"})]},s.key))]})}),e.jsx(R,{placeholder:"Buscar nome, email ou telefone...",value:P,onChange:s=>me(s.target.value),className:"max-w-sm"}),e.jsx(ie,{children:e.jsxs(oe,{className:"p-0",children:[G?e.jsx("div",{className:"flex justify-center py-10",children:e.jsx(Q,{className:"h-5 w-5 animate-spin"})}):e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{className:"bg-muted/50 text-left",children:e.jsxs("tr",{children:[e.jsx("th",{className:"p-3",children:"Nome"}),e.jsx("th",{className:"p-3",children:"Email"}),e.jsx("th",{className:"p-3",children:"Telefone"}),e.jsx("th",{className:"p-3",children:"Reservas"}),e.jsx("th",{className:"p-3",children:"Total gasto"}),e.jsx("th",{className:"p-3",children:"Ãltima"}),e.jsx("th",{className:"p-3 text-right",children:"Ações"})]})}),e.jsxs("tbody",{children:[he.map(s=>e.jsxs("tr",{className:"border-t hover:bg-muted/30",children:[e.jsxs("td",{className:"p-3 font-medium cursor-pointer",onClick:()=>H(s.key),children:[s.name||e.jsx("span",{className:"text-xs italic text-muted-foreground",children:"sem nome"}),s.names.length>1&&e.jsxs("div",{className:"text-xs font-normal text-muted-foreground",children:["também: ",s.names.slice(1).join(", ")]})]}),e.jsx("td",{className:"p-3 text-muted-foreground",children:s.email||e.jsx("span",{className:"text-xs italic",children:"â"})}),e.jsx("td",{className:"p-3 text-muted-foreground",children:s.phone||e.jsx("span",{className:"text-xs italic",children:"â"})}),e.jsx("td",{className:"p-3",children:s.count}),e.jsx("td",{className:"p-3",children:V(s.total)}),e.jsx("td",{className:"p-3 text-xs",children:re(s.last)}),e.jsx("td",{className:"p-3",children:e.jsx("div",{className:"flex justify-end gap-1",children:c&&e.jsxs(e.Fragment,{children:[e.jsx(w,{variant:"ghost",size:"icon","aria-label":"Editar",onClick:()=>Y(s),children:e.jsx(le,{className:"h-4 w-4"})}),e.jsx(w,{variant:"ghost",size:"icon","aria-label":"Excluir",onClick:()=>D(s),children:e.jsx(Z,{className:"h-4 w-4 text-red-600"})})]})})})]},s.key)),f.length===0&&e.jsx("tr",{children:e.jsx("td",{colSpan:7,className:"p-6 text-center text-muted-foreground",children:"Nenhum cliente."})})]})]})}),!G&&f.length>0&&e.jsx(ke,{total:f.length,page:O,pageSize:F,onPageChange:X,onPageSizeChange:de})]})}),e.jsx(Ne,{open:!!q,onOpenChange:s=>!s&&H(null),children:e.jsxs(ve,{className:"w-full sm:max-w-md overflow-auto",children:[e.jsx(_e,{children:e.jsx(ye,{children:(n==null?void 0:n.name)||(n==null?void 0:n.email)||(n==null?void 0:n.phone)||"Cliente"})}),n&&e.jsxs("div",{className:"mt-2 space-y-1 text-sm text-muted-foreground",children:[n.email&&e.jsxs("div",{children:["ð§ ",n.email]}),n.phone&&e.jsxs("div",{children:["ð± ",n.phone]})]}),(n==null?void 0:n.email)&&e.jsx(Ee,{email:n.email}),e.jsx("div",{className:"mt-4 space-y-3",children:xe.map(s=>e.jsxs("div",{className:"border rounded-md p-3 text-sm",children:[e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"font-medium",children:we(s.start_date,s.end_date)}),e.jsx("span",{children:V(Number(s.total_amount))})]}),e.jsxs("div",{className:"flex justify-between text-xs text-muted-foreground",children:[e.jsx("span",{className:"capitalize",children:s.status}),s.source&&e.jsx("span",{children:s.source})]}),e.jsx("div",{className:"mt-1 text-xs",children:B.get(s.id)?e.jsxs("span",{className:"inline-block rounded bg-green-500/10 text-green-700 px-2 py-0.5",children:["Pago ",V(B.get(s.id)||0)]}):e.jsx("span",{className:"inline-block rounded bg-muted text-muted-foreground px-2 py-0.5",children:"Não pago"})})]},s.id))}),n&&c&&e.jsxs("div",{className:"mt-6 flex gap-2",children:[e.jsxs(w,{variant:"outline",className:"flex-1",onClick:()=>Y(n),children:[e.jsx(le,{className:"mr-2 h-4 w-4"})," Editar"]}),e.jsxs(w,{variant:"destructive",className:"flex-1",onClick:()=>D(n),children:[e.jsx(Z,{className:"mr-2 h-4 w-4"})," Excluir"]})]})]})}),e.jsx(J,{open:!!j,onOpenChange:s=>!s&&L(null),children:e.jsxs(ee,{children:[e.jsxs(se,{children:[e.jsx(te,{children:"Editar cliente"}),e.jsxs(ae,{children:["Alterações serão aplicadas em todas as ",j==null?void 0:j.count," reserva",j&&j.count>1?"s":""," deste contato."]})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{children:[e.jsx("label",{className:"text-xs text-muted-foreground",children:"Nome"}),e.jsx(R,{value:N.name,onChange:s=>T({...N,name:s.target.value})})]}),e.jsxs("div",{children:[e.jsx("label",{className:"text-xs text-muted-foreground",children:"Email"}),e.jsx(R,{type:"email",value:N.email,onChange:s=>T({...N,email:s.target.value})})]}),e.jsxs("div",{children:[e.jsx("label",{className:"text-xs text-muted-foreground",children:"Telefone"}),e.jsx(R,{value:N.phone,onChange:s=>T({...N,phone:s.target.value})})]})]}),e.jsxs(ne,{children:[e.jsx(w,{variant:"outline",onClick:()=>L(null),children:"Cancelar"}),e.jsx(w,{onClick:pe,disabled:z,children:z?e.jsx(Q,{className:"h-4 w-4 animate-spin"}):"Salvar"})]})]})}),e.jsx(J,{open:!!m,onOpenChange:s=>!s&&D(null),children:e.jsxs(ee,{children:[e.jsxs(se,{children:[e.jsx(te,{children:"Excluir cliente?"}),e.jsxs(ae,{children:["Isso vai apagar ",e.jsx("strong",{children:m==null?void 0:m.count})," reserva",m&&m.count>1?"s":""," deste contato (",(m==null?void 0:m.email)||(m==null?void 0:m.ph
1one),"). Esta ação não pode ser desfeita."]})]}),e.jsxs(ne,{children:[e.jsx(w,{variant:"outline",onClick:()=>D(null),children:"Cancelar"}),e.jsx(w,{variant:"destructive",onClick:fe,disabled:z,children:z?e.jsx(Q,{className:"h-4 w-4 animate-spin"}):"Excluir tudo"})]})]})})]})}function Ee({email:o}){const[c,S]=l.useState(null);if(l.useEffect(()=>{let h=!0;return(async()=>{const{data:p}=await k.from("profiles").select("id,full_name,phone,cpf,birth_date,city").ilike("email",o).maybeSingle();let $=[];if(p){const{data:B}=await k.from("customer_vehicles").select("plate,model,color,is_primary").eq("user_id",p.id);$=B||[]}h&&S({profile:p,vehicles:$})})(),()=>{h=!1}},[o]),!(c!=null&&c.profile))return null;const u=c.profile;return e.jsxs("div",{className:"mt-4 rounded-md border p-3 text-sm space-y-1",children:[e.jsx("div",{className:"font-medium",children:"Cadastro na conta"}),u.full_name&&e.jsxs("div",{children:["Nome: ",u.full_name]}),u.phone&&e.jsxs("div",{children:["Telefone: ",u.phone]}),u.cpf&&e.jsxs("div",{children:["CPF: ",u.cpf]}),u.birth_date&&e.jsxs("div",{children:["Nascimento: ",re(u.birth_date)]}),u.city&&e.jsxs("div",{children:["Cidade: ",u.city]}),c.vehicles.length>0&&e.jsxs("div",{className:"pt-1",children:[e.jsx("div",{className:"font-medium",children:"VeÃculos"}),c.vehicles.map((h,p)=>e.jsxs("div",{children:[h.plate,h.model?` · ${h.model}`:"",h.color?` · ${h.color}`:"",h.is_primary?" (principal)":""]},p))]})]})}export{Le 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.