PageSourceSearch

https://localmusicx.com/assets/city-scraping-BsOmVkZv.js

js localmusicx.com collected 2026-10-08 02:55:35 UTC 144,533 bytes, 17 lines download raw bytes

1import{c as Ks,bB as E,bC as Us,r as P,u as en,a as ie,b as J,j as e,C as w,d as z,e as K,J as N,N as Ae,O as Ce,Q as Ee,R as Oe,U as D,_ as Ue,B as U,D as _n,h as qn,i as zn,k as Kn,l as Un,o as ce,p as G,q as ee,t as Vn,bz as Wn,ar as Xe,bD as Gn,b1 as Ta,L as Xt,G as Ts,X as xt,ah as ue,z as Ra,a4 as lt,al as Da,f as Fe,W as ne,bh as Qn,v as Et,w as Ot,x as Tt,y as Rt,aP as $e,aR as Dt,m as Fa,as as Yn,a7 as $a,a8 as La,a9 as Ma,aa as Ia,ab as Ba,ac as _a,ad as qa,ae as za}from"./index-D1gByzCh.js";import{T as Te,a as Re,b as V,c as h,d as De,e as m}from"./table-DDGQtUFl.js";import{S as ht}from"./switch-CfG_8TQO.js";import{T as Zn,a as Xn,b as pt,c as ft}from"./tabs-RFP_tOmf.js";import{P as Rs}from"./progress-B97lDB1B.js";import{a as Jn}from"./addMonths-CoI6CM7N.js";import{A as Hn}from"./arrow-left-C06HTsOD.js";import{C as Ds}from"./calendar-clock-B3IHcDXr.js";import{Z as Jt}from"./zap-CzNUftXR.js";import{T as Fs}from"./trending-up-TRxPjcqu.js";import{A as Ka}from"./activity-C3KLebo8.js";import{U as Ua}from"./users-Cqa6Vjju.js";import{C as Ht}from"./circle-x-65DSAk1J.js";import{f as We,L as Ie,m as es,i as jt,b as ss,A as tn,c as Me,d as He,e as ei,g as Is,h as ti,j as sn,G as an,k as yt,l as as,n as ns,D as si,u as nn,S as Va,o as ai,p as rn,q as Bs,r as ni,E as ii,s as ri,t as li,a as Ve,X as gt,Y as bt,v as di,R as Ft,C as $t,T as Lt,w as ci,B as ts}from"./BarChart-Dn_ygJTp.js";import{L as oi}from"./Line-BRHB_fGd.js";import{T as $s}from"./triangle-alert-fWVsp2EP.js";import{f as Le}from"./formatDistanceToNow-DLoy0U0K.js";import"./formatDistance-BvwPo72M.js";import"./differenceInCalendarMonths-CEKWlNrV.js";/**
2 * @license lucide-react v0.453.0 - ISC
3 *
4 * This source code is licensed under the ISC license.
5 * See the LICENSE file in the root directory of this source tree.
6 */const mi=Ks("MailCheck",[["path",{d:"M22 13V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v12c0 1.1.9 2 2 2h8",key:"12jkf8"}],["path",{d:"m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7",key:"1ocrg3"}],["path",{d:"m16 19 2 2 4-4",key:"1b14m6"}]]);/**
7 * @license lucide-react v0.453.0 - ISC
8 *
9 * This source code is licensed under the ISC license.
10 * See the LICENSE file in the root directory of this source tree.
11 */const Wa=Ks("MailX",[["path",{d:"M22 13V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v12c0 1.1.9 2 2 2h9",key:"1j9vog"}],["path",{d:"m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7",key:"1ocrg3"}],["path",{d:"m17 17 4 4",key:"1b3523"}],["path",{d:"m21 17-4 4",key:"uinynz"}]]);/**
12 * @license lucide-react v0.453.0 - ISC
13 *
14 * This source code is licensed under the ISC license.
15 * See the LICENSE file in the root directory of this source tree.
16 */const Ls=Ks("ShieldX",[["path",{d:"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",key:"oel41y"}],["path",{d:"m14.5 9.5-5 5",key:"17q4r4"}],["path",{d:"m9.5 9.5 5 5",key:"18nt4w"}]]);function ui(s,a){return Jn(s,-a)}var xi=["layout","type","stroke","connectNulls","isRange","ref"],hi=["key"],ln;function vt(s){"@babel/helpers - typeof";return vt=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(a){return typeof a}:function(a){return a&&typeof Symbol=="function"&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},vt(s)}function dn(s,a){if(s==null)return{};var i=pi(s,a),n,l;if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(s);for(l=0;l<c.length;l++)n=c[l],!(a.indexOf(n)>=0)&&Object.prototype.propertyIsEnumerable.call(s,n)&&(i[n]=s[n])}return i}function pi(s,a){if(s==null)return{};var i={};for(var n in s)if(Object.prototype.hasOwnProperty.call(s,n)){if(a.indexOf(n)>=0)continue;i[n]=s[n]}return i}function dt(){return dt=Object.assign?Object.assign.bind():function(s){for(var a=1;a<arguments.length;a++){var i=arguments[a];for(var n in i)Object.prototype.hasOwnProperty.call(i,n)&&(s[n]=i[n])}return s},dt.apply(this,arguments)}function Ga(s,a){var i=Object.keys(s);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(s);a&&(n=n.filter(function(l){return Object.getOwnPropertyDescriptor(s,l).enumerable})),i.push.apply(i,n)}return i}function Je(s){for(var a=1;a<arguments.length;a++){var i=arguments[a]!=null?arguments[a]:{};
vendor: 21,157 bytes, line 16
16a%2?Ga(Object(i),!0).forEach(function(n){Be(s,n,i[n])}):Object.getOwnPropertyDescriptors?Object.defineProperties(s,Object.getOwnPropertyDescriptors(i)):Ga(Object(i)).forEach(function(n){Object.defineProperty(s,n,Object.getOwnPropertyDescriptor(i,n))})}return s}function fi(s,a){if(!(s instanceof a))throw new TypeError("Cannot call a class as a function")}function Qa(s,a){for(var i=0;i<a.length;i++){var n=a[i];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(s,on(n.key),n)}}function ji(s,a,i){return a&&Qa(s.prototype,a),i&&Qa(s,i),Object.defineProperty(s,"prototype",{writable:!1}),s}function gi(s,a,i){return a=is(a),bi(s,cn()?Reflect.construct(a,i||[],is(s).constructor):a.apply(s,i))}function bi(s,a){if(a&&(vt(a)==="object"||typeof a=="function"))return a;if(a!==void 0)throw new TypeError("Derived constructors may only return object or undefined");return yi(s)}function yi(s){if(s===void 0)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return s}function cn(){try{var s=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch{}return(cn=function(){return!!s})()}function is(s){return is=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(i){return i.__proto__||Object.getPrototypeOf(i)},is(s)}function vi(s,a){if(typeof a!="function"&&a!==null)throw new TypeError("Super expression must either be null or a function");s.prototype=Object.create(a&&a.prototype,{constructor:{value:s,writable:!0,configurable:!0}}),Object.defineProperty(s,"prototype",{writable:!1}),a&&_s(s,a)}function _s(s,a){return _s=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(n,l){return n.__proto__=l,n},_s(s,a)}function Be(s,a,i){return a=on(a),a in s?Object.defineProperty(s,a,{value:i,enumerable:!0,configurable:!0,writable:!0}):s[a]=i,s}function on(s){var a=Ni(s,"string");return vt(a)=="symbol"?a:a+""}function Ni(s,a){if(vt(s)!="object"||!s)return s;var i=s[Symbol.toPrimitive];if(i!==void 0){var n=i.call(s,a||"default");if(vt(n)!="object")return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return(a==="string"?String:Number)(s)}var Ge=function(s){function a(){var i;fi(this,a);for(var n=arguments.length,l=new Array(n),c=0;c<n;c++)l[c]=arguments[c];return i=gi(this,a,[].concat(l)),Be(i,"state",{isAnimationFinished:!0}),Be(i,"id",nn("recharts-area-")),Be(i,"handleAnimationEnd",function(){var o=i.props.onAnimationEnd;i.setState({isAnimationFinished:!0}),ns(o)&&o()}),Be(i,"handleAnimationStart",function(){var o=i.props.onAnimationStart;i.setState({isAnimationFinished:!1}),ns(o)&&o()}),i}return vi(a,s),ji(a,[{key:"renderDots",value:function(n,l,c){var o=this.props.isAnimationActive,y=this.state.isAnimationFinished;if(o&&!y)return null;var p=this.props,j=p.dot,x=p.points,b=p.dataKey,f=We(this.props,!1),C=We(j,!0),O=x.map(function(T,W){var $=Je(Je(Je({key:"dot-".concat(W),r:3},f),C),{},{index:W,cx:T.x,cy:T.y,dataKey:b,value:T.value,payload:T.payload,points:x});return a.renderDotItem(j,$)}),v={clipPath:n?"url(#clipPath-".concat(l?"":"dots-").concat(c,")"):null};return E.createElement(Ie,dt({className:"recharts-area-dots"},v),O)}},{key:"renderHorizontalRect",value:function(n){var l=this.props,c=l.baseLine,o=l.points,y=l.strokeWidth,p=o[0].x,j=o[o.length-1].x,x=n*Math.abs(p-j),b=es(o.map(function(f){return f.y||0}));return jt(c)&&typeof c=="number"?b=Math.max(c,b):c&&Array.isArray(c)&&c.length&&(b=Math.max(es(c.map(function(f){return f.y||0})),b)),jt(b)?E.createElement("rect",{x:p<j?p:p-x,y:0,width:x,height:Math.floor(b+(y?parseInt("".concat(y),10):1))}):null}},{key:"renderVerticalRect",value:function(n){var l=this.props,c=l.baseLine,o=l.points,y=l.strokeWidth,p=o[0].y,j=o[o.length-1].y,x=n*Math.abs(p-j),b=es(o.map(function(f){return f.x||0}));return jt(c)&&typeof c=="number"?b=Math.max(c,b):c&&Array.isArray(c)&&c.length&&(b=Math.max(es(c.map(function(f){return f.x||0})),b)),jt(b)?E.createElement("rect",{x:0,y:p<j?p:p-x,width:b+(y?parseInt("".concat(y),10):1),height:Math.floor(x)}):null}},{key:"renderClipRect",value:function(n){var l=this.props.layout;return l==="vertical"?this.renderVerticalRect(n):this.renderHorizontalRect(n)}},{key:"renderAreaStatically",value:function(n,l,c,o){var y=this.props,p=y.layout,j=y.type,x=y.stroke,b=y.connectNulls,f=y.isRange;y.ref;var C=dn(y,xi);return E.createElement(Ie,{clipPath:c?"url(#clipPath-".concat(o,")"):null},E.createElement(ss,dt({},We(C,!0),{points:n,connectNulls:b,type:j,baseLine:l,layout:p,stroke:"none",className:"recharts-area-area"})),x!=="none"&&E.createElement(ss,dt({},We(this.props,!1),{className:"recharts-area-curve",layout:p,type:j,connectNulls:b,fill:"none",points:n})),x!=="none"&&f&&E.createElement(ss,dt({},We(this.props,!1),{className:"recharts-area-curve",layout:p,type:j,connectNulls:b,fill:"none",points:l})))}},{key:"renderAreaWithAnimation",value:function(n,l){var c=this,o=this.props,y=o.points,p=o.baseLine,j=o.isAnimationActive,x=o.animationBegin,b=o.animationDuration,f=o.animationEasing,C=o.animationId,O=this.state,v=O.prevPoints,T=O.prevBaseLine;return E.createElement(tn,{begin:x,duration:b,isActive:j,easing:f,from:{t:0},to:{t:1},key:"area-".concat(C),onAnimationEnd:this.handleAnimationEnd,onAnimationStart:this.handleAnimationStart},function(W){var $=W.t;if(v){var L=v.length/y.length,A=y.map(function(Y,ve){var te=Math.floor(ve*L);if(v[te]){var je=v[te],se=Me(je.x,Y.x),Qe=Me(je.y,Y.y);return Je(Je({},Y),{},{x:se($),y:Qe($)})}return Y}),B;if(jt(p)&&typeof p=="number"){var Q=Me(T,p);B=Q($)}else if(He(p)||ei(p)){var re=Me(T,0);B=re($)}else B=p.map(function(Y,ve){var te=Math.floor(ve*L);if(T[te]){var je=T[te],se=Me(je.x,Y.x),Qe=Me(je.y,Y.y);return Je(Je({},Y),{},{x:se($),y:Qe($)})}return Y});return c.renderAreaStatically(A,B,n,l)}return E.createElement(Ie,null,E.createElement("defs",null,E.createElement("clipPath",{id:"animationClipPath-".concat(l)},c.renderClipRect($))),E.createElement(Ie,{clipPath:"url(#animationClipPath-".concat(l,")")},c.renderAreaStatically(y,p,n,l)))})}},{key:"renderArea",value:function(n,l){var c=this.props,o=c.points,y=c.baseLine,p=c.isAnimationActive,j=this.state,x=j.prevPoints,b=j.prevBaseLine,f=j.totalLength;return p&&o&&o.length&&(!x&&f>0||!Is(x,o)||!Is(b,y))?this.renderAreaWithAnimation(n,l):this.renderAreaStatically(o,y,n,l)}},{key:"render",value:function(){var n,l=this.props,c=l.hide,o=l.dot,y=l.points,p=l.className,j=l.top,x=l.left,b=l.xAxis,f=l.yAxis,C=l.width,O=l.height,v=l.isAnimationActive,T=l.id;if(c||!y||!y.length)return null;var W=this.state.isAnimationFinished,$=y.length===1,L=Us("recharts-area",p),A=b&&b.allowDataOverflow,B=f&&f.allowDataOverflow,Q=A||B,re=He(T)?this.id:T,Y=(n=We(o,!1))!==null&&n!==void 0?n:{r:3,strokeWidth:2},ve=Y.r,te=ve===void 0?3:ve,je=Y.strokeWidth,se=je===void 0?2:je,Qe=ti(o)?o:{},kt=Qe.clipDot,Bt=kt===void 0?!0:kt,tt=te*2+se;return E.createElement(Ie,{className:L},A||B?E.createElement("defs",null,E.createElement("clipPath",{id:"clipPath-".concat(re)},E.createElement("rect",{x:A?x:x-C/2,y:B?j:j-O/2,width:A?C:C*2,height:B?O:O*2})),!Bt&&E.createElement("clipPath",{id:"clipPath-dots-".concat(re)},E.createElement("rect",{x:x-tt/2,y:j-tt/2,width:C+tt,height:O+tt}))):null,$?null:this.renderArea(Q,re),(o||$)&&this.renderDots(Q,Bt,re),(!v||W)&&sn.renderCallByParent(this.props,y))}}],[{key:"getDerivedStateFromProps",value:function(n,l){return n.animationId!==l.prevAnimationId?{prevAnimationId:n.animationId,curPoints:n.points,curBaseLine:n.baseLine,prevPoints:l.curPoints,prevBaseLine:l.curBaseLine}:n.points!==l.curPoints||n.baseLine!==l.curBaseLine?{curPoints:n.points,curBaseLine:n.baseLine}:null}}])}(P.PureComponent);ln=Ge;Be(Ge,"displayName","Area");Be(Ge,"defaultProps",{stroke:"#3182bd",fill:"#3182bd",fillOpacity:.6,xAxisId:0,yAxisId:0,legendType:"line",connectNulls:!1,points:[],dot:!1,activeDot:!0,hide:!1,isAnimationActive:!an.isSsr,animationBegin:0,animationDuration:1500,animationEasing:"ease"});Be(Ge,"getBaseValue",function(s,a,i,n){var l=s.layout,c=s.baseValue,o=a.props.baseValue,y=o??c;if(jt(y)&&typeof y=="number")return y;var p=l==="horizontal"?n:i,j=p.scale.domain();if(p.type==="number"){var x=Math.max(j[0],j[1]),b=Math.min(j[0],j[1]);return y==="dataMin"?b:y==="dataMax"||x<0?x:Math.max(Math.min(j[0],j[1]),0)}return y==="dataMin"?j[0]:y==="dataMax"?j[1]:j[0]});Be(Ge,"getComposedData",function(s){var a=s.props,i=s.item,n=s.xAxis,l=s.yAxis,c=s.xAxisTicks,o=s.yAxisTicks,y=s.bandSize,p=s.dataKey,j=s.stackedData,x=s.dataStartIndex,b=s.displayedData,f=s.offset,C=a.layout,O=j&&j.length,v=ln.getBaseValue(a,i,n,l),T=C==="horizontal",W=!1,$=b.map(function(A,B){var Q;O?Q=j[x+B]:(Q=yt(A,p),Array.isArray(Q)?W=!0:Q=[v,Q]);var re=Q[1]==null||O&&yt(A,p)==null;return T?{x:as({axis:n,ticks:c,bandSize:y,entry:A,index:B}),y:re?null:l.scale(Q[1]),value:Q,payload:A}:{x:re?null:n.scale(Q[1]),y:as({axis:l,ticks:o,bandSize:y,entry:A,index:B}),value:Q,payload:A}}),L;return O||W?L=$.map(function(A){var B=Array.isArray(A.value)?A.value[0]:null;return T?{x:A.x,y:B!=null&&A.y!=null?l.scale(B):null}:{x:B!=null?n.scale(B):null,y:A.y}}):L=T?l.scale(v):n.scale(v),Je({points:$,baseLine:L,layout:C,isRange:W},f)});Be(Ge,"renderDotItem",function(s,a){var i;if(E.isValidElement(s))i=E.cloneElement(s,a);else if(ns(s))i=s(a);else{var n=Us("recharts-area-dot",typeof s!="boolean"?s.className:""),l=a.key,c=dn(a,hi);i=E.createElement(si,dt({},c,{key:l,className:n}))}return i});function Nt(s){"@babel/helpers - typeof";return Nt=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(a){return typeof a}:function(a){return a&&typeof Symbol=="function"&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},Nt(s)}function wi(s,a){if(!(s instanceof a))throw new TypeError("Cannot call a class as a function")}function ki(s,a){for(var i=0;i<a.length;i++){var n=a[i];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(s,xn(n.key),n)}}function Si(s,a,i){return a&&ki(s.prototype,a),Object.defineProperty(s,"prototype",{writable:!1}),s}function Pi(s,a,i){return a=rs(a),Ai(s,mn()?Reflect.construct(a,i||[],rs(s).constructor):a.apply(s,i))}function Ai(s,a){if(a&&(Nt(a)==="object"||typeof a=="function"))return a;if(a!==void 0)throw new TypeError("Derived constructors may only return object or undefined");return Ci(s)}function Ci(s){if(s===void 0)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return s}function mn(){try{var s=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch{}return(mn=function(){return!!s})()}function rs(s){return rs=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(i){return i.__proto__||Object.getPrototypeOf(i)},rs(s)}function Ei(s,a){if(typeof a!="function"&&a!==null)throw new TypeError("Super expression must either be null or a function");s.prototype=Object.create(a&&a.prototype,{constructor:{value:s,writable:!0,configurable:!0}}),Object.defineProperty(s,"prototype",{writable:!1}),a&&qs(s,a)}function qs(s,a){return qs=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(n,l){return n.__proto__=l,n},qs(s,a)}function un(s,a,i){return a=xn(a),a in s?Object.defineProperty(s,a,{value:i,enumerable:!0,configurable:!0,writable:!0}):s[a]=i,s}function xn(s){var a=Oi(s,"string");return Nt(a)=="symbol"?a:a+""}function Oi(s,a){if(Nt(s)!="object"||!s)return s;var i=s[Symbol.toPrimitive];if(i!==void 0){var n=i.call(s,a||"default");if(Nt(n)!="object")return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return(a==="string"?String:Number)(s)}var ds=function(s){function a(){return wi(this,a),Pi(this,a,arguments)}return Ei(a,s),Si(a,[{key:"render",value:function(){return null}}])}(E.Component);un(ds,"displayName","ZAxis");un(ds,"defaultProps",{zAxisId:0,range:[64,64],scale:"auto",type:"number"});var Ti=["option","isActive"];function Mt(){return Mt=Object.assign?Object.assign.bind():function(s){for(var a=1;a<arguments.length;a++){var i=arguments[a];for(var n in i)Object.prototype.hasOwnProperty.call(i,n)&&(s[n]=i[n])}return s},Mt.apply(this,arguments)}function Ri(s,a){if(s==null)return{};var i=Di(s,a),n,l;if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(s);for(l=0;l<c.length;l++)n=c[l],!(a.indexOf(n)>=0)&&Object.prototype.propertyIsEnumerable.call(s,n)&&(i[n]=s[n])}return i}function Di(s,a){if(s==null)return{};var i={};for(var n in s)if(Object.prototype.hasOwnProperty.call(s,n)){if(a.indexOf(n)>=0)continue;i[n]=s[n]}return i}function Fi(s){var a=s.option,i=s.isActive,n=Ri(s,Ti);return typeof a=="string"?E.createElement(Va,Mt({option:E.createElement(ai,Mt({type:a},n)),isActive:i,shapeType:"symbols"},n)):E.createElement(Va,Mt({option:a,isActive:i,shapeType:"symbols"},n))}function wt(s){"@babel/helpers - typeof";return wt=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(a){return typeof a}:function(a){return a&&typeof Symbol=="function"&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},wt(s)}function It(){return It=Object.assign?Object.assign.bind():function(s){for(var a=1;a<arguments.length;a++){var i=arguments[a];for(var n in i)Object.prototype.hasOwnProperty.call(i,n)&&(s[n]=i[n])}return s},It.apply(this,arguments)}function Ya(s,a){var i=Object.keys(s);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(s);a&&(n=n.filter(function(l){return Object.getOwnPropertyDescriptor(s,l).enumerable})),i.push.apply(i,n)}return i}function Se(s){for(var a=1;a<arguments.length;a++){var i=arguments[a]!=null?arguments[a]:{};a%2?Ya(Object(i),!0).forEach(function(n){et(s,n,i[n])}):Object.getOwnPropertyDescriptors?Object.defineProperties(s,Object.getOwnPropertyDescriptors(i)):Ya(Object(i)).forEach(function(n){Object.defineProperty(s,n,Object.getOwnPropertyDescriptor(i,n))})}return s}function $i(s,a){if(!(s instanceof a))throw new TypeError("Cannot call a class as a function")}function Za(s,a){for(var i=0;i<a.length;i++){var n=a[i];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(s,pn(n.key),n)}}function Li(s,a,i){return a&&Za(s.prototype,a),i&&Za(s,i),Object.defineProperty(s,"prototype",{writable:!1}),s}function Mi(s,a,i){return a=ls(a),Ii(s,hn()?Reflect.construct(a,i||[],ls(s).constructor):a.apply(s,i))}function Ii(s,a){if(a&&(wt(a)==="object"||typeof a=="function"))return a;if(a!==void 0)throw new TypeError("Derived constructors may only return object or undefined");return Bi(s)}function Bi(s){if(s===void 0)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return s}function hn(){try{var s=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch{}return(hn=function(){return!!s})()}function ls(s){return ls=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(i){return i.__proto__||Object.getPrototypeOf(i)},ls(s)}function _i(s,a){if(typeof a!="function"&&a!==null)throw new TypeError("Super expression must either be null or a function");s.prototype=Object.create(a&&a.prototype,{constructor:{value:s,writable:!0,configurable:!0}}),Object.defineProperty(s,"prototype",{writable:!1}),a&&zs(s,a)}function zs(s,a){return zs=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(n,l){return n.__proto__=l,n},zs(s,a)}function et(s,a,i){return a=pn(a),a in s?Object.defineProperty(s,a,{value:i,enumerable:!0,configurable:!0,writable:!0}):s[a]=i,s}function pn(s){var a=qi(s,"string");return wt(a)=="symbol"?a:a+""}function qi(s,a){if(wt(s)!="object"||!s)return s;var i=s[Symbol.toPrimitive];if(i!==void 0){var n=i.call(s,a||"default");if(wt(n)!="object")return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return(a==="string"?String:Number)(s)}var cs=function(s){function a(){var i;$i(this,a);for(var n=arguments.length,l=new Array(n),c=0;c<n;c++)l[c]=arguments[c];return i=Mi(this,a,[].concat(l)),et(i,"state",{isAnimationFinished:!1}),et(i,"handleAnimationEnd",function(){i.setState({isAnimationFinished:!0})}),et(i,"handleAnimationStart",function(){i.setState({isAnimationFinished:!1})}),et(i,"id",nn("recharts-scatter-")),i}return _i(a,s),Li(a,[{key:"renderSymbolsStatically",value:function(n){var l=this,c=this.props,o=c.shape,y=c.activeShape,p=c.activeIndex,j=We(this.props,!1);return n.map(function(x,b){var f=p===b,C=f?y:o,O=Se(Se({},j),x);return E.createElement(Ie,It({className:"recharts-scatter-symbol",key:"symbol-".concat(x==null?void 0:x.cx,"-").concat(x==null?void 0:x.cy,"-").concat(x==null?void 0:x.size,"-").concat(b)},ni(l.props,x,b),{role:"img"}),E.createElement(Fi,It({option:C,isActive:f,key:"symbol-".concat(b)},O)))})}},{key:"renderSymbolsWithAnimation",value:function(){var n=this,l=this.props,c=l.points,o=l.isAnimationActive,y=l.animationBegin,p=l.animationDuration,j=l.animationEasing,x=l.animationId,b=this.state.prevPoints;return E.createElement(tn,{begin:y,duration:p,isActive:o,easing:j,from:{t:0},to:{t:1},key:"pie-".concat(x),onAnimationEnd:this.handleAnimationEnd,onAnimationStart:this.handleAnimationStart},function(f){var C=f.t,O=c.map(function(v,T){var W=b&&b[T];if(W){var $=Me(W.cx,v.cx),L=Me(W.cy,v.cy),A=Me(W.size,v.size);return Se(Se({},v),{},{cx:$(C),cy:L(C),size:A(C)})}var B=Me(0,v.size);return Se(Se({},v),{},{size:B(C)})});return E.createElement(Ie,null,n.renderSymbolsStatically(O))})}},{key:"renderSymbols",value:function(){var n=this.props,l=n.points,c=n.isAnimationActive,o=this.state.prevPoints;return c&&l&&l.length&&(!o||!Is(o,l))?this.renderSymbolsWithAnimation():this.renderSymbolsStatically(l)}},{key:"renderErrorBar",value:function(){var n=this.props.isAnimationActive;if(n&&!this.state.isAnimationFinished)return null;var l=this.props,c=l.points,o=l.xAxis,y=l.yAxis,p=l.children,j=rn(p,ii);return j?j.map(function(x,b){var f=x.props,C=f.direction,O=f.dataKey;return E.cloneElement(x,{key:"".concat(C,"-").concat(O,"-").concat(c[b]),data:c,xAxis:o,yAxis:y,layout:C==="x"?"vertical":"horizontal",dataPointFormatter:function(T,W){return{x:T.cx,y:T.cy,value:C==="x"?+T.node.x:+T.node.y,errorVal:yt(T,W)}}})}):null}},{key:"renderLine",value:function(){var n=this.props,l=n.points,c=n.line,o=n.lineType,y=n.lineJointType,p=We(this.props,!1),j=We(c,!1),x,b;if(o==="joint")x=l.map(function(L){return{x:L.cx,y:L.cy}});else if(o==="fitting"){var f=ri(l),C=f.xmin,O=f.xmax,v=f.a,T=f.b,W=function(A){return v*A+T};x=[{x:C,y:W(C)},{x:O,y:W(O)}]}var $=Se(Se(Se({},p),{},{fill:"none",stroke:p&&p.fill},j),{},{points:x});return E.isValidElement(c)?b=E.cloneElement(c,$):ns(c)?b=c($):b=E.createElement(ss,It({},$,{type:y})),E.createElement(Ie,{className:"recharts-scatter-line",key:"recharts-scatter-line"},b)}},{key:"render",value:function(){var n=this.props,l=n.hide,c=n.points,o=n.line,y=n.className,p=n.xAxis,j=n.yAxis,x=n.left,b=n.top,f=n.width,C=n.height,O=n.id,v=n.isAnimationActive;if(l||!c||!c.length)return null;var T=this.state.isAnimationFinished,W=Us("recharts-scatter",y),$=p&&p.allowDataOverflow,L=j&&j.allowDataOverflow,A=$||L,B=He(O)?this.id:O;return E.createElement(Ie,{className:W,clipPath:A?"url(#clipPath-".concat(B,")"):null},$||L?E.createElement("defs",null,E.createElement("clipPath",{id:"clipPath-".concat(B)},E.createElement("rect",{x:$?x:x-f/2,y:L?b:b-C/2,width:$?f:f*2,height:L?C:C*2}))):null,o&&this.renderLine(),this.renderErrorBar(),E.createElement(Ie,{key:"recharts-scatter-symbols"},this.renderSymbols()),(!v||T)&&sn.renderCallByParent(this.props,c))}}],[{key:"getDerivedStateFromProps",value:function(n,l){return n.animationId!==l.prevAnimationId?{prevAnimationId:n.animationId,curPoints:n.points,prevPoints:l.curPoints}:n.points!==l.curPoints?{curPoints:n.points}:null}}])}(P.PureComponent);et(cs,"displayName","Scatter");et(cs,"defaultProps",{xAxisId:0,yAxisId:0,zAxisId:0,legendType:"circle",lineType:"joint",lineJointType:"linear",data:[],shape:"circle",hide:!1,isAnimationActive:!an.isSsr,animationBegin:0,animationDuration:400,animationEasing:"linear"});et(cs,"getComposedData",function(s){var a=s.xAxis,i=s.yAxis,n=s.zAxis,l=s.item,c=s.displayedData,o=s.xAxisTicks,y=s.yAxisTicks,p=s.offset,j=l.props.tooltipType,x=rn(l.props.children,Bs),b=He(a.dataKey)?l.props.dataKey:a.dataKey,f=He(i.dataKey)?l.props.dataKey:i.dataKey,C=n&&n.dataKey,O=n?n.range:ds.defaultProps.range,v=O&&O[0],T=a.scale.bandwidth?a.scale.bandwidth():0,W=i.scale.bandwidth?i.scale.bandwidth():0,$=c.map(function(L,A){var B=yt(L,b),Q=yt(L,f),re=!He(C)&&yt(L,C)||"-",Y=[{name:He(a.dataKey)?l.props.name:a.name||a.dataKey,unit:a.unit||"",value:B,payload:L,dataKey:b,type:j},{name:He(i.dataKey)?l.props.name:i.name||i.dataKey,unit:i.unit||"",value:Q,payload:L,dataKey:f,type:j}];re!=="-"&&Y.push({name:n.name||n.dataKey,unit:n.unit||"",value:re,payload:L,dataKey:C,type:j});var ve=as({axis:a,ticks:o,bandSize:T,entry:L,index:A,dataKey:b}),te=as({axis:i,ticks:y,bandSize:W,entry:L,index:A,dataKey:f}),je=re!=="-"?n.scale(re):v,se=Math.sqrt(Math.max(je,0)/Math.PI);return Se(Se({},L),{},{cx:ve,cy:te,x:ve-se,y:te-se,xAxis:a,yAxis:i,zAxis:n,width:2*se,height:2*se,size:je,node:{x:B,y:Q,z:re},tooltipPayload:Y,tooltipPosition:{x:ve,y:te},payload:L},x&&x[A]&&x[A].props)});return Se({points:$},p)});
16var zi=li({chartName:"ComposedChart",GraphicalChild:[oi,Ge,Ve,cs],axisComponents:[{axisType:"xAxis",AxisComp:gt},{axisType:"yAxis",AxisComp:bt},{axisType:"zAxis",AxisComp:ds}],formatAxisMap:di});function Xa({schedule:s}){return e.jsxs("div",{className:"flex flex-wrap gap-1",children:[s.timeoutPaused&&e.jsx(ce,{variant:"secondary",children:"Paused (timeout)"}),s.calendarUnreachableAt&&e.jsx(ce,{variant:"destructive",children:"Unreachable"}),!s.enabled&&e.jsx(ce,{variant:"outline",children:"Disabled"}),!s.timeoutPaused&&!s.calendarUnreachableAt&&s.enabled&&e.jsx(ce,{variant:"outline",children:"Enabled"})]})}const Ja=s=>s?new Date(s).toLocaleString():"Not scheduled";function Ki({filter:s="all"}){const{toast:a}=en(),[i,n]=P.useState(["timeout-paused","unreachable","help-email-sent"].includes(s)?s:"all");P.useEffect(()=>{n(["timeout-paused","unreachable","help-email-sent"].includes(s)?s:"all")},[s]);const[l,c]=P.useState(""),[o,y]=P.useState(null),{data:p=[],isLoading:j,isError:x,refetch:b}=ie({queryKey:["/api/admin/scrape-schedules"],refetchInterval:3e4}),f=p.find(v=>v.id===o),C=J({mutationFn:v=>G("POST",`/api/admin/scrape-schedules/${v}/reset`),onSuccess:()=>{ee.invalidateQueries({queryKey:["/api/admin/scrape-schedules"]}),ee.invalidateQueries({queryKey:["/api/admin/scraping-analytics"]}),ee.invalidateQueries({queryKey:["/api/admin/entity-scraper-health"]}),ee.invalidateQueries({queryKey:["/api/curator/scrape-schedule"]}),a({title:"Schedule reset",description:"Failure count cleared and next run set to now."})},onError:v=>a({title:"Reset failed",description:v.message,variant:"destructive"})}),O=p.filter(v=>(i==="all"||i==="timeout-paused"&&v.timeoutPaused||i==="unreachable"&&v.calendarUnreachableAt||i==="help-email-sent"&&v.calendarHelpEmailSentAt)&&`${v.entityName} ${v.citySlug} ${v.entityType}`.toLowerCase().includes(l.toLowerCase()));return e.jsxs(w,{children:[e.jsx(z,{children:e.jsx(K,{children:"Entity scrape schedules"})}),e.jsxs(N,{className:"space-y-4",children:[e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsxs(Ae,{value:i,onValueChange:n,children:[e.jsx(Ce,{className:"w-52","aria-label":"Schedule status","data-testid":"select-schedule-status",children:e.jsx(Ee,{})}),e.jsxs(Oe,{children:[e.jsx(D,{value:"all",children:"All schedules"}),e.jsx(D,{value:"timeout-paused",children:"Paused (timeout)"}),e.jsx(D,{value:"unreachable",children:"Unreachable"}),e.jsx(D,{value:"help-email-sent",children:"Help email sent"})]})]}),e.jsx(Ue,{className:"max-w-sm",placeholder:"Search entity or city","aria-label":"Search schedules",value:l,onChange:v=>c(v.target.value)}),e.jsx(U,{variant:"outline",onClick:()=>b(),children:"Refresh"})]}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Timeout-paused means at least 3 consecutive failures with the next run more than 7 days away. Showing ",O.length," schedules."]}),e.jsx("div",{className:"overflow-x-auto",children:e.jsxs(Te,{children:[e.jsx(Re,{children:e.jsxs(V,{children:[e.jsx(h,{children:"Entity"}),e.jsx(h,{children:"City"}),e.jsx(h,{children:"Status"}),e.jsx(h,{children:"Failures"}),e.jsx(h,{children:"Next run"}),e.jsx(h,{children:"Review"})]})}),e.jsx(De,{children:j||x||O.length===0?e.jsx(V,{children:e.jsx(m,{colSpan:6,children:j?"Loading schedules…":x?"Could not load schedules. Try Refresh.":"No matching schedules."})}):O.map(v=>e.jsxs(V,{"data-testid":`row-entity-schedule-${v.id}`,children:[e.jsxs(m,{children:[v.entityName,e.jsx("div",{className:"text-xs text-muted-foreground",children:v.entityType})]}),e.jsx(m,{children:v.citySlug}),e.jsx(m,{children:e.jsx(Xa,{schedule:v})}),e.jsx(m,{children:v.consecutiveFailures}),e.jsx(m,{children:Ja(v.nextRunAt)}),e.jsx(m,{children:e.jsx(U,{variant:"outline",size:"sm",onClick:()=>y(v.id),children:"Details"})})]},v.id))})]})}),e.jsx(_n,{open:!!f,onOpenChange:v=>{v||y(null)},children:e.jsxs(qn,{children:[e.jsxs(zn,{children:[e.jsx(Kn,{children:f==null?void 0:f.entityName}),e.jsx(Un,{children:"Review the schedule and clear timeout deferral."})]}),f&&e.jsxs("div",{className:"space-y-3",children:[e.jsx(Xa,{schedule:f}),e.jsx("p",{className:"text-sm break-all",children:f.calendarPageUrl}),e.jsxs("p",{children:["Frequency: ",f.frequency]}),e.jsxs("p",{children:["Consecutive failures: ",f.consecutiveFailures]}),e.jsxs("p",{children:["Next run: ",Ja(f.nextRunAt)]}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Reset clears consecutive failures and sets the next run to now. It does not start a scrape immediately, enable disabled schedules, or clear unreachable status."}),e.jsx(U,{disabled:C.isPending,onClick:()=>C.mutate(f.id),"data-testid":"button-reset-entity-schedule",children:C.isPending?"Resetting…":"Reset schedule"})]})]})})]})]})}function ye({label:s,value:a,sub:i,color:n}){return e.jsxs("div",{className:"flex flex-col gap-0.5",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:s}),e.jsx("p",{className:`text-2xl font-bold tabular-nums ${n??""}`,children:a}),i&&e.jsx("p",{className:"text-xs text-muted-foreground",children:i})]})}function Ha({status:s}){const i={sent:{label:"Sent",variant:"secondary"},clicked:{label:"Clicked",variant:"default"},failed:{label:"Failed",variant:"destructive"},completed:{label:"Success",variant:"default"},partial:{label:"Partial",variant:"secondary"},error:{label:"Error",variant:"destructive"},pending:{label:"Pending",variant:"outline"}}[s]??{label:s,variant:"outline"};return e.jsx(ce,{variant:i.variant,children:i.label})}const Ms=["activation","analytics","email","health","discovery","schedules"];function or(){var xa,ha,pa,fa,ja,ga,ba,ya,va,Na,wa,ka,Sa,Pa,Aa,Ca;const{toast:s}=en();Vn();const a=Wn(),[i,n]=P.useState(()=>{const t=new URLSearchParams(window.location.search).get("tab");return Ms.includes(t)?t:"activation"});P.useEffect(()=>{const t=new URLSearchParams(a).get("tab");Ms.includes(t)&&n(t)},[a]);const[l,c]=P.useState("all"),[o,y]=P.useState(""),[p,j]=P.useState(()=>Xe(Gn(new Date,30),"yyyy-MM-dd")),[x,b]=P.useState(""),[f,C]=P.useState(""),[O,v]=P.useState(""),[T,W]=P.useState("all"),[$,L]=P.useState(""),[A,B]=P.useState(null),[Q,re]=P.useState(null),[Y,ve]=P.useState(null),[te,je]=P.useState(""),[se,Qe]=P.useState("30"),[kt,Bt]=P.useState("10"),[tt,fn]=P.useState(!1),[Vs,jn]=P.useState(!1),[st,gn]=P.useState(!1),[bn,os]=P.useState(!1),[ae,Ws]=P.useState(null),[I,Gs]=P.useState(null),[at,_t]=P.useState(null),[S,ms]=P.useState(null),[yn,us]=P.useState(!1),[H,vn]=P.useState(null),[nt,Nn]=P.useState(""),[Qs,wn]=P.useState("25"),[_e,Ys]=P.useState(null),[ct,Zs]=P.useState(null),[Ne,Xs]=P.useState(null),[ot,Js]=P.useState(null),{data:St}=ie({queryKey:["/api/public/curated-cities"]}),{data:Hs}=ie({queryKey:["/api/admin/city-scraping/city-promoters/all/preview/active"],queryFn:async()=>{try{return await G("GET","/api/admin/city-scraping/city-promoters/all/preview/active").then(t=>t.json())}catch(t){if(String((t==null?void 0:t.message)||"").startsWith("404:"))return null;throw t}},enabled:!at&&!I}),{data:ea}=ie({queryKey:["/api/admin/city-scraping/city-promoters/all/preview",at],queryFn:()=>G("GET",`/api/admin/city-scraping/city-promoters/all/preview/${at}`).then(t=>t.json()),enabled:!!at,refetchInterval:at?2e3:!1});P.useEffect(()=>{const t=ea??Hs;t&&(ms(t),t.result&&(Gs(t.result),t.operation==="enroll"&&t.status==="completed"&&(ee.invali
16dateQueries({queryKey:["/api/admin/city-scraping/overview"]}),ee.invalidateQueries({queryKey:["/api/admin/city-scraping/problem-entities"]}))),t.status==="completed"||t.status==="failed"?_t(null):at||_t(t.jobId))},[Hs,ea,at]);const{data:_,isLoading:kn,refetch:Sn}=ie({queryKey:["/api/admin/city-scraping/overview"]}),{data:xe,isLoading:Pn,refetch:An}=ie({queryKey:["/api/admin/city-scraping/analytics"],queryFn:()=>G("GET","/api/admin/city-scraping/analytics?limit=200").then(t=>t.json())}),{data:q,isLoading:Cn,refetch:En}=ie({queryKey:["/api/admin/city-scraping/email-analytics"]}),{data:qt,isLoading:On,refetch:Ui}=ie({queryKey:["/api/admin/city-scraping/problem-entities"]}),qe=J({mutationFn:t=>G("POST","/api/admin/city-scraping/bulk-activate",{entityType:t,staggerDays:7}).then(r=>r.json()),onSuccess:t=>{s({title:"Schedules activated",description:t.message}),ee.invalidateQueries({queryKey:["/api/admin/city-scraping/overview"]})},onError:()=>s({title:"Error",description:"Failed to activate schedules",variant:"destructive"})}),xs=J({mutationFn:()=>G("POST","/api/admin/city-scraping/enable-email-invites").then(t=>t.json()),onSuccess:t=>{s({title:"Email invites enabled",description:t.message}),ee.invalidateQueries({queryKey:["/api/admin/city-scraping/overview"]})},onError:()=>s({title:"Error",description:"Failed to enable email invites",variant:"destructive"})}),hs=J({mutationFn:()=>G("POST","/api/admin/city-scraping/repair-schedules").then(t=>t.json()),onSuccess:t=>{s({title:"Schedules repaired",description:t.message}),ee.invalidateQueries({queryKey:["/api/admin/city-scraping/overview"]})},onError:()=>s({title:"Error",description:"Failed to repair schedules",variant:"destructive"})}),ps=J({mutationFn:()=>G("POST","/api/admin/scrape-schedules/cleanup-dead-urls",{dryRun:!1}).then(t=>t.json()),onSuccess:t=>{const r=t.disabled===0?"No matching schedules found — data is already clean.":`Disabled ${t.disabled} schedule(s). Patterns: ${Object.entries(t.byPattern).map(([g,F])=>`${g} (${F})`).join(", ")}`;s({title:t.disabled===0?"All clean":`Disabled ${t.disabled} dead schedule(s)`,description:r}),ee.invalidateQueries({queryKey:["/api/admin/city-scraping/overview"]})},onError:()=>s({title:"Error",description:"Failed to run dead-URL cleanup",variant:"destructive"})}),{data:me,isLoading:fs}=ie({queryKey:["/api/admin/scheduler-status"],refetchInterval:3e4}),ta=J({mutationFn:t=>G("POST","/api/admin/toggle-scheduler",{enabled:t}).then(r=>r.json()),onSuccess:t=>{s({title:t.enabled?"Scheduler enabled":"Scheduler disabled",description:t.message}),ee.invalidateQueries({queryKey:["/api/admin/scheduler-status"]})},onError:()=>s({title:"Error",description:"Failed to toggle scheduler",variant:"destructive"})}),{data:k,isLoading:js}=ie({queryKey:["/api/admin/google-places-status"],refetchInterval:3e4}),sa=J({mutationFn:t=>G("POST","/api/admin/toggle-google-places",{enabled:t}).then(r=>r.json()),onSuccess:t=>{s({title:t.enabled?"Google Places enabled":"Google Places disabled",description:t.message}),ee.invalidateQueries({queryKey:["/api/admin/google-places-status"]})},onError:()=>s({title:"Error",description:"Failed to toggle Google Places",variant:"destructive"})}),{data:he,isLoading:gs}=ie({queryKey:["/api/admin/calendar-discovery-status"],refetchInterval:3e4}),aa=J({mutationFn:t=>G("POST","/api/admin/toggle-calendar-discovery",{enabled:t}).then(r=>r.json()),onSuccess:t=>{s({title:t.enabled?"Calendar Discovery enabled":"Calendar Discovery disabled",description:t.message}),ee.invalidateQueries({queryKey:["/api/admin/calendar-discovery-status"]})},onError:()=>s({title:"Error",description:"Failed to toggle Calendar Discovery",variant:"destructive"})}),zt=J({mutationFn:t=>G("POST","/api/admin/osm-url-backfill",{citySlug:t||void 0,limit:25}).then(r=>r.json()),onSuccess:t=>{B(t),re(r=>({checked:((r==null?void 0:r.checked)??0)+t.checked,found:((r==null?void 0:r.found)??0)+t.found,updated:((r==null?void 0:r.updated)??0)+t.updated})),s({title:t.remaining>0?"Batch complete":"Backfill complete",description:t.message})},onError:()=>s({title:"Error",description:"OSM URL backfill failed",variant:"destructive"})}),bs=J({mutationFn:t=>G("POST","/api/admin/osm-city-url-test",{citySlug:t}).then(r=>r.json()),onSuccess:t=>{ve(t),s({title:"OSM city test complete",description:t.message})},onError:()=>s({title:"Error",description:"OSM city URL test failed",variant:"destructive"})}),Kt=J({mutationFn:({citySlug:t})=>G("POST","/api/admin/google-places-osm-enrich",{citySlug:t,phase:"sweep"}).then(r=>r.json()),onSuccess:t=>{Ys(t),Zs(r=>({swept:((r==null?void 0:r.swept)??0)+t.swept,matched:((r==null?void 0:r.matched)??0)+t.matched,websiteAdded:((r==null?void 0:r.websiteAdded)??0)+t.websiteAdded,placeIdAdded:((r==null?void 0:r.placeIdAdded)??0)+t.placeIdAdded})),s({title:"Sweep complete",description:t.message})},onError:t=>s({title:"Error",description:(t==null?void 0:t.message)||"Google Places sweep failed",variant:"destructive"})}),Ut=J({mutationFn:({citySlug:t,limit:r})=>G("POST","/api/admin/google-places-osm-enrich",{citySlug:t,phase:"individual",limit:r}).then(g=>g.json()),onSuccess:t=>{Xs(t),Js(r=>({swept:((r==null?void 0:r.swept)??0)+t.swept,matched:((r==null?void 0:r.matched)??0)+t.matched,websiteAdded:((r==null?void 0:r.websiteAdded)??0)+t.websiteAdded,placeIdAdded:((r==null?void 0:r.placeIdAdded)??0)+t.placeIdAdded})),s({title:t.remaining>0?"Batch complete":"Individual lookup complete",description:t.message})},onError:t=>s({title:"Error",description:(t==null?void 0:t.message)||"Google Places individual lookup failed",variant:"destructive"})}),na=J({mutationFn:t=>G("POST",`/api/admin/city-scraping/email-analytics/${t}/resend`).then(r=>r.json()),onSuccess:t=>{s({title:"Email resent",description:t.message}
16),ee.invalidateQueries({queryKey:["/api/admin/city-scraping/email-analytics"]})},onError:()=>s({title:"Error",description:"Failed to resend email",variant:"destructive"})}),Vt=J({mutationFn:t=>G("POST","/api/admin/city-scraping/discover-calendars",t).then(r=>r.json()),onSuccess:t=>{vn(t),t.error?s({title:"Discovery failed",description:t.error,variant:"destructive"}):(s({title:"Discovery complete",description:`${t.phases.enrollment.enrolled} new schedule(s) created`}),ee.invalidateQueries({queryKey:["/api/admin/city-scraping/overview"]}))},onError:t=>s({title:"Error",description:t.message||"Discovery failed",variant:"destructive"})}),ys=J({mutationFn:t=>G("POST","/api/admin/city-scraping/city-promoters/preview",t).then(r=>r.json()),onSuccess:t=>{Ws(t),s({title:"City promoter preview complete",description:`${t.counts.eligibleForEnrollment} schedule(s) are ready for confirmation`}),ee.invalidateQueries({queryKey:["/api/admin/city-scraping/overview"]})},onError:t=>s({title:"Preview failed",description:(t==null?void 0:t.message)||"City promoter preview failed",variant:"destructive"})}),Wt=J({mutationFn:t=>G("POST","/api/admin/city-scraping/city-promoters/enroll",{...t,confirm:!0}).then(r=>r.json()),onSuccess:t=>{Ws(t),os(!1),s({title:"City promoter enrollment complete",description:`${t.enrollment.created} created, ${t.enrollment.reenabled} re-enabled, ${t.enrollment.skipped} skipped`}),ee.invalidateQueries({queryKey:["/api/admin/city-scraping/overview"]}),ee.invalidateQueries({queryKey:["/api/admin/city-scraping/problem-entities"]})},onError:t=>s({title:"Enrollment failed",description:(t==null?void 0:t.message)||"City promoter enrollment failed",variant:"destructive"})}),vs=J({mutationFn:t=>G("POST","/api/admin/city-scraping/city-promoters/all/preview",t).then(r=>r.json()),onSuccess:t=>{Gs(null),_t(t.jobId),ms(t),s({title:t.status==="running"?"All-city promoter preview started":"All-city promoter preview queued",description:"You can leave this page open while each curated city is checked."})},onError:t=>s({title:"All-city preview failed",description:(t==null?void 0:t.message)||"All-city city promoter preview failed",variant:"destructive"})}),Gt=J({mutationFn:t=>G("POST","/api/admin/city-scraping/city-promoters/all/enroll",{...t,confirm:!0}).then(r=>r.json()),onSuccess:t=>{_t(t.jobId),ms(t),us(!1),s({title:"All-city promoter enrollment started",description:"Schedules will be updated in the background as each city completes."})},onError:t=>s({title:"All-city enrollment failed",description:(t==null?void 0:t.message)||"All-city city promoter enrollment failed",variant:"destructive"})}),{data:Pt,refetch:Tn}=ie({queryKey:["/api/admin/city-scraping/city-schedules"]}),{data:d,isLoading:Ns,refetch:ia}=ie({queryKey:["/api/admin/entity-scraper-health"],refetchInterval:6e4}),{data:le,isLoading:Ye,refetch:Rn}=ie({queryKey:["/api/admin/scraping-analytics"]}),[mt,Dn]=P.useState("7"),{data:Qt,isLoading:Fn,refetch:ra}=ie({queryKey:["/api/admin/city-scraping/batch-runs"]}),la=(Qt??[]).some(t=>t.status==="in-progress"),{data:Yt}=ie({queryKey:["/api/admin/scrape-queue/abort-status"],enabled:la,refetchInterval:la?4e3:!1}),[ws,da]=P.useState(new Set),ks=J({mutationFn:({batchLabel:t})=>G("POST",`/api/admin/entity-scraper/${encodeURIComponent(t)}/abort`).then(r=>r.json()),onSuccess:(t,r)=>{da(F=>new Set(F).add(r.runId)),s({title:"Force stop sent",description:"The entity scraper will stop after the current venue URL finishes."});const g=()=>ra().then(F=>{var pe;((pe=F.data)==null?void 0:pe.some(u=>u.id===r.runId&&u.status==="in-progress"))?setTimeout(g,5e3):da(u=>{const M=new Set(u);return M.delete(r.runId),M})});setTimeout(g,5e3)},onError:t=>s({title:"Error",description:(t==null?void 0:t.message)||"Failed to abort entity scraper",variant:"destructive"})}),{data:$n,isLoading:Ln}=ie({queryKey:["/api/admin/city-scraping/hourly-load"]}),{data:Ss,isLoading:Mn}=ie({queryKey:["/api/admin/city-scraping/timeline",mt],queryFn:()=>G("GET",`/api/admin/city-scraping/timeline?days=${mt}`).then(t=>t.json())}),{data:Ps}=ie({queryKey:["/api/admin/city-scraping/error-events",mt],queryFn:()=>G("GET",`/api/admin/city-scraping/error-events?days=${mt}`).then(t=>t.json())}),ca=J({mutationFn:({id:t,frequency:r})=>G("PUT",`/api/admin/scraping-schedules/${t}`,{frequency:r}).then(g=>g.json()),onSuccess:()=>{s({title:"Frequency updated",description:"Schedule updated and next run recalculated."}
16),ee.invalidateQueries({queryKey:["/api/admin/city-scraping/city-schedules"]})},onError:()=>s({title:"Error",description:"Failed to update frequency",variant:"destructive"})}),[oa,In]=P.useState("monthly"),As=J({mutationFn:t=>G("POST","/api/admin/city-scraping/bulk-set-frequency",{frequency:t}).then(r=>r.json()),onSuccess:t=>{s({title:"Bulk frequency updated",description:`${t.updated} city schedules set to ${t.frequency}.`}),ee.invalidateQueries({queryKey:["/api/admin/city-scraping/city-schedules"]})},onError:()=>s({title:"Error",description:"Failed to bulk update frequency",variant:"destructive"})}),Zt=P.useMemo(()=>((xe==null?void 0:xe.history)??[]).filter(t=>{var r,g;if(l!=="all"&&t.entityType!==l)return!1;if(o){const F=o.toLowerCase(),Z=(r=t.citySlug)==null?void 0:r.toLowerCase().includes(F),pe=(g=t.entityName)==null?void 0:g.toLowerCase().includes(F);if(!Z&&!pe)return!1}return!(p&&t.scrapedAt<p||x&&t.scrapedAt>x+"T23:59:59"||f!==""&&(t.extractionQualityScore??100)<Number(f)||O!==""&&(t.extractionQualityScore??100)>Number(O))}).sort((t,r)=>(t.extractionQualityScore??100)-(r.extractionQualityScore??100)),[xe==null?void 0:xe.history,l,o,p,x,f,O]),Cs=P.useMemo(()=>{if(!(q!=null&&q.recent))return[];const t={};for(let r=5;r>=0;r--){const g=Ta(ui(new Date,r)),F=Xe(g,"MMM yyyy");t[F]={sent:0,clicked:0}}for(const r of q.recent){const g=r.sentAt?new Date(r.sentAt):new Date(r.createdAt),F=Ta(g),Z=Xe(F,"MMM yyyy");Z in t&&(t[Z].sent++,r.clickedAt&&t[Z].clicked++)}return Object.entries(t).map(([r,g])=>({week:r,...g}))},[q==null?void 0:q.recent]),oe=P.useMemo(()=>{if(!_)return null;const t=new Date,r=new Date(t.getFullYear(),t.getMonth()+1,0),g=new Date(r);g.setDate(r.getDate()-7);const F=t>=g&&t<=r,Z=_.schedules.total,pe=_.schedules.ranThisMonth,u=Z>0?pe/Z*100:0,M=Math.max(0,Math.round((r.getTime()-t.getTime())/864e5)),fe=_.schedules.circuitBreakerTripped??0;let de="on-track";return fe>0?de="paused":(F&&u<50&&M<=3||u<30&&M<=1)&&(de="at-risk"),{inWindow:F,pct:u,daysLeft:M,status:de,ranThisMonth:pe,total:Z,batchWindowStart:g,endOfMonth:r}},[_]),Pe=xe==null?void 0:xe.summary,ge=q==null?void 0:q.funnel,Bn=ge&&ge.sent>0?(ge.clicked/ge.sent*100).toFixed(1):"0.0",ma=(S==null?void 0:S.status)==="queued"||(S==null?void 0:S.status)==="running",Es=ma&&(S==null?void 0:S.operation)==="enroll",ua=(S==null?void 0:S.status)==="failed"&&S.operation==="enroll";return e.jsxs("div",{className:"container mx-auto px-4 py-6 max-w-6xl",children:[e.jsxs("div",{className:"flex items-center gap-3 mb-6",children:[e.jsx(Xt,{href:"/admin",children:e.jsxs(U,{variant:"ghost",size:"sm",className:"gap-1","data-testid":"button-back-admin",children:[e.jsx(Hn,{className:"h-4 w-4"}),"Admin"]})}),e.jsx("div",{className:"h-5 w-px bg-border"}),e.jsxs("div",{children:[e.jsxs("h1",{className:"text-xl sm:text-2xl font-bold flex items-center gap-2","data-testid":"text-page-title",children:[e.jsx(Ds,{className:"h-5 w-5 text-primary"}),"City Scraping Dashboard"]}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Manage monthly schedules, analytics, and email tracking"})]})]}),e.jsxs(Zn,{value:i,onValueChange:t=>{Ms.includes(t)&&n(t)},children:[e.jsxs(Xn,{className:"w-full sm:w-auto mb-6","data-testid":"tabs-city-scraping",children:[e.jsx(pt,{value:"schedules","data-testid":"tab-entity-schedules",children:"Schedules"}),e.jsxs(pt,{value:"activation","data-testid":"tab-activation",children:[e.jsx(Jt,{className:"h-4 w-4 mr-1.5"}),"Activation"]}),e.jsxs(pt,{value:"analytics","data-testid":"tab-analytics",children:[e.jsx(Fs,{className:"h-4 w-4 mr-1.5"}),"Scraping"]}),e.jsxs(pt,{value:"email","data-testid":"tab-email",children:[e.jsx(Ts,{className:"h-4 w-4 mr-1.5"}),"Email"]}),e.jsxs(pt,{value:"health","data-testid":"tab-health",children:[e.jsx(Ka,{className:"h-4 w-4 mr-1.5"}),"Health"]}),e.jsxs(pt,{value:"discovery","data-testid":"tab-discovery",children:[e.jsx(xt,{className:"h-4 w-4 mr-1.5"}),"Discovery"]})]}),e.jsx(ft,{value:"schedules",children:e.jsx(Ki,{filter:new URLSearchParams(a).get("filter")??"all"})}),e.jsxs(ft,{value:"activation",className:"space-y-4",children:[e.jsx(w,{className:me!=null&&me.enabled?"border-green-400 dark:border-green-700":"border-amber-400 dark:border-amber-600",children:e.jsx(N,{className:"pt-4 pb-4",children:e.jsxs("div",{className:"flex items-center justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx(ue,{htmlFor:"scheduler-toggle-main",className:"text-sm font-semibold",children:"Automated Scheduler"}),e.jsx("p",{className:"text-xs text-muted-foreground mt-0.5",children:fs?"Loading...":me!=null&&me.enabled?`Running hourly · scrapes fire in the D-7 batch window each month (${me.timezone})`:"Off — schedules exist but nothing will run until you enable this"})]}),e.jsxs("div",{className:"flex items-center gap-2 shrink-0",children:[e.jsx("span",{className:`text-xs font-medium ${me!=null&&me.enabled?"text-green-600 dark:text-green-400":"text-amber-600 dar
16k:text-amber-400"}`,children:fs?"…":me!=null&&me.enabled?"ON":"OFF"}),e.jsx(ht,{id:"scheduler-toggle-main",checked:(me==null?void 0:me.enabled)??!1,onCheckedChange:t=>ta.mutate(t),disabled:fs||ta.isPending,"data-testid":"switch-scheduler-toggle-main"})]})]})})}),e.jsx(w,{className:he!=null&&he.enabled?"border-slate-200 dark:border-slate-700":"border-amber-400 dark:border-amber-600",children:e.jsx(N,{className:"pt-4 pb-4",children:e.jsxs("div",{className:"flex items-center justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx(ue,{htmlFor:"calendar-discovery-toggle",className:"text-sm font-semibold",children:"Calendar Discovery"}),e.jsx("p",{className:"text-xs text-muted-foreground mt-0.5",children:gs?"Loading...":he!=null&&he.enabled?"Running hourly at :30 · finds and enrolls new venue calendar URLs":"Off — hourly :30 discovery runs are paused"})]}),e.jsxs("div",{className:"flex items-center gap-2 shrink-0",children:[e.jsx("span",{className:`text-xs font-medium ${he!=null&&he.enabled?"text-green-600 dark:text-green-400":"text-amber-600 dark:text-amber-400"}`,children:gs?"…":he!=null&&he.enabled?"ON":"OFF"}),e.jsx(ht,{id:"calendar-discovery-toggle",checked:(he==null?void 0:he.enabled)??!0,onCheckedChange:t=>aa.mutate(t),disabled:gs||aa.isPending,"data-testid":"switch-calendar-discovery-toggle"})]})]})})}),e.jsx(w,{className:d!=null&&d.circuitBreaker.active||((d==null?void 0:d.overdueCount)??0)>=50?"border-red-400 dark:border-red-700":((d==null?void 0:d.overdueCount)??0)>=20?"border-amber-400 dark:border-amber-600":"border-slate-200 dark:border-slate-700",children:e.jsx(N,{className:"pt-4 pb-4",children:e.jsxs("div",{className:"flex items-center justify-between gap-4 flex-wrap",children:[e.jsxs("div",{children:[e.jsxs("p",{className:"text-sm font-semibold flex items-center gap-1.5",children:[d!=null&&d.circuitBreaker.active?e.jsx(Ls,{className:"h-4 w-4 text-red-500"}):e.jsx(Ra,{className:"h-4 w-4 text-green-500"}),"Entity Scraper (3×/day)"]}),e.jsx("p",{className:"text-xs text-muted-foreground mt-0.5",children:Ns?"Loading...":d!=null&&d.circuitBreaker.active?"Circuit breaker TRIPPED — scraping paused":`${(d==null?void 0:d.totalEnabledSchedules)??0} schedules · batch ${(d==null?void 0:d.batchSize)??60} · next run ${d!=null&&d.nextRunAt?Le(new Date(d.nextRunAt),{addSuffix:!0}):"soon"}`})]}),e.jsxs("div",{className:"flex items-center gap-4 text-sm",children:[e.jsxs("div",{className:"text-center",children:[e.jsx("p",{className:`font-semibold tabular-nums ${((d==null?void 0:d.overdueCount)??0)>=50?"text-red-600 dark:text-red-400":((d==null?void 0:d.overdueCount)??0)>=20?"text-amber-600 dark:text-amber-400":"text-muted-foreground"}`,children:(d==null?void 0:d.overdueCount)??"—"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"overdue"})]}),e.jsxs("div",{className:"text-center",children:[e.jsx("p",{className:"font-semibold tabular-nums",children:(d==null?void 0:d.processedToday)??"—"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"done today"})]}),e.jsx("button",{onClick:()=>ia(),className:"text-xs text-muted-foreground hover:text-foreground underline underline-offset-2","data-testid":"btn-refresh-scraper-health-activation",children:"refresh"})]})]})})}),e.jsx(w,{className:"border-blue-400 dark:border-blue-700",children:e.jsx(N,{className:"pt-4 pb-4",children:e.jsx("div",{className:"flex items-start justify-between gap-4",children:e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"text-sm font-semibold mb-1",children:"Venue Discovery Sources"}),e.jsxs("div",{className:"flex flex-wrap gap-2 mb-1.5",children:[e.jsxs("span",{className:"inline-flex items-center gap-1 text-xs font-medium px-2 py-0.5 rounded-full bg-blue-100 dark:bg-blue-900 text-blue-700 dark:text-blue-300","data-testid":"badge-osm-primary",children:[e.jsx("span",{className:"w-1.5 h-1.5 rounded-full bg-blue-500 inline-block"}),"OSM / Overpass — Primary (free, no quota)"]}),e.jsxs("span",{className:`inline-flex items-center gap-1 text-xs font-medium px-2 py-0.5 rounded-full ${(k==null?void 0:k.enabled)!==!1?"bg-green-100 dark:bg-green-900 text-green-700 dark:text-green-300":"bg-amber-100 dar
16k:bg-amber-900 text-amber-700 dark:text-amber-300"}`,"data-testid":"badge-gp-enrichment",children:[e.jsx("span",{className:`w-1.5 h-1.5 rounded-full inline-block ${(k==null?void 0:k.enabled)!==!1?"bg-green-500":"bg-amber-500"}`}),"Google Places — Enrichment only ",(k==null?void 0:k.enabled)!==!1?"(ON)":"(OFF)"]})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Venue discovery uses OpenStreetMap/Overpass (free). Google Places supplements with Maps URLs, phone numbers, and website lookup when enabled."})]})})})}),e.jsx(w,{className:(k==null?void 0:k.enabled)!==!1?"border-green-400 dark:border-green-700":"border-amber-400 dark:border-amber-600",children:e.jsx(N,{className:"pt-4 pb-4",children:e.jsxs("div",{className:"flex items-center justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx(ue,{htmlFor:"google-places-toggle",className:"text-sm font-semibold",children:"Google Places API"}),e.jsx("p",{className:"text-xs text-muted-foreground mt-0.5",children:js?"Loading...":(k==null?void 0:k.enabled)!==!1?"Active — supplemental enrichment (Maps URLs, phone, website) when OSM lacks data":"Off — Google Places enrichment paused; OSM-only venue discovery still runs"})]}),e.jsxs("div",{className:"flex items-center gap-2 shrink-0",children:[e.jsx("span",{className:`text-xs font-medium ${(k==null?void 0:k.enabled)!==!1?"text-green-600 dark:text-green-400":"text-amber-600 dark:text-amber-400"}`,children:js?"…":(k==null?void 0:k.enabled)!==!1?"ON":"OFF"}),e.jsx(ht,{id:"google-places-toggle",checked:(k==null?void 0:k.enabled)!==!1,onCheckedChange:t=>sa.mutate(t),disabled:js||sa.isPending,"data-testid":"switch-google-places-toggle"})]})]})})}),kn?e.jsx("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-4",children:[...Array(4)].map((t,r)=>e.jsx(w,{children:e.jsx(N,{className:"pt-4",children:e.jsx("div",{className:"h-12 bg-muted animate-pulse rounded"})})},r))}):_?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid grid-cols-2 lg:grid-cols-3 gap-3",children:[e.jsx(w,{"data-testid":"stat-venues-eligible",children:e.jsx(N,{className:"pt-4 pb-4",children:e.jsx(ye,{label:"Eligible Venues",value:_.venues.total,sub:`${_.venues.withSchedule} scheduled · ${_.venues.withoutSchedule} pending`})})}),e.jsx(w,{"data-testid":"stat-artists-eligible",children:e.jsx(N,{className:"pt-4 pb-4",children:e.jsx(ye,{label:"Eligible Artists",value:_.artists.total,sub:`${_.artists.withSchedule} scheduled · ${_.artists.withoutSchedule} pending`})})}),e.jsx(w,{"data-testid":"stat-promoters-eligible",children:e.jsx(N,{className:"pt-4 pb-4",children:e.jsx(ye,{label:"Eligible Promoters",value:((xa=_.promoters)==null?void 0:xa.total)??0,sub:`${((ha=_.promoters)==null?void 0:ha.withSchedule)??0} scheduled · ${((pa=_.promoters)==null?void 0:pa.withoutSchedule)??0} pending`})})})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsx(w,{"data-testid":"stat-active-schedules",children:e.jsx(N,{className:"pt-4 pb-4",children:e.jsx(ye,{label:"Active Schedules",value:_.schedules.total,sub:`${_.schedules.ranThisMonth} ran this month · ${_.schedules.neverRan} never ran`})})}),e.jsx(w,{"data-testid":"stat-circuit-breaker",className:(_.schedules.circuitBreakerTripped??0)>0?"border-destructive":"",children:e.jsx(N,{className:"pt-4 pb-4",children:e.jsx(ye,{label:"Circuit-Breaker Paused",value:_.schedules.circuitBreakerTripped??0,sub:"auto-disabled after 5+ consecutive failures",color:(_.schedules.circuitBreakerTripped??0)>0?"text-destructive":""})})})]}),e.jsxs(w,{children:[e.jsx(z,{className:"pb-2",children:e.jsxs(K,{className:"text-sm flex items-center gap-2",children:[e.jsx(lt,{className:"h-4 w-4"}),"Schedule Coverage"]})}),e.jsx(N,{className:"space-y-3",children:[{label:"Venues",d:_.venues,testId:"venue"},{label:"Artists",d:_.artists,testId:"artist"},...(((fa=_.promoters)==null?void 0:fa.total)??0)>0?[{label:"Promoters",d:_.promoters,testId:"promoter"}]:[]].map(({label:t,d:r,testId:g})=>e.jsxs("div",{children:[e.jsxs("div",{className:"flex justify-between text-xs text-muted-foreground mb-1",children:[e.jsx("span",{children:t}),e.jsxs("span",{className:"flex gap-2",children:[e.jsxs("span",{children:[r.withSchedule," / ",r.total," scheduled"]}),(r.inviteEligible??0)>0&&e.jsxs("span",{className:"text-blue-500 dark:text-blue-400",children:["· ",r.inviteEligible," invite-eligible"]})]})]}
16),e.jsx(Rs,{value:r.total?r.withSchedule/r.total*100:0,className:"h-2","data-testid":`progress-${g}-coverage`})]},g))})]}),oe&&e.jsxs(w,{className:oe.status==="paused"?"border-destructive":oe.status==="at-risk"?"border-amber-400 dark:border-amber-600":"border-green-400 dark:border-green-700",children:[e.jsx(z,{className:"pb-2",children:e.jsxs(K,{className:"text-sm flex items-center gap-2",children:[e.jsx(Ds,{className:"h-4 w-4"}),"Monthly Batch Progress",e.jsx(ce,{variant:oe.status==="paused"?"destructive":oe.status==="at-risk"?"secondary":"default",className:"ml-auto capitalize",children:oe.status==="on-track"?"✓ On Track":oe.status==="at-risk"?"⚠ At Risk":"⏸ Paused"})]})}),e.jsxs(N,{className:"space-y-2",children:[e.jsxs("div",{className:"flex justify-between text-xs text-muted-foreground mb-1",children:[e.jsxs("span",{children:[oe.ranThisMonth," / ",oe.total," schedules ran this month"]}),e.jsxs("span",{children:[oe.daysLeft,"d left in month"]})]}),e.jsx(Rs,{value:oe.pct,className:`h-2 ${oe.status==="paused"?"[&>div]:bg-destructive":oe.status==="at-risk"?"[&>div]:bg-amber-500":"[&>div]:bg-green-500"}`,"data-testid":"progress-batch-window"}),oe.inWindow?e.jsxs("p",{className:"text-xs text-muted-foreground",children:["Currently in D-7 batch window (started ",Xe(oe.batchWindowStart,"MMM d"),")"]}):e.jsxs("p",{className:"text-xs text-muted-foreground",children:["Batch window opens ",Xe(oe.batchWindowStart,"MMM d")," · ",oe.daysLeft,"d remaining this month"]})]})]}),e.jsx(w,{className:"bg-amber-50 dark:bg-amber-950/20 border-amber-200 dark:border-amber-800",children:e.jsx(N,{className:"pt-4 pb-4",children:e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx(Da,{className:"h-5 w-5 text-amber-600 shrink-0 mt-0.5"}),e.jsxs("div",{className:"text-sm",children:[e.jsx("p",{className:"font-medium text-amber-800 dark:text-amber-200",children:"Estimated activation load"}),e.jsxs("p",{className:"text-amber-700 dark:text-amber-300 mt-0.5",children:["Activating all unscheduled entities will add approximately"," ",e.jsx("strong",{children:_.estimatedLoad.browserlessSessions})," Browserless sessions and ~",e.jsxs("strong",{children:["$",_.estimatedLoad.estimatedAiCostUsd]})," in AI costs over the 7-day stagger window."]})]})]})})})]}):null,e.jsxs(w,{children:[e.jsxs(z,{className:"pb-2",children:[e.jsx(K,{className:"text-sm",children:"Actions"}),e.jsx(Fe,{children:"Bulk operations for schedule management"})]}),e.jsxs(N,{className:"flex flex-col sm:flex-row flex-wrap gap-3",children:[e.jsxs(U,{onClick:()=>qe.mutate("all"),disabled:qe.isPending,"data-testid":"button-bulk-activate-all",className:"min-h-[44px]",children:[qe.isPending?e.jsx(ne,{className:"h-4 w-4 mr-2 animate-spin"}):e.jsx(Jt,{className:"h-4 w-4 mr-2"}),"Activate All Unscheduled"]}),e.jsxs(U,{variant:"outline",onClick:()=>qe.mutate("venue"),disabled:qe.isPending,"data-testid":"button-bulk-activate-venues",className:"min-h-[44px]",children:[e.jsx(Ua,{className:"h-4 w-4 mr-2"}),"Venues Only"]}),e.jsxs(U,{variant:"outline",onClick:()=>qe.mutate("artist"),disabled:qe.isPending,"data-testid":"button-bulk-activate-artists",className:"min-h-[44px]",children:[e.jsx(xt,{className:"h-4 w-4 mr-2"}),"Artists Only"]}),e.jsxs(U,{variant:"outline",onClick:()=>qe.mutate("promoter"),disabled:qe.isPending,"data-testid":"button-bulk-activate-promoters",className:"min-h-[44px]",children:[e.jsx(Ua,{className:"h-4 w-4 mr-2"}),"Promoters Only"]}),e.jsxs(U,{variant:"outline",onClick:()=>xs.mutate(),disabled:xs.isPending,"data-testid":"button-enable-email-invites",className:"min-h-[44px]",children:[xs.isPending?e.jsx(ne,{className:"h-4 w-4 mr-2 animate-spin"}):e.jsx(Ts,{className:"h-4 w-4 mr-2"}),"Enable All Email Invites"]}),e.jsxs(U,{variant:"outline",onClick:()=>hs.mutate(),disabled:hs.isPending,"data-testid":"button-repair-schedules",className:"min-h-[44px]",children:[hs.isPending?e.jsx(ne,{className:"h-4 w-4 mr-2 animate-spin"}):e.jsx(Qn,{className:"h-4 w-4 mr-2"}),"Repair Null Next-Run Dates"]}),e.jsxs(U,{variant:"outline",onClick:()=>ps.mutate(),disabled:ps.isPending,"data-testid":"button-cleanup-dead-urls",className:"min-h-[44px]",children:[ps.isPending?e.jsx(ne,{className:"h-4 w-4 mr-2 animate-spin"}):e.jsx(Ht,{className:"h-4 w-4 mr-2"}),"Clean Up Dead URLs"]}),e.jsxs(U,{variant:"ghost",onClick:()=>{Sn(),An(),En(),ra()},"data-testid":"button-refresh-all",className:"min-h-[44px]",children:[e.jsx(ne,{className:"h-4 w-4 mr-2"}),"Refresh"]})]})]}),e.jsxs(w,{children:[e.jsxs(z,{children:[e.jsxs(K,{className:"text-base flex items-center gap-2",children:[e.jsx(lt,{className:"h-4 w-4 text-blue-500"}),"OSM Website URL Tools"]}),e.jsx(Fe,{children:"Backfill missing website URLs for OSM-only venues (those with an OSM ID but no website_url or events_page_url) by querying the Overpass API. Use the city test to preview OSM website tag coverage before running the full backfill."})]}),e.jsxs(N,{className:"space-y-6",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(ue,{className:"text-sm font-medium",children:"City URL Coverage Test (read-only)"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Run a live OSM discovery for a city and see what % of venues have a website tag, without writing anything to the DB."}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs(Ae,{value:$,onValueChange:L,children:[e.jsx(Ce,{className:"max-w-xs","data-testid":"select-osm-test-city",children:e.jsx(Ee,{placeholder:"Select a city…"})}),e.jsx(Oe,{children:(St??[]).map(t=>e.jsxs(D,{value:t.slug,children:[t.name,t.state?`, ${t.state}`:""]},t.slug))})]}),e.jsxs(U,{variant:"outline",onClick:()=>bs.mutate($),disabled:!$||bs.isPending,"data-testid":"button-osm-city-test",className:"min-h-[44px]",children:[bs.isPending?e.jsx(ne,{className:"h-4 w-4 mr-2 animate-spin"}):e.jsx(xt,{className:"h-4 w-4 mr-2"}),"Run Test"]})]}),Y&&e.jsxs("div",{className:"mt-2 p-3 rounded-lg bg-blue-50 dark:bg-blue-950 border border-blue-200 dark:border-blue-800 text-sm space-y-1",children:[e.jsx("p",{className:"font-medium text-blue-800 dark:text-blue-200",children:Y.city}),e.jsxs("div",{className:"grid grid-cols-2 gap-x-4 gap-y-1 text-blue-700 dark:text-blue-300",children:[e.jsx("span",{children:"OSM venues found:"}),e.jsx("span",{className:"font-mono",children:Y.totalFound}),e.jsx("span",{children:"With website tag:"}),e.jsxs("span",{className:"font-mono",children:[Y.withWebsiteTag," (",Y.websiteCoverage,"%)"]}),e.jsx("span",{children:"Already in DB:"}),e.jsx("span",{className:"font-mono",children:Y.alreadyInDb}),e.jsx("span",{children:"Net-new:"}),e.jsx("span",{className:"font-mono",children:Y.netNew})]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(ue,{className:"text-sm font-medium",children:"OSM Website URL Backfill"}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:["Queries Overpass for the ",e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"website"}),", ",e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"contact:website"}),", or ",e.jsx("code",{className:"text-xs bg-muted px-1 rounded",children:"url"}),' tag for each OSM-only venue with no URL. Processes 25 venues per batch (~28 sec). Click "Run Next Batch" to continue until all are done.']}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs(Ae,{value:T,onValueChange:t=>{W(t),B(null),re(null)},children:[e.jsx(Ce,{className:"max-w-xs","data-testid":"select-osm-backfill-city",children:e.jsx(Ee,{placeholder:"Select city or all…"})}),e.jsxs(Oe,{children:[e.jsx(D,{value:"all",children:"All cities (global)"}),(St??[]).map(t=>e.jsxs(D,{value:t.slug,children:[t.name,t.state?`, ${t.state}`:""]},t.slug))]})]}),e.jsxs(U,{variant:"outline",onClick:()=>zt.mutate(T==="all"?void 0:T),disabled:zt.isPending,"data-testid":"button-osm-backfill",className:"min-h-[44px]",children:[zt.isPending?e.jsx(ne,{className:"h-4 w-4 mr-2 animate-spin"}):e.jsx(Jt,{className:"h-4 w-4 mr-2"}
16),zt.isPending?"Running batch…":A&&A.remaining>0?`Run Next Batch (${A.remaining} left)`:"Run Backfill"]})]}),A&&e.jsxs("div",{className:"mt-2 p-3 rounded-lg bg-green-50 dark:bg-green-950 border border-green-200 dark:border-green-800 text-sm space-y-2",children:[e.jsx("p",{className:"font-medium text-green-800 dark:text-green-200 text-xs uppercase tracking-wide",children:"Last batch"}),e.jsxs("div",{className:"grid grid-cols-2 gap-x-4 gap-y-1 text-green-700 dark:text-green-300",children:[e.jsx("span",{children:"Checked:"}),e.jsx("span",{className:"font-mono",children:A.checked}),e.jsx("span",{children:"URLs found:"}),e.jsx("span",{className:"font-mono",children:A.found}),e.jsx("span",{children:"Updated:"}),e.jsx("span",{className:"font-mono font-semibold",children:A.updated}),A.remaining>0&&e.jsxs(e.Fragment,{children:[e.jsx("span",{children:"Remaining:"}),e.jsx("span",{className:"font-mono text-amber-600 dark:text-amber-400",children:A.remaining})]})]}),Q&&Q.checked>A.checked&&e.jsxs(e.Fragment,{children:[e.jsx("p",{className:"font-medium text-green-800 dark:text-green-200 text-xs uppercase tracking-wide pt-1 border-t border-green-200 dark:border-green-800",children:"Running total"}),e.jsxs("div",{className:"grid grid-cols-2 gap-x-4 gap-y-1 text-green-700 dark:text-green-300",children:[e.jsx("span",{children:"Total checked:"}),e.jsx("span",{className:"font-mono",children:Q.checked}),e.jsx("span",{children:"Total updated:"}),e.jsx("span",{className:"font-mono font-semibold",children:Q.updated})]})]}),A.remaining===0&&e.jsx("p",{className:"text-green-700 dark:text-green-300 font-medium",children:"✓ All done!"})]})]})]})]}),e.jsxs(w,{className:(k==null?void 0:k.enabled)===!1?"border-amber-400 dark:border-amber-600 opacity-75":"",children:[e.jsxs(z,{children:[e.jsxs(K,{className:"text-base flex items-center gap-2",children:[e.jsx(xt,{className:"h-4 w-4 text-green-500"}),"Google Places Enrichment",(k==null?void 0:k.enabled)===!1&&e.jsx(ce,{variant:"secondary",className:"ml-auto text-amber-700 dark:text-amber-300 bg-amber-100 dark:bg-amber-900",children:"GP Off"})]}),e.jsx(Fe,{children:'Enrich OSM-only venues (no website URL) using Google Places. Phase 1 "Sweep" runs 5 category Text Searches for the city and fuzzy-matches results against known venues — one GP call covers up to 20 venues. Phase 2 "Individual Lookup" finds venues the sweep missed, one by one.'})]}),e.jsxs(N,{className:"space-y-6",children:[(k==null?void 0:k.enabled)===!1&&e.jsxs("div",{className:"p-3 rounded-lg bg-amber-50 dark:bg-amber-950 border border-amber-200 dark:border-amber-800 text-sm text-amber-800 dark:text-amber-200 flex items-center gap-2",children:[e.jsx(Da,{className:"h-4 w-4 shrink-0"}),"Google Places is currently disabled. Enable it using the toggle above to use enrichment."]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(ue,{className:"text-sm font-medium",children:"City"}),e.jsxs(Ae,{value:nt,onValueChange:t=>{Nn(t),Ys(null),Zs(null),Xs(null),Js(null)},children:[e.jsx(Ce,{className:"max-w-xs","data-testid":"select-gp-enrich-city",children:e.jsx(Ee,{placeholder:"Select a city…"})}),e.jsx(Oe,{children:(St??[]).map(t=>e.jsxs(D,{value:t.slug,children:[t.name,t.state?`, ${t.state}`:""]},t.slug))})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(ue,{className:"text-sm font-medium",children:"Phase 1 — Category Sweep"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Runs 5 category Text Searches (bars, restaurants, nightclubs, music venues, breweries) using Places API v1 with a field mask that includes website and phone — so all data is returned in the same call with no extra Place Details requests. Most cost-efficient — run this first."}),e.jsx(Et,{children:e.jsxs(Ot,{children:[e.jsx(Tt,{asChild:!0,children:e.jsx("span",{className:"inline-block",children:e.jsxs(U,{variant:"outline",onClick:()=>Kt.mutate({citySlug:nt}),disabled:!nt||Kt.isPending||(k==null?void 0:k.enabled)===!1,"data-testid":"button-gp-sweep",className:"min-h-[44px]",children:[Kt.isPending?e.jsx(ne,{className:"h-4 w-4 mr-2 animate-spin"}):e.jsx(lt,{className:"h-4 w-4 mr-2"}),Kt.isPending?"Running sweep…":"Run Sweep"]})})}),((k==null?void 0:k.enabled)===!1||!nt)&&e.jsx(Rt,{children:(k==null?void 0:k.enabled)===!1?"Google Places is disabled — enable it with the toggle above":"Select a city first"})]})}),_e&&e.jsxs("div",{className:"mt-2 p-3 rounded-lg bg-green-50 dark:bg-green-950 border border-green-200 dark:border-green-800 text-sm space-y-2",children:[e.jsx("p",{className:"font-medium text-green-800 dark:text-green-200 text-xs uppercase tracking-wide",children:"Sweep result"}),e.jsxs("div",{className:"grid grid-cols-2 gap-x-4 gap-y-1 text-green-700 dark:text-green-300",children:[e.jsx("span",{children:"GP results swept:"}),e.jsx("span",{className:"font-mono",children:_e.swept}),e.jsx("span",{children:"Venues matched:"}),e.jsx("span",{className:"font-mono",children:_e.matched}),e.jsx("span",{children:"Website URLs added:"}),e.jsx("span",{className:"font-mono font-semibold",children:_e.websiteAdded}),e.jsx("span",{children:"Place IDs added:"}),e.jsx("span",{className:"font-mono",children:_e.placeIdAdded}),_e.remaining>0&&e.jsxs(e.Fragment,{children:[e.jsx("span",{children:"Still unmatched:"}
16),e.jsx("span",{className:"font-mono text-amber-600 dark:text-amber-400",children:_e.remaining})]})]}),ct&&ct.swept>_e.swept&&e.jsxs(e.Fragment,{children:[e.jsx("p",{className:"font-medium text-green-800 dark:text-green-200 text-xs uppercase tracking-wide pt-1 border-t border-green-200 dark:border-green-800",children:"Cumulative totals (all runs)"}),e.jsxs("div",{className:"grid grid-cols-2 gap-x-4 gap-y-1 text-green-700 dark:text-green-300",children:[e.jsx("span",{children:"Total GP results:"}),e.jsx("span",{className:"font-mono",children:ct.swept}),e.jsx("span",{children:"Total venues matched:"}),e.jsx("span",{className:"font-mono",children:ct.matched}),e.jsx("span",{children:"Total websites added:"}),e.jsx("span",{className:"font-mono font-semibold",children:ct.websiteAdded}),e.jsx("span",{children:"Total place IDs added:"}),e.jsx("span",{className:"font-mono",children:ct.placeIdAdded})]})]}),_e.remaining===0&&e.jsx("p",{className:"text-green-700 dark:text-green-300 font-medium",children:"✓ All matched!"})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(ue,{className:"text-sm font-medium",children:"Phase 2 — Individual Lookup"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"For venues the sweep didn't match, searches Google Places individually by venue name. Uses 2 GP calls per venue (Text Search + Place Details). Run this after the sweep to catch remaining venues."}),e.jsxs("div",{className:"flex gap-2 items-center flex-wrap",children:[e.jsxs(Ae,{value:Qs,onValueChange:wn,children:[e.jsx(Ce,{className:"w-32","data-testid":"select-gp-individual-limit",children:e.jsx(Ee,{})}),e.jsxs(Oe,{children:[e.jsx(D,{value:"10",children:"10 venues"}),e.jsx(D,{value:"25",children:"25 venues"}),e.jsx(D,{value:"50",children:"50 venues"})]})]}),e.jsx(Et,{children:e.jsxs(Ot,{children:[e.jsx(Tt,{asChild:!0,children:e.jsx("span",{className:"inline-block",children:e.jsxs(U,{variant:"outline",onClick:()=>Ut.mutate({citySlug:nt,limit:Number(Qs)}),disabled:!nt||Ut.isPending||(k==null?void 0:k.enabled)===!1,"data-testid":"button-gp-individual",className:"min-h-[44px]",children:[Ut.isPending?e.jsx(ne,{className:"h-4 w-4 mr-2 animate-spin"}):e.jsx(Jt,{className:"h-4 w-4 mr-2"}),Ut.isPending?"Looking up…":Ne&&Ne.remaining>0?`Run Next Batch (${Ne.remaining} left)`:"Run Individual Lookup"]})})}),((k==null?void 0:k.enabled)===!1||!nt)&&e.jsx(Rt,{children:(k==null?void 0:k.enabled)===!1?"Google Places is disabled — enable it with the toggle above":"Select a city first"})]})})]}),Ne&&e.jsxs("div",{className:"mt-2 p-3 rounded-lg bg-blue-50 dark:bg-blue-950 border border-blue-200 dark:border-blue-800 text-sm space-y-2",children:[e.jsx("p",{className:"font-medium text-blue-800 dark:text-blue-200 text-xs uppercase tracking-wide",children:"Individual lookup result"}),e.jsxs("div",{className:"grid grid-cols-2 gap-x-4 gap-y-1 text-blue-700 dark:text-blue-300",children:[e.jsx("span",{children:"Venues searched:"}),e.jsx("span",{className:"font-mono",children:Ne.swept}),e.jsx("span",{children:"Matches found:"}),e.jsx("span",{className:"font-mono",children:Ne.matched}),e.jsx("span",{children:"Website URLs added:"}),e.jsx("span",{className:"font-mono font-semibold",children:Ne.websiteAdded}),e.jsx("span",{children:"Place IDs added:"}),e.jsx("span",{className:"font-mono",children:Ne.placeIdAdded}),Ne.remaining>0&&e.jsxs(e.Fragment,{children:[e.jsx("span",{children:"Remaining:"}),e.jsx("span",{className:"font-mono text-amber-600 dark:text-amber-400",children:Ne.remaining})]})]}),ot&&ot.swept>Ne.swept&&e.jsxs(e.Fragment,{children:[e.jsx("p",{className:"font-medium text-blue-800 dark:text-blue-200 text-xs uppercase tracking-wide pt-1 border-t border-blue-200 dark:border-blue-800",children:"Cumulative totals (all batches)"}),e.jsxs("div",{className:"grid grid-cols-2 gap-x-4 gap-y-1 text-blue-700 dark:text-blue-300",children:[e.jsx("span",{children:"Total searched:"}),e.jsx("span",{className:"font-mono",children:ot.swept}),e.jsx("span",{children:"Total matched:"}),e.jsx("span",{className:"font-mono",children:ot.matched}),e.jsx("span",{children:"Total websites added:"}),e.jsx("span",{className:"font-mono font-semibold",children:ot.websiteAdded}),e.jsx("span",{children:"Total place IDs added:"}),e.jsx("span",{className:"font-mono",children:ot.placeIdAdded})]})]}),Ne.remaining===0&&e.jsx("p",{className:"text-blue-700 dark:text-blue-300 font-medium",children:"✓ All done!"})]})]})]})]}),e.jsxs(w,{children:[e.jsxs(z,{children:[e.jsxs(K,{className:"text-base flex items-center gap-2",children:[e.jsx(Ds,{className:"h-4 w-4 text-primary"}),"City Scraping Schedules",Pt&&e.jsxs(ce,{variant:"secondary",className:"ml-auto",children:[Pt.total," cities"]})]}),e.jsx(Fe,{children:"Set how often each city's Perplexity discovery pass runs. Monthly is recommended — the Entity Scraper (3×/day) keeps known venues fresh between city runs."}),e.jsxs("div",{className:"flex items-center gap-2 pt-1",children:[e.jsx("span",{className:"text-sm text-muted-foreground",children:"Set all cities to:"}),e.jsxs(Ae,{value:oa,onValueChange:In,children:[e.jsx(Ce,{className:"w-36 h-8 text-sm","data-testid":"select-bulk-frequency",children:e.jsx(Ee,{})}),e.jsxs(Oe,{children:[e.jsx(D,{value:"weekly",children:"Weekly"}),e.jsx(D,{value:"twice_monthly",children:"Twice monthly"}),e.jsx(D,{value:"monthly",children:"Monthly"}),e.jsx(D,{value:"manual",children:"Manual only"})]})]}),e.jsx(U,{size:"sm",variant:"outline","data-testid":"button-bulk-set-frequency",disabled:As.isPending,onClick:()=>
16As.mutate(oa),children:As.isPending?"Updating…":"Apply to all"})]})]}),e.jsxs(N,{children:[e.jsx($e,{className:"h-[400px]",children:e.jsxs(Te,{children:[e.jsx(Re,{children:e.jsxs(V,{children:[e.jsx(h,{children:"City"}),e.jsx(h,{children:"Country"}),e.jsx(h,{children:"Frequency"}),e.jsx(h,{children:"Next Run"}),e.jsx(h,{children:"Last Scraped"})]})}),e.jsx(De,{children:Pt?Pt.schedules.length===0?e.jsx(V,{children:e.jsx(m,{colSpan:5,className:"text-center text-muted-foreground py-8",children:"No city schedules found"})}):Pt.schedules.map(t=>e.jsxs(V,{"data-testid":`row-city-schedule-${t.id}`,children:[e.jsxs(m,{className:"font-medium",children:[t.city,t.state?`, ${t.state}`:"",!t.isActive&&e.jsx(ce,{variant:"outline",className:"ml-2 text-xs",children:"Inactive"})]}),e.jsx(m,{className:"text-muted-foreground text-sm",children:t.country}),e.jsx(m,{children:e.jsxs(Ae,{value:t.frequency,onValueChange:r=>ca.mutate({id:t.id,frequency:r}),disabled:ca.isPending,children:[e.jsx(Ce,{className:"w-40 h-8 text-sm","data-testid":`select-frequency-${t.id}`,children:e.jsx(Ee,{})}),e.jsxs(Oe,{children:[e.jsx(D,{value:"hourly",children:"Hourly"}),e.jsx(D,{value:"daily",children:"Daily"}),e.jsx(D,{value:"every_2_days",children:"Every 2 days"}),e.jsx(D,{value:"every_3_days",children:"Every 3 days"}),e.jsx(D,{value:"weekly",children:"Weekly"}),e.jsx(D,{value:"twice_monthly",children:"Twice monthly"}),e.jsx(D,{value:"monthly",children:"Monthly"}),e.jsx(D,{value:"manual",children:"Manual only"})]})]})}),e.jsx(m,{className:"text-sm text-muted-foreground",children:t.nextScheduledRun?new Date(t.nextScheduledRun)<=new Date?e.jsx("span",{className:"text-amber-600 dark:text-amber-400 font-medium",children:"Due now"}):Le(new Date(t.nextScheduledRun),{addSuffix:!0}):"—"}),e.jsx(m,{className:"text-sm text-muted-foreground",children:t.lastScrapedAt?Le(new Date(t.lastScrapedAt),{addSuffix:!0}):"Never"})]},t.id)):e.jsx(V,{children:e.jsx(m,{colSpan:5,className:"text-center text-muted-foreground py-8",children:"Loading…"})})})]})}),e.jsx("div",{className:"mt-2 flex justify-end",children:e.jsxs(U,{variant:"ghost",size:"sm",onClick:()=>Tn(),"data-testid":"button-refresh-city-schedules",children:[e.jsx(ne,{className:"h-3.5 w-3.5 mr-1.5"}),"Refresh"]})})]})]})]}),e.jsx(ft,{value:"analytics",className:"space-y-4",children:Pn?e.jsx("div",{className:"h-40 bg-muted animate-pulse rounded-lg"}):Pe?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-3",children:[e.jsx(w,{children:e.jsx(N,{className:"pt-4 pb-4",children:e.jsx(ye,{label:"Total Scrapes",value:Pe.totalScrapes})})}),e.jsx(w,{children:e.jsx(N,{className:"pt-4 pb-4",children:e.jsx(ye,{label:"Success Rate",value:`${(Pe.successRate*100).toFixed(0)}%`,color:Pe.successRate>=.9?"text-green-600":Pe.successRate>=.7?"":"text-destructive"})})}),e.jsx(w,{children:e.jsx(N,{className:"pt-4 pb-4",children:e.jsx(ye,{label:"Avg Quality (w/ events)",value:Pe.avgQualityScore?`${Math.round(Pe.avgQualityScore)}%`:"—"})})}),e.jsx(w,{children:e.jsx(N,{className:"pt-4 pb-4",children:e.jsx(ye,{label:"AI Cost (30d)",value:`$${Number(Pe.totalAiCostUsd).toFixed(2)}`})})})]}),Pe.byEntityType&&Object.keys(Pe.byEntityType).length>0&&e.jsxs(w,{children:[e.jsx(z,{className:"pb-2",children:e.jsx(K,{className:"text-sm",children:"By Entity Type"})}),e.jsx(N,{children:e.jsx("div",{className:"flex flex-wrap gap-3",children:Object.entries(Pe.byEntityType).map(([t,r])=>e.jsxs("div",{className:"flex items-center gap-2 text-sm bg-muted rounded-md px-3 py-2",children:[e.jsx("span",{className:"font-medium capitalize",children:t}),e.jsxs("span",{className:"text-muted-foreground",children:[r.count," scrapes"]}),r.avgQuality>0&&e.jsxs(ce,{variant:"secondary",children:[Math.round(r.avgQuality),"% quality"]})]},t))})})]}),!On&&qt&&qt.problems.length>0&&e.jsxs(w,{className:"border-destructive",children:[e.jsxs(z,{className:"pb-2",children:[e.jsxs(K,{className:"text-sm flex items-center gap-2 text-destructive",children:[e.jsx(Ht,{className:"h-4 w-4"}),"Problem Entities (",qt.total,")"]}),e.jsx(Fe,{children:"Schedules with repeated failures or circuit-breaker pauses"})]}),e.jsx(N,{className:"p-0",children:e.jsx($e,{className:"max-h-[30vh]",children:e.jsxs(Te,{children:[e.jsx(Re,{children:e.jsxs(V,{children:[e.jsx(h,{children:"Entity"}),e.jsx(h,{children:"Failures"}),e.jsx(h,{className:"hidden md:table-cell",children:"Last Error"}),e.jsx(h,{children:"Status"})]})}),e.jsx(De,{children:qt.problems.map(t=>e.jsxs(V,{"data-testid":`row-problem-${t.id}`,children:[e.jsxs(m,{children:[e.jsx("div",{className:"font-medium text-sm",children:t.entityName}),e.jsx("div",{className:"text-xs text-muted-foreground capitalize",children:t.entityType})]}),e.jsx(m,{children:e.jsxs(ce,{variant:t.consecutiveFailures>=5?"destructive":"secondary",children:[t.consecutiveFailures," in a row"]})}),e.jsx(m,{className:"hidden md:table-cell text-xs text-muted-foreground max-w-[200px] truncate",children:t.lastRunError||"—"}),e.jsx(m,{children:t.circuitBreakerPausedAt?e.jsx(ce,{variant:"destructive",children:"Circuit tripped"}):t.enabled?e.jsx(ce,{variant:"secondary",children:"Active"}):e.jsx(ce,{variant:"outline",children:"Disabled"})})]},t.id))})]})})})]}),e.jsxs(w,{children:[e.jsxs(z,{className:"pb-2",children:[e.jsx(K,{className:"text-sm",children:"Scrape History (last 30 days)"}),e.jsxs("div",{className:"grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-6 gap-2 mt-2",children:[e.jsxs(Ae,{value:l,onValueChange:t=>c(t),children:[e.jsx(Ce,{className:"h-8 text-xs","data-testid":"select-entity-type-filter",children:e.jsx(Ee,{placeholder:"All types"})}),e.jsxs(Oe,{children:[e.jsx(D,{value:"all",children:"All types"}),e.jsx(D,{value:"venue",children:"Venues"}),e.jsx(D,{value:"artist",children:"Artists"}),e.jsx(D,{value:"promoter",children:"Promoters"})]})]}),e.jsx(Ue,{className:"h-8 text-xs",placeholder:"City slug or entity name",value:o,onChange:t=>y(t.target.value),"data-testid":"input-city-filter"}),e.jsx(Ue,{type:"date",className:"h-8 text-xs",placeholder:"From date",value:p,onChange:t=>j(t.target.value),"data-testid":"input-date-from"}),e.jsx(Ue,{type:"date",className:"h-8 text-xs",placeholder:"To date",value:x,onChange:t=>b(t.target.value),"data-testid":"input-date-to"}),e.jsx(Ue,{type:"number",className:"h-8 text-xs",placeholder:"Quality min %",min:0,max:100,value:f,onChange:t=>C(t.target.value),"data-testid":"input-quality-min"}),e.jsx(Ue,{type:"number",className:"h-8 text-xs",placeholder:"Quality max %",min:0,max:100,value:O,onChange:t=>v(t.target.value),"data-testid":"input-quality-max"})]}),Zt.length!==(((ja=xe==null?void 0:xe.history)==null?void 0:ja.length)??0)&&e.jsxs("p",{className:"text-xs text-muted-foreground mt-1",children:["Showing ",Zt.length," of ",((ga=xe==null?void 0:xe.history)==null?void 0:ga.length)??0," rows"]})]}),e.jsx(N,{className:"p-0",children:e.jsx($e,{className:"h-[50vh]",children:e.jsxs(Te,{children:[e.jsx(Re,{className:"sticky top-0 bg-background z-10",children:e.jsxs(V,{children:[e.jsx(h,{children:"Entity"}),e.jsx(h,{className:"hidden md:table-cell",children:"Fetch"}),e.jsx(h,{className:"hidden md:table-cell",children:"Parser"}),e.jsx(h,{children:"Events"}),e.jsx(h,{className:"hidden lg:table-cell",children:"Quality"}),e.jsx(h,{children:"Status"}),e.jsx(h,{className:"hidden lg:table-cell",children:"Error"}),e.jsx(h,{className:"hidden md:table-cell",children:"When"})]})}),e.jsx(De,{children:Zt.length===0?e.jsx(V,{children:e.jsx(m,{colSpan:8,className:"text-center text-muted-foreground py-8",children:"No scrape history found"})}):Zt.map(t=>e.jsxs(V,{"data-testid":`row-history-${t.id}`,children:[e.jsxs(m,{children:[e.jsx("div",{className:"font-medium text-sm truncate max-w-[160px]",children:t.entityName}),e.jsxs("div",{className:"text-xs text-muted-foreground capitalize",children:[t.entityType,t.citySlug?` · ${t.citySlug}`:""]})]}),e.jsxs(m,{className:"hidden md:table-cell text-xs text-muted-foreground",children:[e.jsx("div",{children:t.fetchMethod??"—"}),t.fetchDurationMs!=null&&e.jsxs("div",{className:"text-muted-foreground
16/60",children:[t.fetchDurationMs,"ms"]})]}),e.jsx(m,{className:"hidden md:table-cell text-xs text-muted-foreground",children:t.parserUsed??"—"}),e.jsxs(m,{className:"text-sm tabular-nums",children:[e.jsx("span",{className:"font-medium",children:t.eventsImported}),e.jsxs("span",{className:"text-muted-foreground",children:["/",t.eventsFound]})]}),e.jsx(m,{className:"hidden lg:table-cell text-sm",children:t.extractionQualityScore!=null?`${t.extractionQualityScore}%`:"—"}),e.jsx(m,{children:e.jsx(Ha,{status:t.status})}),e.jsx(m,{className:"hidden lg:table-cell text-xs text-muted-foreground max-w-[140px]",children:e.jsx("span",{className:"truncate block",title:t.errorMessage??void 0,children:t.errorMessage??"—"})}),e.jsx(m,{className:"hidden md:table-cell text-xs text-muted-foreground",children:t.scrapedAt?Le(new Date(t.scrapedAt),{addSuffix:!0}):"—"})]},t.id))})]})})})]})]}):e.jsx("div",{className:"text-center py-12 text-muted-foreground",children:"No analytics data available"})}),e.jsx(ft,{value:"email",className:"space-y-4",children:Cn?e.jsx("div",{className:"h-40 bg-muted animate-pulse rounded-lg"}):ge?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid grid-cols-2 sm:grid-cols-4 gap-3",children:[e.jsx(w,{children:e.jsxs(N,{className:"pt-4 pb-4",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[e.jsx(Ts,{className:"h-4 w-4 text-muted-foreground"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Sent"})]}),e.jsx("p",{className:"text-2xl font-bold tabular-nums","data-testid":"stat-emails-sent",children:ge.sent})]})}),e.jsx(w,{children:e.jsxs(N,{className:"pt-4 pb-4",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[e.jsx(mi,{className:"h-4 w-4 text-green-500"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Clicked"})]}),e.jsx("p",{className:"text-2xl font-bold tabular-nums text-green-600","data-testid":"stat-emails-clicked",children:ge.clicked}),ge.sent>0&&e.jsxs("p",{className:"text-xs text-muted-foreground",children:[Bn,"% rate"]})]})}),e.jsx(w,{children:e.jsxs(N,{className:"pt-4 pb-4",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[e.jsx(Dt,{className:"h-4 w-4 text-blue-500"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Verified"})]}),e.jsx("p",{className:"text-2xl font-bold tabular-nums","data-testid":"stat-events-verified",children:ge.verified})]})}),e.jsx(w,{children:e.jsxs(N,{className:"pt-4 pb-4",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[e.jsx(Wa,{className:"h-4 w-4 text-destructive"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"No Response"})]}),e.jsx("p",{className:"text-2xl font-bold tabular-nums","data-testid":"stat-no-response",children:((ba=q==null?void 0:q.noResponse)==null?void 0:ba.length)??0}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"7+ days, no click"})]})})]}),Cs.some(t=>t.sent>0)&&e.jsxs(w,{children:[e.jsx(z,{className:"pb-2",children:e.jsxs(K,{className:"text-sm flex items-center gap-2",children:[e.jsx(Fs,{className:"h-4 w-4 text-primary"}),"Monthly Invitation Trend (last 6 months)"]})}),e.jsxs(N,{children:[e.jsx("div",{className:"flex items-end gap-1 h-24 w-full","data-testid":"chart-weekly-trend",children:Cs.map(t=>{const r=Math.max(...Cs.map(F=>F.sent),1),g=Math.round(t.sent/r*100);return e.jsxs("div",{className:"flex-1 flex flex-col items-center gap-0.5 min-w-0",title:`${t.week}: ${t.sent} sent, ${t.clicked} clicked`,children:[e.jsxs("div",{className:"w-full flex flex-col justify-end gap-px",style:{height:"72px"},children:[e.jsx("div",{className:"w-full bg-primary/20 rounded-t",style:{height:`${g}%`,minHeight:t.sent>0?"4px":0}}),t.clicked>0&&e.jsx("div",{className:"w-full bg-green-500/60 rounded-t absolute",style:{height:`${Math.round(t.clicked/r*100)}%`,bottom:0,position:"relative",marginTop:"-100%"}})]}),e.jsx("div",{className:"text-[9px] text-muted-foreground text-center truncate w-full",children:t.week}),t.sent>0&&e.jsx("div",{className:"text-[9px] font-medium text-center",children:t.sent})]},t.week)})}),e.jsxs("div",{className:"flex items-center gap-3 mt-2 text-xs text-muted-foreground",children:[e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx("span",{className:"inline-block w-3 h-3 rounded bg-primary/20"})," Sent"]}),e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx("span",{className:"inline-block w-3 h-3 rounded bg-green-500/60"})," Clicked"]})]})]})]}),Object.keys(ge.byEntityType).length>0&&e.jsxs(w,{children:[e.jsx(z,{className:"pb-2",children:e.jsx(K,{className:"text-sm",children:"By Entity Type"})}),e.jsx(N,{children:e.jsx("div",{className:"flex flex-wrap gap-3",children:Object.entries(ge.byEntityType).map(([t,r])=>e.jsxs("div",{className:"flex items-center gap-2 text-sm bg-muted rounded-md px-3 py-2",children:[e.jsx("span",{className:"font-medium capitalize",children:t}),e.jsxs("span",{className:"text-muted-foreground",children:[r.sent," sent"]}),e.jsx("span",{className:"text-muted-foreground",children:"·"}),e.jsxs("span",{className:"text-green-600",children:[r.clicked," clicked"]}),r.verified>0&&e.jsxs(ce,{variant:"default",children:[r.verified," verified"]})]},t))})})]}),ge.byCity&&Object.keys(ge.byCity).filter(t=>t!=="unknown").length>0&&e.jsxs(w,{children:[e.jsxs(z,{className:"pb-2",children:[e.jsx(K,{className:"text-sm",children:"By City"}),e.jsx(Fe,{children:"Verification email engagement per city"})]}),e.jsx(N,{className:"p-0",children:e.jsx($e,{className:"max-h-[30vh]",children:e.jsxs(Te,{children:[e.jsx(Re,{className:"sticky top-0 bg-background z-10",children:e.jsxs(V,{children:[e.jsx(h,{children:"City"}),e.jsx(h,{children:"Sent"}),e.jsx(h,{children:"Clicked"}),e.jsx(h,{children:"Rate"}),e.jsx(h,{className:"hidden sm:table-cell",children:"Verified"})]})}),e.jsx(De,{children:Object.entries(ge.byCity).filter(([t])=>t!=="unknown").sort(([,t],[,r])=>r.sent-t.sent).map(([t,r])=>{const g=r.sent>0?(r.clicked/r.sent*100).toFixed(0):"0";return e.jsxs(V,{"data-testid":`row-city-funnel-${t}`,children:[e.jsx(m,{className:"font-medium text-sm capitalize",children:t.replace(/-/g," ")}),e.jsx(m,{className:"tabular-nums",children:r.sent}),e.jsx(m,{className:"tabular-nums text-green-600",children:r.clicked}),e.jsx(m,{children:e.jsxs(ce,{variant:Number(g)>=30?"default":Number(g)>=10?"secondary":"outline",children:[g,"%"]})}),e.jsx(m,{className:"hidden sm:table-cell tabular-nums",children:r.verified})]},t)})})]})})})]}),(((ya=q==null?void 0:q.noResponse)==null?void 0:ya.length)??0)>0&&e.jsxs(w,{className:"border-amber-200 dark:border-amber-800",children:[e.jsxs(z,{className:"pb-2",children:[e.jsxs(K,{className:"text-sm flex items-center gap-2 text-amber-700 dark:text-amber-300",children:[e.jsx(Fa,{className:"h-4 w-4"}),"No Response (7+ days, ",q.noResponse.length,")"]}),e.jsx(Fe,{children:"Sent but never clicked — consider follow-up or removal"})]}),e.jsx(N,{className:"p-0",children:e.jsx($e,{className:"max-h-[30vh] min-h-[80px]",children:e.jsxs(Te,{children:[e.jsx(Re,{className:"sticky top-0 bg-background z-10",children:e.jsxs(V,{children:[e.jsx(h,{children:"Entity"}),e.jsx(h,{className:"hidden sm:table-cell",children:"Recipient"}),e.jsx(h,{children:"Sent"}),e.jsx(h,{children:"Action"})]})}),e.jsx(De,{children:q.noResponse.map(t=>e.jsxs(V,{"data-testid":`row-no-response-${t.id}`,children:[e.jsxs(m,{children:[e.jsx("div",{className:"font-medium text-sm",children:t.entityName}),e.jsx("div",{className:"text-xs text-muted-foreground capitalize",children:t.entityType})]}),e.jsx(m,{className:"hidden sm:table-cell text-sm text-muted-foreground",children:t.recipientEmail}),e.jsx(m,{className:"text-xs text-muted-foreground",children:t.sentAt?Le(new Date(t.sentAt),{addSuffix:!0}):"—"}),e.jsx(m,{children:e.jsxs(U,{size:"sm",variant:"outline",className:"h-7 text-xs gap-1",disabled:na.isPending,onClick:()=>na.mutate(t.id),"data-testid":`button-resend-${t.id}`,children:[e.jsx(Yn,{className:"h-3 w-3"}),"Resend"]})})]},t.id))})]})})})]}),(((va=q==null?void 0:q.failed)==null?void 0:va.length)??0)>0&&e.jsxs(w,{className:"border-destructive/30",children:[e.jsx(z,{className:"pb-2",children:e.jsxs(K,{className:"text-sm flex items-center gap-2 text-destructive",children:[e.jsx(Wa,{className:"h-4 w-4"}),"Failed Sends (",q.failed.length,")"]})}),e.jsx(N,{className:"p-0",children:e.jsx($e,{className:"max-h-[25vh] min-h-[80px]",children:e.jsxs(Te,{children:[e.jsx(Re,{className:"sticky top-0 bg-background z-10",children:e.jsxs(V,{children:[e.jsx(h,{children:"Entity"}),e.jsx(h,{className:"hidden sm:table-cell",children:"Recipient"}),e.jsx(h,{className:"hidden md:table-cell",children:"Error"}),e.jsx(h,{children:"When"})]})}),e.jsx(De,{children:q.failed.map(t=>e.jsxs(V,{"data-testid":`row-failed-email-${t.id}`,children:[e.jsxs(m,{children:[e.jsx("div",{className:"font-medium text-sm",children:t.entityName}),e.jsxs("div",{className:"text-xs text-muted-foreground capitalize",children:[t.entityType,t.citySlug?` · ${t.citySlug}`:""]})]}),e.jsx(m,{className:"hidden sm:table-cell text-sm text-muted-foreground",children:t.recipientEmail}),e.jsx(m,{className:"hidden md:table-cell text-xs text-destructive/80 max-w-[200px] truncate",children:t.errorMessage||"—"}),e.jsx(m,{className:"text-xs text-muted-foreground",children:t.createdAt?Le(new Date(t.createdAt),{addSuffix:!0}):"—"})]},t.id))})]})})})]}),e.jsxs(w,{children:[e.jsx(z,{className:"pb-2",children:e.jsx(K,{className:"text-sm",children:"All Recent Batches (last 30 days)"})}),e.jsx(N,{className:"p-0",children:e.jsx($e,{className:"max-h-[50vh] min-h-[200px]",children:e.jsxs(Te,{children:[e.jsx(Re,{className:"sticky top-0 bg-background z-10",children:e.jsxs(V,{children:[e.jsx(h,{children:"Entity"}),e.jsx(h,{className:"hidden sm:table-cell",children:"Recipient"}),e.jsx(h,{children:"Status"}),e.jsx(h,{className:"hidden md:table-cell",children:"Verified"}),e.jsx(h,{className:"hidden md:table-cell",children:"Profile"}),e.jsx(h,{children:"Sent"})]})}),e.jsx(De,{children:(((Na=q==null?void 0:q.recent)==null?void 0:Na.length)??0)===0?e.jsx(V,{children:e.jsx(m,{colSpan:6,className:"text-center text-muted-foreground py-8",children:"No email batches yet"})}):q.recent.map(t=>e.jsxs(V,{"data-testid":`row-email-batch-${t.id}`,children:[e.jsxs(m,{children:[e.jsx("div",{className:"font-medium text-sm truncate max-w-[140px]",children:t.entityName}),e.jsx("div",{className:"text-xs text-muted-foreground capitalize",children:t.entityType})]}),e.jsx(m,{className:"hidden sm:table-cell text-sm text-muted-foreground truncate max-w-[160px]",children:t.recipientEmail}),e.jsx(m,{children:e.jsx(Ha,{status:t.clickedAt?"clicked":t.status})}),e.jsx(m,{className:"hidden md:table-cell text-sm tabular-nums",children:t.eventsVerified}),e.jsx(m,{className:"hidden md:table-cell text-sm",children:t.profileUpdated?e.jsx(Dt,{className:"h-4 w-4 text-green-500"}
16):e.jsx(Ht,{className:"h-4 w-4 text-muted-foreground/40"})}),e.jsx(m,{className:"text-xs text-muted-foreground",children:t.sentAt?Le(new Date(t.sentAt),{addSuffix:!0}):"—"})]},t.id))})]})})})]})]}):e.jsx("div",{className:"text-center py-12 text-muted-foreground",children:"No email analytics available"})}),e.jsxs(ft,{value:"health",className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-base font-semibold",children:"Entity Scraper Health"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Real-time status of the venue/artist calendar scraper"})]}),e.jsxs(U,{variant:"outline",size:"sm",onClick:()=>ia(),disabled:Ns,"data-testid":"button-refresh-scraper-health",children:[e.jsx(ne,{className:`h-4 w-4 mr-1.5 ${Ns?"animate-spin":""}`}),"Refresh"]})]}),(d==null?void 0:d.circuitBreaker.active)&&e.jsx(w,{className:"border-red-400 dark:border-red-700 bg-red-50 dark:bg-red-950/30",children:e.jsx(N,{className:"pt-4 pb-4",children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(Ls,{className:"h-5 w-5 text-red-600 dark:text-red-400 shrink-0"}),e.jsxs("div",{children:[e.jsx("p",{className:"text-sm font-semibold text-red-700 dark:text-red-300",children:"Service Circuit Breaker ACTIVE"}),e.jsxs("p",{className:"text-xs text-red-600 dark:text-red-400 mt-0.5",children:[d.circuitBreaker.consecutiveFailures," consecutive Browserless failures detected — all entity scraping is paused",d.circuitBreaker.pausedUntil?` until ${new Date(d.circuitBreaker.pausedUntil).toLocaleString()}`:"","."]})]})]})})}),e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-4",children:[e.jsx(w,{"data-testid":"card-total-schedules",children:e.jsx(N,{className:"pt-4 pb-4",children:e.jsx(ye,{label:"Total Enabled Schedules",value:(d==null?void 0:d.totalEnabledSchedules)??"—",sub:"venue + artist calendars"})})}),e.jsx(w,{"data-testid":"card-overdue-count",children:e.jsx(N,{className:"pt-4 pb-4",children:e.jsx(ye,{label:"Overdue",value:(d==null?void 0:d.overdueCount)??"—",sub:"past their next-run date",color:d&&d.overdueCount>=50?"text-red-600 dark:text-red-400":d&&d.overdueCount>=20?"text-amber-600 dark:text-amber-400":void 0})})}),e.jsx(w,{"data-testid":"card-processed-today",children:e.jsx(N,{className:"pt-4 pb-4",children:e.jsx(ye,{label:"Processed (24h)",value:(d==null?void 0:d.processedToday)??"—",sub:`of ${(d==null?void 0:d.batchSize)??60} per batch`})})}),e.jsx(w,{"data-testid":"card-circuit-breaker",children:e.jsx(N,{className:"pt-4 pb-4",children:e.jsx(ye,{label:"Circuit Breaker Failures",value:(d==null?void 0:d.circuitBreaker.consecutiveFailures)??"—",sub:d!=null&&d.circuitBreaker.active?"ACTIVE — paused":"consecutive (threshold 5)",color:d!=null&&d.circuitBreaker.active?"text-red-600 dark:text-red-400":void 0})})})]}),e.jsxs(w,{children:[e.jsx(z,{className:"pb-2",children:e.jsxs(K,{className:"text-sm flex items-center gap-2",children:[e.jsx(Fa,{className:"h-4 w-4"}),"Schedule Configuration"]})}),e.jsx(N,{className:"space-y-3",children:e.jsxs("div",{className:"grid grid-cols-2 gap-4 text-sm",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Batch Size"}),e.jsxs("p",{className:"font-semibold tabular-nums",children:[(d==null?void 0:d.batchSize)??30," entities/run"]})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Daily Capacity"}),e.jsxs("p",{className:"font-semibold tabular-nums",children:[((d==null?void 0:d.batchSize)??30)*((d==null?void 0:d.runsPerDay)??24)," entities/day (",(d==null?void 0:d.runsPerDay)??24," runs/day)"]})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Last Run"}),e.jsx("p",{className:"font-semibold",children:d!=null&&d.lastRunAt?Le(new Date(d.lastRunAt),{addSuffix:!0}):"Never"})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:"Next Scheduled Run"}),e.jsx("p",{className:"font-semibold",children:d!=null&&d.nextRunAt?Le(new Date(d.nextRunAt),{addSuffix:!0}):"Hourly (top of each hour)"}),(d==null?void 0:d.nextRunAt)&&e.jsx("p",{className:"text-xs text-muted-foreground",children:new Date(d.nextRunAt).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",timeZoneName:"short"})})]})]})})]}),e.jsxs(w,{children:[e.jsxs(z,{className:"pb-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs(K,{className:"text-sm flex items-center gap-2",children:[e.jsx(Fs,{className:"h-4 w-4"}),"Scraper Trends"]}),e.jsxs(Ae,{value:mt,onValueChange:Dn,children:[e.jsx(Ce,{className:"h-7 w-28 text-xs","data-testid":"select-timeline-days",children:e.jsx(Ee,{})}),e.jsxs(Oe,{children:[e.jsx(D,{value:"1",children:"1 day"}),e.jsx(D,{value:"3",children:"3 days"}),e.jsx(D,{value:"7",children:"7 days"}),e.jsx(D,{value:"14",children:"14 days"}),e.jsx(D,{value:"30",children:"30 days"})]})]})]}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"Entities scraped over time (Pacific Time). Blue = scheduled batch, orange = pipeline/ad-hoc."})]}),e.jsxs(N,{className:"space-y-4",children:[Mn?e.jsx("div",{className:"h-44 bg-muted animate-pulse rounded"}):!Ss||Ss.length===0?e.jsx("p",{className:"text-xs text-muted-foreground py-8 text-center",children:"No timeline data for this period."}):e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-4 mb-2 text-xs text-muted-foreground flex-wrap",children:[e.jsxs("span",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"inline-block w-3 h-3 rounded-sm bg-blue-500"}
16),"Scheduled batch"]}),e.jsxs("span",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"inline-block w-3 h-3 rounded-sm bg-orange-400"}),"Pipeline / ad-hoc"]}),Ps&&Ps.length>0&&e.jsxs("span",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"text-red-500 font-bold text-[10px]",children:"⚠"}),"Error event"]})]}),e.jsx("div",{className:"h-44",children:e.jsx(Ft,{width:"100%",height:"100%",children:(()=>{const t=R=>R===0?"12AM":R<12?`${R}AM`:R===12?"12PM":`${R-12}PM`,r=(R,we)=>{const rt=new Date(R+"T00:00:00");return`${Xe(rt,"MMM d")} ${t(we)}`},g=new Map;(Ps??[]).forEach(R=>{g.set(r(R.scrapeDate,R.hour),R)});const F=(d==null?void 0:d.overdueCount)??0,Z=new Map;Ss.forEach(R=>Z.set(`${R.scrapeDate}|${R.hour}`,R));const pe=Date.now(),u=Number(mt),M=pe-u*24*60*60*1e3,fe=u*24,de=Array.from({length:fe},(R,we)=>{const rt=M+we*60*60*1e3,X=new Date(rt),Ct=X.getFullYear(),Ze=String(X.getMonth()+1).padStart(2,"0"),ze=String(X.getDate()).padStart(2,"0"),Ea=`${Ct}-${Ze}-${ze}`,Os=X.getHours(),Oa=r(Ea,Os),ke=Z.get(`${Ea}|${Os}`),Ke=g.get(Oa);return{label:Oa,isMidnight:Os===0,scheduledEntities:(ke==null?void 0:ke.scheduledEntities)??0,adHocEntities:(ke==null?void 0:ke.adHocEntities)??0,totalEvents:(ke==null?void 0:ke.totalEvents)??0,totalEntities:(ke==null?void 0:ke.totalEntities)??0,backlog:F,errorCount:(Ke==null?void 0:Ke.errorCount)??0,errorTypes:(Ke==null?void 0:Ke.types)??[],errorSummary:(Ke==null?void 0:Ke.summary)??""}}),be=new Set(g.keys()),ut=de.map(R=>R.scheduledEntities+R.adHocEntities).filter(R=>R>0).sort((R,we)=>R-we),At=ut.length?ut[Math.floor(ut.length*.95)]:void 0,it=At!==void 0?Math.ceil(At*1.15):"auto";return e.jsxs(zi,{data:de,margin:{top:16,right:4,left:-20,bottom:0},children:[e.jsxs("defs",{children:[e.jsxs("linearGradient",{id:"colorScheduled",x1:"0",y1:"0",x2:"0",y2:"1",children:[e.jsx("stop",{offset:"5%",stopColor:"#3b82f6",stopOpacity:.3}),e.jsx("stop",{offset:"95%",stopColor:"#3b82f6",stopOpacity:.05})]}),e.jsxs("linearGradient",{id:"colorAdHoc",x1:"0",y1:"0",x2:"0",y2:"1",children:[e.jsx("stop",{offset:"5%",stopColor:"#fb923c",stopOpacity:.3}),e.jsx("stop",{offset:"95%",stopColor:"#fb923c",stopOpacity:.05})]})]}),e.jsx($t,{strokeDasharray:"3 3",vertical:!1}),e.jsx(gt,{dataKey:"label",interval:0,tickLine:!1,axisLine:!1,height:28,tick:R=>{const{x:we,y:rt,payload:X,index:Ct}=R,Ze=de[Ct];return Ze?e.jsxs("g",{transform:`translate(${we},${rt})`,children:[e.jsx("line",{x1:0,y1:0,x2:0,y2:Ze.isMidnight?5:3,stroke:Ze.isMidnight?"#9ca3af":"#e5e7eb",strokeWidth:1}),Ze.isMidnight&&e.jsx("text",{x:0,dy:14,textAnchor:"middle",fontSize:8,fill:"#9ca3af",children:X.value.split(" ").slice(0,-1).join(" ")})]}):e.jsx("g",{})}}),e.jsx(bt,{tick:{fontSize:10},tickLine:!1,axisLine:!1,allowDecimals:!1,domain:[0,it]}),e.jsx(Lt,{content:({active:R,payload:we,label:rt})=>{if(!R||!(we!=null&&we.length))return null;const X=we[0].payload,Ct=Array.isArray(X.errorTypes)?X.errorTypes.filter(ze=>typeof ze=="string"):[],Ze={"log:scraping":"Scraping error","log:api":"API error","log:database":"DB error","log:system":"System error"};return e.jsxs("div",{className:"bg-background border rounded p-2 text-xs shadow-md space-y-1 max-w-[230px]",children:[e.jsxs("p",{className:"font-medium",children:[rt," PT"]}),e.jsxs("p",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"inline-block w-2 h-2 rounded-sm bg-blue-500"}),X.scheduledEntities," scheduled"]}),e.jsxs("p",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"inline-block w-2 h-2 rounded-sm bg-orange-400"}),X.adHocEntities," pipeline"]}),e.jsxs("div",{className:"pt-0.5 border-t space-y-0.5 text-muted-foreground",children:[e.jsxs("p",{children:[X.totalEntities," entities/hr"]}),e.jsxs("p",{children:[X.totalEvents," events/hr"]}),e.jsxs("p",{children:[X.backlog," overdue in queue ",e.jsx("span",{className:"opacity-60",children:"(now)"})]})]}),X.errorCount>0&&e.jsxs("div",{className:"pt-0.5 border-t border-red-200 space-y-0.5",children:[e.jsxs("p",{className:"text-red-600 dark:text-red-400 font-medium flex items-center gap-1",children:["⚠ ",X.errorCount," error",X.errorCount!==1?"s":""]}),Ct.map(ze=>e.jsx("p",{className:"text-red-500 dark:text-red-400 pl-3",children:Ze[ze]??(ze.startsWith("service:")?`${ze.replace("service:","")} outage`:ze)},ze)),X.errorSummary&&e.jsx("p",{className:"text-muted-foreground pl-3 truncate",title:X.errorSummary,children:X.errorSummary})]})]})}}),e.jsx(Ge,{type:"monotone",dataKey:"scheduledEntities",stackId:"entities",stroke:"#3b82f6",fill:"url(#colorScheduled)",strokeWidth:1.5,dot:!1,name:"Scheduled"}),e.jsx(Ge,{type:"monotone",dataKey:"adHocEntities",stackId:"entities",stroke:"#fb923c",fill:"url(#colorAdHoc)",strokeWidth:1.5,dot:!1,name:"Pipeline"}),Array.from(be).map(R=>e.jsx(ci,{x:R,stroke:"#ef4444",strokeDasharray:"3 3",strokeWidth:1.5,label:{value:"⚠",position:"insideBottom",fill:"#ef4444",fontSize:10}},R))]})})()})})]}),e.jsx("div",{className:"border-t pt-4",children:e.jsx("p",{className:"text-xs font-medium text-muted-foreground mb-3 uppercase tracking-wide",children:"Hourly average — last 7 days"})}),Ln?e.jsx("div",{className:"h-44 bg-muted animate-pulse rounded"}):e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-4 mb-2 text-xs text-muted-foreground",children:[e.jsxs("span",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"inline-block w-3 h-3 rounded-sm bg-blue-500"}
16),"Scheduled batch"]}),e.jsxs("span",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"inline-block w-3 h-3 rounded-sm bg-orange-400"}),"Pipeline / ad-hoc"]})]}),e.jsx("div",{className:"h-40",children:e.jsx(Ft,{width:"100%",height:"100%",children:e.jsxs(ts,{data:Array.from({length:24},(t,r)=>{const g=($n??[]).find(Z=>Z.hour===r);return{label:r===0?"12AM":r<12?`${r}AM`:r===12?"12PM":`${r-12}PM`,scheduledAvg:(g==null?void 0:g.scheduledAvg)??0,adHocAvg:(g==null?void 0:g.adHocAvg)??0,totalEvents:(g==null?void 0:g.totalEvents)??0,avgPerDay:(g==null?void 0:g.avgPerDay)??0}}),margin:{top:4,right:4,left:-20,bottom:0},children:[e.jsx($t,{strokeDasharray:"3 3",vertical:!1}),e.jsx(gt,{dataKey:"label",tick:{fontSize:9},interval:2,tickLine:!1,axisLine:!1}),e.jsx(bt,{tick:{fontSize:10},tickLine:!1,axisLine:!1,allowDecimals:!1}),e.jsx(Lt,{content:({active:t,payload:r,label:g})=>{if(!t||!(r!=null&&r.length))return null;const F=r[0].payload;return F.avgPerDay===0?null:e.jsxs("div",{className:"bg-background border rounded p-2 text-xs shadow-md space-y-1",children:[e.jsxs("p",{className:"font-medium",children:[g," PT"]}),F.scheduledAvg>0&&e.jsxs("p",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"inline-block w-2 h-2 rounded-sm bg-blue-500"}),F.scheduledAvg," scheduled avg/day"]}),F.adHocAvg>0&&e.jsxs("p",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"inline-block w-2 h-2 rounded-sm bg-orange-400"}),F.adHocAvg," pipeline avg/day"]}),e.jsxs("p",{className:"text-muted-foreground pt-0.5 border-t",children:[F.totalEvents," events total (last 7d)"]})]})}}),e.jsx(Ve,{dataKey:"scheduledAvg",stackId:"load",fill:"#3b82f6",name:"Scheduled"}),e.jsx(Ve,{dataKey:"adHocAvg",stackId:"load",fill:"#fb923c",name:"Pipeline",radius:[2,2,0,0]})]})})}),e.jsx("p",{className:"text-[10px] text-muted-foreground mt-1.5",children:"Entity scraper runs every hour · 30 venues per run · 720/day capacity"})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-xs font-medium text-muted-foreground mb-2 uppercase tracking-wide",children:"Recent Batch Runs"}),Fn?e.jsx("div",{className:"space-y-2",children:[1,2,3].map(t=>e.jsx("div",{className:"h-8 bg-muted animate-pulse rounded"},t))}):!Qt||Qt.length===0?e.jsx("p",{className:"text-xs text-muted-foreground py-4 text-center",children:"No batch run history found. Runs appear here after the first scheduled scrape batch completes."}):e.jsxs(Te,{children:[e.jsx(Re,{children:e.jsxs(V,{children:[e.jsx(h,{className:"text-xs",children:"When"}),e.jsx(h,{className:"text-xs",children:"Batch"}),e.jsx(h,{className:"text-xs",children:"Status"}),e.jsx(h,{className:"text-xs text-right",children:"Entities"}),e.jsx(h,{className:"text-xs text-right",children:"Events"}),e.jsx(h,{className:"text-xs text-right hidden sm:table-cell",children:"Duration"}),e.jsx(h,{className:"text-xs text-right hidden md:table-cell",children:"EPH"}),e.jsx(h,{className:"text-xs text-right hidden md:table-cell",children:"DB T/O"}),e.jsx(h,{className:"text-xs"})]})}),e.jsx(De,{children:(Qt??[]).slice(0,10).map(t=>{var fe;const r=(()=>{if(t.batchLabel==="startup-catch-up")return"bg-gray-100 text-gray-600 dark:bg-gray-800 dark:text-gray-400";const de=t.batchLabel.match(/^(\d+)(AM|PM)$/);if(!de)return"bg-gray-100 text-gray-600 dark:bg-gray-800 dark:text-gray-400";let be=parseInt(de[1],10);return de[2]==="PM"&&be!==12&&(be+=12),de[2]==="AM"&&be===12&&(be=0),be>=0&&be<6?"bg-slate-100 text-slate-600 dark:bg-slate-800 dark:text-slate-300":be>=6&&be<12?"bg-blue-100 text-blue-700 dark:bg-blue-900/40 dark:text-blue-300":be>=12&&be<18?"bg-purple-100 text-purple-700 dark:bg-purple-900/40 dark:text-purple-300":"bg-indigo-100 text-indigo-700 dark:bg-indigo-900/40 dark:text-indigo-300"})(),g=t.dbTimeoutCount===0?"text-muted-foreground":t.dbTimeoutCount<10?"text-amber-600 dark:text-amber-400 font-semibold":"text-red-600 dark:text-red-400 font-semibold",F=t.status==="in-progress"&&(ws.has(t.id)||((fe=Yt==null?void 0:Yt.entityScraper)==null?void 0:fe.abortRequested)===!0&&Yt.entityScraper.activeBatchLabel===t.batchLabel),Z={complete:{label:"done",cls:"bg-green-100 text-green-700 dark:bg-green-900/40 dark:text-green-300"},"zero-entities":{label:"no work",cls:"bg-gray-100 text-gray-500 dark:bg-gray-800 dark:text-gray-400"},checkpoint:{label:"checkpoint",cls:"bg-amber-100 text-amber-700 dark:bg-amber-900/40 dark:text-amber-300"}
16,"in-progress":F?{label:"stopping…",cls:"bg-orange-100 text-orange-700 dark:bg-orange-900/40 dark:text-orange-300 animate-pulse"}:{label:"running…",cls:"bg-blue-100 text-blue-700 dark:bg-blue-900/40 dark:text-blue-300 animate-pulse"},interrupted:{label:"interrupted",cls:"bg-red-100 text-red-700 dark:bg-red-900/40 dark:text-red-300"},failed:{label:"failed",cls:"bg-red-100 text-red-700 dark:bg-red-900/40 dark:text-red-300"},aborted:{label:"aborted",cls:"bg-orange-100 text-orange-700 dark:bg-orange-900/40 dark:text-orange-300"}},pe=Z[t.status??"complete"]??Z.complete,u=t.status==="interrupted"||t.status==="in-progress",M=u&&(t.partialCities??0)>0;return e.jsxs(V,{"data-testid":`row-batch-run-${t.id}`,children:[e.jsx(m,{className:"text-xs text-muted-foreground whitespace-nowrap",children:e.jsx(Et,{children:e.jsxs(Ot,{children:[e.jsx(Tt,{children:Le(new Date(t.runAt),{addSuffix:!0})}),e.jsx(Rt,{children:new Date(t.runAt).toLocaleString("en-US",{timeZone:"America/Los_Angeles",timeZoneName:"short"})})]})})}),e.jsx(m,{children:e.jsx("span",{className:`text-xs font-mono px-1.5 py-0.5 rounded ${r}`,children:t.batchLabel})}),e.jsx(m,{children:e.jsx("span",{className:`text-xs px-1.5 py-0.5 rounded ${pe.cls}`,children:pe.label})}),e.jsx(m,{className:"text-xs text-right tabular-nums",children:u?M?e.jsx(Et,{children:e.jsxs(Ot,{children:[e.jsx(Tt,{asChild:!0,children:e.jsxs("span",{className:"text-muted-foreground italic",children:["~",t.partialCities]})}),e.jsxs(Rt,{children:["Partial — ",t.partialCities," cities scraped before interruption"]})]})}):e.jsx("span",{className:"text-muted-foreground",children:"—"}):e.jsxs(e.Fragment,{children:[t.successCount>0&&e.jsx("span",{className:"text-green-600 dark:text-green-400 font-medium",children:t.successCount}),t.failureCount>0&&e.jsxs("span",{className:"text-red-500 ml-1",children:["(-",t.failureCount,")"]}),t.successCount===0&&t.failureCount===0&&e.jsx("span",{className:"font-medium",children:t.processed}),t.status==="checkpoint"&&t.totalEntities>0&&e.jsxs("span",{className:"text-muted-foreground ml-1",children:["/",t.totalEntities]})]})}),e.jsx(m,{className:`text-xs text-right tabular-nums ${u||t.eventsFound===0?"text-muted-foreground":"font-medium"}`,children:u?M?e.jsx(Et,{children:e.jsxs(Ot,{children:[e.jsx(Tt,{asChild:!0,children:e.jsxs("span",{className:"italic",children:["~",t.partialEvents,(t.partialNovelEvents??0)>0&&e.jsxs("span",{className:"text-muted-foreground ml-1",children:["(+",t.partialNovelEvents," new)"]})]})}),e.jsxs(Rt,{children:["Partial — events found before interruption. ",t.partialNovelEvents," were new to the DB."]})]})}):"—":t.eventsFound}),e.jsx(m,{className:"text-xs text-right tabular-nums text-muted-foreground hidden sm:table-cell",children:u?"—":t.durationMin!=null?`${t.durationMin}m`:"—"}),e.jsx(m,{className:"text-xs text-right tabular-nums text-muted-foreground hidden md:table-cell",children:u?"—":t.entitiesPerHour!=null?t.entitiesPerHour:"—"}),e.jsx(m,{className:`text-xs text-right tabular-nums hidden md:table-cell ${u?"text-muted-foreground":g}`,children:u?"—":t.dbTimeoutCount}),e.jsx(m,{className:"text-right",children:t.status==="in-progress"&&e.jsx(U,{size:"sm",variant:"destructive",className:"h-6 text-xs px-2",disabled:ks.isPending||ws.has(t.id),onClick:()=>ks.mutate({batchLabel:t.batchLabel,runId:t.id}),"data-testid":`button-force-stop-${t.id}`,children:ks.isPending||ws.has(t.id)?"Stopping…":"Force Stop"})})]},t.id)})})]})]})]})]}),(()=>{const t={browserless_content:"Browserless",static_http:"Static HTTP",perplexity_search:"Perplexity",image_vision:"Image Vision",ical_feed:"iCal Feed",image_ai_extraction:"AI Image Upload",unknown:"Unknown"},r=u=>t[u]??u,g=le?[...le.byMethod].sort((u,M)=>M.yieldPct-u.yieldPct):[],F=g.map(u=>({name:r(u.method),yieldPct:u.yieldPct,nonYieldPct:Math.max(0,100-u.yieldPct),totalEvents:u.totalEvents,avgSec:u.avgSec,total:u.total})),Z=g.filter(u=>u.minWastedOnZeros>0).sort((u,M)=>M.minWastedOnZeros-u.minWastedOnZeros).map(u=>({name:r(u.method),minutes:u.minWastedOnZeros})),pe=((le==null?void 0:le.weeklyTrend)??[]).map(u=>({weekLabel:u.week?Xe(new Date(u.week+"T12:00:00"),"MMM d"):"?",yielded:u.yielded,zeroResult:u.zeroResult,hardFailures:u.hardFailures,totalEventsFound:u.totalEventsFound}));return e.jsxs(w,{children:[e.jsxs(z,{className:"pb-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs(K,{className:"text-sm flex items-center gap-2",children:[e.jsx(Ka,{className:"h-4 w-4"}),"Calendar Scraping Performance"]}),e.jsxs(U,{variant:"outline",size:"sm",onClick:()=>Rn(),disabled:Ye,"data-testid":"button-refresh-scraping-analytics",children:[e.jsx(ne,{className:`h-4 w-4 mr-1.5 ${Ye?"animate-spin":""}`}),"Refresh"]})]}),le&&e.jsxs("p",{className:"text-xs text-muted-foreground mt-1",children:[le.totalHistoryRows.toLocaleStr
16ing()," scrape records",le.oldestRecord?` · since ${Xe(new Date(le.oldestRecord+"T12:00:00"),"MMM d, yyyy")}`:""]})]}),e.jsxs(N,{className:"space-y-6",children:[e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-3 gap-3",children:[e.jsxs("div",{className:"rounded-lg border bg-muted/30 p-3 text-center","data-testid":"stat-timeout-paused-count",children:[e.jsx("p",{className:"text-xs text-muted-foreground mb-1",children:"Paused (timeout)"}),Ye?e.jsx("div",{className:"h-6 w-12 bg-muted animate-pulse rounded mx-auto"}):e.jsx("p",{className:"text-xl font-bold tabular-nums",children:(le==null?void 0:le.timeoutPausedCount)??0}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"3+ failures · next run over 7 days away"}),e.jsx(Xt,{href:"/admin/city-scraping?tab=schedules&filter=timeout-paused",onClick:()=>n("schedules"),className:"text-xs text-primary underline-offset-2 hover:underline mt-2 inline-block","data-testid":"link-view-timeout-paused",children:"View list"})]}),e.jsxs("div",{className:"rounded-lg border bg-muted/30 p-3 text-center","data-testid":"stat-unreachable-count",children:[e.jsx("p",{className:"text-xs text-muted-foreground mb-1",children:"Unreachable Calendars"}),Ye?e.jsx("div",{className:"h-6 w-12 bg-muted animate-pulse rounded mx-auto"}):e.jsx("p",{className:"text-xl font-bold tabular-nums",children:(le==null?void 0:le.unreachableCount)??0}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"5+ consecutive zero-result runs"}),e.jsx(Xt,{href:"/admin/city-scraping?tab=schedules&filter=unreachable",className:"text-xs text-primary underline-offset-2 hover:underline mt-2 inline-block","data-testid":"link-view-unreachable",children:"View list"})]}),e.jsxs("div",{className:"rounded-lg border bg-muted/30 p-3 text-center","data-testid":"stat-help-email-count",children:[e.jsx("p",{className:"text-xs text-muted-foreground mb-1",children:"Help Emails Sent"}),Ye?e.jsx("div",{className:"h-6 w-12 bg-muted animate-pulse rounded mx-auto"}):e.jsx("p",{className:"text-xl font-bold tabular-nums",children:(le==null?void 0:le.helpEmailSentCount)??0}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"Outreach to venue operators"}),e.jsx(Xt,{href:"/admin/city-scraping?tab=schedules&filter=help-email-sent",className:"text-xs text-primary underline-offset-2 hover:underline mt-2 inline-block","data-testid":"link-view-help-emails",children:"View list"})]})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-xs font-medium text-muted-foreground mb-3 uppercase tracking-wide",children:"Yield Rate by Scraping Method"}),Ye?e.jsx("div",{className:"h-48 bg-muted animate-pulse rounded"}):F.length===0?e.jsx("p",{className:"text-xs text-muted-foreground text-center py-8",children:"No method data yet."}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"h-52",children:e.jsx(Ft,{width:"100%",height:"100%",children:e.jsxs(ts,{data:F,layout:"vertical",margin:{top:0,right:48,left:4,bottom:0},children:[e.jsx(gt,{type:"number",domain:[0,100],tick:{fontSize:10},tickFormatter:u=>`${u}%`}),e.jsx(bt,{type:"category",dataKey:"name",tick:{fontSize:11},width:100}),e.jsx($t,{strokeDasharray:"3 3",horizontal:!1}),e.jsx(Lt,{content:({active:u,payload:M})=>{var de;if(!u||!(M!=null&&M.length))return null;const fe=(de=M[0])==null?void 0:de.payload;return e.jsxs("div",{className:"bg-background border rounded shadow-sm p-2 text-xs space-y-0.5",children:[e.jsx("p",{className:"font-semibold",children:fe.name}),e.jsxs("p",{children:["Yield: ",e.jsxs("strong",{children:[fe.yieldPct,"%"]})," (",fe.total.toLocaleString()," runs)"]}),e.jsxs("p",{children:["Events found: ",e.jsx("strong",{children:fe.totalEvents.toLocaleString()})]}),fe.avgSec!=null&&e.jsxs("p",{children:["Avg duration: ",e.jsxs("strong",{children:[fe.avgSec,"s"]})]})]})}}),e.jsx(Ve,{dataKey:"yieldPct",stackId:"a",fill:"#22c55e",radius:[0,0,0,0],name:"yieldPct",children:F.map((u,M)=>e.jsx(Bs,{fill:u.yieldPct>=75?"#16a34a":u.yieldPct>=50?"#22c55e":u.yieldPct>=25?"#f59e0b":"#ef4444"},M))}),e.jsx(Ve,{dataKey:"nonYieldPct",stackId:"a",fill:"#e5e7eb",name:"nonYieldPct"})]})})}),e.jsx("p",{className:"text-xs text-muted-foreground text-center mt-1",children:"Green = found events · Gray = ran but found nothing"})]})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-xs font-medium text-muted-foreground mb-3 uppercase tracking-wide",children:"Weekly Scraping Outcomes (last 12 weeks)"}),Ye?e.jsx("div",{className:"h-44 bg-muted animate-pulse rounded"}):pe.length===0?e.jsx("p",{className:"text-xs text-muted-foreground text-center py-8",children:"No weekly data yet."}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex items-center gap-4 mb-2 text-xs text-muted-foreground flex-wrap",children:[e.jsxs("span",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"inline-block w-3 h-2 rounded-sm bg-green-500"})," Found events"]}),e.jsxs("span",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"inline-block w-3 h-2 rounded-sm bg-amber-400"})," Zero results"]}),e.jsxs("span",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"inline-block w-3 h-2 rounded-sm bg-red-400"})," Hard failures"]})]}),e.jsx("div",{className:"h-44",children:e.jsx(Ft,{width:"100%",height:"100%",children:e.jsxs(ts,{data:pe,margin:{top:0,right:8,left:-16,bottom:0},children:[e.jsx($t,{strokeDasharray:"3 3",vertical:!1}),e.jsx(gt,{dataKey:"weekLabel",tick:{fontSize:10}}),e.jsx(bt,{tick:{fontSize:10}}),e.jsx(Lt,{content:({active:u,payload:M,label:fe})=>{var ut,At;if(!u||!(M!=null&&M.length))return null;const de=M.reduce((it,R)=>it+Number(R.value??0),0),be=((At=(ut=M[0])==null?void 0:ut.payload)==null?void 0:At.totalEventsFound)??0;return e.jsxs("div",{className:"bg-background border rounded shadow-sm p-2 text-xs space-y-0.5",children:[e.jsxs("p",{className:"font-semibold",children:["Week of ",fe]}),M.map((it,R)=>e.jsxs("p",{style:{color:String(it.color)}
16,children:[it.name,": ",Number(it.value).toLocaleString()]},R)),e.jsxs("p",{className:"pt-0.5 border-t mt-0.5",children:["Total runs: ",de.toLocaleString()]}),e.jsxs("p",{children:["Events found: ",e.jsx("strong",{children:be.toLocaleString()})]})]})}}),e.jsx(Ve,{dataKey:"yielded",stackId:"s",fill:"#22c55e",name:"Found events"}),e.jsx(Ve,{dataKey:"zeroResult",stackId:"s",fill:"#fbbf24",name:"Zero results"}),e.jsx(Ve,{dataKey:"hardFailures",stackId:"s",fill:"#f87171",name:"Hard failures",radius:[2,2,0,0]})]})})})]})]}),!Ye&&Z.length>0&&e.jsxs("div",{children:[e.jsx("p",{className:"text-xs font-medium text-muted-foreground mb-3 uppercase tracking-wide",children:"Time Spent on Zero-Result Scrapes"}),e.jsx("div",{className:"h-36",children:e.jsx(Ft,{width:"100%",height:"100%",children:e.jsxs(ts,{data:Z,layout:"vertical",margin:{top:0,right:48,left:4,bottom:0},children:[e.jsx(gt,{type:"number",tick:{fontSize:10},tickFormatter:u=>`${u}m`}),e.jsx(bt,{type:"category",dataKey:"name",tick:{fontSize:11},width:100}),e.jsx($t,{strokeDasharray:"3 3",horizontal:!1}),e.jsx(Lt,{formatter:u=>[`${u} min`,"Wasted"]}),e.jsx(Ve,{dataKey:"minutes",fill:"#f59e0b",radius:[0,3,3,0],children:Z.map((u,M)=>e.jsx(Bs,{fill:u.minutes>500?"#ef4444":u.minutes>100?"#f59e0b":"#fbbf24"},M))})]})})}),e.jsx("p",{className:"text-xs text-muted-foreground text-center mt-1",children:"Cumulative minutes where scrape completed but no events were found"})]})]})]})})(),e.jsxs(w,{className:d!=null&&d.circuitBreaker.active?"border-red-400 dark:border-red-700":"border-green-400/50 dark:border-green-700/50",children:[e.jsx(z,{className:"pb-2",children:e.jsxs(K,{className:"text-sm flex items-center gap-2",children:[d!=null&&d.circuitBreaker.active?e.jsx(Ls,{className:"h-4 w-4 text-red-500"}):e.jsx(Ra,{className:"h-4 w-4 text-green-500"}),"Service-Level Circuit Breaker"]})}),e.jsxs(N,{className:"text-sm space-y-1",children:[e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-muted-foreground",children:"Status"}),e.jsx("span",{className:`font-semibold ${d!=null&&d.circuitBreaker.active?"text-red-600 dark:text-red-400":"text-green-600 dark:text-green-400"}`,children:d!=null&&d.circuitBreaker.active?"TRIPPED — scraping paused":"OK"})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-muted-foreground",children:"Consecutive Failures"}),e.jsxs("span",{className:"font-semibold tabular-nums",children:[(d==null?void 0:d.circuitBreaker.consecutiveFailures)??0," / 5"]})]}),(d==null?void 0:d.circuitBreaker.pausedUntil)&&e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-muted-foreground",children:"Paused Until"}),e.jsx("span",{className:"font-semibold",children:new Date(d.circuitBreaker.pausedUntil).toLocaleString()})]}),e.jsx("p",{className:"text-xs text-muted-foreground pt-1",children:"State is persisted across server restarts. Resets automatically when the pause window expires."})]})]})]}),e.jsxs(ft,{value:"discovery",className:"space-y-6",children:[e.jsxs(w,{className:"border-indigo-400 dark:border-indigo-700",children:[e.jsx(z,{children:e.jsxs("div",{className:"flex items-start justify-between gap-4 flex-wrap",children:[e.jsxs("div",{children:[e.jsxs(K,{className:"flex items-center gap-2",children:[e.jsx(lt,{className:"h-5 w-5 text-indigo-500"}),"All-City Promoter Enrollment"]}),e.jsx(Fe,{children:"Preview and enroll eligible city promoters across every active curated city. Homepage-only profiles remain excluded unless you opt in below."})]}),e.jsx(U,{variant:"outline","data-testid":"button-preview-all-city-promoters",disabled:vs.isPending||Gt.isPending||(S==null?void 0:S.status)==="queued"||(S==null?void 0:S.status)==="running",onClick:()=>vs.mutate({limit:parseInt(se)||100,includeHomepageFallback:st}),children:vs.isPending?e.jsxs(e.Fragment,{children:[e.jsx(ne,{className:"h-4 w-4 mr-2 animate-spin"}),"Starting preview…"]}):(S==null?void 0:S.status)==="queued"||(S==null?void 0:S.status)==="running"?e.jsxs(e.Fragment,{children:[e.jsx(ne,{className:"h-4 w-4 mr-2 animate-spin"}),"Previewing all cities…"]}):e.jsxs(e.Fragment,{children:[e.jsx(lt,{className:"h-4 w-4 mr-2"}),"Preview all cities"]})})]})}),S&&(S.status==="queued"||S.status==="running")&&e.jsx(N,{className:"pt-0",children:e.jsxs("div",{className:"rounded-md border bg-muted/30 p-4 space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(ne,{className:"h-4 w-4 animate-spin text-indigo-500"}),e.jsx("p",{className:"font-medium",children:S.operation==="enroll"?S.progress.currentCityName?`Enrolling schedules for ${S.progress.currentCityName}`:"Preparing schedule enrollment":S.progress.currentCityName?`Checking ${S.progress.currentCityName}`:"Preparing city checks"})]}),e.jsxs("span",{className:"text-sm tabular-nums text-muted-foreground",children:[S.progress.citiesCompleted," / ",S.progress.citiesTotal||"…"," cities"]})]}),e.jsx(Rs,{value:S.progress.citiesTotal>0?S.progress.citiesCompleted/S.progress.citiesTotal*100:0}),e.jsx("p",{className:"text-xs text-muted-foreground",children:S.operation==="enroll"?"This runs in the background. Schedule changes are applied as each city completes.":"This runs in the background. You can leave this page open; no schedules are changed by the preview."}),S.progress.cityResults.length>0&&e.jsxs("p",{className:"text-xs text-muted-foreground",children:["Last completed: ",(wa=S.progress.cityResults[S.progress.cityResults.length-1])==null?void 0:wa.cityName]})]})}),(S==null?void 0:S.status)==="failed"&&e.jsx(N,{className:"pt-0",children:e.jsxs("div",{className:"rounded-md border border-destructive/40 bg-destructive/5 p-4 text-sm text-destructive",children:["All-city ",S.operation==="enroll"?"enrollment":"preview"," failed:"," ",S.error||"The background job stopped unexpectedly."]})}),I&&e.jsxs(N,{className:"space-y-4",children:[e.jsx("div",{className:"grid grid-cols-2 sm:grid-cols-4 gap-3",children:[["Cities checked",I.
16counts.cities],["Profiles checked",I.counts.profiles],["Ready to enroll",I.counts.eligibleForEnrollment],["Already enabled",I.counts.alreadyEnabledSchedules],["Disabled to re-enable",I.counts.disabledSchedules],["Homepage only",I.counts.homepageOnlyFallbacks],["Unresolved",I.counts.unresolved],["City failures",I.counts.cityFailures]].map(([t,r])=>e.jsxs("div",{className:"rounded-md border bg-muted/30 p-3",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:t}),e.jsx("p",{className:"text-xl font-bold tabular-nums",children:r})]},t))}),e.jsxs("div",{className:"flex items-center justify-between gap-3 flex-wrap border-t pt-4",children:[e.jsxs("div",{children:[e.jsx("p",{className:"font-semibold",children:I.confirmed?"Enrollment results":Es?"Enrollment in progress":ua?"Enrollment failed":"Ready for confirmation"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:I.confirmed?`${((ka=I.enrollment)==null?void 0:ka.created)??0} created · ${((Sa=I.enrollment)==null?void 0:Sa.reenabled)??0} re-enabled · ${((Pa=I.enrollment)==null?void 0:Pa.skipped)??0} skipped`:Es?"Schedule changes are being applied city by city in the background.":ua?"The background enrollment stopped before completing.":"No schedules have been changed by this preview."})]}),!I.confirmed&&e.jsxs($a,{open:yn,onOpenChange:us,children:[e.jsx(U,{"data-testid":"button-confirm-all-city-promoters",disabled:I.counts.eligibleForEnrollment===0||Gt.isPending||ma,onClick:()=>us(!0),children:Gt.isPending||Es?e.jsxs(e.Fragment,{children:[e.jsx(ne,{className:"h-4 w-4 mr-2 animate-spin"}),"Enrolling…"]}):e.jsxs(e.Fragment,{children:[e.jsx(Dt,{className:"h-4 w-4 mr-2"}),"Confirm all-city enrollment"]})}),e.jsxs(La,{children:[e.jsxs(Ma,{children:[e.jsx(Ia,{children:"Enroll city promoters across all cities?"}),e.jsxs(Ba,{children:["This will create or re-enable ",I.counts.eligibleForEnrollment," ","monthly city-promoter schedule(s) across ",I.counts.cities," ","active curated cities. Existing enabled schedules will be skipped, unresolved"," ","profiles will remain unscheduled, and no events will be imported now.",!st&&I.counts.homepageOnlyFallbacks>0?` ${I.counts.homepageOnlyFallbacks} homepage-only profile(s) will remain unscheduled.`:""]})]}),e.jsxs(_a,{children:[e.jsx(qa,{children:"Cancel"}),e.jsx(za,{"data-testid":"button-confirm-all-city-promoters-action",onClick:()=>Gt.mutate({limit:parseInt(se)||100,includeHomepageFallback:st}),children:"Enroll schedules"})]})]})]})]}),I.warnings.length>0||(Aa=I.enrollment)!=null&&Aa.errors.length?e.jsxs("div",{className:"rounded-md border border-amber-300 bg-amber-50 dark:border-amber-800 dark:bg-amber-950/30 p-3 space-y-1",children:[I.warnings.map(t=>e.jsxs("p",{className:"text-sm text-amber-800 dark:text-amber-300 flex items-start gap-2",children:[e.jsx($s,{className:"h-4 w-4 mt-0.5 shrink-0"}),t]},t)),(((Ca=I.enrollment)==null?void 0:Ca.errors)??[]).map(t=>e.jsxs("p",{className:"text-sm text-amber-800 dark:text-amber-300 flex items-start gap-2",children:[e.jsx($s,{className:"h-4 w-4 mt-0.5 shrink-0"}),t]},`enrollment-${t}`))]}):null,e.jsx($e,{className:"h-64 rounded border",children:e.jsxs(Te,{children:[e.jsx(Re,{children:e.jsxs(V,{children:[e.jsx(h,{children:"City"}),e.jsx(h,{children:"Status"}),e.jsx(h,{className:"text-right",children:"Profiles"}),e.jsx(h,{className:"text-right",children:"Ready"}),I.confirmed&&e.jsx(h,{className:"text-right",children:"Created"}),I.confirmed&&e.jsx(h,{className:"text-right",children:"Failed"})]})}),e.jsx(De,{children:I.cities.map(t=>{var r,g;return e.jsxs(V,{children:[e.jsx(m,{className:"font-medium",children:t.cityName}),e.jsxs(m,{children:[e.jsx(ce,{variant:t.status==="failed"?"destructive":"default",children:t.status==="failed"?"Failed":"Complete"}),t.error&&e.jsx("p",{className:"text-xs text-muted-foreground mt-1 max-w-[260px]",children:t.error})]}),e.jsx(m,{className:"text-right",children:t.counts.profiles}),e.jsx(m,{className:"text-right",children:t.counts.eligibleForEnrollment}),I.confirmed&&e.jsx(m,{className:"text-right",children:((r=t.enrollment)==null?void 0:r.created)??0}),I.confirmed&&e.jsx(m,{className:"text-right",children:((g=t.enrollment)==null?void 0:g.failed)??0})]},t.citySlug)}
16)})]})})]})]}),e.jsxs(w,{className:"border-indigo-400 dark:border-indigo-700",children:[e.jsxs(z,{children:[e.jsxs(K,{className:"flex items-center gap-2",children:[e.jsx(lt,{className:"h-5 w-5 text-indigo-500"}),"City Promoter Enrollment"]}),e.jsxs(Fe,{children:["Preview and enroll only promoters with subtype ",e.jsx("code",{className:"text-xs",children:"city"})," for the selected city. The preview probes known metadata and bounded calendar paths; it never creates or enables schedules."]})]}),e.jsxs(N,{className:"space-y-4",children:[e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(ue,{htmlFor:"city-promoter-city",children:"City"}),e.jsxs(Ae,{value:te,onValueChange:je,children:[e.jsx(Ce,{id:"city-promoter-city","data-testid":"select-city-promoter-city",children:e.jsx(Ee,{placeholder:"Select a city…"})}),e.jsx(Oe,{children:(St??[]).map(t=>e.jsxs(D,{value:t.slug,children:[t.name,t.state?`, ${t.state}`:""]},t.slug))})]})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(ue,{htmlFor:"city-promoter-limit",children:"Profiles per run"}),e.jsx(Ue,{id:"city-promoter-limit","data-testid":"input-city-promoter-limit",type:"number",min:1,max:500,value:se,onChange:t=>Qe(t.target.value)})]})]}),e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx(ht,{id:"city-promoter-homepage-fallback","data-testid":"switch-city-promoter-homepage-fallback",checked:st,onCheckedChange:gn}),e.jsxs("div",{children:[e.jsx(ue,{htmlFor:"city-promoter-homepage-fallback",className:"text-sm",children:"Allow homepage-only fallback scheduling"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Off by default. A homepage is not treated as an events calendar unless you explicitly opt in."})]})]}),e.jsx(U,{"data-testid":"button-preview-city-promoters",disabled:!te||ys.isPending||Wt.isPending,onClick:()=>ys.mutate({citySlug:te,limit:parseInt(se)||100,includeHomepageFallback:st}),children:ys.isPending?e.jsxs(e.Fragment,{children:[e.jsx(ne,{className:"h-4 w-4 mr-2 animate-spin"}),"Probing city promoters…"]}):e.jsxs(e.Fragment,{children:[e.jsx(lt,{className:"h-4 w-4 mr-2"}),"Preview city enrollment"]})}),ae&&e.jsxs("div",{className:"space-y-4 border-t pt-4",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3 flex-wrap",children:[e.jsxs("div",{children:[e.jsxs("p",{className:"font-semibold",children:[ae.cityName," enrollment preview"]}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:["URL metadata updated: ",ae.counts.metadataUpdated," · schedules unchanged"]})]}),e.jsxs($a,{open:bn,onOpenChange:os,children:[e.jsx(U,{"data-testid":"button-confirm-city-promoter-enrollment",disabled:ae.counts.eligibleForEnrollment===0||Wt.isPending,onClick:()=>os(!0),children:Wt.isPending?e.jsxs(e.Fragment,{children:[e.jsx(ne,{className:"h-4 w-4 mr-2 animate-spin"}),"Enrolling…"]}):e.jsxs(e.Fragment,{children:[e.jsx(Dt,{className:"h-4 w-4 mr-2"}),"Confirm enrollment"]})}),e.jsxs(La,{children:[e.jsxs(Ma,{children:[e.jsx(Ia,{children:"Enroll city promoters?"}),e.jsxs(Ba,{children:["This will create or re-enable ",ae.counts.eligibleForEnrollment," monthly city-promoter schedule(s) for ",ae.cityName,". Existing enabled schedules will be skipped. No events will be imported now.",!st&&ae.counts.homepageOnlyFallbacks>0?` ${ae.counts.homepageOnlyFallbacks} homepage-only profile(s) will remain unscheduled.`:""]})]}),e.jsxs(_a,{children:[e.jsx(qa,{children:"Cancel"}),e.jsx(za,{"data-testid":"button-confirm-city-promoter-enrollment-action",onClick:()=>Wt.mutate({citySlug:te,limit:parseInt(se)||100,includeHomepageFallback:st}),children:"Enroll schedules"})]})]})]})]}),e.jsx("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-3",children:[["Known event URLs",ae.counts.knownEventUrls],["Newly discovered",ae.counts.newlyDiscoveredEventUrls],["Homepage only",ae.counts.homepageOnlyFallbacks],["Unresolved",ae.counts.unresolved],["Already enabled",ae.counts.alreadyEnabledSchedules],["Disabled to re-enable",ae.counts.disabledSchedules],["Ready to enroll",ae.counts.eligibleForEnrollment],["Profiles checked",ae.counts.profiles]].map(([t,r])=>e.jsxs("div",{className:"rounded-md border bg-muted/30 p-3",children:[e.jsx("p",{className:"text-xs text-muted-foreground",children:t}),e.jsx("p",{className:"text-xl font-bold tabular-nums",children:r})]},t))}),ae.warnings.length>0&&e.jsx("div",{className:"rounded-md border border-amber-300 bg-amber-50 dark:border-amber-800 dark:bg-amber-950/30 p-3 space-y-1",children:ae.warnings.map(t=>e.jsxs("p",{className:"text-sm text-amber-800 dark:text-amber-300 flex items-start gap-2",children:[e.jsx($s,{className:"h-4 w-4 mt-0.5 shrink-0"}),t]},t))}
16),e.jsx($e,{className:"h-64 rounded border",children:e.jsxs(Te,{children:[e.jsx(Re,{children:e.jsxs(V,{children:[e.jsx(h,{children:"Promoter"}),e.jsx(h,{children:"URL outcome"}),e.jsx(h,{children:"Schedule"}),e.jsx(h,{className:"text-right",children:"Verified"})]})}),e.jsx(De,{children:ae.profiles.map(t=>e.jsxs(V,{children:[e.jsx(m,{className:"font-medium",children:t.promoterName}),e.jsx(m,{children:e.jsxs("div",{className:"max-w-[360px]",children:[e.jsx(ce,{variant:t.source==="unresolved"?"destructive":t.source==="homepage_fallback"?"secondary":"default",children:t.source==="homepage_fallback"?"homepage fallback":t.source}),t.selectedUrl&&e.jsx("p",{className:"text-xs text-muted-foreground truncate mt-1",title:t.selectedUrl,children:t.selectedUrl}),t.reason&&e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:t.reason})]})}),e.jsx(m,{className:"text-xs capitalize",children:t.scheduleStatus.replace("_"," ")}),e.jsx(m,{className:"text-right",children:t.verified?e.jsx(Dt,{className:"h-4 w-4 text-green-600 ml-auto"}):e.jsx(Ht,{className:"h-4 w-4 text-muted-foreground ml-auto"})})]},t.promoterId))})]})})]})]})]}),e.jsxs(w,{children:[e.jsxs(z,{children:[e.jsxs(K,{className:"flex items-center gap-2",children:[e.jsx(xt,{className:"h-5 w-5 text-purple-500"}),"Calendar Discovery Pipeline"]}),e.jsx(Fe,{children:"Finds venues in a city that have web event calendars but are not yet in the entity scraper. Phase 1 sweeps Google Places for new venues. Phase 2 crawls each venue's website for an events page. Phase 3 validates the page and auto-enrolls it in the entity scraper if events are found. Typical Google Places cost: ~$0.18 per city run (5 API calls)."})]}),e.jsxs(N,{className:"space-y-4",children:[e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4",children:[e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(ue,{htmlFor:"discover-city",children:"City"}),e.jsxs(Ae,{value:te,onValueChange:je,children:[e.jsx(Ce,{id:"discover-city","data-testid":"select-discover-city",children:e.jsx(Ee,{placeholder:"Select a city…"})}),e.jsx(Oe,{children:(St??[]).map(t=>e.jsxs(D,{value:t.slug,children:[t.name,t.state?`, ${t.state}`:""]},t.slug))})]})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(ue,{htmlFor:"discover-limit",children:"Venue limit per run"}),e.jsx(Ue,{id:"discover-limit","data-testid":"input-discover-limit",type:"number",min:1,max:100,value:se,onChange:t=>Qe(t.target.value)})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(ue,{htmlFor:"discover-perplexity-limit",children:"Max Perplexity calls"}),e.jsx(Ue,{id:"discover-perplexity-limit","data-testid":"input-discover-perplexity-limit",type:"number",min:0,max:50,value:kt,onChange:t=>Bt(t.target.value)}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Perplexity is only used when HTTP crawling fails to find a calendar link."})]})]}),e.jsxs("div",{className:"flex flex-wrap gap-6 pt-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(ht,{id:"discover-skip-places","data-testid":"switch-discover-skip-places",checked:tt,onCheckedChange:fn}),e.jsx(ue,{htmlFor:"discover-skip-places",className:"text-sm",children:"Skip Google Places sweep (Phase 1)"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(ht,{id:"discover-dry-run","data-testid":"switch-discover-dry-run",checked:Vs,onCheckedChange:jn}),e.jsx(ue,{htmlFor:"discover-dry-run",className:"text-sm",children:"Dry run (discover but don't enroll)"})]})]}),e.jsx(U,{"data-testid":"button-run-discovery",disabled:!te||Vt.isPending,onClick:()=>Vt.mutate({citySlug:te,limit:parseInt(se)||30,skipPlacesSweep:tt,perplexityLimit:parseInt(kt)||10,dryRun:Vs}),className:"w-full sm:w-auto",children:Vt.isPending?e.jsxs(e.Fragment,{children:[e.jsx(ne,{className:"h-4 w-4 mr-2 animate-spin"}),"Running discovery…"]}):e.jsxs(e.Fragment,{children:[e.jsx(xt,{className:"h-4 w-4 mr-2"}),"Run Calendar Discovery"]})}),Vt.isPending&&e.jsxs("p",{className:"text-sm text-muted-foreground",children:["This can take a few minutes. The pipeline crawls up to ",se," venue websites and validates any calendar pages it finds."]})]})]}),H&&e.jsxs(e.Fragment,{children:[H.error&&e.jsx(w,{className:"border-red-400 dark:border-red-700",children:e.jsx(N,{className:"pt-4",children:e.jsxs("p",{className:"text-sm text-red-600 dark:text-red-400 font-medium",children:["Error: ",H.error]})})}),e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-3 gap-4",children:[e.jsxs(w,{children:[e.jsx(z,{className:"pb-2",children:e.jsx(K,{className:"text-sm font-medium text-muted-foreground",children:"Phase 1 — Places Sweep"})}),e.jsx(N,{className:"space-y-1 text-sm",children:H.phases.placesSweep.skipped?e.jsx("p",{className:"text-muted-foreground italic",children:"Skipped"}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{children:"API calls"}),e.jsx("span",{className:"font-semibold tabular-nums","data-testid":"stat-places-api-calls",children:H.phases.placesSweep.apiCalls})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{children:"New venues added"}),e.jsx("span",{className:"font-semibold tabular-nums text-green-600 dark:text-green-400","data-testid":"stat-places-new-venues",children:H.phases.placesSweep.newVenuesAdded})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{children:"Website URLs enriched"}),e.jsx("span",{className:"font-semibold tabular-nums","data-testid":"stat-places-enriched",children:H.phases.placesSweep.websiteUrlsEnriched})]})]})})]}),e.jsxs(w,{children:[e.jsx(z,{className:"pb-2",children:e.jsx(K,{className:"text-sm font-medium text-muted-foreground",children:"Phase 2 — URL Discovery"})}),e.jsxs(N,{className:"space-y-1 text-sm",children:[e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{children:"Venues checked"}),e.jsx("span",{className:"font-semibold tabular-nums","data-testid":"stat-discovery-checked",children:H.phases.urlDiscovery.venuesChecked})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{children:"Found via HTTP crawl"}),e.jsx("span",{className:"font-semibold tabular-nums text-green-600 dark:text-green-400","data-testid":"stat-discovery-http",children:H.phases.urlDiscovery.foundByHttp})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{children:"Found via Perplexity"}),e.jsx("span",{className:"font-semibold tabular-nums text-blue-600 dar
16k:text-blue-400","data-testid":"stat-discovery-perplexity",children:H.phases.urlDiscovery.foundByPerplexity})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{children:"Already had URL"}),e.jsx("span",{className:"font-semibold tabular-nums","data-testid":"stat-discovery-existing",children:H.phases.urlDiscovery.alreadyHadUrl})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{children:"Not found"}),e.jsx("span",{className:"font-semibold tabular-nums text-muted-foreground","data-testid":"stat-discovery-not-found",children:H.phases.urlDiscovery.notFound})]}),H.phases.urlDiscovery.perplexityBudgetHit&&e.jsx("p",{className:"text-xs text-amber-600 dark:text-amber-400 pt-1",children:"Perplexity budget reached"})]})]}),e.jsxs(w,{children:[e.jsx(z,{className:"pb-2",children:e.jsx(K,{className:"text-sm font-medium text-muted-foreground",children:"Phase 3 — Enrollment"})}),e.jsxs(N,{className:"space-y-1 text-sm",children:[e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{children:"URLs validated"}),e.jsx("span",{className:"font-semibold tabular-nums","data-testid":"stat-enroll-tested",children:H.phases.enrollment.tested})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{children:"Schedules created"}),e.jsx("span",{className:"font-semibold tabular-nums text-green-600 dark:text-green-400","data-testid":"stat-enroll-created",children:H.phases.enrollment.enrolled})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{children:"Validation failed"}),e.jsx("span",{className:"font-semibold tabular-nums text-muted-foreground","data-testid":"stat-enroll-failed",children:H.phases.enrollment.validationFailed})]}),H.phases.enrollment.dryRun&&e.jsx("p",{className:"text-xs text-amber-600 dark:text-amber-400 pt-1",children:"Dry run — no schedules created"})]})]})]}),e.jsxs(w,{children:[e.jsx(z,{className:"pb-2",children:e.jsx("div",{className:"flex items-center justify-between",children:e.jsxs(K,{className:"text-sm font-medium",children:["Run log — ",H.cityName," (",(H.durationMs/1e3).toFixed(1),"s)"]})})}),e.jsx(N,{children:e.jsx($e,{className:"h-64 w-full rounded border bg-muted/40 p-3",children:e.jsx("pre",{className:"text-xs whitespace-pre-wrap font-mono leading-5","data-testid":"discovery-log",children:H.log.join(`
17`)})})})]})]})]})]})]})}export{or 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.