1import{a as o,j as e}from"./vendor-query-CRhh6spR.js";import{B as k,ah as E,I as b,s as F}from"./index-BkVb42KZ.js";import{C as d}from"./card-CScRmu7W.js";import{L as _}from"./label-Xk_s6Ck5.js";import"./vendor-react-BAmwgVqg.js";import"./vendor-charts-BVeOEGzI.js";import"./vendor-stripe-2y4Jo9_W.js";import"./vendor-supabase-Csx7YFID.js";const T=28.5383,q=-81.3792,A=35,c=(l,r)=>r===0?"â":`${Math.round(100*l/r)}%`,M=(l,r="")=>l==null?"not tracked":`${Number.isInteger(l)?l:l.toFixed(1)}${r}`;function a({label:l,value:r,sub:n}){return e.jsxs(d,{className:"p-4",children:[e.jsx("div",{className:"text-xs uppercase tracking-wide text-muted-foreground",children:l}),e.jsx("div",{className:"text-2xl font-semibold mt-1",children:r}),n&&e.jsx("div",{className:"text-xs text-muted-foreground mt-1",children:n})]})}function x({n:l,title:r}){return e.jsxs("h2",{className:"text-lg font-semibold mt-8 mb-3 flex items-baseline gap-2",children:[e.jsxs("span",{className:"text-muted-foreground tabular-nums",children:[l,"."]}),r]})}function W(){var N,y,w;const[l,r]=o.useState(T),[n,u]=o.useState(q),[g,S]=o.useState(A),[s,C]=o.useState(null),[p,f]=o.useState(null),[h,v]=o.useState(!1);async function j(){v(!0),f(null);const{data:t,error:i}=await F.rpc("get_orlando_beachhead",{center_lat:l,center_lng:n,radius_miles:g});i?f(i.message):C(t),v(!1)}o.useEffect(()=>{j()},[]);const L=o.useMemo(()=>s?new Date(s.generated_at).toLocaleString():"â",[s]);return e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-start justify-between gap-4 flex-wrap",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold",children:"Orlando Beachhead"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Read-only internal analytics. All metrics filtered to the boundary below."})]}),e.jsxs("div",{className:"flex items-center gap-2 text-xs text-muted-foreground",children:[e.jsxs("span",{children:["Last refreshed: ",L]}),e.jsxs(k,{size:"sm",variant:"outline",onClick:j,disabled:h,className:"gap-1",children:[e.jsx(E,{className:`h-3 w-3 ${h?"animate-spin":""}`}),"Refresh"]})]})]}),e.jsx(d,{className:"p-4 bg-muted/30",children:e.jsxs("div",{className:"flex items-end gap-3 flex-wrap",children:[e.jsxs("div",{children:[e.jsx(_,{className:"text-xs",children:"Center lat"}),e.jsx(b,{className:"w-32",type:"number",step:"0.0001",value:l,onChange:t=>r(parseFloat(t.target.value))})]}),e.jsxs("div",{children:[e.jsx(_,{className:"text-xs",children:"Center lng"}),e.jsx(b,{className:"w-32",type:"number",step:"0.0001",value:n,onChange:t=>u(parseFloat(t.target.value))})]}),e.jsxs("div",{children:[e.jsx(_,{className:"text-xs",children:"Radius (mi)"}),e.jsx(b,{className:"w-24",type:"number",step:"1",value:g,onChange:t=>S(parseFloat(t.target.value))})]}),e.jsx(k,{onClick:j,disabled:h,children:"Apply"}),e.jsx("div",{className:"ml-auto text-xs text-muted-foreground",children:((N=s==null?void 0:s.boundary)==null?void 0:N.label)??"â"})]})}),p&&e.jsx(d,{className:"p-4 border-destructive bg-destructive/10 text-destructive",children:p}),!s&&!p&&e.jsx(d,{className:"p-6 text-muted-foreground",children:"Loadingâ¦"}),s&&e.jsxs(e.Fragment,{children:[e.jsx(x,{n:1,title:"Supply â Orlando workers"}),e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-3",children:[e.jsx(a,{label:"Total workers",value:s.supply.total_workers}),e.jsx(a,{label:"Completed profile",value:s.supply.completed_profile,sub:c(s.supply.completed_profile,s.supply.total_workers)}),e.jsx(a,{label:"Push reach",value:s.supply.with_device_token,sub:`device token · ${c(s.supply.with_device_token,s.supply.total_workers)}`}),e.jsx(a,{label:"SMS reach",value:s.supply.with_sms_optin,sub:`opted-in · ${c(s.supply.with_sms_optin,s.supply.total_workers)}`})]}),e.jsxs(d,{className:"p-4 mt-3",children:[e.jsx("div",{className:"text-xs uppercase text-muted-foreground mb-2",children:"Workers by trade"}),e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"text-left text-muted-foreground border-b",children:[e.jsx("th",{className:"py-1",children:"Trade"}),e.jsx("th",{className:"py-1 text-right",children:"Workers"}),e.jsx("th",{className:"py-1 text-right",children:"% of supply"})]})}),e.jsxs("tbody",{children:[s.supply.trade_breakdown.length===0&&e.jsx("tr",{children:e.jsx("td",{colSpan:3,className:"py-2 text-muted-foreground",children:"No skills recorded yet."})}),s.supply.trade_breakdown.map(t=>e.jsxs("tr",{className:"border-b last:border-b-0",children:[e.jsx("td",{className:"py-1",children:t.trade}),e.jsx("td",{className:"py-1 text-right tabular-nums",children:t.workers}),e.jsx("td",{className:"py-1 text-right tabular-nums text-muted-foreground",children:c(t.workers,s.supply.total_workers)})]},t.trade))]})]})]}),e.jsx(x,{n:2,title:"Demand â Orlando jobs"}),e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-3",children:[e.jsx(a,{label:"Total jobs (all time)",value:s.demand.total_jobs}),e.jsx(a,{label:"Posted last 7d",value:s.demand.jobs_last_7d}),e.jsx(a,{label:"Open right now",value:s.demand.open_now,sub:"no hire yet"}),e.jsx(a,{label:"Avg / day (14d)",value:s.demand.per_day_14d.length?(s.demand.per_day_14d.reduce((t,i)=>
1t+i.n,0)/14).toFixed(1):0})]}),e.jsxs(d,{className:"p-4 mt-3",children:[e.jsx("div",{className:"text-xs uppercase text-muted-foreground mb-2",children:"Jobs per day · last 14 days"}),e.jsx("div",{className:"flex items-end gap-1 h-24",children:s.demand.per_day_14d.map(t=>{const i=Math.max(1,...s.demand.per_day_14d.map($=>$.n));return e.jsx("div",{className:"flex-1 bg-primary/70 rounded-t",style:{height:`${t.n/i*100}%`},title:`${t.day}: ${t.n}`},t.day)})}),e.jsxs("div",{className:"flex justify-between text-micro text-muted-foreground mt-1",children:[e.jsx("span",{children:((y=s.demand.per_day_14d[0])==null?void 0:y.day)??""}),e.jsx("span",{children:((w=s.demand.per_day_14d.at(-1))==null?void 0:w.day)??""})]})]}),e.jsxs(d,{className:"p-4 mt-3",children:[e.jsx("div",{className:"text-xs uppercase text-muted-foreground mb-2",children:"Jobs by trade"}),e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"text-left text-muted-foreground border-b",children:[e.jsx("th",{className:"py-1",children:"Trade"}),e.jsx("th",{className:"py-1 text-right",children:"Jobs"})]})}),e.jsxs("tbody",{children:[s.demand.trade_breakdown.length===0&&e.jsx("tr",{children:e.jsx("td",{colSpan:2,className:"py-2 text-muted-foreground",children:"No jobs yet."})}),s.demand.trade_breakdown.map(t=>e.jsxs("tr",{className:"border-b last:border-b-0",children:[e.jsx("td",{className:"py-1",children:t.trade}),e.jsx("td",{className:"py-1 text-right tabular-nums",children:t.jobs})]},t.trade))]})]})]}),e.jsx(x,{n:3,title:"Liquidity â the scoreboard"}),e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-3",children:[e.jsx(a,{label:"Fill rate",value:`${s.liquidity.fill_rate_pct}%`,sub:`${s.liquidity.jobs_with_apps} jobs with â¥1 app`}),e.jsx(a,{label:"Dead-listing rate",value:`${s.liquidity.dead_rate_pct}%`,sub:`${s.liquidity.dead_jobs} jobs with 0 apps`}),e.jsx(a,{label:"Median time â first app",value:s.liquidity.median_hours_to_first_app==null?"â":`${s.liquidity.median_hours_to_first_app.toFixed(1)}h`}),e.jsx(a,{label:"Median apps / job",value:M(s.liquidity.median_apps_per_job)})]}),e.jsxs(d,{className:"p-4 mt-3 border-primary/40",children:[e.jsx("div",{className:"text-xs uppercase text-muted-foreground mb-2",children:"Trade-level liquidity â which trade is closest to working"}),e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"text-left text-muted-foreground border-b",children:[e.jsx("th",{className:"py-1",children:"Trade"}),e.jsx("th",{className:"py-1 text-right",children:"Open jobs"}),e.jsx("th",{className:"py-1 text-right",children:"Workers available"}),e.jsx("th",{className:"py-1 text-right",children:"Jobs w/ â¥1 app"}),e.jsx("th",{className:"py-1 text-right",children:"Fill rate"})]})}),e.jsxs("tbody",{children:[s.liquidity.trade_table.length===0&&e.jsx("tr",{children:e.jsx("td",{colSpan:5,className:"py-2 text-muted-foreground",children:"No trade-level data yet."})}),s.liquidity.trade_table.map(t=>e.jsxs("tr",{className:"border-b last:border-b-0",children:[e.jsx("td",{className:"py-1 font-medium",children:t.trade}),e.jsx("td",{className:"py-1 text-right tabular-nums",children:t.open_jobs}),e.jsx("td",{className:"py-1 text-right tabular-nums",children:t.workers}),e.jsx("td",{className:"py-1 text-right tabular-nums",children:t.jobs_with_apps}),e.jsxs("td",{className:"py-1 text-right tabular-nums font-semibold",children:[t.fill_rate_pct,"%"]})]},t.trade))]})]})})]}),e.jsx(x,{n:4,title:"Invite delivery health (last 14d)"}),e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-5 gap-3",children:[e.jsx(a,{label:"Total invites",value:s.invite_health.total_invites_14d}),e.jsx(a,{label:"In-app",value:s.invite_health.in_app,sub:c(s.invite_health.in_app,s.invite_health.total_invites_14d)}),e.jsx(a,{label:"Push eligible",value:s.invite_health.push_eligible,sub:c(s.invite_health.push_eligible,s.invite_health.total_invites_14d)}),e.jsx(a,{label:"SMS sent",value:s.invite_health.sms_sent,sub:c(s.invite_health.sms_sent,s.invite_health.total_invites_14d)}),e.jsx(a,{label:"Email sent",value:s.invite_health.email_sent,sub:c(s.inv
1ite_health.email_sent,s.invite_health.total_invites_14d)})]}),e.jsxs(d,{className:"p-3 mt-2 text-xs text-muted-foreground",children:[e.jsx("div",{className:"font-medium mb-1",children:"Counting rules"}),e.jsx("ul",{className:"space-y-0.5",children:Object.entries(s.invite_health.notes).map(([t,i])=>e.jsxs("li",{children:[e.jsx("span",{className:"font-mono",children:t})," â ",i]},t))})]}),e.jsx(x,{n:5,title:"Activation funnels (Orlando)"}),e.jsxs("div",{className:"grid md:grid-cols-2 gap-3",children:[e.jsxs(d,{className:"p-4",children:[e.jsx("div",{className:"text-xs uppercase text-muted-foreground mb-2",children:"Worker funnel"}),e.jsx(m,{label:"Signed up",value:s.worker_funnel.signed_up,base:s.worker_funnel.signed_up}),e.jsx(m,{label:"Completed profile",value:s.worker_funnel.completed_profile,base:s.worker_funnel.signed_up}),e.jsx(m,{label:"Applied â¥1 job",value:s.worker_funnel.applied_at_least_once,base:s.worker_funnel.signed_up})]}),e.jsxs(d,{className:"p-4",children:[e.jsx("div",{className:"text-xs uppercase text-muted-foreground mb-2",children:"Contractor funnel"}),e.jsx(m,{label:"Signed up (all)",value:s.contractor_funnel.signed_up_all,base:s.contractor_funnel.signed_up_all}),e.jsx(m,{label:"Posted â¥1 Orlando job",value:s.contractor_funnel.posted_orlando_job,base:s.contractor_funnel.signed_up_all}),e.jsx(m,{label:"Made â¥1 hire",value:s.contractor_funnel.made_hire,base:s.contractor_funnel.signed_up_all}),e.jsx("div",{className:"text-micro text-muted-foreground mt-2",children:`"Signed up" counts all contractors â we don't capture location at signup, so geo-scoping the top of the contractor funnel isn't tracked.`})]})]})]})]})}function m({label:l,value:r,base:n}){const u=n===0?0:Math.round(100*r/n);return e.jsxs("div",{className:"py-1.5 border-b last:border-b-0",children:[e.jsxs("div",{className:"flex items-baseline justify-between text-sm",children:[e.jsx("span",{children:l}),e.jsxs("span",{className:"tabular-nums font-semibold",children:[r,e.jsxs("span",{className:"text-muted-foreground font-normal ml-2",children:[u,"%"]})]})]}),e.jsx("div",{className:"h-1.5 bg-muted rounded mt-1 overflow-hidden",children:e.jsx("div",{className:"h-full bg-primary",style:{width:`${u}%`}})})]})}export{W 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.