1import{j as e,r}from"./vendor-react-Dak0qFzn.js";import{cE as z,cn as u,t as l,B as c,h as q,C as Ce,E as be,F as $,i as re,H as K,J as X,K as G,M as J,N as ie,L as x,I as S,W as Q,X as Se}from"./index-CkP0Ysi6.js";import{T as Te,a as we,b as ee,c as g,d as Pe,e as j}from"./table-Bztvit-x.js";import{S as ne,a as le,b as ce,c as oe,d as F}from"./select-BM3YwBkF.js";import{T as Ee,a as De,b as se,c as ae}from"./tabs-CeFY87P_.js";import{E as de}from"./empty-state-BbW66hnb.js";import{T as me}from"./page-skeleton-CgSJ5_Pb.js";import{l as Ie}from"./users-i5aYwjYJ.js";import{ch as he,ci as xe,aR as Y,at as ue,bS as pe,X as ke,d as Z,T as Re}from"./vendor-icons-DQbXH2Ms.js";import"./vendor-ui-B9Hlh5h7.js";function Ae(){return z("/api/sales/pipelines")}function Le(i){return u("/api/sales/pipelines",{method:"POST",body:i})}function Oe(i,o){return u(`/api/sales/pipelines/${encodeURIComponent(i)}`,{method:"PATCH",body:o})}function $e(i){return u(`/api/sales/pipelines/${encodeURIComponent(i)}`,{method:"DELETE"})}function Fe(i,o){return u(`/api/sales/pipelines/${encodeURIComponent(i)}/stages`,{method:"POST",body:o})}function Ue(i,o){return u(`/api/sales/pipelines/stages/${encodeURIComponent(i)}`,{method:"PATCH",body:o})}function Be(i){return u(`/api/sales/pipelines/stages/${encodeURIComponent(i)}`,{method:"DELETE"})}function He(i=!1){return z(`/api/sales/territories${i?"?activeOnly=true":""}`)}function Me(i){return u("/api/sales/territories",{method:"POST",body:i})}function We(i,o){return u(`/api/sales/territories/${encodeURIComponent(i)}`,{method:"PATCH",body:o})}function _e(i){return u(`/api/sales/territories/${encodeURIComponent(i)}`,{method:"DELETE"})}function ze(){return z("/api/sales/territories/performance")}function Ve(){return z("/api/sales/territories/overlaps")}function te(i){return new Intl.NumberFormat("en-US",{style:"currency",currency:"USD",maximumFractionDigits:0}).format(i)}function rs(){return e.jsxs("div",{className:"space-y-6 p-6",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold",children:"Sales Configuration"}),e.jsx("p",{className:"text-muted-foreground",children:"Manage deal pipelines, stages, and sales territories"})]}),e.jsxs(Ee,{defaultValue:"pipelines",children:[e.jsxs(De,{children:[e.jsxs(se,{value:"pipelines",children:[e.jsx(he,{className:"mr-1.5 h-4 w-4"})," Pipelines"]}),e.jsxs(se,{value:"territories",children:[e.jsx(xe,{className:"mr-1.5 h-4 w-4"})," Territories"]})]}),e.jsx(ae,{value:"pipelines",children:e.jsx(qe,{})}),e.jsx(ae,{value:"territories",children:e.jsx(Ke,{})})]})]})}function qe(){const[i,o]=r.useState([]),[V,U]=r.useState(!0),[T,B]=r.useState(!1),[f,y]=r.useState(!1),[w,P]=r.useState(""),[v,m]=r.useState(null),[p,E]=r.useState(""),[D,I]=r.useState(50),[h,N]=r.useState("open"),[k,C]=r.useState(!1),d=r.useCallback(()=>{U(!0),Ae().then(o).catch(()=>l.error("Failed to load pipelines")).finally(()=>U(!1))},[]);r.useEffect(()=>{d()},[d]);async function R(){if(!w.trim()){l.error("Pipeline name is required");return}B(!0);try{await Le({name:w.trim()}),l.success("Pipeline created with default stages"),y(!1),P(""),d()}catch(a){l.error(a instanceof Error?a.message:"Failed to create pipeline")}finally{B(!1)}}async function H(a){try{await Oe(a.id,{isActive:!a.is_active}),d()}catch(n){l.error(n instanceof Error?n.message:"Failed to update pipeline")}}async function A(a){try{await $e(a.id),l.success("Pipeline deleted"),d()}catch(n){l.error(n instanceof Error?n.message:"Failed to delete pipeline")}}async function M(){if(v){if(!p.trim()){l.error("Stage name is required");return}C(!0);try{await Fe(v.id,{name:p.trim(),probability:h==="won"?100:h==="lost"?0:D,isWon:h==="won",isLost:h==="lost"}),l.success("Stage added"),m(null),E(""),I(50),N("open"),d()}catch(a){l.error(a instanceof Error?a.message:"Failed to add stage")}finally{C(!1)}}}async function L(a){try{await Be(a),l.success("Stage removed"),d()}catch(n){l.error(n instanceof Error?n.message:"Failed to remove stage")}}async function W(a,n){const O=window.prompt("Stage name",n);if(!(!O||O.trim()===n))try{await Ue(a,{name:O.trim()}),d()}catch(_){l.error(_ instanceof Error?_.message:"Failed to rename stage")}}
1return e.jsxs("div",{className:"space-y-4 mt-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:"Each pipeline has ordered stages with win probabilities used by forecasting and the kanban board."}),e.jsxs(c,{onClick:()=>y(!0),children:[e.jsx(Y,{className:"mr-1.5 h-4 w-4"})," New Pipeline"]})]}),V?e.jsx(me,{rows:4,cols:3}):i.length===0?e.jsx(de,{icon:he,title:"No pipelines",description:"Create a pipeline to define your deal stages"}):e.jsx("div",{className:"space-y-4",children:i.map(a=>e.jsxs(q,{children:[e.jsx(Ce,{className:"pb-3",children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs(be,{className:"text-base flex items-center gap-2",children:[a.name,a.is_default&&e.jsx($,{children:"Default"}),!a.is_active&&e.jsx($,{variant:"secondary",children:"Inactive"})]}),e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsxs(c,{variant:"outline",size:"sm",onClick:()=>m(a),children:[e.jsx(Y,{className:"h-3.5 w-3.5 mr-1"})," Stage"]}),e.jsx(c,{variant:"ghost",size:"sm",onClick:()=>H(a),children:a.is_active?"Deactivate":"Activate"}),!a.is_default&&e.jsx(c,{variant:"ghost",size:"icon",onClick:()=>A(a),children:e.jsx(ue,{className:"h-4 w-4 text-destructive"})})]})]})}),e.jsx(re,{children:e.jsxs("div",{className:"flex flex-wrap gap-2",children:[(a.stages??[]).map(n=>e.jsxs("div",{className:"flex items-center gap-1.5 rounded-full border px-3 py-1 text-sm",style:{borderColor:n.color},children:[e.jsx("span",{className:"w-2 h-2 rounded-full",style:{backgroundColor:n.color}}),e.jsx("span",{className:"font-medium",children:n.name}),e.jsxs("span",{className:"text-muted-foreground text-xs",children:[n.probability,"%"]}),n.is_won&&e.jsx($,{variant:"secondary",className:"text-[10px] px-1",children:"Won"}),n.is_lost&&e.jsx($,{variant:"secondary",className:"text-[10px] px-1",children:"Lost"}),e.jsx("button",{type:"button",className:"ml-0.5 text-muted-foreground hover:text-foreground",onClick:()=>W(n.id,n.name),title:"Rename stage",children:e.jsx(pe,{className:"h-3 w-3"})}),e.jsx("button",{type:"button",className:"text-muted-foreground hover:text-destructive",onClick:()=>L(n.id),title:"Remove stage",children:e.jsx(ke,{className:"h-3 w-3"})})]},n.id)),(a.stages??[]).length===0&&e.jsx("p",{className:"text-sm text-muted-foreground",children:"No stages yet"})]})})]},a.id))}),e.jsx(K,{open:f,onOpenChange:y,children:e.jsxs(X,{className:"sm:max-w-[420px]",children:[e.jsxs(G,{children:[e.jsx(J,{children:"New Pipeline"}),e.jsx(ie,{children:"Created with the standard six stages (Lead â Won/Lost) â edit them afterwards."})]}),e.jsxs("div",{children:[e.jsx(x,{children:"Name"}),e.jsx(S,{value:w,onChange:a=>P(a.target.value),placeholder:"Enterprise Deals"})]}),e.jsxs(Q,{children:[e.jsx(c,{variant:"ghost",onClick:()=>y(!1),children:"Cancel"}),e.jsxs(c,{onClick:R,disabled:T,children:[T&&e.jsx(Z,{className:"mr-1.5 h-4 w-4 animate-spin"}),"Create"]})]})]})}),e.jsx(K,{open:!!v,onOpenChange:a=>{a||m(null)},children:e.jsxs(X,{className:"sm:max-w-[420px]",children:[e.jsx(G,{children:e.jsxs(J,{children:["Add Stage â ",v?.name]})}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{children:[e.jsx(x,{children:"Stage name"}),e.jsx(S,{value:p,onChange:a=>E(a.target.value),placeholder:"Contract Review"})]}),e.jsxs("div",{className:"grid gap-3 sm:grid-cols-2",children:[e.jsxs("div",{children:[e.jsx(x,{children:"Type"}),e.jsxs(ne,{value:h,onValueChange:a=>N(a),children:[e.jsx(le,{children:e.jsx(ce,{})}),e.jsxs(oe,{children:[e.jsx(F,{value:"open",children:"Open stage"}),e.jsx(F,{value:"won",children:"Won (closes deal)"}),e.jsx(F,{value:"lost",children:"Lost (closes deal)"})]})]})]}),h==="open"&&e.jsxs("div",{children:[e.jsx(x,{children:"Win probability %"}),e.jsx(S,{type:"number",min:0,max:100,value:D,onChange:a=>I(Math.max(0,Math.min(100,Number(a.target.value)||0)))})]})]})]}),e.jsxs(Q,{children:[e.jsx(c,{variant:"ghost",onClick:()=>m(null),children:"Cancel"}),e.jsxs(c,{onClick:M,disabled:k,children:[k&&e.jsx(Z,{className:"mr-1.5 h-4 w-4 animate-spin"}),"Add Stage"]})]})]})})]})}function Ke(){const[i,o]=r.useState([]),[V,U]=r.useState([]),[T,B]=r.useState([]),[f,y]=r.useState([]),[w,P]=r.useState(!0),[v,m]=r.useState(!1),[p,E]=r.useState(null),[D,I]=r.useState(!1),[h,N]=r.useState(""),[k,C]=r.useState(""),[d,R]=r.useState(""),[H,A]=r.useState(""),[M,L]=r.useState(""),[W,a]=r.useState([]),n=r.useCallback(()=>{P(!0),Promise.all([He().catch(()=>
1[]),ze().catch(()=>[]),Ve().catch(()=>[]),Ie().catch(()=>[])]).then(([s,t,b,Ne])=>{o(s),U(t),B(Array.isArray(b)?b:[]),y(Ne)}).finally(()=>P(!1))},[]);r.useEffect(()=>{n()},[n]);const O=new Map(V.map(s=>[s.territoryId,s])),_=s=>{if(!s)return"â";const t=f.find(b=>b.id===s);return t?`${t.firstName??""} ${t.lastName??""}`.trim()||t.email:s.slice(0,8)};function ge(){E(null),N(""),C(""),R(""),A(""),L(""),a([]),m(!0)}function je(s){E(s),N(s.name),C(s.description??""),R((s.criteria?.region??[]).join(", ")),A((s.criteria?.industry??[]).join(", ")),L(s.managerId??""),a(s.assignedReps??[]),m(!0)}async function fe(){if(!h.trim()){l.error("Territory name is required");return}I(!0);const s={region:d.split(",").map(t=>t.trim()).filter(Boolean),industry:H.split(",").map(t=>t.trim()).filter(Boolean)};try{const t={name:h.trim(),description:k.trim()||void 0,criteria:s,assignedReps:W,managerId:M||void 0};p?(await We(p.id,t),l.success("Territory updated")):(await Me(t),l.success("Territory created")),m(!1),n()}catch(t){l.error(t instanceof Error?t.message:"Failed to save territory")}finally{I(!1)}}async function ye(s){try{await _e(s.id),l.success("Territory deleted"),n()}catch(t){l.error(t instanceof Error?t.message:"Failed to delete territory")}}function ve(s){a(t=>t.includes(s)?t.filter(b=>b!==s):[...t,s])}return e.jsxs("div",{className:"space-y-4 mt-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:"Territories group accounts and deals by region/industry criteria and drive rep assignment."}),e.jsxs(c,{onClick:ge,children:[e.jsx(Y,{className:"mr-1.5 h-4 w-4"})," New Territory"]})]}),T.length>0&&e.jsx(q,{className:"border-amber-300 dark:border-amber-800",children:e.jsxs(re,{className:"pt-4 pb-4 flex items-start gap-3",children:[e.jsx(Re,{className:"h-5 w-5 text-amber-600 shrink-0 mt-0.5"}),e.jsxs("div",{className:"text-sm",children:[e.jsx("p",{className:"font-medium",children:"Overlapping territory criteria detected"}),e.jsx("ul",{className:"text-muted-foreground mt-1 space-y-0.5",children:T.slice(0,5).map((s,t)=>e.jsxs("li",{children:[s.territoryA," â ",s.territoryB," (",s.overlapType,s.detail?`: ${s.detail}`:"",")"]},t))})]})]})}),w?e.jsx(me,{rows:4,cols:6}):i.length===0?e.jsx(de,{icon:xe,title:"No territories",description:"Create territories to organize accounts by region or industry"}):e.jsx(q,{children:e.jsxs(Te,{children:[e.jsx(we,{children:e.jsxs(ee,{children:[e.jsx(g,{children:"Territory"}),e.jsx(g,{children:"Criteria"}),e.jsx(g,{children:"Manager"}),e.jsx(g,{className:"text-right",children:"Reps"}),e.jsx(g,{className:"text-right",children:"Deals"}),e.jsx(g,{className:"text-right",children:"Pipeline"}),e.jsx(g,{className:"text-right",children:"Won"}),e.jsx(g,{})]})}),e.jsx(Pe,{children:i.map(s=>{const t=O.get(s.id);return e.jsxs(ee,{children:[e.jsxs(j,{children:[e.jsx("span",{className:"font-medium",children:s.name}),!s.isActive&&e.jsx($,{variant:"secondary",className:"ml-2",children:"Inactive"})]}),e.jsx(j,{className:"text-sm text-muted-foreground max-w-[220px] truncate",children:[...s.criteria?.region??[],...s.criteria?.industry??[]].join(", ")||"â"}),e.jsx(j,{className:"text-sm",children:_(s.managerId)}),e.jsx(j,{className:"text-right",children:s.assignedReps?.length??0}),e.jsx(j,{className:"text-right",children:t?.dealCount??s.dealCount??0}),e.jsx(j,{className:"text-right",children:t?te(t.pipelineValue):"â"}),e.jsx(j,{className:"text-right",children:t?te(t.wonValue):"â"}),e.jsxs(j,{className:"text-right whitespace-nowrap",children:[e.jsx(c,{variant:"ghost",size:"icon",onClick:()=>je(s),children:e.jsx(pe,{className:"h-4 w-4"})}),e.jsx(c,{variant:"ghost",size:"icon",onClick:()=>ye(s),children:e.jsx(ue,{className:"h-4 w-4 text-destructive"})})]})]},s.id)})})]})}),e.jsx(K,{open:v,onOpenChange:m,children:e.jsxs(X,{className:"sm:max-w-[560px] max-h-[85vh] overflow-y-auto",children:[e.jsxs(G,{children:[e.jsx(J,{children:p?"Edit Territory":"New Territory"}),e.jsx(ie,{children:"Accounts matching the region/industry criteria roll up to this territory."})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{children:[e.jsx(x,{children:"Name"}),e.jsx(S,{value:h,onChange:s=>N(s.target.value),placeholder:"US Southeast"})]}),e.jsxs("div",{children:[e.jsx(x,{children:"Description (optional)"}),e.jsx(Se,{value:k,onChange:s=>C(s.target.value),className:"h-16"})]}),e.jsxs("div",{className:"grid gap-3 sm:grid-cols-2",children:[e.jsxs("div",{children:[e.jsx(x,{children:"Regions (comma-separated)"}),e.jsx(S,{value:d,onChange:s=>R(s.target.value),placeholder:"TX, FL, GA"})]}),e.jsxs("div",{children:[e.jsx(x,{children:"Industries (comma-separated)"}),e.jsx(S,{value:H,onChange:s=>A(s.target.value),placeholder:"Healthcare, Defense"})]})]}),e.jsxs("div",{children:[e.jsx(x,{children:"Manager"}),e.jsxs(ne,{value:M||"none",onValueChange:s=>L(s==="none"?"":s),children:[e.jsx(le,{children:e.jsx(ce,{placeholder:"No manager"})}),e.jsxs(oe,{children:[e.jsx(F,{value:"none",children:"No manager"}),f.map(s=>e.jsx(F,{value:s.id,children:`${s.firstName??""} ${s.lastName??""}`.trim()||s.email},s.id))]})]})]}),e.jsxs("div",{children:[e.jsx(x,{children:"Assigned reps"}),e.jsxs("div",{className:"max-h-36 overflow-y-auto rounded-md border p-2 space-y-1",children:[f.map(s=>e.jsxs("label",{className:"flex items-center gap-2 text-sm cursor-pointer",children:[e.jsx("input",{type:"checkbox",className:"h-3.5 w-3.5 accent-primary",checked:W.includes(s.id
1),onChange:()=>ve(s.id)}),`${s.firstName??""} ${s.lastName??""}`.trim()||s.email]},s.id)),f.length===0&&e.jsx("p",{className:"text-xs text-muted-foreground",children:"No users found"})]})]})]}),e.jsxs(Q,{children:[e.jsx(c,{variant:"ghost",onClick:()=>m(!1),children:"Cancel"}),e.jsxs(c,{onClick:fe,disabled:D,children:[D&&e.jsx(Z,{className:"mr-1.5 h-4 w-4 animate-spin"}),p?"Save Changes":"Create Territory"]})]})]})})]})}export{rs 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.