1import{r,j as e}from"./react-vendor-BRrUKPtI.js";import{A as b}from"./AdminLayout-Df3DyQHu.js";import{A as o}from"./AdminMetricCard-B4ue3qC9.js";import{A}from"./AdminLineChart-DJFgElL9.js";import{A as C}from"./AdminBarChart-lVNotzdW.js";import{A as G}from"./AdminDoughnutChart-DFc7aVtk.js";function Z(){const[R,g]=r.useState(!0),[S,f]=r.useState(!1),[v,j]=r.useState(null),[a,L]=r.useState(null),[x,T]=r.useState([]),[s,D]=r.useState({page:1,limit:50,total:0,totalPages:0}),[y,P]=r.useState({airports:[],types:[]}),[m,$]=r.useState("30d"),[p,M]=r.useState(""),[u,W]=r.useState(""),F=async()=>{try{const t=await fetch(`/api/admin/metrics/reports?period=${m}`);if(!t.ok){if(t.status===401){window.location.href="/login?redirect=/admin/reports";return}if(t.status===403){j("You do not have permission to access this page.");return}throw new Error("Failed to fetch metrics")}const i=await t.json();i.success&&L(i.data)}catch(t){j(t instanceof Error?t.message:"Failed to load metrics")}},c=r.useCallback(async(t,i,l)=>{try{f(!0);const d=new URLSearchParams({page:t.toString(),limit:"50"});i&&d.set("airport",i),l&&d.set("type",l);const k=await fetch(`/api/admin/reports?${d}`);if(!k.ok)throw new Error("Failed to fetch reports");const n=await k.json();n.success&&(T(n.data.reports),D(n.data.pagination),P(n.data.filters))}catch(d){console.error("Failed to fetch reports:",d)}finally{f(!1)}},[]);r.useEffect(()=>{(async()=>{g(!0),await F(),await c(1,"",""),g(!1)})()},[m,c]);const N=t=>{c(t,p,u)},E=t=>{M(t),c(1,t,u)},z=t=>{W(t),c(1,p,t)},h=t=>new Date(t).toLocaleString("en-US",{month:"short",day:"numeric",hour:"numeric",minute:"2-digit"}),w=t=>t<=15?"text-green-600":t<=30?"text-yellow-600":t<=45?"text-orange-600":"text-red-600",_=t=>{switch(t){case"security":return"fa-shield-alt";case"immigration":return"fa-passport";case"customs":return"fa-box";case"checkin":return"fa-suitcase";case"baggage":return"fa-suitcase-rolling";case"lounge":return"fa-couch";default:return"fa-clock"}};if(R)return e.jsx(b,{currentPage:"reports",children:e.jsx("div",{className:"flex items-center justify-center h-64",children:e.jsxs("div",{className:"text-center",children:[e.jsx("i",{className:"fas fa-spinner fa-spin text-3xl text-blue-500 mb-4"}),e.jsx("p",{className:"text-[var(--board-text-dim)]",children:"Loading crowd reports..."})]})})});if(v)return e.jsx(b,{currentPage:"reports",children:e.jsxs("div",{className:"bg-red-900/20 border border-red-800 rounded-xl p-6 text-center",children:[e.jsx("i",{className:"fas fa-exclamation-circle text-red-500 text-3xl mb-4"}),e.jsx("p",{className:"text-red-400",children:v})]})});const U=a?.byDay.map(t=>({date:t.date,value:t.count}))||[],B=a?.byDay.map(t=>({date:t.date,value:Math.round(t.avg_wait||0)}))||[],H=t=>{switch(t){case"security":return"rgb(59, 130, 246)";case"immigration":return"rgb(168, 85, 247)";case"customs":return"rgb(234, 179, 8)";case"checkin":return"rgb(34, 197, 94)";case"baggage":return"rgb(249, 115, 22)";case"lounge":return"rgb(236, 72, 153)";default:return"rgb(107, 114, 128)"}},q=a?.byType.map(t=>({label:t.checkpoint_type.charAt(0).toUpperCase()+t.checkpoint_type.slice(1),value:t.count,color:H(t.checkpoint_type)}))||[],I=a?.byAirport.slice(0,10).map(t=>({label:t.airport_code,value:t.count}))||[],Y=a?.byHour.map(t=>({label:`${t.hour}:00`,value:t.count}))||[];return e.jsx(b,{currentPage:"reports",children:e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-2xl font-bold text-[var(--board-text)]",children:"Crowd Reports"}),e.jsx("p",{className:"text-[var(--board-text-dim)] mt-1",children:"User-submitted wait time reports and analytics"})]}),e.jsxs("select",{value:m,onChange:t=>$(t.target.value),className:"px-4 py-2 border border-[var(--board-border)] rounded-lg bg-[var(--board-surface)] text-[var(--board-text)] focus:outline-none focus:ring-2 focus:ring-blue-500",children:[e.jsx("option",{value:"7d",children:"Last 7 days"}),e.jsx("option",{value:"30d",children:"Last 30 days"}),e.jsx("option",{value:"90d",children:"Last 90 days"})]})]}),e.jsxs("div",{className:"grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-6 gap-4",children:[e.jsx(o,{title:"Total Reports",value:a?.summary.total_reports||0,icon:"fa-bullhorn",color:"blue"}),e.jsx(o,{title:"Contributors",value:a?.summary.unique_reporters||0,icon:"fa-users",color:"green"}),e.jsx(o,{title:"Airports",value:a?.summary.airports_covered||0,icon:"fa-plane",color:"purple"}),e.jsx(o,{title:"Avg Wait",value:`${Math.round(a?.summary.avg_wait||0)}m`,icon:"fa-clock",color:"yellow"}),e.jsx(o,{title:"Min Wait",value:`${a?.summary.min_wait||0}m`,icon:"fa-arrow-down",color:"green"}),e.jsx(o,{title:"Max Wait",value:`${a?.summary.max_wait||0}m`,icon:"fa-arrow-up",color:"red"})]}),e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-6",children:[e.jsx(A,{data:U,title:"Reports Per Day",yAxisLabel:"Reports",color:"rgb(59, 130, 246)"}),e.jsx(A,{data:B,title:"Average Wait Time Per Day",yAxisLabel:"Minutes",color:"rgb(234, 179, 8)"})]}),e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-3 gap-6",children:[e.jsx(G,{data:q,title:"Reports by Checkpoint Type"}),e.jsx(C,{data:I,title:"Top Reporting Airports",horizontal:!0}),e.jsx(C,{data:Y,title:"Reports by Hour (UTC)",horizontal:!1})]}),a?.highWaitAlerts&&a.highWaitAlerts.length>0&&e.jsxs("div",{className:"bg-red-900/20 border border-red-800 rounded-xl p-6",children:[e.jsxs("h3",{className:"text-lg font-semibold text-red-400 mb-4 flex items-center gap-2",children:[e.jsx("i",{className:"fas fa-exclamation-triangle"}),"High Wait Time Alerts (45+ minutes)"]}),e.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3",children:a.highWaitAlerts.map((t,i)=>e.jsxs("div",{className:"bg-[var(--board-surface)] rounded-lg p-3 border border-red-900",children:[e.jsxs("div",{className:"flex items-center justify-between mb-1",children:[e.jsx("span",{className:"font-medium text-[var(--board-text)]",children:t.airport_code}),e.jsxs("span",{className:"text-red-500 font-bold",children:[t.wait_time_minutes,"m"]})]}),e.jsxs("div",{className:"text-sm text-[var(--board-text-dim)]",children:[t.checkpoint_type," ",t.terminal&&`- ${t.terminal}`]}),e.jsx("div",{className:"text-xs text-[var(--board-text-muted)] mt-1",children:h(t.reported_at)})]},i))})]}),e.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-6 gap-4",children:a?.byType.map(t=>{const i=t.checkpoint_type==="security"?"bg-blue-900/30":t.checkpoint_type==="immigration"?"bg-purple-900/30":t.checkpoint_type==="customs"?"bg-yellow-900/30":t.checkpoint_type==="checkin"?"bg-green-900/30":t.checkpoint_type==="baggage"?"bg-orange-900/30":t.checkpoint_type==="lounge"?"bg-pink-900/30":"bg-[var(--board-border)]",l=t.checkpoint_type==="security"?"text-blue-400":t.checkpoint_type==="immigration"?"text-purple-400":t.checkpoint_type==="customs"?"text-yellow-400":t.checkpoint_type==="checkin"?"text-green-400":t.checkpoint_type==="baggage"?"text-orange-400":t.checkpoint_type==="lounge"?"text-pink-400":"text-[var(--board-text-dim)]";return e.jsxs("div",{className:"bg-[var(--board-surface)] rounded-xl shadow-sm border border-[var(--board-border)] p-4",children:[e.jsxs("div",{className:"flex items-center gap-3 mb-3",children:[e.jsx("div",{className:`p-2 rounded-lg ${i}`,children:e.jsx("i",{className:`fas ${_(t.checkpoint_type)} ${l}`})}),e.jsxs("div",{children:[e.jsx("h4",{className:"font-medium text-[var(--board-text)] capitalize",children:t.checkpoint_type}),e.jsxs("p",{className:"text-sm text-[var(--board-text-dim)]",children:[t.count," reports"]})]})]}),e.jsxs("div",{className:"grid grid-cols-3 gap-2 text-center text-sm",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-[var(--board-text-muted)]",children:"Min"}),e.jsxs("p",{className:"font-medium text-green-500",children:[t.min_wait,"m"]})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-[var(--board-text-muted)]",children:"Avg"}),e.jsxs("p",{className:"font-medium text-yellow-500",children:[Math.round(t.avg_wait),"m"]})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-[var(--board-text-muted)]",children:"Max"}),e.jsxs("p",{className:"font-medium text-red-500",children:[t.max_wait,"m"]})]})]})]},t.checkpoint_type)})}),e.jsxs("div",{className:"bg-[var(--board-surface)] rounded-xl shadow-sm border border-[var(--board-border)]",children:[e.jsxs("div",{className:"p-4 border-b border-[var(--board-border)]",children:[e.jsx("h3",{className:"text-lg font-semibold text-[var(--board-text)] mb-4",children:"All Reports"}),e.jsxs("div",{className:"flex flex-col sm:flex-row gap-4",children:[e.jsxs("select",{value:p,onChange:t=>E(t.target.value),className:"px-4 py-2 border border-[var(--board-border)] rounded-lg bg-[var(--board-surface)] text-[var(--board-text)] focu
1s:outline-none focus:ring-2 focus:ring-blue-500",children:[e.jsx("option",{value:"",children:"All airports"}),y.airports.map(t=>e.jsx("option",{value:t,children:t},t))]}),e.jsxs("select",{value:u,onChange:t=>z(t.target.value),className:"px-4 py-2 border border-[var(--board-border)] rounded-lg bg-[var(--board-surface)] text-[var(--board-text)] focus:outline-none focus:ring-2 focus:ring-blue-500",children:[e.jsx("option",{value:"",children:"All types"}),y.types.map(t=>e.jsx("option",{value:t,children:t},t))]})]})]}),e.jsx("div",{className:"overflow-x-auto",children:S?e.jsxs("div",{className:"p-8 text-center text-[var(--board-text-muted)]",children:[e.jsx("i",{className:"fas fa-spinner fa-spin text-2xl mb-2"}),e.jsx("p",{children:"Loading reports..."})]}):x.length===0?e.jsxs("div",{className:"p-8 text-center text-[var(--board-text-muted)]",children:[e.jsx("i",{className:"fas fa-inbox text-2xl mb-2"}),e.jsx("p",{children:"No reports found"})]}):e.jsxs(e.Fragment,{children:[e.jsxs("table",{className:"w-full hidden md:table",children:[e.jsx("thead",{className:"bg-[var(--board-surface)]",children:e.jsxs("tr",{children:[e.jsx("th",{className:"px-4 py-3 text-left text-xs font-medium text-[var(--board-text-dim)] uppercase",children:"Airport"}),e.jsx("th",{className:"px-4 py-3 text-left text-xs font-medium text-[var(--board-text-dim)] uppercase",children:"Type"}),e.jsx("th",{className:"px-4 py-3 text-left text-xs font-medium text-[var(--board-text-dim)] uppercase",children:"Wait"}),e.jsx("th",{className:"px-4 py-3 text-left text-xs font-medium text-[var(--board-text-dim)] uppercase",children:"Terminal"}),e.jsx("th",{className:"px-4 py-3 text-left text-xs font-medium text-[var(--board-text-dim)] uppercase",children:"Reporter"}),e.jsx("th",{className:"px-4 py-3 text-left text-xs font-medium text-[var(--board-text-dim)] uppercase",children:"Reported"})]})}),e.jsx("tbody",{className:"divide-y divide-[var(--board-border)]",children:x.map(t=>e.jsxs("tr",{className:"hover:bg-[var(--board-surface)]",children:[e.jsx("td",{className:"px-4 py-3",children:e.jsx("span",{className:"font-medium text-[var(--board-text)]",children:t.airport_code})}),e.jsx("td",{className:"px-4 py-3",children:e.jsxs("span",{className:"inline-flex items-center gap-1.5 text-sm text-[var(--board-text-dim)]",children:[e.jsx("i",{className:`fas ${_(t.checkpoint_type)} text-[var(--board-text-muted)]`}),e.jsx("span",{className:"capitalize",children:t.checkpoint_type})]})}),e.jsx("td",{className:"px-4 py-3",children:e.jsxs("span",{className:`font-semibold ${w(t.wait_time_minutes)}`,children:[t.wait_time_minutes,"m"]})}),e.jsx("td",{className:"px-4 py-3 text-sm text-[var(--board-text-dim)]",children:t.terminal||"-"}),e.jsx("td",{className:"px-4 py-3 text-sm text-[var(--board-text-dim)]",children:t.user_email?e.jsx("span",{className:"text-blue-400",children:t.user_email}):e.jsx("span",{className:"text-[var(--board-text-muted)]",children:"Anonymous"})}),e.jsx("td",{className:"px-4 py-3 text-sm text-[var(--board-text-dim)]",children:h(t.reported_at)})]},t.id))})]}),e.jsx("div",{className:"md:hidden divide-y divide-[var(--board-border)]",children:x.map(t=>e.jsxs("div",{className:"p-4",children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"font-medium text-[var(--board-text)]",children:t.airport_code}),e.jsx("span",{className:"text-sm text-[var(--board-text-dim)] capitalize",children:t.checkpoint_type})]}),e.jsxs("span",{className:`font-semibold ${w(t.wait_time_minutes)}`,children:[t.wait_time_minutes,"m"]})]}),e.jsxs("div",{className:"text-sm text-[var(--board-text-dim)]",children:[t.terminal&&e.jsxs("span",{children:["Terminal ",t.terminal," - "]}),h(t.reported_at)]}),t.user_email&&e.jsx("div",{className:"text-sm text-blue-400 mt-1",children:t.user_email})]},t.id))})]})}),s.totalPages>1&&e.jsxs("div",{className:"px-4 py-3 border-t border-[var(--board-border)] flex items-center justify-between",children:[e.jsxs("div",{className:"text-sm text-[var(--board-text-dim)]",children:["Showing ",(s.page-1)*s.limit+1," -"," ",Math.min(s.page*s.limit,s.total)," of ",s.total]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("button",{onClick:()=>N(s.page-1),disabled:s.page===1,className:"px-3 py-1 text-sm border border-[var(--board-border)] rounded-lg text-[var(--board-text)] disabled:opacity-50 disabled:cursor-not-allowed hover:bg-[var(--board-surface)]",children:e.jsx("i",{className:"fas fa-chevron-left"})}),e.jsx("button",{onClick:()=>N(s.page+1),disabled:s.page===s.totalPages,className:"px-3 py-1 text-sm border border-[var(--board-border)] rounded-lg text-[var(--board-text)] disabled:opacity-50 disabled:cursor-not-allowed hover:bg-[var(--board-surface)]",children:e.jsx("i",{className:"fas fa-chevron-right"})})]})]})]})]})})}export{Z as AdminCrowdReportsPage};
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.