1import{a as D,j as e}from"./vendor-query-CRhh6spR.js";import{L as he}from"./LoadErrorCard-B2FnJgy6.js";import{o as fe}from"./post-job-sheet-BxL-Oe-u.js";import{u as ge}from"./use-primary-query-LdYs10m3.js";import{u as be,b as B,e as ye,g as U,L as je,s as A}from"./index-BkVb42KZ.js";import{u as ve}from"./use-subscription-Q7kB2EwX.js";import{H as we}from"./Head-B4hXUiBE.js";import{u as Ne}from"./vendor-react-BAmwgVqg.js";import{C as _e}from"./chart-column-UiAhC4rs.js";import{D as ke}from"./download-C8JTs7FR.js";import{S as Y}from"./sparkles-BuBBRAeM.js";import{C as G}from"./clock-B5A68DmX.js";import{E as Ce}from"./eye-D9PTLHAC.js";import{U as De}from"./users-CLblnKO6.js";import{C as Se}from"./circle-check-BibDl6sq.js";import{T as Ae}from"./trending-up-WeSkWL9_.js";import{A as Te}from"./arrow-up-down-BaWw1Y0Q.js";import{M as Me}from"./map-pin-BnyER353.js";import{L as Le}from"./lock-BhoZ9g-C.js";import{C as Re}from"./calendar-BOzI1TJy.js";import{Z as Ee}from"./zap-lWgtODcO.js";import{m as Pe}from"./vendor-motion-BcLIBd36.js";import{A as Oe}from"./arrow-up-right-CJcAkOBd.js";import{A as Fe}from"./arrow-down-right-B7fS_wLW.js";import{R as He,B as Ue,C as Be,X as Ie,Y as Ve,T as Qe,a as Je,b as $e}from"./vendor-charts-BVeOEGzI.js";import"./vendor-supabase-Csx7YFID.js";import"./vendor-stripe-2y4Jo9_W.js";const K={"7d":7,"30d":30,"90d":90,all:null};function H(c,m){return m===0?c===0?0:null:(c-m)/m*100}function L({label:c,value:m,delta:x,icon:y,suffix:t}){const{t:p}=B(),l=x!==null&&x>=0;return e.jsxs(Pe.div,{initial:{opacity:0,y:6},animate:{opacity:1,y:0},className:"rounded-card bg-card border border-border/60 p-4 shadow-sm",children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("span",{className:"text-caption uppercase tracking-wider font-semibold text-muted-foreground",children:c}),e.jsx(y,{className:"w-4 h-4 text-muted-foreground"})]}),e.jsxs("div",{className:"flex items-baseline gap-1",children:[e.jsx("span",{className:"text-3xl font-bold text-primary tabular-nums",children:m}),t&&e.jsx("span",{className:"text-sm text-muted-foreground",children:t})]}),x!==null&&e.jsxs("div",{className:U("flex items-center gap-1 mt-2 text-xs font-medium",l?"text-emerald-600":"text-rose-600"),children:[l?e.jsx(Oe,{className:"w-3 h-3"}):e.jsx(Fe,{className:"w-3 h-3"}),e.jsx("span",{children:p.contractorAnalytics.deltaVsPrior(Number(Math.abs(x).toFixed(0)))})]})]})}function ze({data:c}){const{t:m}=B();if(!c.length||c[0].value===0)return e.jsx("div",{className:"text-sm text-muted-foreground py-12 text-center",children:m.contractorAnalytics.funnelEmpty});const x=c[0].value,y=c.map(t=>({...t,pct:x?Math.round(t.value/x*100):0}));return e.jsx(He,{width:"100%",height:220,children:e.jsxs(Ue,{data:y,layout:"vertical",margin:{left:16,right:24},children:[e.jsx(Be,{stroke:"hsl(var(--border))",strokeDasharray:"3 3",horizontal:!1}),e.jsx(Ie,{type:"number",stroke:"hsl(var(--muted-foreground))",fontSize:11}),e.jsx(Ve,{type:"category",dataKey:"stage",stroke:"hsl(var(--muted-foreground))",fontSize:11,width:90}),e.jsx(Qe,{cursor:{fill:"hsl(var(--primary) / 0.06)"},contentStyle:{background:"hsl(var(--card))",border:"1px solid hsl(var(--border))",borderRadius:8,fontSize:12},formatter:(t,p,l)=>[`${t} (${l.payload.pct}%)`,m.contractorAnalytics.funnelWorkersLabel]}),e.jsx(Je,{dataKey:"value",radius:[0,6,6,0],children:y.map((t,p)=>e.jsx($e,{fill:`hsl(var(--primary) / ${1-p*.18})`},p))})]})})}function vt(){const{user:c}=be(),m=Ne(),{effectiveTier:x}=ve(),{t:y}=B(),t=y.contractorAnalytics,p={"7d":t.rangeLast7,"30d":t.rangeLast30,"90d":t.rangeLast90,all:t.rangeAll},[l,q]=D.useState("30d"),[X,Z]=D.useState({key:"created_at",dir:"desc"}),{open:W}=ye(),ee=!0,T=x==="paid",j=D.useMemo(()=>{const s=K[l];return s===null?null:new Date(Date.now()-s*864e5).toISOString()},[l]),R=D.useMemo(()=>{const s=K[l];return s===null?null:new Date(Date.now()-s*2*864e5).toISOString()},[l]),{data:v,isLoading:te,isError:se,refetch:ae}=ge({queryKey:["contractor-analytics",c==null?void 0:c.id,l],enabled:!!c&&ee,queryFn:async()=>{const s=c.id;let o=A.from("jobs").select("id, title, status, created_at, closed_at, filled_slots, slots, boosted_until, skills, location").eq("contractor_id",s).is("deleted_at",null);
1j&&(o=o.gte("created_at",j));const{data:g=[]}=await o,h=g.map(a=>a.id);let b=[],u=[],C=[],_=[];if(h.length){let a=A.from("job_views").select("job_id, viewer_id, viewed_at").in("job_id",h);j&&(a=a.gte("viewed_at",j)),b=(await a).data??[];let d=A.from("applications").select("id, job_id, worker_id, status, created_at").in("job_id",h);j&&(d=d.gte("created_at",j)),u=(await d).data??[],R&&j&&(C=(await A.from("job_views").select("id").in("job_id",h).gte("viewed_at",R).lt("viewed_at",j)).data??[],_=(await A.from("applications").select("id, status").in("job_id",h).gte("created_at",R).lt("created_at",j)).data??[])}const E=Date.now(),r=g.map(a=>{const d=b.filter(f=>f.job_id===a.id),M=u.filter(f=>f.job_id===a.id),F=M.filter(f=>f.status!=="withdrawn").length,$=M.filter(f=>f.status==="accepted"),z=$.map(f=>new Date(f.created_at).getTime()).sort((f,xe)=>f-xe)[0],me=new Date(a.created_at).getTime(),pe=a.closed_at?new Date(a.closed_at).getTime():E,ue=Math.max(1,Math.round((pe-me)/864e5));return{id:a.id,title:a.title,status:a.status,created_at:a.created_at,closed_at:a.closed_at,filled_slots:a.filled_slots??0,slots:a.slots??1,boosted_until:a.boosted_until,views:d.length,matches:F,applicants:M.length,accepted:$.length,days_open:ue,match_rate:d.length?F/d.length:0,first_accepted_at:z?new Date(z).toISOString():null,skills:a.skills??[],city:a.location??null,weekday:new Date(a.created_at).getDay()}}),i=r.reduce((a,d)=>a+d.views,0),S=r.reduce((a,d)=>a+d.matches,0),P=r.reduce((a,d)=>a+d.applicants,0),Q=r.reduce((a,d)=>a+d.accepted,0),J=P?Q/P*100:0,O=r.filter(a=>a.first_accepted_at).map(a=>(new Date(a.first_accepted_at).getTime()-new Date(a.created_at).getTime())/864e5),le=O.length?O.reduce((a,d)=>a+d,0)/O.length:0,ce=_.filter(a=>a.status==="accepted").length,ie=_.length?ce/_.length*100:0,de={views:H(i,C.length),matches:H(S,_.filter(a=>a.status!=="withdrawn").length),acceptance:H(J,ie),time_to_fill:null};return{rows:r,totals:{totalViews:i,totalMatches:S,acceptanceRate:J,avgTimeToFill:le,totalApplicants:P,totalAccepted:Q},deltas:de}}}),w=(v==null?void 0:v.rows)??[],n=v==null?void 0:v.totals,N=v==null?void 0:v.deltas,I=Ye(w,X),re=D.useMemo(()=>{const s=(n==null?void 0:n.totalViews)??0,o=(n==null?void 0:n.totalMatches)??0,g=(n==null?void 0:n.totalApplicants)??0,h=(n==null?void 0:n.totalAccepted)??0;return[{stage:t.funnelStageViewed,value:s},{stage:t.funnelStageMatched,value:o},{stage:t.funnelStageApplied,value:g},{stage:t.funnelStageAccepted,value:h}]},[n,t]),V=D.useMemo(()=>[...w].filter(s=>s.views>=3).sort((s,o)=>o.match_rate-s.match_rate).slice(0,3),[w]),k=D.useMemo(()=>{if(!w.length)return null;const s=new Map,o=new Map,g=new Map;w.forEach(r=>{r.city&&s.set(r.city,(s.get(r.city)??0)+r.matches),r.skills.forEach(S=>o.set(S,(o.get(S)??0)+r.matches));const i=g.get(r.weekday)??{jobs:0,matches:0};i.jobs+=1,i.matches+=r.matches,g.set(r.weekday,i)});const h=[...s.entries()].sort((r,i)=>i[1]-r[1]).slice(0,3),b=[...o.entries()].sort((r,i)=>i[1]-r[1]).slice(0,5),u=t.weekdays,C=[...g.entries()].map(([r,i])=>({day:u[r],avg:i.jobs?i.matches/i.jobs:0})).sort((r,i)=>i.avg-r.avg)[0],_=w.reduce((r,i)=>r+i.matches,0)/Math.max(w.length,1),E=C&&_>0?Math.round((C.avg-_)/_*100):0;return{topCities:h,topSkills:b,bestDay:C,dayLift:E}},[w,t]),ne=()=>{const o=[[t.csvHeaders.title,t.csvHeaders.status,t.csvHeaders.views,t.csvHeaders.matches,t.csvHeaders.applicants,t.csvHeaders.accepted,t.csvHeaders.daysOpen,t.csvHeaders.boosted,t.csvHeaders.created].join(",")];I.forEach(u=>{const C=u.boosted_until&&new Date(u.boosted_until)>new Date?t.csvYes:t.csvNo;o.push([JSON.stringify(u.title),u.status,u.views,u.matches,u.applicants,u.accepted,u.days_open,C,u.created_at].join(","))});const g=new Blob([o.join(` 2`)],{type:"text/csv;charset=utf-8"}),h=URL.createObjectURL(g),b=document.createElement("a");b.href=h,b.download=`knuckl-analytics-${l}-${new Date().toISOString().slice(0,10)}.csv`,document.body.appendChild(b),b.click(),document.body.removeChild(b),URL.revokeObjectURL(h)},oe=s=>Z(o=>o.key===s?{key:s,dir:o.dir==="asc"?"desc":"asc"}:{key:s,dir:"desc"});return e.jsxs("div",{className:"px-3 py-4 space-y-5 sm:px-5 sm:py-5 max-w-6xl mx-auto",children:[e.jsx(we,{title:t.headTitle,de
2scription:t.headDescription}),e.jsxs("div",{className:"flex flex-wrap items-end justify-between gap-3",children:[e.jsxs("div",{children:[e.jsxs("h1",{className:"font-display text-2xl sm:text-3xl text-foreground flex items-center gap-2",children:[e.jsx(_e,{className:"w-6 h-6 text-primary"})," ",t.pageTitle]}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:t.pageSubtitle(p[l].toLowerCase())})]}),T&&e.jsxs("button",{onClick:ne,className:"inline-flex items-center gap-2 rounded-xl border border-border bg-card px-3 py-2 text-sm font-medium hover:bg-muted transition",children:[e.jsx(ke,{className:"w-4 h-4"})," ",t.exportCsv]})]}),e.jsx("div",{className:"flex flex-wrap gap-2",children:Object.keys(p).map(s=>e.jsx("button",{onClick:()=>q(s),className:U("px-3 py-1.5 rounded-full text-xs font-medium border transition",l===s?"bg-primary text-primary-foreground border-primary":"bg-card text-muted-foreground border-border hover:text-foreground"),children:p[s]},s))}),se?e.jsx(he,{onRetry:()=>void ae()}):te||!n?e.jsx("div",{className:"flex items-center justify-center py-20",children:e.jsx(je,{className:"w-6 h-6 animate-spin text-primary"})}):w.length===0?e.jsxs("div",{className:"rounded-card bg-card border border-border p-10 text-center",children:[e.jsx(Y,{className:"w-8 h-8 text-primary mx-auto mb-3"}),e.jsx("h3",{className:"font-display text-lg text-foreground mb-1",children:t.emptyNoJobsTitle}),e.jsx("p",{className:"text-sm text-muted-foreground mb-4",children:t.emptyNoJobsBody}),e.jsx("button",{onClick:fe,className:"rounded-xl bg-primary text-primary-foreground px-4 py-2 text-sm font-semibold",children:t.emptyNoJobsCta})]}):n.totalViews===0&&n.totalApplicants===0?e.jsxs("div",{className:"rounded-card bg-card border border-border p-10 text-center",children:[e.jsx(G,{className:"w-8 h-8 text-primary mx-auto mb-3"}),e.jsx("h3",{className:"font-display text-lg text-foreground mb-1",children:t.emptyNoActivityTitle}),e.jsx("p",{className:"text-sm text-muted-foreground",children:t.emptyNoActivityBody})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-3",children:[e.jsx(L,{label:t.kpiTotalViews,value:n.totalViews,delta:(N==null?void 0:N.views)??null,icon:Ce}),e.jsx(L,{label:t.kpiTotalMatches,value:n.totalMatches,delta:(N==null?void 0:N.matches)??null,icon:De}),e.jsx(L,{label:t.kpiAcceptanceRate,value:`${n.acceptanceRate.toFixed(0)}%`,delta:(N==null?void 0:N.acceptance)??null,icon:Se}),e.jsx(L,{label:t.kpiAvgTimeToFill,value:n.avgTimeToFill?n.avgTimeToFill.toFixed(1):"â",delta:null,icon:G,suffix:n.avgTimeToFill?t.kpiDays:void 0})]}),e.jsxs("div",{className:"rounded-card bg-card border border-border/60 p-4 shadow-sm",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-3",children:[e.jsx(Ae,{className:"w-4 h-4 text-primary"}),e.jsx("h2",{className:"font-display text-lg",children:t.funnelTitle})]}),e.jsx(ze,{data:re})]}),V.length>0&&e.jsxs("div",{children:[e.jsxs("h2",{className:"font-display text-lg mb-3 flex items-center gap-2",children:[e.jsx(Y,{className:"w-4 h-4 text-primary"})," ",t.topPerformersTitle]}),e.jsx("div",{className:"grid sm:grid-cols-3 gap-3",children:V.map(s=>(s.boosted_until&&new Date(s.boosted_until)>new Date,e.jsxs("div",{className:"rounded-card bg-card border border-border p-4 shadow-sm",children:[e.jsx("p",{className:"text-sm font-semibold line-clamp-2 mb-2",children:s.title}),e.jsxs("p",{className:"text-xs text-muted-foreground mb-3",children:[t.matchRateLabel,": ",e.jsxs("span",{className:"text-primary font-semibold",children:[Math.round(s.match_rate*100),"%"]})]})]},s.id)))})]}),e.jsxs("div",{className:"rounded-card bg-card border border-border/60 shadow-sm overflow-hidden",children:[e.jsx("div",{className:"p-4 border-b border-border/60",children:e.jsx("h2",{className:"font-display text-lg",children:t.perJobTitle})}),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-xs uppercase tracking-wider text-muted-foreground",children:e.jsx("tr",{children:[{k:"title",l:t.colJob},{k:"status",l:t.colStatus},{k:"views",l:t.colViews},{k:"matches",l:t.colMatches},{k:"applicants",l:t.colApplicants},{k:"accepted",l:t.colAccepted},{k:"days_open",l:t.colDaysOpen},{k:"created_at",l:t.colBoost}].map(s=>e.jsx("th",{className:"text-left font-semibold px-3 py-2 whitespace-nowrap cursor-pointer select-none",onClick:()=>oe(s.k),children:e.jsxs("span",{className:"inline-flex items-center gap-1",children:[s.l,e.
2jsx(Te,{className:"w-3 h-3 opacity-50"})]})},s.k))})}),e.jsx("tbody",{children:I.map(s=>(s.boosted_until&&new Date(s.boosted_until)>new Date,e.jsxs("tr",{className:"border-t border-border/60 hover:bg-muted/30",children:[e.jsx("td",{className:"px-3 py-2",children:e.jsx("button",{onClick:()=>m(`/contractor/jobs/${s.id}`),className:"text-left font-medium text-foreground hover:text-primary line-clamp-1",children:s.title})}),e.jsx("td",{className:"px-3 py-2",children:e.jsx("span",{className:"px-2 py-0.5 rounded-full text-caption font-medium bg-muted text-foreground capitalize",children:y.common[s.status]??s.status})}),e.jsx("td",{className:"px-3 py-2 tabular-nums",children:s.views}),e.jsx("td",{className:"px-3 py-2 tabular-nums",children:s.matches}),e.jsx("td",{className:"px-3 py-2 tabular-nums",children:s.applicants}),e.jsx("td",{className:"px-3 py-2 tabular-nums",children:s.accepted}),e.jsx("td",{className:"px-3 py-2 tabular-nums",children:s.days_open}),e.jsx("td",{className:"px-3 py-2",children:e.jsx("span",{className:"text-muted-foreground",children:"â"})})]},s.id)))})]})})]}),e.jsxs("div",{className:"rounded-card bg-card border border-border/60 p-4 shadow-sm relative overflow-hidden",children:[e.jsxs("div",{className:"flex items-center justify-between mb-3",children:[e.jsxs("h2",{className:"font-display text-lg flex items-center gap-2",children:[e.jsx(Me,{className:"w-4 h-4 text-primary"})," ",t.workerInsightsTitle]}),!T&&e.jsxs("span",{className:"inline-flex items-center gap-1 text-caption font-semibold px-2 py-1 rounded-full bg-primary/10 text-primary",children:[e.jsx(Le,{className:"w-3 h-3"})," ",t.paidPlanBadge]})]}),e.jsx("div",{className:U(!T&&"blur-sm pointer-events-none select-none"),children:k?e.jsxs("div",{className:"grid sm:grid-cols-3 gap-4",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-xs uppercase tracking-wider text-muted-foreground mb-2",children:t.topAreas}),k.topCities.length?e.jsx("ul",{className:"text-sm space-y-1",children:k.topCities.map(([s,o])=>e.jsxs("li",{className:"flex justify-between",children:[e.jsx("span",{className:"truncate mr-2",children:s}),e.jsx("span",{className:"text-muted-foreground tabular-nums",children:o})]},s))}):e.jsx("p",{className:"text-xs text-muted-foreground",children:t.notEnoughData})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-xs uppercase tracking-wider text-muted-foreground mb-2",children:t.topSkills}),k.topSkills.length?e.jsx("div",{className:"flex flex-wrap gap-1.5",children:k.topSkills.map(([s,o])=>e.jsxs("span",{className:"px-2 py-0.5 rounded-full bg-primary/10 text-primary text-xs",children:[s," · ",o]},s))}):e.jsx("p",{className:"text-xs text-muted-foreground",children:t.notEnoughData})]}),e.jsxs("div",{children:[e.jsxs("p",{className:"text-xs uppercase tracking-wider text-muted-foreground mb-2 flex items-center gap-1",children:[e.jsx(Re,{className:"w-3 h-3"})," ",t.bestPostingDay]}),k.bestDay?e.jsx("p",{className:"text-sm",children:t.bestDaySentence(k.bestDay.day,k.dayLift)}):e.jsx("p",{className:"text-xs text-muted-foreground",children:t.notEnoughData})]})]}):e.jsx("p",{className:"text-sm text-muted-foreground",children:t.noInsightsYet})}),!T&&e.jsx("div",{className:"absolute inset-0 flex items-end justify-center p-4 bg-gradient-to-t from-card via-card/80 to-transparent",children:e.jsxs("button",{onClick:()=>W("generic",t.upgradeReasonInsights),className:"rounded-xl bg-primary text-primary-foreground px-4 py-2 text-sm font-semibold inline-flex items-center gap-2",children:[e.jsx(Ee,{className:"w-4 h-4"})," ",t.upgradeToPaid]})})]})]})]})}function Ye(c,m){return D.useMemo(()=>{const x=[...c].sort((y,t)=>{const p=y[m.key],l=t[m.key];return p==null&&l==null?0:p==null?1:l==null?-1:typeof p=="number"&&typeof l=="number"?p-l:String(p).localeCompare(String(l))});return m.dir==="asc"?x:x.reverse()},[c,m])}export{vt 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.