1import{u as Se,b as je,a as we,V as be,j as s,B as p,L as Ne}from"./index-C9VyRByS.js";import{r as n,at as ve,x as Ce,u as ee,aJ as ke,aq as Ee,M as Le,aM as Ae,aN as Fe}from"./icons-Dk9ia89R.js";import{P as Ie}from"./page-header-BapO8lcs.js";import{u as Me}from"./sandbox-BB7rpX9h.js";import{u as Re}from"./useQuery-DwXbu02t.js";import{m as Pe,n as ze}from"./workspace-queries-BwGSHjQO.js";import{r as Oe,b as $e,L as te,e as De,a as Te}from"./list-view-Bo1lHrNw.js";import{c as se,C as _e}from"./entity-rows-ClKpcigG.js";import{n as U,c as V}from"./CountryFlag-XUuu8iqv.js";import{u as Be,i as Ge}from"./list-url-filters-BxvLH598.js";import"./queryOptions-C9woPjwX.js";import"./kbd-BLyrb5u9.js";import"./command-menu-host-DogwMDAn.js";import"./sidebar-nav-B9fLWvsz.js";import"./list-selection-gEcAN2ZM.js";import"./dropdown-menu-Br7A3ifT.js";import"./index-DuU_63WQ.js";import"./index-4ZCr8EaA.js";import"./index-SqWoeikz.js";import"./index-CNSOSpc_.js";import"./hover-intent-BVJL3ioV.js";import"./badge-DDXsmDR6.js";import"./CardBrandIcon-DZrnkIrt.js";import"./GatewayIcon-DS6IcOT6.js";import"./aptpay-DVOe_hDw.js";import"./nmi-BjDQzXct.js";import"./paysio-BD4LuS7Z.js";import"./tooltip-dthSM347.js";import"./index-BfqoL0OZ.js";import"./transaction-status-DR5Q9gCn.js";import"./date-tz-BzwnfJlN.js";import"./detail-ui-DRBKVlan.js";import"./collapsible-Dx-K7pN4.js";import"./index-BXVX2Q8H.js";import"./utils-BrMmMMMC.js";const re=["Analyzing format","Extracting customers","Importing customers"],j=50,Ue={"last-desc":"Recently active","last-asc":"Dormant longest","date-desc":"Newest customer","date-asc":"Oldest customer","spent-desc":"Highest spend","spent-asc":"Lowest spend","transactions-desc":"Most orders","transactions-asc":"Fewest orders","name-asc":"Name AâZ","name-desc":"Name ZâA"},H={high:"$500+",medium:"$100â$500",low:"$1â$100",none:"No spend"},ne={all:"All",repeat:"Repeat",once:"One-time",none:"No orders"},Ve=Object.keys(ne).map(a=>({id:a,label:ne[a]})),K={nmi:"NMI",stripe:"Stripe",aptpay:"AptPay"},He=[];function Et(){const{activeWorkspace:a,authFetch:w}=Se(),{workspaceSlug:f}=je({strict:!1}),oe=we(),{isSandboxMode:z}=Me(),ae=be(),[b,ie]=n.useState("date"),[N,le]=n.useState("desc"),[u,O]=n.useState("all"),[l,v]=n.useState([]),[c,C]=n.useState([]),[m,k]=n.useState([]),[E,L]=n.useState(()=>{const e=Number(new URLSearchParams(window.location.search).get("page"));return Number.isFinite(e)&&e>1?e:1}),g=n.useRef(null),[A,y]=n.useState("idle"),[Q,F]=n.useState(""),[i,$]=n.useState(null),[ce,q]=n.useState(0),Y=n.useRef(w);Y.current=w;const D=Re(Pe(w,(a==null?void 0:a.id)??"",z)),h=D.data??He,T=D.isPending,I=`${b}-${N}-${u}-${l.join(",")}-${c.join(",")}-${m.join(",")}`,Z=n.useRef(I);Z.current!==I&&(Z.current=I,L(1)),Be("customers",e=>{const t=(e.country??[]).map(r=>U(r)).filter(r=>!!r);t.length!==0&&(O("all"),v([]),C([]),k(t),L(1))}),n.useEffect(()=>{if(!Ge("customers",f))return;const e=new URLSearchParams;E>1&&e.set("page",String(E));const t=e.toString(),r=`/${f}/customers${t?`?${t}`:""}`;Oe("customers","Customers",r),r!==window.location.pathname+window.location.search&&oe({to:r,replace:!0})},[E,f]),n.useEffect(()=>{if(A!=="importing")return;const e=setInterval(()=>q(t=>(t+1)%re.length),2e3);return()=>clearInterval(e)},[A]);async function me(e){var r;const t=(r=e.target.files)==null?void 0:r[0];if(!(!t||!a)){F(""),$(null),y("importing"),q(0);try{const o=new FormData;
1o.append("file",t),o.append("workspaceId",a.id),o.append("sandbox",String(z));const S=await Y.current("/api/customer-import/execute",{method:"POST",body:o});if(!S.ok){const G=await S.json().catch(()=>null);F((G==null?void 0:G.error)||"Import failed"),y("idle");return}const B=await S.json();$(B),y("done"),await D.refetch()}catch{F("Something went wrong during import."),y("idle")}finally{g.current&&(g.current.value="")}}}function pe(){y("idle"),F(""),$(null)}const J=n.useMemo(()=>{const e=new Set;for(const t of h)for(const r of t.processorTypes??[])e.add(r);return[...e].sort().map(t=>({value:t,label:K[t]||t}))},[h]),X=n.useMemo(()=>{const e=new Set;for(const t of h){const r=U(t.countryCode??t.billingCountry);r&&e.add(r)}return[...e].map(t=>({value:t,label:V(t)})).sort((t,r)=>t.label.localeCompare(r.label))},[h]),M=n.useMemo(()=>{let e=h;return u!=="all"&&(e=e.filter(t=>{switch(u){case"repeat":return t.transactionCount>1;case"once":return t.transactionCount===1;case"none":return t.transactionCount===0;default:return!0}})),l.length>0&&(e=e.filter(t=>{const r=t.totalSpent/100;return l.some(o=>{switch(o){case"high":return r>=500;case"medium":return r>=100&&r<500;case"low":return r>=1&&r<100;case"none":return r===0}})})),c.length>0&&(e=e.filter(t=>(t.processorTypes??[]).some(r=>c.includes(r)))),m.length>0&&(e=e.filter(t=>{const r=U(t.countryCode??t.billingCountry);return!!r&&m.includes(r)})),e=[...e].sort((t,r)=>{let o=0;switch(b){case"date":o=new Date(t.createdAt).getTime()-new Date(r.createdAt).getTime();break;case"spent":o=t.totalSpent-r.totalSpent;break;case"transactions":o=t.transactionCount-r.transactionCount;break;case"name":o=se(t).localeCompare(se(r));break;case"last":{const S=t.lastOrderAt?new Date(t.lastOrderAt).getTime():0,B=r.lastOrderAt?new Date(r.lastOrderAt).getTime():0;o=S-B;break}}return N==="asc"?o:-o}),e},[h,b,N,u,l,c,m]),x=M.length,R=Math.max(1,Math.ceil(x/j)),d=Math.min(E,R),P=n.useMemo(()=>M.slice((d-1)*j,d*j),[M,d]);n.useEffect(()=>{try{sessionStorage.setItem("paysio:nav:customers",JSON.stringify({ids:P.map(e=>e.id),total:x}))}catch{}},[P,x]);const de=`${b}-${N}`,ue=u!=="all"||l.length>0||c.length>0||m.length>0,he=[...l.length>0?[{key:"spend",dimension:"Spend",values:l.map(e=>H[e]),onRemove:()=>v([])}]:[],...c.length>0?[{key:"gateway",dimension:"Gateway",values:c.map(e=>K[e]||e),onRemove:()=>C([])}]:[],...m.length>0?[{key:"country",dimension:"Country",values:m.map(e=>V(e)),onRemove:()=>k([])}]:[]],xe=[{id:"spend",label:"Spend",options:Object.entries(H).map(([e,t])=>({value:e,label:t})),selected:l.map(e=>({value:e,label:H[e]}))},...J.length>1?[{id:"gateway",label:"Gateway",options:J,selected:c.map(e=>({value:e,label:K[e]||e}))}]:[],...X.length>1?[{id:"country",label:"Country",options:X,selected:m.map(e=>({value:e,label:V(e)}))}]:[]],_=(e,t)=>{e(r=>r.includes(t)?r.filter(o=>o!==t):[...r,t])},fe=(e,t)=>{e==="spend"?_(v,t.value):e==="gateway"?_(C,t.value):e==="country"&&_(k,t.value)};function ge(){O("all"),v([]),C([]),k([])}const ye=A==="importing"?s.jsxs(p,{variant:"outline",size:"sm",disabled:!0,className:"h-7 gap-1.5 px-2.5 text-[12px] font-medium tracking-normal [&_svg]:size-3.5",children:[s.jsx(ke,{className:"shrink-0 text-primary"}),s.jsx("span",{className:"tool-shimmer",children:re[ce]})]}):s.jsxs(p,{variant:"outline",size:"sm",onClick:()=>{var e;return(e=g.current)==null?void 0:e.click()},className:"h-7 gap-1.5 px-2.5 text-[12px] font-medium tracking-normal [&_svg]:size-3.5",children:[s.jsx(Ee,{}),"Import"]}),W=s.jsx(Te,{icons:[s.jsx(ee,{}),s.jsx(Le,{}),s.jsx(Ae,{}),s.jsx(Fe,{})]});return s.jsxs("section",{className:"relative flex h-full flex-col",children:[s.jsx(Ie,{title:"Customers",icon:s.jsx(ee,{}),actions:s.jsxs(s.Fragment,{children:[!T&&ye,!T&&R>1&&s.jsxs(s.Fragment,{children:[s.jsxs("span",{className:"pl-2 pr-0.5 text-[12px] tabular-nums text-muted-foreground",children:[(d-1)*j+1,"â",Math.min(d*j,x)," of ",x]}),s.jsx(p,{variant:"ghost",size:"icon",disabled:d<=1,onClick:()=>L(e=>Math.max(1,e-1)),"aria-label":"Previous page",className:"size-7 text-muted-foreground hover:text-foreground",children:s.jsx(ve,{className:"size-4"})}),s.jsx(p,{variant:"ghost",size:"icon",disabled:d>=R,onClick:()=>L(e=>Math.min(R,e+1)),"aria-label":"Next page",className:"size-7 text-muted-foreground hover:text-foreground",children:s.jsx(Ce,{className:"size-4"})})]})]})}),s.jsx($e,{presets:Ve,presetId:u,onPresetSelect:e=>O(e),chips:he,filters:xe,onFilterSelect:fe,display:[{label:"Ordering",value:de,onValueChange:e=>{const[t,r]=e.split("-");ie(t),le(r)},options:Object.entries(Ue).map(([e,t])=>({value:e,label:t}))}]}),s.jsx("input",{ref:g,type:"file",accept:".csv,.json,.txt,.tsv",className:"hidden",onChange:me}),Q&&s.jsx("p",{className:"shrink-0 px-3 pb-2 text-[13px] text-destructive",children:Q}),A==="done"&&i&&s.jsxs("div",{className:"mx-3 mb-2 shrink-0 space-y-2 rounded-[10px] border border-border bg-card p-3",children:[s.jsxs("p",{className:"text-[13px] font-medium",children:[i.imported," customer",i.imported!==1?"s":""," imported",i.skipped>0&&s.jsxs("span",{className:"text-muted-foreground",children:[" · ",i.skipped," skipped"]}),i.totalErrors>0&&s.jsxs("span",{className:"text-destructive",children:[" · ",i.totalErrors," error",i.totalErrors!==1?"s":""]})]}),i.errors.length>0&&s.jsx("div",{className:"max-h-32 overflow-y-auto rounded-lg bg-muted/50 p-2",children:i.errors.map((e,t)=>s.jsx("p",{className:"text-[11px] text-muted-foreground",children:e},t))}),s.jsx(p,{variant:"outline",size:"sm",className:"h-7 px-2.5 text-[12px]",onClick:pe,children:"Done"})]}),s.jsx("div",{className:"min-h-0 flex-1 overflow-y-auto [scrollbar-width:none] [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden",children:T?s.jsx("div",{className:"space-y-1 p-3",children:[1,2,3,4,5].map(e=>s.jsx("div",{className:"h-10 skeleton rounded-lg bg-muted"},e))}):x===0?ue?s.jsx(te,{icons:W,title:"No matching customers",description:"No customers match the filters you've applied. Try widening or clearing them to see more.",actions:s.jsx(p,{size:"sm",className:"h-7 px-2.5 text-[12px]",onClick:ge,children:"Clear filters"})}):s.jsx(te,{icons:W,title:"No customers yet",description:z?"Anyone who checks out in sandbox lands here, with their order count and lifetime spend.":"Anyone who checks out lands here, with their order count and lifetime spend. You can also bring an existing list over.",actions:s.jsxs(s.Fragment,{children:[s.jsx(p,{size:"sm",className:"h-7 px-2.5 text-[12px]",onClick:()=>{var e;return(e=g.current)==null?void 0:e.click()},children:"Import customers"}),s.jsx(p,{variant:"outline",size:"sm",asChild:!0,className:"h-7 px-2.5 text-[12px]",children:s.jsx(Ne,{to:`/${f}/payment-links/new`,children:"Create payment link"})})]})}):s.jsx(De,{resource:"customers",ids:P.map(e=>e.id),allIds:M.map(e=>e.id),resetKey:I,className:"px-1.5 pb-1.5",children:P.map(e=>s.jsx(_e,{customer:e,workspaceSlug:f,timezone:a==null?void 0:a.timezone,onHover:()=>ze(ae,w,(a==null?void 0:a.id)??"",e.id)},e.id))})})]})}export{Et as CustomersPage};
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.