1import{u as ae,W as le,r as i,j as t,B as o,c7 as g,ao as ie,cV as $,C as re,T as ne,cd as de,ce,ch as oe,cf as xe,ak as me,aE as ue,ca as he,cT as pe,am as ge}from"./index-CMqj2Al3.js";import{a as z}from"./index-DCn_Q08p.js";import{S as k,a as L,b as je}from"./admin-utils-BHiI58Vl.js";import{B as be}from"./badge-o-0m8Tn-.js";import{S as x,a as m,b as u,c as h,d as r}from"./select-B6gOamOn.js";import{P as fe}from"./plus-Bho-UPkd.js";import{S as ve}from"./search-DSPiCvgg.js";import{F as Ne}from"./filter-BSPMIhX7.js";import{M as Se}from"./mail-GkhjkdnB.js";import"./loader-circle-C-PWi2Uh.js";import"./building-2-BocFibHM.js";import"./calendar-check-vSz9Z_o4.js";import"./tag-DfpEZh13.js";import"./share-2-BGjPq4oo.js";import"./file-text-Yip-RFl-.js";import"./shield-check-DrgtBIoJ.js";import"./users-ew7OPEEO.js";import"./ban-D_eudGi-.js";import"./copy-CcsnX5lH.js";import"./trophy-C76Qjg3d.js";import"./clock-D3IH-vol.js";import"./book-open-DDWcysoS.js";import"./message-square-D6SCCY63.js";import"./index-B4v8T9u2.js";import"./chevron-up-CIdiK_Cn.js";const Ce=["reserved","sold","cancelled"],ye=Object.keys(L).filter(p=>!Ce.includes(p)),ze=Object.fromEntries(ye.map(p=>[p,L[p]]));function Qe(){const[,p]=ae(),{toast:E}=le(),[w,B]=i.useState(null),[F,D]=i.useState([]),[U,I]=i.useState(0),[j,d]=i.useState(1),[M,W]=i.useState(1),[G,A]=i.useState(!0),[f,J]=i.useState(""),[c,T]=i.useState(""),[v,Y]=i.useState(""),[N,q]=i.useState(""),[S,K]=i.useState(""),[H,Q]=i.useState(!1),[X,C]=i.useState(!1),[a,n]=i.useState({name:"",phone:"",email:"",source:"site",budgetMin:"",budgetMax:"",desiredRooms:"",desiredHouse:"",notes:""}),[O,P]=i.useState(!1),[V,y]=i.useState([]),b=i.useRef(null),R=i.useCallback(async()=>{try{const e=await z("/api/admin/crm/stats");B(e)}catch(e){console.debug("[crm] Failed to fetch stats:",e)}},[]),_=i.useCallback(async()=>{A(!0);try{const e=new URLSearchParams;e.set("page",String(j)),e.set("limit","30"),f&&e.set("status",f),c&&e.set("source",c),v&&e.set("house",v),N&&e.set("rooms",N),S&&e.set("search",S);const s=await z(`/api/admin/crm/leads?${e}`);D(s.data),I(s.total),W(s.totalPages)}catch(e){console.debug("[crm] Failed to fetch leads:",e)}finally{A(!1)}},[j,f,c,v,N,S]);i.useEffect(()=>{R()},[R]),i.useEffect(()=>{_()},[_]);const Z=i.useCallback(async e=>{if(!e||e.length<4){y([]);return}try{const s=await z(`/api/admin/crm/clients/check-duplicates?phone=${encodeURIComponent(e)}`,{suppressToast:!0});y(s||[])}catch(s){console.debug("[crm] Failed to check duplicates:",s),y([])}},[]),ee=e=>{n(s=>({...s,phone:e})),b.current&&clearTimeout(b.current),b.current=setTimeout(()=>{Z(e)},500)};i.useEffect(()=>()=>{b.current&&clearTimeout(b.current)},[]);const te=async()=>{if(!a.name||!ge(a.phone)){E({title:"ÐаполниÑе Ð¸Ð¼Ñ Ð¸ ÑелеÑон",variant:"destructive"});return}P(!0);try{const e={name:a.name,phone:a.phone,source:a.source};a.email&&(e.email=a.email),a.budgetMin&&(e.budgetMin=Number(a.budgetMin)),a.budgetMax&&(e.budgetMax=Number(a.budgetMax)),a.desiredRooms&&(e.desiredRooms=Number(a.desiredRooms)),a.desiredHouse&&(e.desiredHouse=Number(a.desiredHouse)),a.notes&&(e.notes=a.notes),await z("/api/admin/crm/leads",{method:"POST",body:JSON.stringify(e)}),E({title:"ÐаÑвка Ñоздана"}),C(!1),n({name:"",phone:"",email:"",source:"site",budgetMin:"",budgetMax:"",desiredRooms:"",desiredHouse:"",notes:""}),y([]),_(),R()}catch(e){console.debug("[crm] Failed to create lead:",e)}finally{P(!1)}},l=w||{},se=w?[{label:"ÐовÑе",value:(l.new||0)+(l.claimed||0),color:"text-blue-400"},{label:"Ð ÑабоÑе",value:(l.in_progress||0)+(l.awaiting_client||0)+(l.call_attempted||0)+(l.call_completed||0)+(l.no_answer||0)+(l.callback_later||0)+(l.need_discussed||0)+(l.selection_prepared||0)+(l.selection_sent||0)+(l.client_thinking||0)+(l.high_interest||0),color:"text-yellow-400"},{label:"ÐÑÑÑеÑи/ÐÑони",value:(l.meeting_agreed||0)+(l.meeting_scheduled||0)+(l.booking_in_progress||0)+(l.deal_in_progress||0),color:"text-purple-400"},{label:"ÐÑодажи",value:l.won||0,color:"text-green-400"},{label:"ÐоÑеÑÑнÑ",value:l.lost||0,color:"text-zinc-400"},{label:"Спам/ÐÑбли",value:(l.spam||0)+(l.duplicate||0),color:"text-red-400"},{label:"ÐÑоÑÑоÑено задаÑ",value:l.overdueTasks||0,color:(l.overdueTasks||0)>0?"text-red-400":"text-zinc-400"}]:[];return t.jsxs("div",{className:"space-y-6","data-testid":"admin-crm",children:[t.jsxs("div",{className:"flex items-center justify-between gap-2 flex-wrap",children:[t.jsx("h1",{className:"text-xl font-semibold text-white","data-testid":"text-crm-title",children:"CRM â ÐаÑвки"}),t.jsxs(o,{onClick:()=>C(!0),size:"sm","data-testid":"button-create-lead",children:[t.jsx(fe,{className:"w-4 h-4 mr-1"})," ÐÐ¾Ð²Ð°Ñ Ð·Ð°Ñвка"]})]}),w&&t.jsx("div",{className:"grid grid-cols-3 sm:grid-cols-7 gap-3","data-testid":"crm-stats",children:se.map(e=>t.jsxs("div",{className:"bg-zinc-900 border border-zinc-800 rounded-md p-3 text-center","data-testid":`stat-card-${e.label}`,children:[t.jsx("div",{className:`text-2xl font-bold ${e.color}`,"data-testid":`stat-value-${e.label}`,children:e.value}),t.jsx("div",{className:"text-zinc-500 text-xs mt-1",children:e.label})]},e.label))}),t.jsxs("div",{className:"flex items-center gap-2 flex-wrap","data-testid":"source-toggle",children:[t.jsx(o,{variant:c===""?"default":"outline",size:"sm",onClick:()=>{T(""),d(1)},className:c===""?"":"border-zinc-700 text-zinc-400","data-testid":"button-all-leads",children:"ÐÑе заÑвки"}),t.jsx(o,{variant:c==="site"?"default":"outline",size:"sm",onClick:()=>{T("site"),d(1)},className:c==="site"?"":"border-zinc-700 text-zinc-400","data-testid":"button-site-leads",children:"С ÑайÑа"})]}),t.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[t.jsxs("div",{className:"relative flex-1 min-w-[200px]",children:[t.jsx(ve,{className:"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-zinc-500"}),t.jsx(g,{placeholder:"ÐоиÑк по имени или ÑелеÑонÑ...",value:S,onChange:e=>{K(e.target.value),d(1)},className:"pl-9 bg-zinc-900 border-zinc-700","data-testid":"input-search-leads"})]}),t.jsxs(o,{variant:"outline",size:"sm",onClick:()=>Q(!H),className:"border-zinc-700","data-testid":"button-toggle-filters",children:[t.jsx(Ne,{className:"w-4 h-4 mr-1"})," ФилÑÑÑÑ"]})]}),H&&t.jsxs("div",{className:"grid grid-cols-2 sm:grid-cols-4 gap-3 bg-zinc-900 border border-zinc-800 rounded-md p-4",children:[t.jsxs(x,{value:f,onValueChange:e=>{J(e==="all"?"":e),d(1)},children:[t.jsx(m,{"data-testid":"select-filter-status",children:t.jsx(u,{placeholder:"СÑаÑÑÑ"})}),t.jsxs(h,{children:[t.jsx(r,{value:"all",children:"ÐÑе ÑÑаÑÑÑÑ"}),Object.entries(ze).map(([e,s])=>t.jsx(r,{value:e,children:s},e))]})]}),t.jsxs(x,{value:c,onValueChange:e=>{T(e==="all"?"":e),d(1)},children:[t.jsx(m,{"data-testid":"select-filter-source",children:t.jsx(u,{placeholder:"ÐÑÑоÑник"})}),t.jsxs(h,{children:[t.jsx(r,{value:"all",children:"ÐÑе иÑÑоÑники"}),Object.entries(k).map(([e,s])=>t.jsx(r,{value:e,children:s},e))]})]}),t.jsxs(x,{value:v,onValueChange:e=>{Y(e==="all"?"":e),d(1)},children:[t.jsx(m,{"data-testid":"select-filter-house",children:t.jsx(u,{placeholder:"Ðом"})}),t.jsxs(h,{children:[t.jsx(r,{value:"all",children:"ÐÑе дома"}),[1,2,3,4,5,6,7,8].map(e=>t.jsxs(r,{value:String(e),children:["Ðом ",e]},e))]})]}),t.jsxs(x,{value:N,onValueChange:e=>{q(e==="all"?"":e),d(1)},children:[t.jsx(m,{"data-testid":"select-filter-rooms",children:t.jsx(u,{placeholder:"ÐомнаÑÑ"})}),t.jsxs(h,{children:[t.jsx(r,{value:"all",children:"ÐÑе"}),[1,2,3,4,5].map(e=>t.jsxs(r,{value:String(e),children:[e,"-комн."]},e))]})]})]}),t.jsxs("div",{className:"bg-zinc-900 border border-zinc-800 rounded-md overflow-visible",children:[t.jsx("div",{className:"overflow-x-auto",children:t.jsxs("table",{className:"w-full text-sm","data-testid":"table-leads",children:[t.jsx("thead",{children:t.jsxs("tr",{className:"border-b border-zinc-800 text-zinc-500 text-xs",children:[t.jsx("th",{className:"text-left px-4 py-3",children:"ÐлиенÑ"}),t.jsx("th",{className:"text-left px-4 py-3",children:"ÐонÑакÑÑ"}),t.jsx("th",{className:"text-left px-4 py-3",children:"СÑаÑÑÑ"}),t.jsx("th",{className:"text-left px-4 py-3",children:"ÐÑÑоÑник"}),t.jsx("th",{className:"text-left px-4 py-3",children:"ÐÑджеÑ"}),t.jsx("th",{className:"text-left px-4 py-3",children:"ÐожеланиÑ"}),t.jsx("th",{className:"text-left px-4 py-3",children:"ÐаÑа"})]})}),t.jsx("tbody",{children:G?t.jsx("tr",{children:t.jsx("td",{colSpan:7,className:"text-center py-10 text-zinc-500","data-testid":"text-loading",children:"ÐагÑÑзка..."})}):F.length===0?t.jsx("tr",{children:t.jsx("td",{colSpan:7,className:"text-center py-10 text-zinc-500","data-testid":"text-no-leads",children:"ÐÐµÑ Ð·Ð°Ñвок"})}):F.map(e=>t.jsxs("tr",{className:"border-b border-zinc-800/50 cursor-pointer transition-colors hover-elevate",onClick:()=>p(`/crm/${e.id}`),"data-testid":`row-lead-${e.id}`,children:[t.jsxs("td",{className:"px-4 py-3",children:[t.jsx("div",{className:"text-white font-medium","data-testid":`text-lead-name-${e.id}`,children:e.name}),e.notes&&t.jsx("div",{className:"text-zinc-500 text-xs truncate max-w-[200px]",children:e.notes})]}),t.jsxs("td",{className:"px-4 py-3",children:[t.jsxs("div",{className:"flex items-center gap-1 text-zinc-300",children:[t.jsx(ie,{className:"w-3 h-3"})," ",e.phone]}
1),e.email&&t.jsxs("div",{className:"flex items-center gap-1 text-zinc-500 text-xs mt-0.5",children:[t.jsx(Se,{className:"w-3 h-3"})," ",e.email]})]}),t.jsx("td",{className:"px-4 py-3",children:t.jsx(be,{className:`${je[e.status]||"bg-zinc-500/20 text-zinc-400 border-zinc-500/30"} border text-xs no-default-hover-elevate no-default-active-elevate`,"data-testid":`badge-lead-status-${e.id}`,children:L[e.status]||e.status})}),t.jsxs("td",{className:"px-4 py-3",children:[t.jsx("span",{className:"text-zinc-400 text-xs","data-testid":`text-lead-source-${e.id}`,children:k[e.source]||e.source}),e.createdBy&&e.createdBy.startsWith("СайÑ")&&t.jsx("div",{className:"text-emerald-500/80 text-[10px] mt-0.5",children:e.createdBy})]}),t.jsx("td",{className:"px-4 py-3 text-zinc-300 text-xs",children:e.budgetMin||e.budgetMax?t.jsxs(t.Fragment,{children:[e.budgetMin?$(e.budgetMin):"â"," â ",e.budgetMax?$(e.budgetMax):"â"]}):"â"}),t.jsxs("td",{className:"px-4 py-3 text-zinc-400 text-xs",children:[e.desiredRooms&&t.jsxs("span",{className:"mr-2",children:[e.desiredRooms,"-комн."]}),e.desiredHouse&&t.jsxs("span",{children:["Ðом ",e.desiredHouse]}),!e.desiredRooms&&!e.desiredHouse&&"â"]}),t.jsx("td",{className:"px-4 py-3 text-zinc-500 text-xs whitespace-nowrap",children:new Date(e.createdAt).toLocaleDateString("ru-RU")})]},e.id))})]})}),M>1&&t.jsxs("div",{className:"flex items-center justify-between gap-2 px-4 py-3 border-t border-zinc-800",children:[t.jsxs("span",{className:"text-zinc-500 text-xs","data-testid":"text-total-leads",children:["ÐÑего: ",U]}),t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx(o,{variant:"ghost",size:"sm",disabled:j<=1,onClick:()=>d(e=>e-1),"data-testid":"button-prev-page",children:t.jsx(re,{className:"w-4 h-4"})}),t.jsxs("span",{className:"text-zinc-400 text-sm","data-testid":"text-page-info",children:[j," / ",M]}),t.jsx(o,{variant:"ghost",size:"sm",disabled:j>=M,onClick:()=>d(e=>e+1),"data-testid":"button-next-page",children:t.jsx(ne,{className:"w-4 h-4"})})]})]})]}),t.jsx(de,{open:X,onOpenChange:C,children:t.jsxs(ce,{className:"max-w-md",children:[t.jsx(oe,{children:t.jsx(xe,{children:"ÐÐ¾Ð²Ð°Ñ Ð·Ð°Ñвка"})}),t.jsxs("div",{className:"space-y-3",children:[t.jsx(g,{placeholder:"ÐÐ¼Ñ ÐºÐ»Ð¸ÐµÐ½Ñа *",value:a.name,onChange:e=>n(s=>({...s,name:e.target.value})),"data-testid":"input-lead-name"}),t.jsx(g,{type:"tel",inputMode:"tel",placeholder:"ТелеÑон *",value:a.phone,onChange:e=>ee(me(e)),"data-testid":"input-lead-phone"}),V.length>0&&t.jsxs("div",{className:"flex items-start gap-2 bg-amber-500/10 border border-amber-500/30 rounded-md p-3","data-testid":"banner-duplicate-warning",children:[t.jsx(ue,{className:"w-4 h-4 text-amber-400 mt-0.5 shrink-0"}),t.jsxs("div",{className:"text-xs text-amber-300",children:[t.jsx("div",{className:"font-medium mb-1",children:"ÐозможнÑе дÑбли:"}),V.map(e=>t.jsxs("div",{"data-testid":`text-duplicate-${e.id}`,children:[e.name," (",e.phone,")"]},e.id))]})]}),t.jsx(g,{placeholder:"Email",value:a.email,onChange:e=>n(s=>({...s,email:e.target.value})),"data-testid":"input-lead-email"}),t.jsxs(x,{value:a.source,onValueChange:e=>n(s=>({...s,source:e})),children:[t.jsx(m,{"data-testid":"select-lead-source",children:t.jsx(u,{})}),t.jsx(h,{children:Object.entries(k).map(([e,s])=>t.jsx(r,{value:e,children:s},e))})]}),t.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[t.jsx(g,{placeholder:"ÐÑÐ´Ð¶ÐµÑ Ð¾Ñ (млн â½)",type:"number",step:"0.1",value:a.budgetMin,onChange:e=>n(s=>({...s,budgetMin:e.target.value})),"data-testid":"input-lead-budget-min"}),t.jsx(g,{placeholder:"ÐÑÐ´Ð¶ÐµÑ Ð´Ð¾ (млн â½)",type:"number",step:"0.1",value:a.budgetMax,onChange:e=>n(s=>({...s,budgetMax:e.target.value})),"data-testid":"input-lead-budget-max"})]}),t.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[t.jsxs(x,{value:a.desiredRooms,onValueChange:e=>n(s=>({...s,desiredRooms:e})),children:[t.jsx(m,{"data-testid":"select-lead-rooms",children:t.jsx(u,{placeholder:"ÐомнаÑÑ"})}),t.jsx(h,{children:[1,2,3,4,5].map(e=>t.jsxs(r,{value:String(e),children:[e,"-комн."]},e))})]}),t.jsxs(x,{value:a.desiredHouse,onValueChange:e=>n(s=>({...s,desiredHouse:e})),children:[t.jsx(m,{"data-testid":"select-lead-house",children:t.jsx(u,{placeholder:"Ðом"})}),t.jsx(h,{children:[1,2,3,4,5,6,7,8].map(e=>t.jsxs(r,{value:String(e),children:["Ðом ",e]},e))})]})]}),t.jsx(he,{placeholder:"ÐамеÑки",value:a.notes,onChange:e=>n(s=>({...s,notes:e.target.value})),"data-testid":"input-lead-notes"})]}),t.jsxs(pe,{children:[t.jsx(o,{variant:"outline",onClick:()=>C(!1),"data-testid":"button-cancel-lead",children:"ÐÑмена"}),t.jsx(o,{onClick:te,disabled:O,"data-testid":"button-submit-lead",children:O?"Создание...":"СоздаÑÑ"})]})]})})]})}export{Qe 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.