1import{b as O,s as T,j as e,e as B,a1 as _e,x as M,U as Ue,F as ae,G as re,H as ne,a2 as se,J as oe,_ as We,$ as Xe,a0 as Ge,a3 as He,I as De,B as z,D as Je,m as Qe,o as Ze,p as et,L as W,a4 as tt,c as X,u as at}from"./index-BF28QI0-.js";import{cJ as p,f as rt,b as nt,g as st,cw as ot,H as lt,c8 as Me,r as Fe,cq as it}from"./lucide-ikoner-cDyDDUWU.js";import{g as Oe,a as ct,b as dt,c as ut}from"./dateUtils-I8-aabbB.js";import{B as Ne}from"./form-CLLX3wmC.js";import{P as mt,a as gt}from"./page-B_k_ESBv.js";import{c as pt,d as ht}from"./register-B4zbyCSF.js";import{C as q,T as _t,a as I}from"./object-CHfF9TIF.js";import{e as Se}from"./dateRange-DXfRmDWU.js";import{u as Ae}from"./useOrdersBySource-Cl5KDaNw.js";import{f as w,a as me,S as ee,b as C}from"./StatKpi-B02MKEoH.js";import{S as $}from"./StatLineChart-CYY2uPHy.js";import{d as Ee}from"./differenceInDays-BqfPsiHs.js";import{T as xe,a as ve,b as G,c as E,d as fe,e as K}from"./table-ClNxvzSu.js";import{R as xt}from"./resilient-image-CjxFifsS.js";import{u as vt}from"./useProductImageFallbacks-Bu4UTmYO.js";import{f as Ke}from"./fetchAllRows--bL3s_MJ.js";import{S as ft,a as jt,b as yt,c as bt,d as Nt}from"./select-Baay7JdV.js";import{T as St}from"./TeamMemberAvatar-CPtTgfML.js";import"./index-C-Sw174D.js";import"./index-qVSQreeY.js";import"./index-CxJRWVB6.js";import"./index-oK8Oy_Op.js";import"./index-DZZ5z1cz.js";import"./text-Cz91ulOo.js";import"./index-Bz9dXtTt.js";import"./generateCategoricalChart-DJP5wU4t.js";import"./index-1_vBThi_.js";import"./BarChart-ByBjeurp.js";import"./CartesianGrid-CBV8-O2w.js";import"./LineChart-DxjGuTG3.js";import"./differenceInCalendarDays-CUNwG8D2.js";import"./constants-IukJmt8Y.js";import"./imageHostPolicy-BpYoYP31.js";function te(t){return O({queryKey:["crm-overview-statistics-rpc",t],queryFn:async()=>{const{data:a,error:r}=await T.rpc("get_crm_overview_statistics",{p_date_from:t.dateRange?.from?.toISOString()||null,p_date_to:t.dateRange?.to?.toISOString()||null,p_assigned_to:t.assignedTo?.length?t.assignedTo:null,p_sales_channels:t.salesChannels?.length?t.salesChannels:null});if(r)throw console.error("Error fetching CRM overview statistics:",r),r;const s=Array.isArray(a)?a[0]:a;return{total_orders:Number(s?.total_orders||0),total_revenue:Number(s?.total_revenue||0),invoiced_revenue:Number(s?.invoiced_revenue||0),total_cost:Number(s?.total_cost||0),total_profit:Number(s?.total_profit||0),avg_order_value:Number(s?.avg_order_value||0),unique_customers:Number(s?.unique_customers||0),margin_percent:Number(s?.margin_percent||0)}},staleTime:2*60*1e3,gcTime:5*60*1e3,placeholderData:a=>a,enabled:!!t.dateRange})}function kt(t,a=10){return O({queryKey:["top-contacts-statistics-rpc",t,a],queryFn:async()=>{const{data:r,error:n}=await T.rpc("get_top_contacts_statistics",{p_date_from:t.dateRange?.from?.toISOString()||null,p_date_to:t.dateRange?.to?.toISOString()||null,p_limit:a});if(n)throw console.error("Error fetching top contacts statistics:",n),n;return(r||[]).map(s=>({contact_id:s.contact_id,contact_name:s.contact_name||"Okänd",contact_email:s.contact_email,company_id:s.company_id,company_name:s.company_name||"Okänt företag",assigned_to_id:s.assigned_to_id,assigned_to_name:s.assigned_to_name||"Ej tilldelad",avatar_url:s.avatar_url,total_sales:Number(s.total_sales||0),order_count:Number(s.order_count||0),avg_order_value:Number(s.avg_order_value||0)}))},staleTime:2*60*1e3,gcTime:5*60*1e3,enabled:!!t.dateRange})}function Ve(t){return O({queryKey:["order-trend-data-rpc",t],queryFn:async()=>{const{data:a,error:r}=await T.rpc("get_order_trend_data",{p_date_from:t.dateRange?.from?.toISOString()||null,p_date_to:t.dateRange?.to?.toISOString()||null,p_assigned_to:t.assignedTo?.length?t.assignedTo:null});if(r)throw console.error("Error fetching order trend data:",r),r;return(a||[]).map(n=>({period:n.period,order_count:Number(n.order_count||0),total_revenue:Number(n.total_revenue||0)}))},staleTime:2*60*1e3,gcTime:5*60*1e3,enabled:!!t.dateRange})}function Tt(t){return O({queryKey:["customer-growth-chart-rpc",t],queryFn:async()=>{const{data:a,error:r}=await T.rpc("get_customer_growth_chart",{p_date_from:t.dateRange?.from?.toISOString()||null,p_date_to:t.dateRange?.to?.toISOString()||null,p_assigned_to:t.assignedTo?.length?t.assignedTo:null,p_sales_channels:t.salesChannels?.length?t.salesChannels:null});if(r)throw console.error("Error fetching customer growth chart:",r),r;return(a||[]).map(n=>({period:n.period,nya:Number(n.nya||0),aterkommande:Number(n.aterkommande||0)}))},staleTime:2*60*1e3,gcTime:5*60*1e3,enabled:!!t.dateRange})}function Le(t){return O({queryKey:["repeat-customer-stats-rpc",t],queryFn:async()=>{const{data:a,error:r}=await T.rpc("get_repeat_customer_stats",{p_date_from:t.dateRange?.from?.toISOString()||null,p_date_to:t.dateRange?.to?.toISOString()||null,p_assigned_to:t.assignedTo?.length?t.assignedTo:null});if(r)throw console.error("Error fetching repeat customer stats:",r),r;const n=Array.isArray(a)?a[0]:a;return{total_customers:Number(n?.total_customers||0),repeat_customers:Number(n?.repeat_customers||0),repeat_rate:Number(n?.repeat_rate||0)}},staleTime:2*60*1e3,gcTime:5*60*1e3,enabled:!!t.dateRange})}const wt=(t,a,r="created_at")=>(a.dateRange?.from&&(t=t.gte(r,Se(a.dateRange.from,r))),a.dateRange?.to&&(t=t.lte(r,Se(a.dateRange.to,r))),t),Rt=5*60*1e3,Ct=10*60*1e3,qe=2*60*1e3,Dt=t=>O({queryKey:["crm-quotes-analytics",t],queryFn:async()=>{let a=T.from("crm_quotes_analytics").select("*");a=wt(a,t),t.assignedTo?.length&&(a=a.in("assigned_to_id",t.assignedTo)),t.companies?.length&&(a=a.in("company_id",t.companies)),t.quoteStatus?.length&&(a=a.in("status",t.quoteStatus));const{data:r,error:n}=await a;if(n)throw n;return r},staleTime:qe,gcTime:Rt,placeholderData:a=>a,enabled:!!t.dateRange}),Pe=t=>O({queryKey:["crm-top-customers",t],queryFn:async()=>{const{data:a,error:r}=await T.rpc("get_top_customers",{p_date_from:t.dateRange?.from?t.dateRange.from.toISOString():null,p_date_to:t.dateRange?.to?t.dateRange.to.toISOString():null,p_company_ids:t.companies?.length?t.companies:null,p_assigned_to:t.assignedTo?.length?t.assignedTo:null,p_limit:10});if(r)throw r;const n=new Date;return(a??[]).map(s=>
1({company_id:s.company_id,company_name:s.company_name,company_favicon:s.company_favicon??void 0,org_number:s.org_number??null,assigned_to_name:s.assigned_to_name??"Ej tilldelad",assigned_to_image:s.assigned_to_image??null,total_sales:Number(s.total_sales||0),order_count:Number(s.order_count||0),avg_order_value:Number(s.avg_order_value||0),last_order_date:s.last_order_date,year:n.getFullYear(),month:n.getMonth()+1,quarter:Math.floor(n.getMonth()/3)+1}))},staleTime:qe,gcTime:Ct,enabled:!!t.dateRange});function Mt(t){return O({queryKey:["company-goal",t],queryFn:async()=>{const{data:a,error:r}=await T.from("company_goals").select("*").eq("goal_year",t).maybeSingle();if(r)throw r;return a}})}function J({title:t,subtitle:a,columns:r,data:n,loading:s,defaultSortKey:d,defaultSortDir:u="desc",maxRows:o=10,emptyMessage:i="Ingen data tillgänglig",className:m,onRowClick:x,renderExpanded:j,canExpand:k,rowKey:b,onVisibleRowsChange:_}){const[l,N]=p.useState(null),[f,R]=p.useState(d||r[0]?.key||""),[v,A]=p.useState(u),D=c=>{f===c?A(F=>F==="asc"?"desc":"asc"):(R(c),A("desc"))},g=p.useMemo(()=>{const c=r.find(F=>F.key===f);return c?.sortValue?[...n].sort((F,h)=>{const y=c.sortValue(F),S=c.sortValue(h);return typeof y=="number"&&typeof S=="number"?v==="asc"?y-S:S-y:v
1==="asc"?String(y).localeCompare(String(S)):String(S).localeCompare(String(y))}).slice(0,o):n.slice(0,o)},[n,f,v,r,o]);return p.useEffect(()=>{_?.(g)},[g,_]),s?e.jsxs("div",{className:B("space-y-3",m),children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-semibold",children:t}),a&&e.jsx("p",{className:"text-xs text-muted-foreground",children:a})]}),e.jsx("div",{className:"space-y-2",children:Array.from({length:5}).map((c,F)=>e.jsx(_e,{className:"h-10 w-full"},F))})]}):e.jsxs("div",{className:B("space-y-3",m),children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-semibold",children:t}),a&&e.jsx("p",{className:"text-xs text-muted-foreground",children:a})]}),n.length===0?e.jsx("div",{className:"flex items-center justify-center h-24 text-sm text-muted-foreground border rounded-lg",children:i}):e.jsx("div",{className:"border rounded-lg overflow-hidden",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{children:e.jsx("tr",{className:"border-b bg-muted/30",children:r.map(c=>e.jsx("th",{className:B("px-3 py-2 text-xs font-medium text-muted-foreground uppercase tracking-wide",c.align==="right"?"text-right":"text-left",c.sortValue&&"cursor-pointer select-none hover:text-foreground transition-colors"),onClick:()=>c.sortValue&&D(c.key),children:e.jsxs("span",{className:"inline-flex items-center gap-1",children:[c.label,c.sortValue&&(f===c.key?v==="asc"?e.jsx(rt,{className:"h-3 w-3"}):e.jsx(nt,{className:"h-3 w-3"}):e.jsx(st,{className:"h-3 w-3 opacity-30"}))]})},c.key))})}),e.jsx("tbody",{className:"divide-y",children:g.map((c,F)=>{const h=b?b(c):String(F),y=!!j&&(k?k(c):!0),S=y&&l===h,V=y||!!x;return e.jsxs(p.Fragment,{children:[e.jsx("tr",{className:B("transition-colors",V&&"cursor-pointer hover:bg-muted/50",S&&"bg-muted/40"),onClick:()=>{y&&N(S?null:h),x?.(c)},children:r.map(L=>e.jsx("td",{className:B("px-3 py-2",L.align==="right"?"text-right":"text-left"),children:L.render(c,F,S)},L.key))}),S&&e.jsx("tr",{className:"bg-muted/20",children:e.jsx("td",{colSpan:r.length,className:"px-3 pb-3 pt-0",children:j(c)})})]},h)})})]})})]})}const Ft=.005;function Ot(t,a){const r=t-a;return r>Ft?r:0}const H="2026-03-10";function At(t){return t?t>=H:!1}function le(t){return String(Math.round(t)).replace(/\B(?=(\d{3})+(?!\d))/g," ")}function ke(t){return t?t.matbar?new Intl.NumberFormat("sv-SE",{style:"currency",currency:"SEK",minimumFractionDigits:0,maximumFractionDigits:0}).format(t.belopp):`Kan inte mätas före ${t.golv||H}`:"â"}function Et(t){if(!t)return"";if(!t.matbar)return`Ordrar före ${t.golv||H} saknar leveransdatum, sÃ¥ stocken kan inte räknas om.`;const a=[`${le(t.antal)} order`],r=[];return t.avraknat_avbrutna>0&&r.push(`${le(t.avraknat_avbrutna)} ${t.avraknat_avbrutna===1?"avbruten":"avbrutna"}`),t.avraknat_arv>0&&r.push(`${le(t.avraknat_arv)} före ${t.golv||H}`),r.length>0&&a.push(`avräknat ${r.join(" och ")}`),a.join(" · ")}function ie(t){return{matbar:!1,golv:H,datum:t,antal:0,belopp:0,avraknat_avbrutna:0,avraknat_arv:0}}function Kt(t,a=[]){return O({queryKey:["order-backlog-at-date",t,a],queryFn:async()=>{if(!t)return ie("");if(!At(t))return ie(t);const{data:r,error:n}=await T.rpc("get_order_backlog_at_date",{p_date:t,p_assigned_to:a.length?a:void 0});if(n)throw console.error("Error fetching order backlog at date:",n),n;const s=Array.isArray(r)?r[0]:r;return!s||s.measurable!==!0?ie(t):{matbar:!0,golv:s.floor_date||H,datum:s.at_date||t,antal:Number(s.order_count||0),belopp:Number(s.backlog_amount||0),avraknat_avbrutna:Number(s.excluded_cancelled||0),avraknat_arv:Number(s.excluded_legacy||0)}},staleTime:2*60*1e3,gcTime:5*60*1e3,placeholderData:r=>r,enabled:!!t})}function Vt(t){if(!t?.to)return;const a=t.to;return`${a.getFullYear()}-${String(a.getMonth()+1).padStart(2,"0")}-${String(a.getDate()).padStart(2,"0")}`}function $e(t){if(!t)return!1;const a=new Date,{from:r,to:n}=t,s=r.getFullYear()===a.getFullYear()&&r.getMonth()===0&&r.getDate()===1,u=Math.abs(a.getTime()-n.getTime())<2*24*60*60*1e3;return s&&u}function Lt(t,a){if(!a||!$e(a))return null;const r=new Date,n=new Date(r.getFullYear(),0,1),s=Math.max(1,Math.floor((r.getTime()-n.getTime())/(1e3*60*60*24)));return t/s*365}function U(t){return t>=1e6?`${(t/1e6).toFixed(1).replace(".0","")} Mkr`:w(t,"currency")}function P({label:t,value:a,note:r,tone:n}){return e.jsxs(q,{children:[e.jsx("div",{className:"z-sub",style:{marginTop:0},children:t}),e.jsx("div",{className:"z-big",children:a}),r&&e.jsx("div",{className:"z-sub",style:{fontSize:12,marginTop:2,color:n==="positive"?"var(--z-st-gr-fg)":n==="negative"?"var(--z-st-r-fg)":void 0},children:r})]})}function ce({children:t}){return e.jsx("div",{style:{display:"grid",gridTemplateColumns:"repeat(auto-fit, minmax(170px, 1fr))",gap:14},children:t})}function qt({filters:t}){const{data:a,isLoading:r}=te(t),{data:n,isLoading:s}=Ve(t),{data:d}=Le(t),{data:u,isLoading:o}=Pe(t),{data:i,isLoading:m}=Ae({dateRange:t.dateRange,assignedTo:t.assignedTo}),x=Vt(t.dateRange),{data:j}
1=Kt(x,t.assignedTo),k=new Date().getFullYear(),{data:b}=Mt(k),_=$e(t.dateRange),l=a?.invoiced_revenue||0,N=p.useMemo(()=>Lt(l,t.dateRange),[l,t.dateRange]),f=p.useMemo(()=>{if(!_||!b||!b.revenue_target)return null;const c=b.revenue_target,h=(N||0)-c,y=c>0?h/c*100:0,S=new Date,V=new Date(S.getFullYear(),0,1),L=new Date(S.getFullYear(),11,31),Q=Math.max(1,Math.ceil((L.getTime()-S.getTime())/(1e3*60*60*24))),Y=Math.max(1,Math.floor((S.getTime()-V.getTime())/(1e3*60*60*24))),je=Math.max(0,c-l),ye=je/Q*7,be=l/Y*7,Ye=ye-be;return{budget:c,diff:h,diffPercent:y,requiredPerWeek:ye,currentPerWeek:be,deltaPerWeek:Ye,remaining:je}},[_,b,N,l]),R=p.useMemo(()=>n?n.map(c=>({period:c.period,value:c.total_revenue})):[],[n]),v=[{key:"name",label:"Kund",render:c=>e.jsx("span",{className:"font-medium text-sm",children:c.company_name}),sortValue:c=>c.company_name},{key:"orders",label:"Order",align:"right",render:c=>e.jsx("span",{className:"text-sm tabular-nums",children:c.order_count}),sortValue:c=>c.order_count},{key:"revenue",label:"OrderingÃ¥ng",align:"right",render:c=>e.jsx("span",{className:"text-sm font-medium tabular-nums",children:M(c.total_sales,"SEK",{decimals:0})}),sortValue:c=>c.total_sales}],A=c=>{if(!c)return"";const F=c.split("-");return F.length>=2?`${F[1]}/${F[0]?.slice(2)}`:c},D=Ot(a?.total_revenue??0,a?.invoiced_revenue??0),g=D>0?`varav ${M(D,"SEK",{decimals:0})} ej levererat`:"allt levererat";return r?e.jsx(ce,{children:[1,2,3,4,5].map(c=>e.jsx(q,{children:e.jsx("div",{className:"z-sub",children:"Laddarâ¦"})},c))}):e.jsxs(e.Fragment,{children:[e.jsxs(ce,{children:[e.jsx(P,{label:"Fakturerat",value:w(a?.invoiced_revenue||0,"currency")}),e.jsx(P,{label:"OrderingÃ¥ng",value:w(a?.total_revenue||0,"currency"),note:g}),e.jsx(P,{label:"Order",value:w(a?.total_orders||0)}),e.jsx(P,{label:"Bruttomarginal",value:w(a?.margin_percent||0,"percent")}),e.jsx(P,{label:"Ã
terköpsgrad",value:w(d?.repeat_rate||0,"percent")}),e.jsx(P,{label:x?`Orderstock ${x}`:"Orderstock",value:j?.matbar===!1?e.jsx("span",{style:{fontSize:15,fontWeight:500},children:ke(j)}):ke(j),note:Et(j)})]}),N!==null&&e.jsxs(ce,{children:[e.jsx(P,{label:"Ã
rsprognos (run rate)",value:U(N),note:"Baseras pÃ¥ nuvarande takt"}),f&&e.jsxs(e.Fragment,{children:[e.jsx(P,{label:"Budget",value:U(f.budget)}),e.jsx(P,{label:"Gap (prognos vs budget)",value:`${f.diff>=0?"+":""}${U(f.diff)}`,note:f.diff<0?`Kräver +${Math.abs(f.diffPercent).toFixed(0)}% takt`:"Ãver budget",tone:f.diff>=0?"positive":"negative"}),e.jsx(P,{label:"Behövd takt",value:`${U(f.requiredPerWeek)}/v`,note:`Nu: ${U(f.currentPerWeek)}/v (${f.deltaPerWeek<=0?"":"+"}${U(f.deltaPerWeek)})`,tone:f.deltaPerWeek<=0?"positive":"negative"})]})]}),e.jsx(q,{padded:!1,children:e.jsx($,{title:"OrderingÃ¥ng över tid",data:R,loading:s,formatValue:c=>`${(c/1e3).toFixed(0)}k`,formatLabel:A,valueName:"OrderingÃ¥ng"})}),e.jsx(q,{padded:!1,children:e.jsx($,{title:"OrderingÃ¥ng per källa",data:(i||[]).map(c=>({period:c.label,value:c.total})),loading:m,variant:"bar",formatValue:c=>`${(c/1e3).toFixed(0)}k`,valueName:"OrderingÃ¥ng",height:180})}),e.jsx(q,{padded:!1,children:e.jsx(J,{title:"Topp 5 kunder",columns:v,data:u||[],loading:o,maxRows:5,defaultSortKey:"revenue"})})]})}function Pt(t){const{dateFrom:a,dateTo:r,status:n,salesChannel:s}=t;return O({queryKey:["salesperson-statistics-rpc",a,r,n,s],queryFn:async()=>{const{data:d,error:u}=await T.rpc("get_salesperson_statistics",{p_date_from:a?.toISOString()||null,p_date_to:r?.toISOString()||null,p_status:n||null,p_sales_channel:s==="all"?null:s||null});if(u)throw console.error("Error fetching salesperson statistics:",u),u;return(d||[]).map(o=>({user_id:o.user_id,user_name:o.user_name||"Okänd",avatar_url:o.avatar_url,order_count:Number(o.order_count||0),total_revenue:Number(o.total_revenue||0),total_cost:Number(o.total_cost||0),avg_order_value:Number(o.avg_order_value||0),margin_pct:Number(o.margin_pct||0)}))},staleTime:2*60*1e3,gcTime:5*60*1e3})}function $t(t){const{status:a,dateFrom:r,dateTo:n,salesChannel:s,limit:d=10}=t;return O({queryKey:["top-orders-rpc",a,r,n,s,d],queryFn:async()=>{const{data:u,error:o}
1=await T.rpc("get_top_orders",{p_status:a||null,p_date_from:r?.toISOString()||null,p_date_to:n?.toISOString()||null,p_sales_channel:s==="all"?null:s||null,p_limit:d});if(o)throw console.error("Error fetching top orders:",o),o;return(u||[]).map(i=>({order_id:i.order_id,order_number:i.order_number,customer_name:i.customer_name||"Okänd kund",assigned_to_id:i.assigned_to_id,assigned_to_name:i.assigned_to_name||"Okänd",avatar_url:i.avatar_url,sales_channel:i.sales_channel,total_ex_vat:Number(i.total_ex_vat||0),created_at:i.created_at}))},staleTime:2*60*1e3,gcTime:5*60*1e3})}const It=t=>{const a=Ee(t.to,t.from),r=new Date(t.from);r.setDate(r.getDate()-a);const n=new Date(t.from);return{from:r,to:n}},Te=(t,a)=>{const r=t-a,n=a!==0?r/a*100:0;return{current:t,previous:a,change:r,changePercent:n}};function Bt({filters:t}){const a=Ue(),{data:r,isLoading:n}=te(t),{data:s,isLoading:d}=Ve(t),{data:u,isLoading:o}=Pt({dateFrom:t.dateRange?.from,dateTo:t.dateRange?.to}),{data:i,isLoading:m}=$t({dateFrom:t.dateRange?.from,dateTo:t.dateRange?.to,limit:10}),{data:x,isLoading:j}=Ae({dateRange:t.dateRange,assignedTo:t.assignedTo}),k=p.useMemo(()=>({...t,dateRange:It(t.dateRange)}),[t]),{data:b}=te(k),_=p.useMemo(()=>{const g=r?.total_revenue||0,c=b?.total_revenue||0;return me(Te(g,c).changePercent)},[r,b]),l=p.useMemo(()=>{const g=r?.total_orders||0,c=b?.total_orders||0;return me(Te(g,c).changePercent)},[r,b]),N=p.useMemo(()=>s?s.map(g=>({period:g.period,value:g.total_revenue})):[],[s]),f=p.useMemo(()=>u?[...u].sort((g,c)=>c.total_revenue-g.total_revenue).map(g=>({period:g.user_name,value:g.total_revenue})):[],[u]),R=[{key:"order_number",label:"Order",render:g=>e.jsx("span",{className:"font-mono text-xs text-muted-foreground",children:g.order_number})},{key:"customer",label:"Kund",render:g=>e.jsx("span",{className:"text-sm font-medium",children:g.customer_name}),sortValue:g=>g.customer_name},{key:"assigned",label:"Ansvarig",render:g=>e.jsx("span",{className:"text-sm",children:g.assigned_to_name!=="Okänd"?g.assigned_to_name:"-"})},{key:"value",label:"Värde",align:"right",render:g=>e.jsx("span",{className:"text-sm font-medium tabular-nums",children:M(g.total_ex_vat,"SEK",{decimals:0})}),sortValue:g=>g.total_ex_vat}],v=g=>{if(!g)return"";const c=g.split("-");return c.length>=2?`${c[1]}/${c[0]?.slice(2)}`:g},A=(r?.total_orders||0)>0?(r?.total_revenue||0)/(r?.total_orders||1):0,D=(b?.total_orders||0)>0?((r?.total_orders||0)-(b?.total_orders||0))/(b?.total_orders||1)*100:(r?.total_orders||0)>0?100:0;return e.jsxs("div",{className:"space-y-8",children:[e.jsxs(ee,{children:[e.jsx(C,{label:"Orderingång",value:w(r?.total_revenue||0,"currency"),change:_.text,changeType:_.type,loading:n}),e.jsx(C,{label:"Antal order",value:w(r?.total_orders||0),change:l.text,changeType:l.type,loading:n}),e.jsx(C,{label:"Snittorder",value:w(A,"currency"),loading:n}),e.jsx(C,{label:"Ordertillväxt",value:w(D,"percent"),loading:n})]}),e.jsx($,{title:"Orderingång per månad",data:N,loading:d,formatValue:g=>`${(g/1e3).toFixed(0)}k`,formatLabel:v,valueName:"Orderingång"}),e.jsx($,{title:"Orderingång per källa",data:(x||[]).map(g=>({period:g.label,value:g.total})),loading:j,variant:"bar",formatValue:g=>`${(g/1e3).toFixed(0)}k`,valueName:"Orderingång",height:180}),e.jsx($,{title:"Orderingång per säljare",data:f,loading:o,variant:"bar",formatValue:g=>`${(g/1e3).toFixed(0)}k`,valueName:"Orderingång",height:Math.max(200,f.length*40+40)}),e.jsx(J,{title:"Topp 10 order",columns:R,data:i||[],loading:m,maxRows:10,defaultSortKey:"value",onRowClick:g=>a(`/admin/orders/${g.order_id}`)})]})}function zt({filters:t}){const{data:a,isLoading:r}=Dt(t),n=p.useMemo(()=>{if(!a)return{sent:0,conversion:0,avgResponseDays:0,acceptedValue:0};const i=a.filter(_=>_.status!=="draft").length,m=a.filter(_=>_.status==="accepted"),x=i>0?m.length/i*100:0,j=m.reduce((_,l)=>_+l.grand_total,0),k=m.map(_=>{const l=_,N=l.sent_at?new Date(l.sent_at):new Date(_.created_at),f=l.accepted_at?new Date(l.accepted_at):new Date(_.updated_at);return Ee(f,N)}).filter(_=>_>=0),b=k.length>0?k.reduce((_,l)=>_+l,0)/k.length:0;return{sent:i,conversion:x,avgResponseDays:b,acceptedValue:j}},[a]),s=p.useMemo(()=>
1{if(!a)return[];const i=new Map;return a.forEach(m=>{const x=`${m.year}-${String(m.month).padStart(2,"0")}`,j=i.get(x)||{sent:0,accepted:0};m.status!=="draft"&&j.sent++,m.status==="accepted"&&j.accepted++,i.set(x,j)}),Array.from(i.entries()).sort(([m],[x])=>m.localeCompare(x)).map(([m,{sent:x,accepted:j}])=>({period:m,value:x>0?j/x*100:0}))},[a]),d=p.useMemo(()=>{if(!a)return[];const i=new Map;return a.forEach(m=>{const x=m.assigned_to_id||m.created_by_id||"unknown",j=m.assigned_to_name||m.created_by_name||"Okänd",k=i.get(x)||{name:j,sent:0,accepted:0,value:0};m.status!=="draft"&&k.sent++,m.status==="accepted"&&(k.accepted++,k.value+=m.grand_total),i.set(x,k)}),Array.from(i.values()).map(m=>({...m,conversion:m.sent>0?m.accepted/m.sent*100:0}))},[a]),u=[{key:"name",label:"Säljare",render:i=>e.jsx("span",{className:"text-sm font-medium",children:i.name}),sortValue:i=>i.name},{key:"sent",label:"Skickade",align:"right",render:i=>e.jsx("span",{className:"text-sm tabular-nums",children:i.sent}),sortValue:i=>i.sent},{key:"accepted",label:"Accepterade",align:"right",render:i=>e.jsx("span",{className:"text-sm tabular-nums",children:i.accepted}),sortValue:i=>i.accepted},{key:"conversion",label:"Konvertering",align:"right",render:i=>e.jsxs("span",{className:"text-sm tabular-nums",children:[i.conversion.toFixed(1),"%"]}),sortValue:i=>i.conversion},{key:"value",label:"Accepterat värde",align:"right",render:i=>e.jsx("span",{className:"text-sm font-medium tabular-nums",children:M(i.value,"SEK",{decimals:0})}),sortValue:i=>i.value}],o=i=>{if(!i)return"";const m=i.split("-");return m.length>=2?`${m[1]}/${m[0]?.slice(2)}`:i};return e.jsxs("div",{className:"space-y-8",children:[e.jsxs(ee,{children:[e.jsx(C,{label:"Skickade",value:w(n.sent),loading:r}),e.jsx(C,{label:"Konvertering",value:w(n.conversion,"percent"),loading:r}),e.jsx(C,{label:"Snitt svarstid",value:`${n.avgResponseDays.toFixed(1)} dagar`,loading:r}),e.jsx(C,{label:"Accepterat värde",value:w(n.acceptedValue,"currency"),loading:r})]}),e.jsx($,{title:"Konvertering över tid",data:s,loading:r,formatValue:i=>`${i.toFixed(0)}%`,formatLabel:o,valueName:"Konvertering",height:240}),e.jsx(J,{title:"Offertprestanda per säljare",columns:u,data:d,loading:r,defaultSortKey:"value",maxRows:20})]})}function Yt(t){return O({queryKey:["activities-analytics-rpc",t],queryFn:async()=>{const{data:a,error:r}=await T.rpc("get_activities_analytics",{p_date_from:t.dateRange?.from?.toISOString()||null,p_date_to:t.dateRange?.to?.toISOString()||null,p_assigned_to:t.assignedTo?.length?t.assignedTo:null,p_company_ids:t.companies?.length?t.companies:null,p_activity_type_ids:t.activityTypes?.length?t.activityTypes:null});if(r)throw r;const n=Array.isArray(a)?a[0]:a;return{total:Number(n?.total_activities||0),completed:Number(n?.completed_activities||0),completionRate:Number(n?.completion_rate||0),activitiesPer100k:Number(n?.activities_per_100k||0),perUser:n?.per_user||[],perMonth:n?.per_month||[]}},staleTime:2*60*1e3,gcTime:5*60*1e3,enabled:!!t.dateRange})}function Ut({filters:t}){const{data:a,isLoading:r}=Yt(t),n=a?.perMonth||[],s=p.useMemo(()=>a?a.perUser.map(o=>({...o,completionRate:o.total>0?o.completed/o.total*100:0})):[],[a]),d=[{key:"name",label:"Användare",render:o=>e.jsx("span",{className:"text-sm font-medium",children:o.name}),sortValue:o=>o.name},{key:"total",label:"Totalt",align:"right",render:o=>e.jsx("span",{className:"text-sm tabular-nums",children:o.total}),sortValue:o=>o.total},{key:"completed",label:"Slutförda",align:"right",render:o=>e.jsx("span",{className:"text-sm tabular-nums",children:o.completed}),sortValue:o=>o.completed},{key:"rate",label:"Slutförandegrad",align:"right",render:o=>e.jsxs("span",{className:"text-sm tabular-nums",children:[o.completionRate.toFixed(0),"%"]}),sortValue:o=>o.completionRate}],u=o=>{if(!o)return"";const i=o.split("-");return i.length>=2?`${i[1]}/${i[0]?.slice(2)}`:o};return e.jsxs("div",{className:"space-y-8",children:[e.jsxs(ee,{children:[e.jsx(C,{label:"Totalt aktiviteter",value:w(a?.total??0),loading:r}),e.jsx(C,{label:"Slutförandegrad",value:w(a?.completionRate??0,"percent"),loading:r}),e.jsx(C,{label:"Aktiviteter per 100k omsättning",value:a?.activitiesPer100k?a.activitiesPer100k.toFixed(1):"â",loading:r})]}),e.jsx($,{title:"Aktiviteter över tid",data:n,loading:r,formatLabel:u,valueName:"Aktiviteter",height:240}),e.jsx(J,{title:"Aktivitet per användare",columns:d,data:s,loading:r,defaultSortKey:"total",maxRows:20})]})}const Wt=1e3*60*5,Xt=()=>O({queryKey:["total-companies-count"],queryFn:async()=>{const{count:t,error:a}=await T.from("companies").select("*",{count:"exact",head:!0}).eq("is_active",!0);if(a)throw a;return t||0},staleTime:Wt});function Gt({dateFrom:t,dateTo:a,loading:r}){const n={dateRange:t&&a?{from:t,to:a}:void 0,assignedTo:[],companies:[],dealStatus:[],quoteStatus:[],orderStatus:[],activityStatus:[],salesChannels:[],activityTypes:[],products:[],shops:[]},{data:s,isLoading:d}=kt(n,10);return r||d?e.jsxs(ae,{children:[e.jsxs(re,{children:[e.jsx(ne,{children:"Topp 10 Försäljning (Kontakter)"}),e.jsx(se,{children:"Följer inte övriga filter pÃ¥ sidan"})]}),e.jsx(oe,{children:e.jsx("div",{className:"space-y-4",children:[1,2,3,4,5].map(o=>e.jsx(_e,{className:"h-12 w-full"},o))})})]}):!s||s.length===0?e.jsxs(ae,{children:[e.jsxs(re,{children:[e.jsx(ne,{children:"Topp 10 Försäljning (Kontakter)"}),e.jsx(se,{children:"Följer inte övriga filter pÃ¥ sidan"})]}),e.jsx(oe,{children:e.jsxs("div",{className:"text-center py-8",children:[e.jsx(ot,{className:"h-12 w-12 mx-auto mb-3 opacity-50 text-muted-foreground"}),e.jsx("p",{className:"text-muted-foreground",children:"Ingen kontaktdata tillgänglig för vald period."})]})})]}):e.jsxs(ae,{children:[e.jsxs(re,{children:[e.jsx(ne,{children:"Topp 10 Försäljning (Kontakter)"}),e.jsx(se,{children:"Följer inte övriga filter pÃ¥ sidan"})]}),e.jsx(oe,{children:e.jsxs(xe,{children:[e.jsx(ve,{children:e.jsxs(G,{children:[e.jsx(E,{children:"Kontaktperson"}),e.jsx(E,{children:"Företag"}),e.jsx(E,{className:"text-right",children:"Total försäljning"}),e.jsx(E,{className:"text-right",children:"Antal ordrar"}),e.jsx(E,{className:"text-right",children:"Genomsnittligt ordervärde"}),e.jsx(E,{children:"Kundansvarig"})]})}),e.jsx(fe,{children:s.map(o=>e.jsxs(G,{children:[e.jsx(K,{children:e.jsx("p",{className:"font-medium",children:o.contact_name})}),e.jsx(K,{className:"text-sm text-muted-foreground",children:o.company_name}),e.jsx(K,{className:"text-right font-medium",children:M(o.total_sales,"SEK",{decimals:0})}),e.jsx(K,{className:"text-right",children:o.order_count}),e.jsx(K,{className:"text-right font-medium",children:M(o.avg_order_value,"SEK",{decimals:0})}),e.jsx(K,{children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(We,{className:"h-8 w-8",children:[e.jsx(Xe,{src:o.avatar_url||void 0}),e.jsx(Ge,{children:o.assigned_to_name?.substring(0,2).toUpperCase()})]}),e.jsx("span",{className:"text-muted-foreground",children:o.assigned_to_name})]})})]},o.contact_id))})]})})]})}function Ht(t){return O({queryKey:["customer-growth-rpc",t],queryFn:async()=>{const{data:a,error:r}=await T.rpc("get_customer_growth_stats",{p_date_from:t.dateRange?.from?.toISOString()||null,p_date_to:t.dateRange?.to?.toISOString()||null,p_assigned_to:t.assignedTo?.length?t.assignedTo:null});if(r)throw r;const n=Array.isArray(a)?a[0]:a;return{currentCustomers:Number(n?.current_unique_customers||0),previousCustomers:Number(n?.previous_unique_customers||0),growthPercent:Number(n?.growth_percent||0),newCustomers:Number(n?.new_customers||0)}},staleTime:2*60*1e3,enabled:!!t.dateRange})}function Jt({filters:t}){const{data:a,isLoading:r}=Tt(t),{data:n,isLoading:s}=Pe(t),{data:d}=Le(t),{data:u=0}=Xt(),{data:o}=te(t),{data:i}=Ht(t),m=o?.unique_customers||0,x=u>0?m/u*100:0,j=d?.repeat_customers||0,k=i?.newCustomers||0,b=i?.growthPercent||0,_=me(b),l=(a??[]).map(v=>({period:v.period,value:v.nya,value2:v.aterkommande})),N=[{key:"name",label:"Kund",render:v=>e.jsx("span",{className:"text-sm font-medium",children:v.company_name}),sortValue:v=>v.company_name},{key:"orders",label:"Order",align:"right",render:v=>e.jsx("span",{className:"text-sm tabular-nums",children:v.order_count}),sortValue:v=>v.order_count},{key:"revenue",label:"Omsättning",align:"right",render:v=>e.jsx("span",{className:"text-sm font-medium tabular-nums",children:M(v.total_sales,"SEK",{decimals:0})}),sortValue:v=>v.total_sales},{key:"avg",label:"Snittorder",align:"right",render:v=>e.jsx("span",{className:"text-sm tabular-nums",children:M(v.avg_order_value,"SEK",{decimals:0})}),sortValue:v=>v.avg_order_value}],f=v=>{if(!v)return"";const A=v.split("-");return A.length>=2?`${A[1]}/${A[0]?.slice(2)}`:v},R=r||s;return e.jsxs("div",{className:"space-y-8",children:[e.jsxs(ee,{children:[e.jsx(C,{label:"Aktiva kunder",value:w(x,"percent"),loading:R}),e.jsx(C,{label:"Nya kunder",value:w(k),loading:R}),e.jsx(C,{label:"Ã
terkommande",value:w(j),loading:R}),e.jsx(C,{label:"Kundtillväxt",value:w(b,"percent"),change:_.text,changeType:_.type,loading:R})]}),e.jsx($,{title:"Nya vs Ã¥terkommande kunder per mÃ¥nad",data:l,loading:r,formatLabel:f,valueName:"Nya",value2Name:"Ã
terkommande",height:240}
1),e.jsx(J,{title:"Topp 10 kunder",subtitle:"Sorterat efter omsättning",columns:N,data:n||[],loading:s,maxRows:10,defaultSortKey:"revenue"}),e.jsx(Gt,{dateFrom:t.dateRange?.from??null,dateTo:t.dateRange?.to??null})]})}const Ie="image_url.like.http*,meta->>designed_image_url.like.http*,meta->designed_image_url->>designedUrl.like.http*",Be="image_url, designad:meta->designed_image_url",Qt=`product_name, ${Be}`;function ge(t){if(typeof t!="string")return null;const a=t.trim();return/^https?:\/\//i.test(a)&&!/placeholder/i.test(a)?a:null}function ze(t){const a=t.designad,r=a&&typeof a=="object"?a.designedUrl:a;return ge(t.image_url)??ge(r)}async function Zt(t){const a=new Map;if(t.length===0)return a;const r=await Ke((d,u)=>T.from("products").select("id, bild_url").in("id",t).order("id").range(d,u));for(const d of r){const u=ge(d.bild_url);u&&a.set(d.id,u)}const n=t.filter(d=>!a.has(d)),s=await Promise.all(n.map(async d=>{const{data:u,error:o}=await T.from("order_items").select(Be).eq("product_id",d).or(Ie).order("created_at",{ascending:!1}).limit(1).returns();if(o)throw o;return[d,u?.[0]?ze(u[0]):null]}));for(const[d,u]of s)u&&a.set(d,u);return a}async function ea(t){const a=new Map;if(t.length===0)return a;const r=await Ke((n,s)=>T.from("order_items").select(Qt).is("product_id",null).in("product_name",t).or(Ie).order("created_at",{ascending:!1}).order("id").range(n,s).returns());for(const n of r){if(a.has(n.product_name))continue;const s=ze(n);s&&a.set(n.product_name,s)}return a}async function ta(t,a){const[r,n]=await Promise.all([Zt(t),ea(a)]);return{perProdukt:r,perNamn:n}}const aa={perProdukt:new Map,perNamn:new Map};function ra(t,a){const{data:r}=O({queryKey:["statistik-reservbilder",t,a],queryFn:async()=>{const n=await ta(t,a),s=d=>new Map(Array.from(d,([u,o])=>[u,He(o)]));return{perProdukt:s(n.perProdukt),perNamn:s(n.perNamn)}},enabled:t.length>0||a.length>0,staleTime:3e5});return r??aa}const na=new Set(["Frakt","Importerad produkt","Ej produktkopplat"]);function de(t){return!t.product_id&&!na.has(t.product_name)}function sa(t){return O({queryKey:["product-analytics-rpc",t],queryFn:async()=>{const{data:a,error:r}=await T.rpc("get_product_analytics",{p_date_from:t.dateRange?.from?.toISOString()||null,p_date_to:t.dateRange?.to?.toISOString()||null,p_assigned_to:t.assignedTo?.length?t.assignedTo:null});if(r)throw r;return(a||[]).map(n=>({product_id:n.product_id||"",product_name:n.product_name||"Okänd",sku:n.sku||"",supplier_name:n.supplier_name,quantity_sold:Number(n.quantity_sold||0),revenue:Number(n.revenue||0),cost:Number(n.cost||0),profit:Number(n.profit||0),margin_percent:n.margin_percent!=null?Number(n.margin_percent):null,avg_price:Number(n.avg_price||0),order_count:Number(n.order_count||0),has_reliable_cost:n.has_reliable_cost??!1}))},staleTime:2*60*1e3,gcTime:5*60*1e3,enabled:!!t.dateRange})}function oa(t,a){return O({queryKey:["product-variant-analytics",t,a],queryFn:async()=>{if(!t)return[];const{data:r,error:n}=await T.rpc("get_product_variant_analytics",{p_product_id:t,p_date_from:a.dateRange?.from?.toISOString()||null,p_date_to:a.dateRange?.to?.toISOString()||null,p_assigned_to:a.assignedTo?.length?a.assignedTo:null});if(n)throw n;return(r||[]).map(s=>({variant_name:s.variant_name||"Okänd",sku:s.sku||"",quantity_sold:Number(s.quantity_sold||0),revenue:Number(s.revenue||0),cost:Number(s.cost||0),profit:Number(s.profit||0),margin_percent:s.margin_percent!=null?Number(s.margin_percent):null,order_count:Number(s.order_count||0),has_reliable_cost:s.has_reliable_cost??!1}))},enabled:!!t&&!!a.dateRange,staleTime:2*60*1e3})}function la({product:t,filters:a}){const{data:r,isLoading:n}=oa(t.product_id,a),s=p.useMemo(()=>{if(!r)return[];const d={XXS:1,XS:2,S:3,M:4,L:5,XL:6,XXL:7,"2XL":7,XXXL:8,"3XL":8,"4XL":9,"5XL":10,"6XL":11,"ONE SIZE":50,OS:50},u=m=>{const x=m.match(/- ([^(]+)\(([^)]+)\)\s*$/);if(x)return{size:x[1].trim().toUpperCase(),color:x[2].trim(),isVariant:!0};const j=m.match(/- ([A-Z0-9]+)\s*$/i);return j?{size:j[1].trim().toUpperCase(),color:"",isVariant:!0}:{size:"",color:"",isVariant:!1}};return[...r.some(m=>u(m.variant_name).isVariant)?r.filter(m=>u(m.variant_name).isVariant):r].sort((m,x)=>{const j=u(m.variant_name),k=u(x.variant_name),b=j.color.localeCompare(k.color,"sv");if(b!==0)return b;const _=d[j.size]??99,l=d[k.size]??99;return _-l})},[r]);return e.jsxs("div",{children:[e.jsxs("div",{className:"grid grid-cols-4 gap-4 mb-4",children:[e.jsxs("div",{className:"text-center p-3 bg-muted/50 rounded-lg",children:[e.jsx("div",{className:"text-2xl font-bold tabular-nums",children:t.quantity_sold}),e.jsx("div",{className:"text-xs text-muted-foreground",children:"Antal"})]}),e.jsxs("div",{className:"text-center p-3 bg-muted/50 rounded-lg",children:[e.jsx("div",{className:"text-2xl font-bold tabular-nums",children:M(t.revenue,"SEK",{decimals:0})}),e.jsx("div",{className:"text-xs text-muted-foreground",children:"Omsättning"})]}),e.jsxs("div",{className:"text-center p-3 bg-muted/50 rounded-lg",children:[e.jsx("div",{className:"text-2xl font-bold tabular-nums",children:t.has_reliable_cost?M(t.profit,"SEK",{decimals:0}):"â"}),e.jsx("div",{className:"text-xs text-muted-foreground",children:"Vinst"})]}),e.jsxs("div",{className:"text-center p-3 bg-muted/50 rounded-lg",children:[e.jsx("div",{className:"text-2xl font-bold tabular-nums",children:t.margin_percent!=null&&t.has_reliable_cost?`${t.margin_percent.toFixed(1)}%`:"â"}),e.jsx("div",{className:"text-xs text-muted-foreground",children:"Marginal"})]})]}),n?e.jsx(_e,{className:"h-40 w-full"}):s?.length?e.jsxs(xe,{children:[e.jsx(ve,{children:e.jsxs(G,{children:[e.jsx(E,{children:"Variant"}),e.jsx(E,{className:"text-right",children:"Antal"}),e.jsx(E,{className:"text-right",children:"Omsättning"}),e.jsx(E,{className:"text-right",children:"Vinst"}),e.jsx(E,{className:"text-right",children:"Marginal"})]})}),e.jsx(fe,{children:s.map((d,u)=>e.jsxs(G,{children:[e.jsx(K,{children:e.jsxs("div",{children:[e.jsx("span",{className:"text-sm font-medium",children:d.variant_name}),d.sku&&e.jsx("span",{className:"text-xs text-muted-foreground ml-2",children:d.sku})]})}),e.jsx(K,{className:"text-right tabular-nums text-sm",children:d.quantity_sold}),e.jsx(K,{className:"text-right tabular-nums text-sm",children:M(d.revenue,"SEK",{decimals:0})}),e.jsx(K,{className:"text-right tabular-nums text-sm",children:d.has_reliable_cost?M(d.profit,"SEK",{decimals:0}):e.jsx("span",{className:"text-muted-foreground",title:"Kostnad saknas",children:"â"})}),e.jsx(K,{className:"text-right tabular-nums text-sm",children:d.margin_percent!=null&&d.has_reliable_cost?`${d.margin_percent.toFixed(1)}%`:e.jsx("span",{className:"text-muted-foreground",title:"Kostnad saknas",children:"â"})})]},u))})]}):e.jsx("p",{className:"text-muted-foreground text-center py-8",children:"Inga varianter hittades."})]})}function ia({filters:t}){const{data:a,isLoading:r}=sa(t),n=p.useMemo(()=>
1{if(!a)return{totalQty:0,totalRevenue:0,avgMargin:0,activeCount:0,hasMarginData:!1};const l=a.reduce((D,g)=>D+g.quantity_sold,0),N=a.reduce((D,g)=>D+g.revenue,0),f=a.filter(D=>D.has_reliable_cost),R=f.reduce((D,g)=>D+g.revenue,0),v=f.reduce((D,g)=>D+g.profit,0),A=R>0?v/R*100:0;return{totalQty:l,totalRevenue:N,avgMargin:A,activeCount:a.length,hasMarginData:f.length>0}},[a]),s=p.useMemo(()=>{if(!a)return[];const l=new Map;return a.forEach(N=>{N.supplier_name&&l.set(N.supplier_name,(l.get(N.supplier_name)||0)+N.revenue)}),Array.from(l.entries()).sort((N,f)=>f[1]-N[1]).slice(0,15).map(([N,f])=>({period:N,value:f}))},[a]),[d,u]=p.useState(""),[o,i]=p.useState(""),m=p.useCallback(l=>{u(l.map(N=>N.product_id).filter(Boolean).sort().join(",")),i(JSON.stringify(l.filter(de).map(N=>N.product_name).sort()))},[]),x=p.useMemo(()=>d?d.split(","):[],[d]),j=p.useMemo(()=>o?JSON.parse(o):[],[o]),k=vt(x),b=ra(x,j),_=[{key:"name",label:"Produkt",render:(l,N,f)=>{const R=l.product_id?k.get(l.product_id)??b.perProdukt.get(l.product_id):de(l)?b.perNamn.get(l.product_name):void 0,v=e.jsxs("div",{className:"flex items-center gap-2 min-w-0",children:[(l.product_id||de(l))&&(R?e.jsx(xt,{src:R,alt:"",className:"h-8 w-8 rounded",containerClassName:"h-8 w-8 rounded flex-shrink-0",thumbWidth:64,fit:"contain"}):e.jsx("span",{className:"h-8 w-8 rounded bg-muted flex-shrink-0","aria-hidden":"true"})),e.jsx("span",{className:"text-sm font-medium",children:l.product_name}),l.supplier_name&&e.jsx("span",{className:"text-xs text-muted-foreground ml-2",children:l.supplier_name})]});return l.product_id?e.jsxs("div",{className:"flex items-center gap-1.5 text-left",children:[e.jsx(lt,{className:B("h-3.5 w-3.5 text-muted-foreground shrink-0 transition-transform",f&&"rotate-90")}),v]}):e.jsx("div",{className:"flex items-center gap-1.5 pl-5 text-muted-foreground",children:v})},sortValue:l=>l.product_name},{key:"qty",label:"Antal",align:"right",render:l=>e.jsx("span",{className:"text-sm tabular-nums",children:l.quantity_sold}),sortValue:l=>l.quantity_sold},{key:"revenue",label:"Omsättning",align:"right",render:l=>e.jsx("span",{className:"text-sm font-medium tabular-nums",children:M(l.revenue,"SEK",{decimals:0})}),sortValue:l=>l.revenue},{key:"avg",label:"Snittpris",align:"right",render:l=>e.jsx("span",{className:"text-sm tabular-nums",children:M(l.avg_price,"SEK",{decimals:0})}),sortValue:l=>l.avg_price},{key:"margin",label:"Marginal",align:"right",render:l=>l.margin_percent!=null&&l.has_reliable_cost?e.jsxs("span",{className:"text-sm tabular-nums",children:[l.margin_percent.toFixed(1),"%"]}):e.jsx("span",{className:"text-sm text-muted-foreground",title:"Kostnad saknas",children:"â"}),sortValue:l=>l.margin_percent??-1},{key:"profit",label:"Vinst",align:"right",render:l=>l.has_reliable_cost?e.jsx("span",{className:"text-sm font-medium tabular-nums",children:M(l.profit,"SEK",{decimals:0})}):e.jsx("span",{className:"text-sm text-muted-foreground",title:"Kostnad saknas",children:"â"}),sortValue:l=>l.has_reliable_cost?l.profit:-1}];return e.jsxs("div",{className:"space-y-8",children:[e.jsxs(ee,{children:[e.jsx(C,{label:"SÃ¥lda artiklar",value:w(n.totalQty),loading:r}),e.jsx(C,{label:"Produktomsättning",value:w(n.totalRevenue,"currency"),loading:r}),e.jsx(C,{label:"Snittmarginal",value:n.hasMarginData?w(n.avgMargin,"percent"):"â",loading:r}),e.jsx(C,{label:"Aktiva produkter",value:w(n.activeCount),loading:r})]}),e.jsx($,{title:"Omsättning per leverantör",data:s,loading:r,variant:"bar",formatValue:l=>`${(l/1e3).toFixed(0)}k`,valueName:"Omsättning",height:Math.max(200,s.length*40+40)}),e.jsx(J,{title:"Produkter â Prestanda",subtitle:"Klicka pÃ¥ en produkt för att se variantfördelning",columns:_,data:a||[],loading:r,maxRows:25,defaultSortKey:"revenue",rowKey:l=>l.product_id??`namn:${l.product_name}`,canExpand:l=>!!l.product_id,renderExpanded:l=>e.jsx(la,{product:l,filters:t}),onVisibleRowsChange:m})]})}function ue(t){return t===0?"0":t.toString().replace(/\B(?=(\d{3})+(?!\d))/g," ")}function ca(t){return parseFloat(t.replace(/\s/g,""))||0}function pe({value:t,onChange:a,className:r,placeholder:n,step:s}){const[d,u]=p.useState(ue(t)),[o,i]=p.useState(!1),m=p.useRef(null);return p.useEffect(()=>{o||u(ue(t))},[t,o]),e.jsx(De,{ref:m,type:"text",inputMode:"numeric",className:B(r),placeholder:n,step:s,value:d,onFocus:()=>{i(!0)},onBlur:()=>{i(!1);const x=ca(d);
1a(x),u(ue(x))},onChange:x=>{const j=x.target.value;/^[\d\s.,]*$/.test(j)&&u(j)}})}const Z=new Date().getFullYear(),da=[Z-2,Z-1,Z,Z+1];function ua(){const t=new Date().getFullYear(),[a,r]=p.useState({goal_year:t,revenue_target:0,margin_target_percent:0}),[n,s]=p.useState(!0),[d,u]=p.useState(!1),[o,i]=p.useState(0),[m,x]=p.useState(0);p.useEffect(()=>{j()},[]);const j=async()=>{try{const{data:_,error:l}=await T.from("company_goals").select("*").eq("goal_year",t).maybeSingle();if(l)throw l;_&&r(_)}catch(_){console.error("Error fetching company goal:",_)}finally{s(!1)}},k=()=>{i(a.revenue_target),x(a.margin_target_percent),u(!0)},b=async()=>{try{const{error:_}=await T.from("company_goals").upsert({goal_year:t,revenue_target:o,margin_target_percent:m},{onConflict:"goal_year"});if(_)throw _;r(l=>({...l,revenue_target:o,margin_target_percent:m})),u(!1),X.success("BolagsmÃ¥l sparade")}catch(_){console.error("Error saving company goal:",_),X.error("Kunde inte spara bolagsmÃ¥l")}};return n?null:e.jsxs("div",{className:"border rounded-lg p-6 space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Fe,{className:"h-5 w-5 text-muted-foreground"}),e.jsxs("h3",{className:"text-lg font-semibold",children:["Företagets mÃ¥l (",t,")"]})]}),!d&&e.jsxs(z,{size:"sm",variant:"outline",onClick:k,children:[e.jsx(Me,{className:"h-4 w-4 mr-2"}),"Redigera bolagsmÃ¥l"]})]}),d?e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4",children:[e.jsxs("div",{children:[e.jsx(W,{children:"OmsättningsmÃ¥l (SEK)"}),e.jsx(pe,{value:o,onChange:i})]}),e.jsxs("div",{children:[e.jsx(W,{children:"MarginalmÃ¥l (%)"}),e.jsx(De,{type:"number",step:"0.1",value:m,onChange:_=>x(parseFloat(_.target.value)||0)})]})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(z,{size:"sm",onClick:b,children:"Spara"}),e.jsx(z,{size:"sm",variant:"outline",onClick:()=>u(!1),children:"Avbryt"})]})]}):e.jsxs("div",{className:"grid grid-cols-2 gap-6",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-xs text-muted-foreground uppercase font-medium",children:"OmsättningsmÃ¥l"}),e.jsx("p",{className:"admin-kpi",children:M(a.revenue_target,"SEK",{decimals:0})})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-xs text-muted-foreground uppercase font-medium",children:"MarginalmÃ¥l"}),e.jsxs("p",{className:"admin-kpi",children:[a.margin_target_percent," %"]})]})]})]})}function ma(){const[t,a]=p.useState([]),[r,n]=p.useState({}),[s,d]=p.useState(!0),[u,o]=p.useState(!1),[i,m]=p.useState(null),[x,j]=p.useState(Z),[k,b]=p.useState(0),[_,l]=p.useState(Array(12).fill(0)),N=async()=>{try{const{data:h,error:y}=await T.from("team_members_view").select("id, email, full_name, avatar_url, role").eq("is_active",!0).order("full_name");if(y)throw y;a(h||[])}catch(h){console.error("Error fetching users:",h),X.error("Kunde inte hämta användare")}finally{d(!1)}},f=async(h,y)=>{try{const{data:S,error:V}=await T.from("user_budgets").select("annual_budget, monthly_allocations").eq("user_id",h).eq("budget_year",y).maybeSingle();if(V)throw V;if(S){const L=Array(12).fill(0),Q=S.monthly_allocations;Q&&Array.isArray(Q)&&Q.forEach(Y=>{Y.month>=1&&Y.month<=12&&(L[Y.month-1]=Y.amount||0)}),l(L)}else l(Array(12).fill(0))}catch(S){console.error("Error fetching budget:",S),X.error("Kunde inte hämta budget")}},R=async()=>{try{const h=new Date().getFullYear(),{data:y,error:S}=await T.from("user_budgets").select("user_id, annual_budget").eq("budget_year",h);if(S)throw S;const V={};(y||[]).forEach(L=>{V[L.user_id]=L.annual_budget||0}),n(V)}catch(h){console.error("Error fetching budgets:",h)}};p.useEffect(()=>{N(),R()},[]);const v=async h=>{m(h),b(0),await f(h.id,x),o(!0)},A=()=>{const h=Math.floor(k/12);l(Array(12).fill(h))},D=(h,y)=>{const S=[..._];S[h]=y,l(S)},g=()=>_.reduce((h,y)=>h+y,0),c=async()=>{if(i)try{const h=_.map((S,V)=>({month:V+1,amount:S})),{error:y}=await T.from("user_budgets").upsert({user_id:i.id,budget_year:x,annual_budget:g(),monthly_allocations:h},{onConflict:"user_id,budget_year"});if(y)throw y;X.success("Budget sparad"),o(!1),R()}catch(h){console.error("Error saving budget:",h),X.error("Kunde inte spara budget")}},F=["Jan","Feb","Mar","Apr","Maj","Jun","Jul","Aug","Sep","Okt","Nov","Dec"];return s?e.jsx("div",{className:"flex justify-center p-8",children:"Laddar användare..."}):e.jsxs("div",{className:"space-y-8",children:[e.jsx(ua,{}),e.jsxs(xe,{children:[e.jsx(ve,{children:e.jsxs(G,{children:[e.jsx(E,{children:"Användare"}),e.jsx(E,{className:"text-right",children:"Ã
rsbudget"}),e.jsx(E,{children:"Ã
tgärder"})]})}),e.jsx(fe,{children:t.map(h=>e.jsxs(G,{children:[e.jsx(K,{children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(St,{name:h.full_name||void 0,email:h.email,avatarUrl:h.avatar_url||void 0,size:"sm"}),e.jsx("span",{className:"font-medium",children:h.full_name||"-"})]})}),e.jsx(K,{className:"text-right tabular-nums",children:r[h.id]?M(r[h.id]):e.jsx("span",{className:"text-muted-foreground",children:"Ej satt"})}),e.jsx(K,{children:e.jsxs(z,{size:"sm",variant:"outline",onClick:()=>v(h),children:[e.jsx(Me,{className:"h-4 w-4 mr-2"}),"Redigera budget"]})})]}
1,h.id))})]}),t.length===0&&e.jsx("div",{className:"text-center py-8 text-muted-foreground",children:"Inga användare hittades"}),e.jsx(Je,{open:u,onOpenChange:o,children:e.jsxs(Qe,{className:"max-w-4xl max-h-[90vh] overflow-y-auto",children:[e.jsx(Ze,{children:e.jsxs(et,{children:["Redigera budget - ",i?.full_name]})}),i&&e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex gap-4",children:[e.jsxs("div",{className:"flex-1",children:[e.jsx(W,{children:"Ã
r"}),e.jsxs(ft,{value:x.toString(),onValueChange:h=>{const y=parseInt(h);j(y),f(i.id,y)},children:[e.jsx(jt,{children:e.jsx(yt,{})}),e.jsx(bt,{children:da.map(h=>e.jsx(Nt,{value:h.toString(),children:h},h))})]})]}),e.jsxs("div",{className:"flex-1",children:[e.jsx(W,{children:"Belopp att fördela (SEK)"}),e.jsx(pe,{value:k,onChange:b}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:'Hjälp för knappen "Fördela jämnt". Sparas inte.'})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex justify-between items-center mb-4",children:[e.jsx(W,{children:"MÃ¥nadsfördelning"}),e.jsx(z,{size:"sm",variant:"outline",onClick:A,children:"Fördela jämnt"})]}),e.jsx("div",{className:"grid grid-cols-3 gap-3",children:F.map((h,y)=>e.jsxs("div",{children:[e.jsx(W,{className:"text-xs",children:h}),e.jsx(pe,{value:_[y],onChange:S=>D(y,S)})]},y))})]}),e.jsx("div",{className:"bg-muted p-4 rounded-lg",children:e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"font-medium",children:"Ã
rsbudget (summan av mÃ¥naderna):"}),e.jsx("span",{className:"tabular-nums",children:M(g())})]})})]}),e.jsxs(tt,{children:[e.jsx(z,{variant:"outline",onClick:()=>o(!1),children:"Avbryt"}),e.jsx(z,{onClick:c,children:"Spara budget"})]})]})})]})}const ga=[{value:"overview",label:"Ãversikt"},{value:"sales",label:"Försäljning"},{value:"quotes",label:"Offerter"},{value:"activities",label:"Aktiviteter"},{value:"customers",label:"Kunder"},{value:"products",label:"Produkter"},{value:"budgets",label:"MÃ¥l & Budgetar"}],he=[{key:"this_month",label:"Denna mÃ¥nad",getRangeF:ct},{key:"last_month",label:"Förra mÃ¥naden",getRangeF:dt},{key:"ytd",label:"YTD",getRangeF:Oe},{key:"12_months",label:"12 mÃ¥nader",getRangeF:ut}];function we(t,a){return t.getFullYear()===a.getFullYear()&&t.getMonth()===a.getMonth()&&t.getDate()===a.getDate()}function pa(t){for(const a of he){const r=a.getRangeF();if(we(r.from,t.from)&&we(r.to,t.to))return a.key}return"custom"}function Re(t){const a=t.getFullYear(),r=String(t.getMonth()+1).padStart(2,"0"),n=String(t.getDate()).padStart(2,"0");return`${a}-${r}-${n}`}function Ce(t){const[a,r,n]=t.split("-").map(Number);return new Date(a,(r||1)-1,n||1)}function ha({dateRange:t,onDateRangeChange:a}){const r=pa(t);return e.jsxs("div",{style:{display:"flex",gap:8,alignItems:"center",flexWrap:"wrap"},children:[e.jsx(pt,{label:"Period",value:r,onChange:n=>{const s=he.find(d=>d.key===n);s&&a(s.getRangeF())},options:[...he.map(n=>({value:n.key,label:n.label})),{value:"custom",label:"Anpassat"}]}),e.jsx(ht,{from:Re(t.from),to:Re(t.to),onChange:({from:n,to:s})=>{n&&s&&a({from:Ce(n),to:Ce(s)})}})]})}function _a({value:t,onChange:a}){return e.jsxs("div",{role:"group","aria-label":"OmfÃ¥ng",style:{display:"flex",gap:6},children:[e.jsxs(Ne,{variant:t==="personal"?"primary":"ghost",size:"sm","aria-pressed":t==="personal",onClick:()=>a("personal"),children:[e.jsx(it,{size:14,"aria-hidden":!0}),"Mitt"]}),e.jsxs(Ne,{variant:t==="company"?"primary":"ghost",size:"sm","aria-pressed":t==="company",onClick:()=>a("company"),children:[e.jsx(Fe,{size:14,"aria-hidden":!0}),"Företag"]})]})}function xa(){const{user:t}=at(),[a,r]=p.useState(()=>localStorage.getItem("crm-analytics-scope")||"company"),[n,s]=p.useState(Oe),[d,u]=p.useState("overview");p.useEffect(()=>{localStorage.setItem("crm-analytics-scope",a)},[a]);const o=p.useMemo(()=>({dateRange:n,assignedTo:a==="personal"&&t?.id?[t.id]:[],companies:[],dealStatus:[],quoteStatus:[],orderStatus:[],activityStatus:[],salesChannels:[],activityTypes:[],products:[],shops:[]}),[n,a,t?.id]);return e.jsxs(mt,{register:"Statistik",children:[e.jsx(gt,{title:"Statistik",description:"Analysera försäljning, aktiviteter och pipeline"}),e.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",flexWrap:"wrap",gap:8},children:[e.jsx(ha,{dateRange:n,onDateRangeChange:s}),e.jsx(_a,{value:a,onChange:r})]}),e.jsxs(_t,{items:ga,value:d,onValueChange:u,children:[e.jsx(I,{value:"overview",children:e.jsx(qt,{filters:o})}),e.jsx(I,{value:"sales",children:e.jsx(q,{padded:!1,children:e.jsx(Bt,{filters:o})})}),e.jsx(I,{value:"quotes",children:e.jsx(q,{padded:!1,children:e.jsx(zt,{filters:o})})}),e.jsx(I,{value:"activities",children:e.jsx(q,{padded:!1,children:e.jsx(Ut,{filters:o})})}),e.jsx(I,{value:"customers",children:e.jsx(q,{padded:!1,children:e.jsx(Jt,{filters:o})})}),e.jsx(I,{value:"products",children:e.jsx(q,{padded:!1,children:e.jsx(ia,{filters:o})})}),e.jsx(I,{value:"budgets",children:e.jsx(q,{padded:!1,children:e.jsx(ma,{})})})]})]})}function Ja(){return e.jsx(xa,{})}export{Ja 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.