1import{j as e,L as N,r as G}from"./react-vendor-BANyTWx6.js";import{I as O,C as u,g as h,h as j,i as g,B as f,E as Z,e as R,J as L,s as k}from"./index-DQog6sMx.js";import{S}from"./skeleton-X6B3vqlz.js";import{u as U}from"./useQuery-CR-2qB5r.js";import{i as ee,aF as se,U as te,g as ae,aG as ne,aH as ie,aj as re,T as V,W as H,aI as ce,b as le,X as de,Q as oe,aJ as me,y as xe,R as ue,G as he,P as pe}from"./icons-CaVAQkO4.js";import{B as v}from"./badge-XV4jC6rE.js";import{p as je,a as ge,P as fe}from"./PaymentPauseCard-D3inD61H.js";import{F as I,a as $}from"./funnel-Bd7_kBnM.js";import"./ui-radix-LeXTboTU.js";import"./input-BnBR0GbF.js";import"./label-w2ZTj9AX.js";function Ne(){const{getAuthHeaders:s,isAuthenticated:a}=O();return U({queryKey:["admin","dashboard-stats"],enabled:a,staleTime:60*1e3,queryFn:async()=>{const t=await fetch("https://pqjejzychhqpcytxzuoa.supabase.co/functions/v1/admin-dashboard-stats",{headers:{...s(),"Content-Type":"application/json"}});if(!t.ok)throw new Error("Failed to load dashboard stats");return t.json()}})}const ye=new Intl.NumberFormat("pl-PL",{style:"currency",currency:"PLN",maximumFractionDigits:0});function y(s){return ye.format(s||0)}function K(s,a){try{return new Intl.NumberFormat("en-GB",{style:"currency",currency:a||"PLN",maximumFractionDigits:0}).format(s||0)}catch{return`${Math.round(s)} ${a}`}}function D(s,a){return a?(s-a)/a*100:null}function P(s){return new Date(s).toLocaleDateString("en-GB",{day:"2-digit",month:"short"})}function ve(s){return new Date(s).toLocaleDateString("en-GB",{weekday:"short"})}function be({data:s}){const a=[{label:"Bookings today",value:s.bookings,icon:ee},{label:"Revenue today",value:y(s.revenuePln),icon:se},{label:"Guests tonight",value:s.guestsTonight,icon:te},{label:"Cities running tonight",value:s.toursTonight,icon:ae}];return e.jsx(u,{className:"bg-muted/40",children:e.jsx(h,{className:"grid grid-cols-2 gap-4 p-4 md:grid-cols-4",children:a.map(t=>{const i=t.icon;return e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"rounded-md bg-background p-2",children:e.jsx(i,{className:"h-4 w-4 text-muted-foreground"})}),e.jsxs("div",{children:[e.jsx("div",{className:"text-xl font-semibold leading-none",children:t.value}),e.jsx("div",{className:"text-xs text-muted-foreground",children:t.label})]})]},t.label)})})})}function we({change:s}){if(s===null||!isFinite(s))return e.jsx("p",{className:"text-xs text-muted-foreground",children:"no prior period"});const a=s>=0,t=a?ne:ie;return e.jsxs("p",{className:`flex items-center text-xs ${a?"text-primary":"text-destructive"}`,children:[e.jsx(t,{className:"mr-1 h-3 w-3"}),Math.abs(s).toFixed(0),"% vs previous 30d"]})}function ke({kpis:s}){const a=[{title:"Revenue (30d)",value:y(s.revenue30),change:D(s.revenue30,s.revenuePrev30),sub:`${s.guests30} guests booked`},{title:"Bookings (30d)",value:String(s.bookings30),change:D(s.bookings30,s.bookingsPrev30)},{title:"Avg order value",value:y(s.aov30),change:D(s.aov30,s.aovPrev30)},{title:"Promo discounts (30d)",value:`${(s.discountRate30*100).toFixed(1)}%`,sub:`${y(s.discount30)} given away`}];return e.jsx("div",{className:"grid gap-4 md:grid-cols-2 lg:grid-cols-4",children:a.map(t=>e.jsxs(u,{children:[e.jsx(j,{className:"pb-2",children:e.jsx(g,{className:"text-sm font-medium text-muted-foreground",children:t.title})}),e.jsxs(h,{className:"space-y-1",children:[e.jsx("div",{className:"text-2xl font-bold",children:t.value}),"change"in t&&t.change!==void 0?e.jsx(we,{change:t.change??null}):null,t.sub?e.jsx("p",{className:"text-xs text-muted-foreground",children:t.sub}):null]})]},t.title))})}function Ce({attention:s}){var t;const a=[];return s.ungradedApplications>0&&a.push({label:`${s.ungradedApplications} guide applications ungraded`,detail:"Candidates waiting on a first review",to:"/admin/applications"}),s.newVenueApplications>0&&a.push({label:`${s.newVenueApplications} new venue partners`,detail:"Leads go cold fast â reply this week",to:"/admin/venue-applications"}),s.destinationsNeedingSetup.length>0&&a.push({label:`${s.destinationsNeedingSetup.length} cities missing tracking/SEO setup`,detail:s.destinationsNeedingSetup.slice(0,3).map(i=>`${i.city}: ${i.missing.join(", ")}`).join(" · "),to:"/admin/destinations"}),s.exhaustedPromoCodes.length>0&&a.push({label:`${s.exhaustedPromoCodes.length} promo codes exhausted`,detail:s.exhaustedPromoCodes.map(i=>i.code).join(", "),to:"/admin/promo-codes"}),(t=s.staleReviewCities)!=null&&t.length&&a.push({label:`${s.staleReviewCities.length} cities with stale reviews`,detail:s.staleReviewCities.slice(0,3).map(i=>`${i.city}: ${i.daysSinceLastReview===null?"never fetched":`${i.daysSinceLastReview}d old`}${i.lastError?" · last run failed":""}`).join(" · "),to:"/admin/destinations"}),a.length===0?e.jsx(u,{children:e.jsxs(h,{className:"flex items-center gap-3 p-4 text-sm text-muted-foreground",children:[e.jsx(re,{className:"h-4 w-4 text-primary"}),"Nothing needs attention right now."]})}):e.jsx("div",{className:"grid gap-3 md:grid-cols-2 lg:grid-cols-3",children:a.map(i=>e.jsx(u,{className:"border-destructive/40",children:e.jsxs(h,{className:"space-y-2 p-4",children:[e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx(V,{className:"mt-0.5 h-4 w-4 shrink-0 text-destructive"}),e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-medium",children:i.label}),e.jsx("p",{className:"text-xs text-muted-foreground",children:i.detail})]})]}),e.jsx(f,{asChild:!0,size:"sm",variant:"outline",className:"w-full",children:e.jsx(N,{to:i.to,children:"Open"})})]})},i.label))})}function Se({trend:s}){const a=Math.max(1,...s.map(t=>t.revenue));return e.jsx("div",{className:"flex h-16 items-end gap-[2px]",children:s.map(t=>e.jsx("div",{title:`${P(t.date)} · ${y(t.revenue)} · ${t.bookings} bookings`,className:"flex-1 rounded-sm bg-primary/70",style:{height:`${Math.max(2,t.revenue/a*100)}%`}},t.date))})}function $e({byCity:s,trend:a}){const t=s.reduce((i,c)=>i+c.revenue,0)||1;return e.jsxs(u,{children:[e.jsx(j,{children:e.jsx(g,{className:"text-base",children:"Performance by city (30 days)"})}),e.jsxs(h,{className:"space-y-5",children:[e.jsx(Se,{trend:a}),s.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"No bookings in the last 30 days."}):e.jsx("div",{className:"space-y-3",children:s.map(i=>{const c=i.revenue/t*100;return e.jsxs("div",{className:"space-y-1",children:[e.jsxs("div",{className:"flex items-baseline justify-between text-sm",children:[e.jsx("span",{className:"font-medium",children:i.city}),e.jsxs("span",{className:"text-muted-foreground",children:[y(i.revenue)," · ",i.bookings," bookings · ",i.guests," guests"]})]}),e.jsx("div",{className:"h-2 w-full rounded-full bg-muted",children:e.jsx("div",{className:"h-2 rounded-full bg-primary",style:{width:`${c}%`}})}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:[c.toFixed(0),"% of network revenue"]})]},i.slug||i.city)})})]})]})}function Pe({live:s,upcoming:a}){return e.jsxs("div",{className:"space-y-4",children:[e.jsxs(u,{children:[e.jsx(j,{children:e.jsx(g,{className:"text-base",children:"Next 7 days"})}),e.jsx(h,{children:a.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"No upcoming bookings in the next week."}):e.jsx("div",{className:"space-y-2",children:a.map(t=>e.jsxs("div",{className:"flex items-center justify-between text-sm",children:[e.jsxs("span",{className:"text-muted-foreground",children:[ve(t.date)," ",P(t.date)]}),e.jsx("span",{className:"truncate px-2 text-xs text-muted-foreground",children:Object.entries(t.cities).map(([i,c])=>`${i} ${c}`).join(" · ")}),e.jsxs("span",{className:"font-medium",children:[t.guests," guests"]})]},t.date))})})]}),e.jsxs(u,{children:[e.jsx(j,{children:e.jsx(g,{className:"text-base",children:"Live right now"})}),e.jsxs(h,{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx("p",{className:"mb-1 text-xs uppercase text-muted-foreground",children:"Campaign"}),s.campaign?e.jsxs("div",{className:"flex items-center justify-between text-sm",children:[e.jsx("span",{className:"font-medium",children:s.campaign.title}),e.jsxs(v,{variant:"secondary",children:["-",s.campaign.discount_percent,"%"]})]}):e.jsx("p",{className:"text-sm text-muted-foreground",children:"No campaign running."})]}),e.jsxs("div",{children:[e.jsx("p",{className:"mb-1 text-xs uppercase text-muted-foreground",children:"Smart offers enabled"}),s.offers.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"None enabled."}):e.jsx("div",{className:"flex flex-wrap gap-2",children:s.offers.map(t=>e.jsxs(v,{variant:"outline",children:[t.label," -",t.discount,"%",t.cities.length?` · ${t.cities.join(", ")}`:" · all cities"]},t.slug))})]}),e.jsxs("div",{children:[e.jsx("p",{className:"mb-1 text-xs uppercase text-muted-foreground",children:"Top promo codes (30d)"}),s.topPromos.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"No promo code used in the last 30 days."}):e.jsx("div",{className:"space-y-1",children:s.topPromos.map(t=>e.jsxs("div",{className:"flex justify-between text-sm",children:[e.jsx("span",{className:"font-mono",children:t.code}),e.jsxs("span",{className:"text-muted-foreground",children:[t.uses," uses · ",y(t.revenue)]})]},t.code))})]})]})]})]})}function _e({bookings:s}){return e.jsxs(u,{children:[e.jsxs(j,{className:"flex flex-row items-center justify-between space-y-0",children:[e.jsx(g,{className:"text-base",children:"Recent bookings"}),e.jsx(f,{asChild:!0,variant:"link",size:"sm",children:e.jsx(N,{to:"/admin/bookings",children:"View all"})})]}),e.jsx(h,{children:s.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"No bookings yet."}):e.jsx("div",{className:"space-y-3",children:s.map(a=>e.jsxs("div",{className:"flex items-start justify-between gap-3 border-b pb-3 last:border-0 last:pb-0",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("p",{className:"truncate text-sm font-medium",children:a.name||"Unknown"}),e.jsxs("p",{className:"truncate text-xs text-muted-foreground",children:[a.city," · ",a.bookingDate?P(a.bookingDate):"â",a.groupSize?` · ${a.groupSize} pax`:"",a.promoCode?` · ${a.promoCode}`:""]})]}),e.jsxs("div",{className:"shrink-0 text-right",children:[e.jsx("p",{className:"text-sm font-medium",children:K(a.amount,a.currency)}),e.jsx(v,{variant:a.status==="pending"?"outline":"secondary",className:"mt-1 text-[10px]",children:a.status})]})]},a.id))})})]})}function Be({recruitment:s}){const a=Object.entries(s.pipeline).sort((t,i)=>i[1]-t[1]);return e.jsxs(u,{children:[e.jsxs(j,{className:"flex flex-row items-center justify-between space-y-0",children:[e.jsx(g,{className:"text-base",children:"Guides & venue partners"}),e.jsx(f,{asChild:!0,variant:"link",size:"sm",children:e.jsx(N,{to:"/admin/applications",children:"Applications"})})]}),e.jsxs(h,{className:"space-y-4",children:[e.jsx("div",{className:"flex flex-wrap gap-2",children:a.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"No applications yet."}):a.map(([t,i])=>e.jsxs(v,{variant:"secondary",children:[t,": ",i]},t))}),e.jsxs("div",{children:[e.jsx("p",{className:"mb-1 text-xs uppercase text-muted-foreground",children:"Top fresh candidates"}),s.topCandidates.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"Nothing scored above 70 yet."}):e.jsx("div",{className:"space-y-1",children:s.topCandidates.map(t=>e.jsxs("div",{className:"flex items-center justify-between text-sm",children:[e.jsxs("span",{className:"truncate",children:[t.name," ",e.jsxs("span",{className:"text-muted-foreground",children:["· ",t.city]})]}),e.jsx("span",{className:"font-medium",children:t.score})]},t.id))})]}),e.jsxs("div",{children:[e.jsx("p",{className:"mb-1 text-xs uppercase text-muted-foreground",children:"Latest venue applications"}),s.recentVenues.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"No venue applications."}):e.jsx("div",{className:"space-y-1",children:s.recentVenues.map(t=>e.jsxs("div",{className:"flex items-center justify-between text-sm",children:[e.jsxs("span",{className:"truncate",children:[t.name," ",e.jsxs("span",{className:"text-muted-foreground",children:["· ",t.city]})]}),e.jsx(v,{variant:"outline",className:"text-[10px]",children:t.status||"new"})]},t.id))})]})]})]})}function C({ok:s}){return s?e.jsx(le,{className:"h-4 w-4 text-primary"}):e.jsx(de,{className:"h-4 w-4 text-destructive"})}function Ae({rows:s,searchHealth:a}){const[t,i]=G.useState(null),c=Z(),x=async n=>{var m;i(n.slug);const d=[];try{if(!n.ga4Configured||!n.ga4SecretSet)try{const o=await je(n.slug),p=(m=o==null?void 0:o.results)==null?void 0:m[0];p!=null&&p.error&&d.push(`GA4: ${p.error}`)}catch(o){d.push(`GA4: ${o.message}`)}if(!n.gscVerified&&n.domain){R.info("Search Console verification started â DNS can take a minute.");try{const o=await ge(n.domain);o!=null&&o.ok||d.push("Search Console: verification did not complete yet")}catch(o){d.push(`Search Console: ${o.message}`)}}d.length?R.error(d.join(" · ")):R.success(`${n.city} tracking set up`),c.invalidateQueries({queryKey:["admin","dashboard-stats"]})}finally{i(null)}};return e.jsxs(u,{children:[e.jsx(j,{children:e.jsx(g,{className:"text-base",children:"Content & SEO health"})}),e.jsx(h,{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b text-left text-xs uppercase text-muted-foreground",children:[e.jsx("th",{className:"py-2 pr-4",children:"City"}),e.jsx("th",{className:"py-2 pr-4",children:"Posts (30d)"}),e.jsx("th",{className:"py-2 pr-4",children:"Posts total"}),e.jsx("th",{className:"py-2 pr-4",children:"Occasion pages"}),e.jsx("th",{className:"py-2 pr-4",children:"GA4"}),e.jsx("th",{className:"py-2 pr-4",children:"GA4 secret"}),e.jsx("th",{className:"py-2 pr-4",children:"Search Console"}),e.jsx("th",{className:"py-2 pr-4",children:"Search health"}),e.jsx("th",{className:"py-2"})]})}),e.jsx("tbody",{children:s.map(n=>{const d=!n.ga4Configured||!n.ga4SecretSet||!n.gscVerified;return e.jsxs("tr",{className:"border-b last:border-0",children:[e.jsx("td",{className:"py-2 pr-4 font-medium",children:e.jsx(N,{className:"hover:underline",to:`/admin/destination/${encodeURIComponent(n.slug)}`,children:n.city})}),e.jsx("td",{className:"py-2 pr-4",children:n.postsLast30}),e.jsx("td",{className:"py-2 pr-4",children:n.publishedPosts}),e.jsx("td",{className:"py-2 pr-4",children:n.occasionPages}),e.jsx("td",{className:"py-2 pr-4",children:e.jsx(C,{ok:n.ga4Configured})}),e.jsx("td",{className:"py-2 pr-4",children:e.jsx(C,{ok:n.ga4SecretSet})}),e.jsx("td",{className:"py-2 pr-4",children:e.jsx(C,{ok:n.gscVerified})}),e.jsx("td",{className:"py-2 pr-4",children:(()=>{const m=a==null?void 0:a.find(o=>o.slug===n.slug);return m?e.jsx("span",{title:m.ok?"All checks passed":m.issues.join(` 2`),children:e.jsx(C,{ok:m.ok})}):e.jsx("span",{className:"text-xs text-muted-foreground",children:"â"})})()}),e.jsx("td",{className:"py-2 text-right",children:d&&e.jsxs(f,{size:"sm",variant:"outline",disabled:t===n.slug,onClick:()=>x(n),children:[t===n.slug?e.jsx(H,{className:"h-3.5 w-3.5 animate-spin"}):e.jsx(ce,{className:"h-3.5 w-3.5"}),e.jsx("span",{className:"ml-1.5",children:"Set up"})]})})]},n.slug)})})]})})]})}function Re({abandoned:s,onRefresh:a}){const{getAuthHeaders:t}=O(),[i,c]=G.useState(null),x=async n=>{var d,m;c(n);try{const o=await fetch("https://pqjejzychhqpcytxzuoa.supabase.co/functions/v1/recover-abandoned-checkouts",{method:"POST",headers:{...t(),"Content-Type":"application/json"},body:JSON.stringify({bookingId:n,force:!0})}),p=await o.json();if(!o.ok)throw new Error((p==null?void 0:p.error)||"Failed to send reminder");p.sent>0?L({title:"Reminder sent",description:"The customer got a link to finish their booking."}):L({title:"Nothing sent",description:((m=(d=p.skipped)==null?void 0:d[0])==null?void 0:m.reason)||"This checkout is no longer recoverable.",variant:"destructive"}),a()}catch(o){L({title:"Could not send reminder",description:o instanceof Error?o.message:"Unknown error",variant:"destructive"})}finally{c(null)}};return e.jsxs(u,{children:[e.jsx(j,{className:"flex flex-row items-center justify-between space-y-0",children:e.jsxs("div",{children:[e.jsxs(g,{className:"flex items-center gap-2 te
2xt-base",children:[e.jsx(oe,{className:"h-4 w-4"}),"Abandoned checkouts"]}),e.jsxs("p",{className:"mt-1 text-xs text-muted-foreground",children:["Started a booking, never paid · ",s.pending30," in the last 30 days ·"," ",s.valuePln.toLocaleString()," zÅ recoverable"]})]})}),e.jsx(h,{children:s.recoverable.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"No recoverable checkouts. Reminders go out automatically 2 hours after a drop-off."}):e.jsx("div",{className:"space-y-3",children:s.recoverable.map(n=>e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3 border-b pb-3 last:border-0 last:pb-0",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("p",{className:"truncate text-sm font-medium",children:n.name||n.email||"Unknown"}),e.jsxs("p",{className:"truncate text-xs text-muted-foreground",children:[n.city," · ",P(n.bookingDate),n.groupSize?` · ${n.groupSize} pax`:""," · ",K(n.amount,n.currency)]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[n.reminderSentAt?e.jsxs(v,{variant:"secondary",className:"gap-1 text-[10px]",children:[e.jsx(me,{className:"h-3 w-3"}),"Reminded"]}):null,e.jsxs(f,{size:"sm",variant:"outline",disabled:i===n.id||!n.email,onClick:()=>x(n.id),children:[i===n.id?e.jsx(H,{className:"mr-2 h-3.5 w-3.5 animate-spin"}):e.jsx(xe,{className:"mr-2 h-3.5 w-3.5"}),n.reminderSentAt?"Send again":"Send reminder"]})]})]},n.id))})})]})}const Le={bookings_drop:"Bookings drop",conversion_drop:"Conversion drop",payment_failures:"Payment failures",search_health:"Search health",no_upcoming_dates:"No dates",silent_city:"Silent city"};function De({alerts:s}){return s.length?e.jsxs(u,{className:"border-destructive/40",children:[e.jsx(j,{children:e.jsxs(g,{className:"flex items-center gap-2 text-base",children:[e.jsx(V,{className:"h-4 w-4 text-destructive"}),"Network alerts"]})}),e.jsx(h,{children:e.jsx("ul",{className:"space-y-2",children:s.map(a=>e.jsxs("li",{className:"flex items-baseline justify-between gap-3 text-sm",children:[e.jsxs("span",{children:[e.jsx("span",{className:"mr-2 inline-block rounded bg-destructive/15 px-1.5 py-0.5 text-xs font-medium text-destructive",children:Le[a.alert_type]||a.alert_type}),a.message]}),e.jsx(N,{to:`/admin/destination/${encodeURIComponent(a.slug)}`,className:"shrink-0 text-xs text-muted-foreground hover:underline",children:new Date(a.last_sent_at).toLocaleDateString()})]},`${a.alert_type}:${a.slug}`))})})]}):null}function Fe({rows:s}){return e.jsxs(u,{children:[e.jsx(j,{children:e.jsx(g,{className:"text-base",children:"Checkout conversion by city (30 days)"})}),e.jsx(h,{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b text-left text-xs uppercase text-muted-foreground",children:[e.jsx("th",{className:"py-2 pr-4",children:"City"}),e.jsx("th",{className:"py-2 pr-4 text-right",children:"Checkout views"}),e.jsx("th",{className:"py-2 pr-4 text-right",children:"Purchases"}),e.jsx("th",{className:"py-2 text-right",children:"Conversion"})]})}),e.jsxs("tbody",{children:[s.map(a=>e.jsxs("tr",{className:"border-b last:border-0",children:[e.jsx("td",{className:"py-2 pr-4 font-medium",children:e.jsx(N,{className:"hover:underline",to:`/admin/destination/${encodeURIComponent(a.slug)}`,children:a.city})}),e.jsx("td",{className:"py-2 pr-4 text-right",children:a.views}),e.jsx("td",{className:"py-2 pr-4 text-right",children:a.purchases}),e.jsx("td",{className:"py-2 text-right font-medium",children:a.rate===null?"â":`${(a.rate*100).toFixed(1)}%`})]},a.slug)),!s.length&&e.jsx("tr",{children:e.jsx("td",{colSpan:4,className:"py-4 text-center text-muted-foreground",children:"No checkout data yet."})})]})]})})]})}function Te(){return U({queryKey:["admin-funnel-30d"],queryFn:async()=>{var q,z,E;const s=new Date(Date.now()-2592e6).toISOString(),a=new Date(Date.now()-7*864e5).toISOString(),[{data:t},{data:i},{count:c},{count:x}]=await Promise.all([k.from("funnel_events").select("session_id, destination_slug, step, meta, created_at").gte("created_at",s).limit(5e4),k.from("offer_decisions").select("decision, reason, discount_percent").gte("created_at",s).limit(5e4),k.from("bookings").select("id",{count:"exact",head:!0}).gte("created_at",s).eq("status","confirmed"),k.from("bookings").select("id",{count:"exact",head:!0}).gte("created_at",a).eq("status","confirmed")]),n=new Map;for(const r of t||[]){let l=n.get(r.session_id);l||(l={steps:new Set,city:r.destination_slug||"unknown"},n.set(r.session_id,l)),l.steps.add(r.step),r.destination_slug&&(l.city=r.destination_slug)}const d=[];let m=0,o=0;for(const r of n.values())r.steps.has("view_book")?d.push(r):(r.steps.has("payment_started")||r.steps.has("purchase"))&&(m+=1,r.steps.has("purchase")&&(o+=1));const p=r=>$.map((l,w)=>r.filter(X=>$.slice(w).some(Y=>X.steps.has(Y))).length),Q=p(d),b=new Map;for(const r of d)b.has(r.city)||b.set(r.city,[]),b.get(r.city).push(r);const _=new Map,F=new Set;let T=0,M=0;for(const r of t||[]){if(r.step!=="purchase")continue;const l=((q=r.meta)==null?void 0:q.payment_intent)||((z=r.meta)==null?void 0:z.payment_ref)||`${r.session_id}:${r.created_at}`;if(F.has(l))continue;F.add(l),T+=1,r.created_at>=a&&(M+=1);const w=((E=r.meta)==null?void 0:E.payment_method)||"unknown";_.set(w,(_.get(w)||0)+1)}const B=i||[],J=B.filter(r=>r.decision==="shown").length,W=B.filter(r=>r.decision==="suppressed").length,A=new Map;for(const r of B.filter(l=>l.decision==="suppressed")){const l=r.reason||"unknown";A.set(l,(A.get(l)||0)+1)}return{methodMix:Array.from(_.entries()).sort((r,l)=>l[1]-r[1]),overall:$.map((r,l)=>({step:r,sessions:Q[l]})),quickBuy:{started:m,paid:o},reconciliation:{trackedPurchases:T,confirmedBookings:c||0,trackedPurchases7:M,confirmedBookings7:x||0},byCity:Array.from(b.entries()).map(([r,l])=>({city:r,steps:p(l)})).sort((r,l)=>l.steps[0]-r.steps[0]).slice(0,8),offers:{shown:J,suppressed:W,topReasons:Array.from(A.entries()).sort((r,l)=>l[1]-r[1]).slice(0,4)}}},staleTime:5*60*1e3})}function Me(){var i;const{data:s,isLoading:a}=Te();if(a||!s)return e.jsx(S,{className:"h-72 w-full"});const t=((i=s.overall[0])==null?void 0:i.sessions)||0;return e.jsxs("div",{className:"grid gap-4 lg:grid-cols-3",children:[e.jsxs(u,{className:"lg:col-span-2",children:[e.jsx(j,{children:e.jsx(g,{className:"text-base",children:"Booking funnel · last 30 days"})}),e.jsx(h,{className:"space-y-4",children:t===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"No funnel events yet â data starts collecting from the next visitor."}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"space-y-2",children:s.overall.map((c,x)=>{const n=t?Math.round(c.sessions/t*100):0,d=x>0?s.overall[x-1].sessions:c.sessions,m=d?Math.round((d-c.sessions)/d*100):0;return e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"w-36 text-xs text-muted-foreground shrink-0",children:I[c.step]}),e.jsx("div",{className:"flex-1 h-6 rounded bg-muted overflow-hidden",children:e.jsx("div",{className:"h-full bg-primary/70",style:{width:`${n}%`}})}),e.jsxs("div",{className:"w-28 text-right text-xs tabular-nums",children:[c.sessions," · ",n,"%",x>0&&m>0&&e.jsxs("span",{className:"text-destructive",children:[" â",m,"%"]})]})]},c.step)})}),e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-xs",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"text-muted-foreground text-left",children:[e.jsx("th",{className:"py-1 pr-2",children:"City"}),$.map(c=>e.jsx("th",{className:"py-1 px-1 text-right",children:I[c]},c)),e.jsx("th",{className:"py-1 pl-2 text-right",children:"Conv."})]})}),e.jsx("tbody",{children:s.byCity.map(c=>{const x=c.steps[0]?Math.round(c.steps[c.steps.length-1]/c.steps[0]*1e3)/10:0;return e.jsxs("tr",{className:"border-t border-border/60",children:[e.jsx("td",{className:"py-1 pr-2 font-medium capitalize",children:c.city}),c.steps.map((n,d)=>e.jsx("td",{className:"py-1 px-1 text-right tabular-nums",children:n},d)),e.jsxs("td",{className:"py-1 pl-2 text-right tabular-nums font-semibold",children:[x,"%"]})]},c.city)})})]})}),e.jsxs("div",{className:"grid gap-2 sm:grid-cols-2 pt-2 border-t border-border/60 text-xs",children:[e.jsxs("div",{children:[e.jsx("div",{className:"uppercase tracking-wider text-muted-foreground mb-1",children:"Homepage one-tap (not in funnel above)"}),e.jsxs("p",{className:"tabular-nums",children:[s.quickBuy.started," started · ",s.quickBuy.paid," paid"]}),e.jsx("p",{className:"text-muted-foreground",children:"These guests never open /book or /checkout."})]}),e.jsxs("div",{children:[e.jsx("div",{className:"uppercase tracking-wider text-muted-foreground mb-1",children:"Tracking coverage"}),e.jsxs("p",{className:"tabular-nums",children:["Last 7 days:"," ",s.reconciliation.confirmedBookings7?`${Math.round(s.reconciliation.trackedPurchases7/s.reconciliation.confirmedBookings7*100)}%`:"n/a"," ","(",s.reconciliation.trackedPurchases7," tracked ·"," ",s.reconciliation.confirmedBookings7," confirmed)"]}),e.jsxs("p",{className:"tabular-nums",children:["Last 30 days:"," ",s.reconciliation.confirmedBookings?`${Math.round(s.reconciliation.trackedPurchases/s.reconciliation.confirmedBookings*100)}%`:"n/a"," ","(",s.reconciliation.trackedPurchases," tracked ·"," ",s.reconciliation.confirmedBookings," confirmed)"]}),e.jsx("p",{className:"text-muted-foreground",children:"The 7-day number reflects current health. The 30-day one can look lower because older bookings were made before tracking was added."})]})]})]})})]}),e.jsxs(u,{children:[e.jsx(j,{children:e.jsx(g,{className:"text-base",children:"Discount targeting · 30 days"})}),e.jsxs(h,{className:"space-y-3 text-sm",children:[e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-muted-foreground",children:"Offers shown"}),e.jsx("span",{className:"font-semibold tabular-nums",children:s.offers.shown})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-muted-foreground",children:"Suppressed (leakage avoided)"}),e.jsx("span",{className:"font-semibold tabular-nums text-success",children:s.offers.suppressed})]}),e.jsxs("div",{className:"pt-2 border-t border-border/60",children:[e.jsx("div",{className:"text-xs uppercase tracking-wider text-muted-foreground mb-2",children:"Paid with"}),s.methodMix.length===0?e.jsx("p",{className:"text-xs text-muted-foreground",children:"No purchases tracked yet."}):e.jsx("ul",{className:"space-y-1 mb-3",children:s.methodMix.map(([c,x])=>{const n=s.methodMix.reduce((d,[,m])=>d+m,0);return e.jsxs("li",{className:"flex justify-between text-xs",children:[e.jsx("span",{className:"capitalize",children:c.replace(/_/g," ")}),e.jsxs("span",{className:"tabular-nums",children:[x," · ",Math.round(x/n*100),"%"]})]},c)})})]}),e.jsxs("div",{className:"pt-2 border-t border-border/60",children:[e.jsx("div",{className:"text-xs uppercase tracking-wider text-muted-foreground mb-2",children:"Why suppressed"}),s.offers.topReasons.length===0?e.jsx("p",{className:"text-xs text-muted-foreground",children:"No decisions logged yet."}):e.jsx("ul",{className:"space-y-1",children:s.offers.topReasons.map(([c,x])=>e.jsxs("li",{className:"flex justify-between text-xs",children:[e.jsx("span",{className:"capitalize",children:c.replace(/_/g," ")}),e.jsx("span",{className:"tabular-nums",children:x})]},c))})]})]})]})]})}function Je(){const{data:s,isLoading:a,isFetching:t,error:i,refetch:c}=Ne();return e.jsxs("div",{className:"space-y-8",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-3xl font-bold",children:"Dashboard"}),e.jsxs("p",{className:"text-muted-foreground",children:["Sales, demand and growth across the pub crawl network",s?` · ${s.destinations.active} active cities in ${s.destinations.countries} countries`:""]})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs(f,{variant:"outline",onClick:()=>c(),disabled:t,children:[e.jsx(ue,{className:`mr-2 h-4 w-4 ${t?"animate-spin":""}`}),"Refresh"]}),e.jsx(f,{asChild:!0,variant:"outline",children:e.jsxs(N,{to:"/admin/destinations",children:[e.jsx(he,{className:"mr-2 h-4 w-4"}),"Destinations"]})}),e.jsx(f,{asChild:!0,children:e.jsxs(N,{to:"/admin/new",children:[e.jsx(pe,{className:"mr-2 h-4 w-4"}
2),"New Destination"]})})]})]}),i?e.jsx(u,{className:"border-destructive/40",children:e.jsx(h,{className:"p-4 text-sm text-destructive",children:"Could not load dashboard data. Try refreshing."})}):null,a||!s?e.jsxs("div",{className:"space-y-4",children:[e.jsx(S,{className:"h-24 w-full"}),e.jsx("div",{className:"grid gap-4 md:grid-cols-2 lg:grid-cols-4",children:Array.from({length:4}).map((x,n)=>e.jsx(S,{className:"h-28 w-full"},n))}),e.jsx(S,{className:"h-72 w-full"})]}):e.jsxs(e.Fragment,{children:[e.jsx(be,{data:s.today}),e.jsx(ke,{kpis:s.kpis}),e.jsx(De,{alerts:s.alerts||[]}),e.jsx(Ce,{attention:s.attention}),e.jsxs("div",{className:"grid gap-4 lg:grid-cols-3",children:[e.jsx("div",{className:"lg:col-span-2",children:e.jsx($e,{byCity:s.byCity,trend:s.trend})}),e.jsx(Pe,{live:s.live,upcoming:s.upcoming})]}),e.jsx(Re,{abandoned:s.abandoned,onRefresh:()=>c()}),e.jsx(Me,{}),e.jsxs("div",{className:"grid gap-4 lg:grid-cols-2",children:[e.jsx(_e,{bookings:s.recentBookings}),e.jsx(Be,{recruitment:s.recruitment})]}),e.jsx(Fe,{rows:s.conversionByCity||[]}),e.jsx(Ae,{rows:s.contentHealth,searchHealth:s.searchHealth}),e.jsx(fe,{label:"all cities"})]})]})}export{Je 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.