PageSourceSearch

https://deliverimates-production.up.railway.app/assets/SchedulingAnalytics-D1CQvsqM.js

js deliverimates-production.up.railway.app collected 2026-10-03 12:13:12 UTC 12,312 bytes, 2 lines download raw bytes

1import{r as b,v as _,a9 as N,j as e,cF as v,B as w,ab as k,bb as S,U as C,T as L}from"./index-Db4qfLtJ.js";import{i as $}from"./use-auto-schedule-DKQWRGci.js";import{D}from"./download-CboRdteu.js";import{D as E}from"./dollar-sign-Dd_koKVA.js";function F(a){return`$${a.toLocaleString("en-US",{maximumFractionDigits:0})}`}function y(a){return new Date(a+"T12:00:00").toLocaleDateString("en-US",{month:"short",day:"numeric"})}function A(a,i,s){if(s===0)return"normal";const t=(a-i)/s;return t>=2?"very_high":t>=1?"high":t<=-1?"low":"normal"}const u={low:"#9CA3AF",normal:"#10B981",high:"#F59E0B",very_high:"#EF4444"};function p({icon:a,label:i,value:s,sublabel:t,tone:d="neutral"}){const c={neutral:"text-slate-900",good:"text-emerald-700",warn:"text-amber-700",bad:"text-rose-700"};return e.jsxs("div",{className:"bg-white rounded-lg border border-slate-200 p-4",children:[e.jsxs("div",{className:"flex items-center gap-2 text-xs text-slate-500 mb-1",children:[a,e.jsx("span",{children:i})]}),e.jsx("div",{className:`text-2xl font-bold ${c[d]}`,children:s}),t&&e.jsx("div",{className:"text-xs text-slate-500 mt-1",children:t})]})}function g({drivers:a,metric:i,mean:s,stdDev:t}){const d=b.useMemo(()=>[...a].sort((o,n)=>n[i]-o[i]),[a,i]),c=Math.max(...d.map(o=>o[i]),1);return d.length===0?e.jsx("div",{className:"text-sm text-slate-400 py-8 text-center",children:"No data for this period"}):e.jsxs("div",{className:"space-y-1",children:[d.map(o=>{const n=o[i],x=n/c*100,m=i==="total_days"?A(n,s,t):"normal",h=u[m];return e.jsxs("div",{className:"flex items-center gap-2 text-xs",children:[e.jsx("div",{className:"w-32 truncate text-slate-700",title:o.driver_name,children:o.driver_name}),e.jsx("div",{className:"flex-1 h-5 bg-slate-100 rounded relative overflow-hidden",children:e.jsx("div",{className:"absolute inset-y-0 left-0 rounded transition-all",style:{width:`${x}%`,background:h}})}),e.jsx("div",{className:"w-12 text-right tabular-nums font-medium text-slate-700",children:n})]},o.driver_id)}),i==="total_days"&&t>0&&e.jsxs("div",{className:"flex items-center gap-3 mt-3 pt-3 border-t border-slate-100 text-xs text-slate-500",children:[e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx("span",{className:"w-2 h-2 rounded",style:{background:u.low}})," Under (-1σ)"]}),e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx("span",{className:"w-2 h-2 rounded",style:{background:u.normal}})," Fair range"]}),e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx("span",{className:"w-2 h-2 rounded",style:{background:u.high}})," High (+1σ)"]}),e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx("span",{className:"w-2 h-2 rounded",style:{background:u.very_high}})," Very high (+2σ)"]}),e.jsxs("span",{className:"ml-auto",children:["μ = ",s.toFixed(1)," · σ = ",t.toFixed(1)]})]})]})}function B({drivers:a}){const s=b.useMemo(()=>[...a].sort((t,d)=>{if(d.standby_days!==t.standby_days)return d.standby_days-t.standby_days;const c=t.weeks_since_last_standby??999;return(d.weeks_since_last_standby??999)-c}),[a]).filter(t=>t.standby_days>0||t.weeks_since_last_standby!==null);return s.length===0?e.jsx("div",{className:"text-sm text-slate-400 py-8 text-center",children:"No standby assignments in this period"}):e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-xs",children:[e.jsx("thead",{className:"text-left text-slate-500 border-b border-slate-200",children:e.jsxs("tr",{children:[e.jsx("th",{className:"py-2 pr-3 font-medium",children:"Driver"}),e.jsx("th",{className:"py-2 pr-3 font-medium text-right",children:"Standby days"}),e.jsx("th",{className:"py-2 pr-3 font-medium text-right",children:"Last standby"}),e.jsx("th",{className:"py-2 font-medium text-right",children:"Weeks since"})]})}),e.jsx("tbody",{children:s.map(t=>e.jsxs("tr",{className:"border-b border-slate-100",children:[e.jsx("td",{className:"py-2 pr-3 text-slate-900",children:t.driver_name}),e.jsx("td",{className:"py-2 pr-3 text-right tabular-nums font-medium",children:t.standby_days}),e.jsx("td",{className:"py-2 pr-3 text-right text-slate-600",children:t.last_standby_date?y(t.last_standby_date):"—"}),e.jsx("td",{className:"py-2 text-right tabular-nums",children:t.weeks_since_last_standby!==null?e.jsxs("span",{className:t.weeks_since_last_standby>4?"text-amber-600 font-medium":"text-slate-600",children:[t.weeks_since_last_standby,"w"]}):"—"})]},t.driver_id))})]})})}function M({weeklyTotals:a}){if(a.length===0)return e.jsx("div",{className:"text-sm text-slate-400 py-8 text-center",children:"No weekly data yet"});const i=700,s=200,t=30,d=Math.max(...a.map(l=>l.total_hours),1),c=Math.max(...a.map(l=>l.ot_cost),1),o=Math.max(...a.map(l=>l.ot_drivers),1),n=(i-2*t)/Math.max(a.length-1,1),x=(l,r)=>s-t-l/r*(s-2*t),m=a.map((l,r)=>`${r===0?"M":"L"} ${t+r*n} ${x(l.total_hours,d)}`).join(" "),h=a.map((l,r)=>`${r===0?"M":"L"} ${t+r*n} ${x(l.ot_cost,c)}`).join(" "),j=a.map((l,r)=>`${r===0?"M":"L"} ${t+r*n} ${x(l.ot_drivers,o)}`).join(" ");return e.jsxs("div",{children:[e.jsxs("svg",{viewBox:`0 0 ${i} ${s}`,className:"w-full h-auto",preserveAspectRatio:"xMidYMid meet",children:[[0,.25,.5,.75,1].map(l
1=>e.jsx("line",{x1:t,y1:t+l*(s-2*t),x2:i-t,y2:t+l*(s-2*t),stroke:"#E5E7EB",strokeWidth:1},l)),e.jsx("path",{d:m,fill:"none",stroke:"#3B82F6",strokeWidth:2}),e.jsx("path",{d:h,fill:"none",stroke:"#EF4444",strokeWidth:2}),e.jsx("path",{d:j,fill:"none",stroke:"#F59E0B",strokeWidth:2}),a.map((l,r)=>e.jsxs("g",{children:[e.jsx("circle",{cx:t+r*n,cy:x(l.total_hours,d),r:3,fill:"#3B82F6"}),e.jsx("circle",{cx:t+r*n,cy:x(l.ot_cost,c),r:3,fill:"#EF4444"}),e.jsx("circle",{cx:t+r*n,cy:x(l.ot_drivers,o),r:3,fill:"#F59E0B"}),e.jsx("text",{x:t+r*n,y:s-8,textAnchor:"middle",fontSize:9,fill:"#6B7280",children:y(l.week_start)})]},l.week_start))]}),e.jsxs("div",{className:"flex items-center gap-4 mt-2 text-xs text-slate-600",children:[e.jsxs("span",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"w-3 h-0.5 bg-blue-500"})," Total hours"]}),e.jsxs("span",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"w-3 h-0.5 bg-rose-500"})," OT cost"]}),e.jsxs("span",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"w-3 h-0.5 bg-amber-500"})," Drivers over 40hr"]})]})]})}function H(){const[a,i]=b.useState({weeks:4}),{data:s,isLoading:t}=$(a),{data:d}=_(),c=N(d,"standard"),o=()=>{if(!s)return;const n=["Driver","Group","Onboarding","Days","Hours","Standby","Weekends","Callouts","Last standby","OT cost"],x=s.drivers.map(r=>[r.driver_name,r.driver_group,r.onboarding_status,r.total_days,r.total_hours,r.standby_days,r.weekend_days,r.callouts,r.last_standby_date||"",r.projected_ot_cost]),m=[n,...x].map(r=>r.map(f=>`"${f}"`).join(",")).join(`
2`),h=new Blob([m],{type:"text/csv"}),j=URL.createObjectURL(h),l=document.createElement("a");l.href=j,l.download=`scheduling-analytics-${s.start_date}-to-${s.end_date}.csv`,l.click(),URL.revokeObjectURL(j)};return e.jsxs("div",{className:"flex flex-col h-full bg-slate-50",children:[e.jsxs("div",{className:"flex items-center justify-between px-6 py-3 bg-white border-b border-slate-200 flex-shrink-0",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(v,{className:"h-5 w-5 text-slate-500"}),e.jsx("h1",{className:"text-base font-semibold text-slate-900",children:"Scheduling Analytics"})]}),e.jsx("div",{className:"flex items-center gap-2",children:c&&e.jsxs(w,{variant:"outline",size:"sm",onClick:o,disabled:!s||s.drivers.length===0,className:"h-8 gap-1.5",children:[e.jsx(D,{className:"h-3.5 w-3.5"})," Export CSV"]})})]}),e.jsxs("div",{className:"flex items-center gap-3 px-6 py-3 bg-white border-b border-slate-200 flex-wrap",children:[e.jsx("span",{className:"text-xs font-medium text-slate-500",children:"Period:"}),e.jsxs("select",{value:a.weeks||4,onChange:n=>i({...a,weeks:Number(n.target.value),start_date:void 0,end_date:void 0}),className:"text-xs border border-slate-300 rounded px-2 py-1 bg-white",children:[e.jsx("option",{value:4,children:"Last 4 weeks"}),e.jsx("option",{value:8,children:"Last 8 weeks"}),e.jsx("option",{value:12,children:"Last 12 weeks"}),e.jsx("option",{value:26,children:"Last 6 months"})]}),e.jsx("span",{className:"text-xs font-medium text-slate-500 ml-3",children:"Group:"}),e.jsxs("select",{value:a.driver_group||"",onChange:n=>i({...a,driver_group:n.target.value||null}),className:"text-xs border border-slate-300 rounded px-2 py-1 bg-white",children:[e.jsx("option",{value:"",children:"All groups"}),e.jsx("option",{value:"dispatch",children:"Dispatch"}),e.jsx("option",{value:"regular",children:"Regular"}),e.jsx("option",{value:"extra",children:"Extra"})]}),e.jsx("span",{className:"text-xs font-medium text-slate-500 ml-3",children:"Status:"}),e.jsxs("select",{value:a.onboarding_status||"",onChange:n=>i({...a,onboarding_status:n.target.value||null}),className:"text-xs border border-slate-300 rounded px-2 py-1 bg-white",children:[e.jsx("option",{value:"",children:"All statuses"}),e.jsx("option",{value:"active",children:"Active"}),e.jsx("option",{value:"nursery",children:"Nursery"}),e.jsx("option",{value:"ride_along",children:"Ride-Along"})]}),s&&e.jsxs("span",{className:"text-xs text-slate-500 ml-auto",children:[s.start_date," to ",s.end_date]})]}),t&&!s?e.jsx("div",{className:"flex-1 flex items-center justify-center",children:e.jsx(k,{className:"h-6 w-6 animate-spin text-slate-400"})}
2):s?e.jsxs("div",{className:"flex-1 overflow-y-auto p-6 space-y-6",children:[e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-3",children:[e.jsx(p,{icon:e.jsx(S,{className:"h-3.5 w-3.5"}),label:"Total scheduled hours",value:s.kpis.total_scheduled_hours.toLocaleString(),sublabel:`${s.kpis.driver_count} drivers`}),e.jsx(p,{icon:e.jsx(E,{className:"h-3.5 w-3.5"}),label:"Projected OT cost",value:F(s.kpis.total_projected_ot_cost),tone:s.kpis.total_projected_ot_cost>500?"warn":"neutral"}),e.jsx(p,{icon:e.jsx(C,{className:"h-3.5 w-3.5"}),label:"Hours fairness (σ)",value:s.kpis.std_dev_days.toFixed(1),sublabel:"lower = more fair",tone:s.kpis.std_dev_days>4?"warn":"good"}),e.jsx(p,{icon:e.jsx(L,{className:"h-3.5 w-3.5"}),label:"Drivers over 5 days",value:String(s.kpis.drivers_over_5_days),tone:s.kpis.drivers_over_5_days>0?"warn":"good"}),e.jsx(p,{icon:e.jsx(v,{className:"h-3.5 w-3.5"}),label:"Avg weekend days",value:s.kpis.avg_weekend_days.toFixed(1),sublabel:"per driver in period"})]}),e.jsxs("section",{className:"bg-white rounded-lg border border-slate-200 p-4",children:[e.jsxs("div",{className:"flex items-center justify-between mb-3",children:[e.jsx("h2",{className:"text-sm font-semibold text-slate-900",children:"Hours distribution"}),e.jsx("span",{className:"text-xs text-slate-500",children:"Days scheduled per driver"})]}),e.jsx(g,{drivers:s.drivers,metric:"total_days",mean:s.fairness.mean_days,stdDev:s.fairness.std_dev})]}),e.jsxs("section",{className:"bg-white rounded-lg border border-slate-200 p-4",children:[e.jsxs("div",{className:"flex items-center justify-between mb-3",children:[e.jsx("h2",{className:"text-sm font-semibold text-slate-900",children:"Weekend equity"}),e.jsx("span",{className:"text-xs text-slate-500",children:"Sat + Sun days worked per driver"})]}),e.jsx(g,{drivers:s.drivers,metric:"weekend_days",mean:s.kpis.avg_weekend_days,stdDev:0})]}),e.jsxs("section",{className:"bg-white rounded-lg border border-slate-200 p-4",children:[e.jsxs("div",{className:"flex items-center justify-between mb-3",children:[e.jsx("h2",{className:"text-sm font-semibold text-slate-900",children:"Standby rotation"}),e.jsx("span",{className:"text-xs text-slate-500",children:'Catch the "always picked" pattern'})]}),e.jsx(B,{drivers:s.drivers})]}),e.jsxs("section",{className:"bg-white rounded-lg border border-slate-200 p-4",children:[e.jsxs("div",{className:"flex items-center justify-between mb-3",children:[e.jsx("h2",{className:"text-sm font-semibold text-slate-900",children:"Weekly trends"}),e.jsxs("span",{className:"text-xs text-slate-500",children:[s.weekly_totals.length," weeks"]})]}),e.jsx(M,{weeklyTotals:s.weekly_totals})]})]}):e.jsx("div",{className:"flex-1 flex items-center justify-center text-slate-400 text-sm",children:"No analytics data available"})]})}export{H 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.