1import{r as i,j as e,d as P,h as z,I as F,B as o,$ as he,a0 as ue,a1 as xe,a2 as me,a3 as J,bt as pe,aC as fe,T as ge,bk as je,bl as Ne,bq as _e,e as W,f as ee,bj as I,Z as be,aK as ve,ab as se,aI as S}from"./index-DwBWDKUZ.js";import{A as O,b as q,a as B}from"./alert-04nDnLKe.js";import{s as j}from"./useConversionDiagnostics-NQhHwJLG.js";import{a as ye,b as we,c as Ce,u as Se,d as Le,r as ke,f as Ae}from"./useSearchRunLog-COVkpu5f.js";import{u as Te}from"./useFleetAvailability-D7vFoPht.js";const $e="Australia/Sydney";function te(a){return new Intl.DateTimeFormat("en-AU",{timeZone:$e,day:"2-digit",month:"short",hour:"2-digit",minute:"2-digit",hour12:!1}).format(new Date(a))}function D(a){if(!a)return"-";const[h,n,c]=a.split("-");return`${c}/${n}/${h.slice(2)}`}function d(a){return a==null||!Number.isFinite(Number(a))?"-":`$${Number(a).toFixed(2)}`}const Re=[{value:"all",label:"All contexts"},{value:"initial_search",label:"Initial searches"},{value:"promo_eval",label:"Promo evaluations"},{value:"requote",label:"Checkout re-quotes"},{value:"shadow",label:"Shadow searches"},{value:"server",label:"Server"}],re={initial_search:"Initial",promo_eval:"Promo",requote:"Re-quote",shadow:"Shadow",server:"Server",qa:"QA",unknown:"Unclassified"},ae=50;function L(a){return a==null||!Number.isFinite(Number(a))?"-":`${Number(a).toFixed(1)}%`}function N({label:a,value:h,hint:n}){return e.jsxs("div",{className:"rounded-lg border p-3",children:[e.jsx("div",{className:"text-xs text-muted-foreground",children:a}),e.jsx("div",{className:"text-xl font-semibold tabular-nums",children:h}),n?e.jsx("div",{className:"text-xs text-muted-foreground mt-0.5",children:n}):null]})}function Ee({runId:a,context:h,locationName:n}){const{data:c,isLoading:x,error:y}=Le(a,h),_=Te();return x?e.jsx(I,{className:"h-24 w-full"}):y?e.jsxs(O,{variant:"destructive",children:[e.jsx(q,{children:"Could not load offers"}),e.jsx(B,{children:y.message})]}):c!=null&&c.length?e.jsxs("div",{className:"overflow-x-auto",children:[e.jsxs("table",{className:"w-full text-xs",children:[e.jsx("thead",{className:"text-muted-foreground",children:e.jsxs("tr",{className:"border-b",children:[e.jsx("th",{className:"text-left py-1.5 pr-3",children:"Context"}),e.jsx("th",{className:"text-left py-1.5 pr-3",children:"Category (supplier name)"}),e.jsx("th",{className:"text-left py-1.5 pr-3",children:"Vehicle"}),e.jsx("th",{className:"text-right py-1.5 pr-3",children:"Base / day"}),e.jsx("th",{className:"text-right py-1.5 pr-3",children:"Customer / day"}),e.jsx("th",{className:"text-right py-1.5 pr-3",children:"Total before"}),e.jsx("th",{className:"text-right py-1.5 pr-3",children:"Total after"}),e.jsx("th",{className:"text-right py-1.5 pr-3",children:"Discount"}),e.jsx("th",{className:"text-left py-1.5 pr-3",children:"Code"}),e.jsx("th",{className:"text-left py-1.5 pr-3",children:"Availability"}),e.jsx("th",{className:"text-right py-1.5",children:"Fleet at this location"})]})}),e.jsx("tbody",{children:c.map(l=>{var w;const b=((w=_.data)==null?void 0:w.byLocationCategory(n,l.source_category_name))??null;return e.jsxs("tr",{className:"border-b last:border-0",children:[e.jsx("td",{className:"py-1.5 pr-3",children:re[l.context_class??""]??l.context_class??"-"}),e.jsx("td",{className:"py-1.5 pr-3 font-medium",children:l.source_category_name||"-"}),e.jsx("td",{className:"py-1.5 pr-3",children:l.representative_vehicle||"-"}),e.jsx("td",{className:"py-1.5 pr-3 text-right tabular-nums",children:d(l.base_daily_rate)}),e.jsx("td",{className:"py-1.5 pr-3 text-right tabular-nums",children:d(l.customer_daily_rate)}),e.jsx("td",{className:"py-1.5 pr-3 text-right tabular-nums",children:d(l.total_before_discount)}),e.jsx("td",{className:"py-1.5 pr-3 text-right tabular-nums",children:d(l.total_after_discount)}),e.jsx("td",{className:"py-1.5 pr-3 text-right tabular-nums",children:L(l.discount_percent)}),e.jsx("td",{className:"py-1.5 pr-3",children:l.campaign_code||"-"}),e.jsx("td",{className:"py-1.5 pr-3",children:l.is_available?(l.available_count??0)>1?`Available (${l.available_count})`:"Available":"Not available"}),e.jsx("td",{className:"py-1.5 text-right tabular-nums",children:b??"-"})]},l.id)})})]}),e.jsx("p",{className:"mt-2 text-[11px] text-muted-foreground",children:"Availability is what the supplier returned for these dates. Counts before 5 Sep 2026 were not recorded per vehicle, so older rows show at most 1. Fleet at this location is the monthly fleet size from the utilisation import, not live availability."})]}):e.jsx("div",{className:"text-sm text-muted-foreground",children:"No offers recorded for this run."})}function Oe(){var H;const[a,h]=i.useState(()=>j(0)),[n,c]=i.useState(()=>j(0)),[x,y]=i.useState("all"),[_,l]=i.useState("all"),[b,w]=i.useState(""),[C,k]=i.useState(0),[le,M]=i.useState(null),[Q,U]=i.useState(!1),[A,V]=i.useState(!1),T=i.useMemo(()=>({start:a,end:n,context:x,location:_,query:b}),[a,n,x,_,b]),m=ye(T),f=we(T,C,ae),Z=Ce(a,n),K=Se(),$=f.data??[],X=((H=$[0])==null?void 0:H.total_count)??0,G=Math.max(1,Math.ceil(Number(X)/ae)),t=m.data,ne=t!=null&&t.epoch?D(t.epoch.slice(0,10)):"-",p=K.data,R=s=>{g(()=>{h(j(s-1)),c(j(0))})},ie=async()=>{V(!0);try{await ke(),await Promise.all([m.refetch(),f.refetch(),Z.refetch(),K.refetch()]),S.success("Pricing data refreshed")}catch(s){S.error(`Refresh failed: ${s.message}`)}finally{V(!1)}},g=s=>{s(),k(0),M(null)},ce=async()=>{U(!0);try{const s=await Ae(T),u=["search_run_id","first_captured_at","contexts","pickup_location","pickup_date","dropoff_date","rental_days","campaign_code","categories_returned","available_categories","zero_result","events","offers","cheapest_total","median_total","avg_discount_percent"],v=r=>`"${String(r??"").replace(/"/g,'""')}"`,oe=s.map(r=>[r.search_run_id,r.first_captured_at,(r.contexts??[]).join("|"),r.pickup_location_name??r.pickup_location_id??"",r.pickup_date??"",r.dropoff_date??"",r.rental_days??"",r.campaign_code??"",r.categories_returned??"",r.available_categories??"",r.is_zero_result?"yes":"no",r.event_c
1ount??"",r.offer_count??"",r.cheapest_total??"",r.median_total??"",r.avg_discount_percent??""].map(v).join(",")),de=new Blob([[u.join(","),...oe].join(` 2`)],{type:"text/csv;charset=utf-8;"}),Y=URL.createObjectURL(de),E=document.createElement("a");E.href=Y,E.download=`search-pricing-log-${a}_${n}-${x}.csv`,E.click(),URL.revokeObjectURL(Y),S.success(`Exported ${s.length} searches`)}catch(s){S.error(`Export failed: ${s.message}`)}finally{U(!1)}};return e.jsxs("div",{className:"space-y-4",children:[e.jsx(P,{children:e.jsxs(z,{className:"py-3 flex flex-wrap items-center gap-2",children:[e.jsx(F,{value:b,onChange:s=>g(()=>w(s.target.value)),placeholder:"Filter location, code, date, run id",className:"h-9 w-[240px]"}),e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx(F,{type:"date","aria-label":"From date",value:a,min:t!=null&&t.epoch?t.epoch.slice(0,10):void 0,max:n||j(0),onChange:s=>g(()=>h(s.target.value)),className:"h-9 w-[150px]"}),e.jsx("span",{className:"text-xs text-muted-foreground",children:"to"}),e.jsx(F,{type:"date","aria-label":"To date",value:n,min:a||(t!=null&&t.epoch?t.epoch.slice(0,10):void 0),max:j(0),onChange:s=>g(()=>c(s.target.value)),className:"h-9 w-[150px]"})]}),e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(o,{variant:"ghost",size:"sm",onClick:()=>R(1),children:"Today"}),e.jsx(o,{variant:"ghost",size:"sm",onClick:()=>R(7),children:"Last 7 days"}),e.jsx(o,{variant:"ghost",size:"sm",onClick:()=>R(30),children:"Last 30 days"})]}),e.jsxs(he,{value:_,onValueChange:s=>g(()=>l(s)),children:[e.jsx(ue,{className:"h-9 w-[200px]",children:e.jsx(xe,{placeholder:"All locations"})}),e.jsxs(me,{children:[e.jsx(J,{value:"all",children:"All locations"}),(Z.data??[]).map(s=>e.jsx(J,{value:s,children:s},s))]})]}),e.jsxs(o,{variant:"outline",size:"sm",onClick:ce,disabled:Q,children:[e.jsx(pe,{className:"h-4 w-4 mr-1.5"}),Q?"Exporting...":"Export CSV"]}),e.jsxs(o,{variant:"outline",size:"sm",onClick:ie,disabled:A,children:[e.jsx(fe,{className:`h-4 w-4 mr-1.5 ${A?"animate-spin":""}`}),A?"Refreshing...":"Refresh now"]}),e.jsxs("div",{className:"ml-auto flex flex-col items-end gap-0.5",children:[e.jsxs("span",{className:"text-xs text-muted-foreground",children:["Pricing history starts ",ne,". Times shown in Sydney time."]}),p?e.jsxs("span",{className:`text-xs flex items-center gap-1 ${p.is_stale?"text-destructive":"text-muted-foreground"}`,children:[p.is_stale?e.jsx(ge,{className:"h-3.5 w-3.5"}):null,"Data current to ",p.processed_through?te(p.processed_through):"-",p.lag_minutes!==null?` (${p.lag_minutes} min behind)`:""]}):null]})]})}),e.jsx(je,{value:x,onValueChange:s=>g(()=>y(s)),children:e.jsx(Ne,{className:"flex-wrap h-auto",children:Re.map(s=>{var u;return e.jsxs(_e,{value:s.value,children:[s.label,t&&s.value!=="all"?e.jsx("span",{className:"ml-1.5 text-xs text-muted-foreground tabular-nums",children:(((u=t.context_counts)==null?void 0:u[s.value])??0).toLocaleString()}):null]},s.value)})})}),e.jsxs(P,{children:[e.jsx(W,{className:"pb-2",children:e.jsx(ee,{className:"text-base",children:"Search activity"})}),e.jsxs(z,{children:[m.error?e.jsxs(O,{variant:"destructive",children:[e.jsx(q,{children:"Could not load the summary"}),e.jsxs(B,{className:"flex items-center gap-3",children:[m.error.message,e.jsx(o,{size:"sm",variant:"outline",onClick:()=>m.refetch(),children:"Retry"})]})]}):m.isLoading||!t?e.jsx(I,{className:"h-24 w-full"}):e.jsxs("div",{className:"grid gap-3 grid-cols-2 md:grid-cols-4 lg:grid-cols-6",children:[e.jsx(N,{label:"Customer searches",value:t.runs.toLocaleString(),hint:"Each search counted once"}),e.jsx(N,{label:"Zero-result searches",value:t.zero_result_runs.toLocaleString(),hint:t.runs?L(t.zero_result_runs/t.runs*100):"-"}),e.jsx(N,{label:"Locations",value:String(t.locations)}),e.jsx(N,{label:"Price offers",value:t.offers.toLocaleString(),hint:`${t.categories} categories`}),e.jsx(N,{label:"Discounted offers",value:t.discounted_offers.toLocaleString(),hint:`Avg ${L(t.avg_discount_percent)}`}),e.jsx(N,{label:"Median daily rate",value:d(t.median_daily_rate),hint:"Available offers"})]}),t&&!m.isLoading?e.jsxs("p",{className:"text-xs text-muted-foreground mt-3",children:["Like-for-like observation: median total ",d(t.median_total_discounted)," with a discount code vs"," ",d(t.median_total_undiscounted)," without. Observational only - not a controlled test."]}):null]})]}),e.jsxs(P,{children:[e.jsxs(W,{className:"pb-2 flex flex-row items-center justify-between",children:[e.jsx(ee,{className:"text-base",children:"Search Pricing Log"}),e.jsxs("div",{className:"flex items-center gap-2 text-xs text-muted-foreground",children:[e.jsxs("span",{children:[Number(X).toLocaleStr
2ing()," searches - page ",C+1," of ",G]}),e.jsx(o,{size:"sm",variant:"outline",disabled:C===0,onClick:()=>k(s=>Math.max(0,s-1)),children:"Previous"}),e.jsx(o,{size:"sm",variant:"outline",disabled:C+1>=G,onClick:()=>k(s=>s+1),children:"Next"})]})]}),e.jsx(z,{children:f.error?e.jsxs(O,{variant:"destructive",children:[e.jsx(q,{children:"Could not load searches"}),e.jsxs(B,{className:"flex items-center gap-3",children:[f.error.message,e.jsx(o,{size:"sm",variant:"outline",onClick:()=>f.refetch(),children:"Retry"})]})]}):f.isLoading?e.jsx(I,{className:"h-64 w-full"}):$.length===0?e.jsx("div",{className:"text-sm text-muted-foreground py-6 text-center",children:"No searches match these filters."}):e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{className:"text-muted-foreground",children:e.jsxs("tr",{className:"border-b",children:[e.jsx("th",{className:"w-8"}),e.jsx("th",{className:"text-left py-2 pr-3",children:"Time"}),e.jsx("th",{className:"text-left py-2 pr-3",children:"Pickup location"}),e.jsx("th",{className:"text-left py-2 pr-3",children:"Dates"}),e.jsx("th",{className:"text-right py-2 pr-3",children:"Days"}),e.jsx("th",{className:"text-left py-2 pr-3",children:"Contexts"}),e.jsx("th",{className:"text-left py-2 pr-3",children:"Code"}),e.jsx("th",{className:"text-right py-2 pr-3",children:"Categories"}),e.jsx("th",{className:"text-right py-2 pr-3",children:"Cheapest"}),e.jsx("th",{className:"text-right py-2 pr-3",children:"Median"}),e.jsx("th",{className:"text-right py-2 pr-3",children:"Avg disc."}),e.jsx("th",{className:"text-right py-2",children:"Offers"})]})}),e.jsx("tbody",{children:$.map(s=>{const u=le===s.search_run_id;return e.jsxs(i.Fragment,{children:[e.jsxs("tr",{className:"border-b hover:bg-muted/40 cursor-pointer",onClick:()=>M(u?null:s.search_run_id),children:[e.jsx("td",{className:"py-2",children:u?e.jsx(be,{className:"h-4 w-4"}):e.jsx(ve,{className:"h-4 w-4"})}),e.jsx("td",{className:"py-2 pr-3 whitespace-nowrap",children:te(s.first_captured_at)}),e.jsx("td",{className:"py-2 pr-3",children:s.pickup_location_name||s.pickup_location_id||"Unknown"}),e.jsxs("td",{className:"py-2 pr-3 whitespace-nowrap",children:[D(s.pickup_date)," - ",D(s.dropoff_date)]}),e.jsx("td",{className:"py-2 pr-3 text-right tabular-nums",children:s.rental_days??"-"}),e.jsx("td",{className:"py-2 pr-3",children:e.jsx("div",{className:"flex flex-wrap gap-1",children:(s.contexts??[]).map(v=>e.jsx(se,{variant:"secondary",className:"text-[10px] font-normal",children:re[v]??v},v))})}),e.jsx("td",{className:"py-2 pr-3",children:s.campaign_code||"-"}),e.jsx("td",{className:"py-2 pr-3 text-right tabular-nums",children:s.is_zero_result?e.jsx(se,{variant:"outline",className:"text-[10px]",children:"Zero result"}):`${s.available_categories??0}/${s.categories_returned??0}`}),e.jsx("td",{className:"py-2 pr-3 text-right tabular-nums",children:d(s.cheapest_total)}),e.jsx("td",{className:"py-2 pr-3 text-right tabular-nums",children:d(s.median_total)}),e.jsx("td",{className:"py-2 pr-3 text-right tabular-nums",children:L(s.avg_discount_percent)}),e.jsx("td",{className:"py-2 text-right tabular-nums",children:Number(s.offer_count??0).toLocaleString()})]}),u?e.jsx("tr",{className:"border-b bg-muted/20",children:e.jsx("td",{colSpan:12,className:"p-3",children:e.jsx(Ee,{runId:s.search_run_id,context:x,locationName:s.pickup_location_name??null})})}):null]},s.search_run_id)})})]})})})]})]})}export{Oe 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.