1import{r as a,g as Y,s as l,j as e,D as Z,B as u,L as g,I as O,w as R}from"./index-PtGACUVf.js";import{T as ee,a as se,b as x,c,d as te,e as r}from"./table-BzCEyvEt.js";import{D as ae,d as ne,a as re,b as ce,c as ie}from"./dialog-1knjOMG6.js";import{S as B,a as H,b as V,c as q,d}from"./select-BwSQ4ldD.js";import{R as U}from"./refresh-cw-Dc0N6ZOE.js";import{P as le}from"./plus-Dy1doKva.js";import"./index-DU2LHGu_.js";import"./index-BdQq_4o_.js";import"./chevron-up-BZ1Up2zp.js";function ge(){const[f,$]=a.useState([]),[S,F]=a.useState([]),[M,P]=a.useState(!0),[y,w]=a.useState(null),[N,C]=a.useState(!1),[z,_]=a.useState(!1),[h,b]=a.useState(""),[m,A]=a.useState(""),[j,D]=a.useState(""),[T,k]=a.useState("auto"),{toast:n}=Y();a.useEffect(()=>{o(),G()},[]);const o=async()=>{const{data:s}=await l.from("event_sources").select("*").order("created_at",{ascending:!1});$(s||[]),P(!1)},G=async()=>{const{data:s}=await l.from("cities").select("id, name").eq("is_active",!0).order("name");F(s||[])},J=async()=>{if(!h||!m||!j){n({title:"Fill all required fields",variant:"destructive"});return}const{error:s}=await l.from("event_sources").insert({name:h,source_url:m,city_id:j,scrape_strategy:T});s?n({title:"Error adding source",description:s.message,variant:"destructive"}):(n({title:"Event source added"}),_(!1),b(""),A(""),D(""),k("auto"),o())},K=async s=>{w(s),n({title:"Scraping started..."});try{const{data:t,error:i}=await l.functions.invoke("ct-scrape-events",{body:{source_id:s}});if(i)throw i;const E=(t==null?void 0:t.results)||{},p=Object.values(E).reduce((v,I)=>v+(I>0?I:0),0);n({title:"Scrape complete",description:`${p} events inserted`}),o()}catch(t){n({title:"Scrape failed",description:t.message,variant:"destructive"})}finally{w(null)}},Q=async()=>{C(!0),n({title:"Scraping all active sources..."});try{const{data:s,error:t}=await l.functions.invoke("ct-scrape-events",{body:{}});if(t)throw t;const i=(s==null?void 0:s.results)||{},L=Object.entries(i).map(([p,v])=>`${p}: ${v}`).join(", ");n({title:"All sources scraped",description:L||"Done"}),o()}catch(s){n({title:"Scrape failed",description:s.message,variant:"destructive"})}finally{C(!1)}},W=async s=>{await l.from("event_sources").update({is_active:!s.is_active}).eq("id",s.id),o()},X=s=>{var t;return((t=S.find(i=>i.id===s))==null?void 0:t.name)||"â"};return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsxs("h1",{className:"text-2xl font-bold flex items-center gap-2",children:[e.jsx(Z,{className:"h-6 w-6"})," Event Sources"]}),e.jsx("p",{className:"text-muted-foreground",children:"Scrape events from competitor DMO sites"})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs(u,{onClick:Q,disabled:N,variant:"outline",children:[N?e.jsx(g,{className:"h-4 w-4 animate-spin mr-2"}):e.jsx(U,{className:"h-4 w-4 mr-2"}),"Scrape All"]}),e.jsxs(ae,{open:z,onOpenChange:_,children:[e.jsx(ne,{asChild:!0,children:e.jsxs(u,{children:[e.jsx(le,{className:"h-4 w-4 mr-2"})," Add Source"]})}),e.jsxs(re,{children:[e.jsx(ce,{children:e.jsx(ie,{children:"Add Event Source"})}),e.jsxs("div",{className:"space-y-4",children:[e.jsx(O,{placeholder:"Source name (e.g. Visit Lake Geneva Events)",value:h,onChange:s=>b(s.target.value)}),e.jsx(O,{placeholder:"URL (e.g. https://www.visitlakegeneva.com/events/)",value:m,onChange:s=>A(s.target.value)}),e.jsxs(B,{value:j,onValueChange:D,children:[e.jsx(H,{children:e.jsx(V,{placeholder:"Select city"})}),e.jsx(q,{children:S.map(s=>e.jsx(d,{value:s.id,children:s.name},s.id))})]}),e.jsxs(B,{value:T,onValueChange:k,children:[e.jsx(H,{children:e.jsx(V,{})}),e.jsxs(q,{children:[e.jsx(d,{value:"auto",children:"Auto-detect"}),e.jsx(d,{value:"jsonld",children:"JSON-LD only"}),e.jsx(d,{value:"ical",children:"iCal only"}),e.jsx(d,{value:"html",children:"HTML/AI only"})]})]}),e.jsx(u,{onClick:J,className:"w-full",children:"Add Source"})]})]})]})]})]}),e.jsxs(ee,{children:[e.jsx(se,{children:e.jsxs(x,{children:[e.jsx(c,{children:"Name"}),e.jsx(c,{children:"City"}),e.jsx(c,{children:"Strategy"}),e.jsx(c,{children:"Status"}),e.jsx(c,{children:"Events Found"}),e.jsx(c,{children:"Last Scraped"}),e.jsx(c,{children:"Actions"})]})}),e.jsx(te,{children:M?e.jsx(x,{children:e.jsx(r,{colSpan:7,className:"text-center py-8",children:e.jsx(g,{className:"h-5 w-5 animate-spin mx-auto"})})}):f.length===0?e.jsx(x,{children:e.jsx(r,{colSpan:7,className:"text-center py-8 text-muted-foreground",children:"No event sources yet. Add one to get started."})}):f.map(s=>e.jsxs(x,{children:[e.jsx(r,{children:e.jsxs("div",{children:[e.jsx("div",{className:"font-medium",children:s.name}),e.jsx("a",{href:s.source_url,target:"_blank",rel:"noopener",className:"text-xs text-muted-foreground hover:underline truncate block max-w-[250px]",children:s.source_url})]})}
1),e.jsx(r,{children:X(s.city_id)}),e.jsx(r,{children:e.jsx(R,{variant:"outline",children:s.scrape_strategy})}),e.jsx(r,{children:e.jsx(R,{className:"cursor-pointer",variant:s.is_active?"default":"secondary",onClick:()=>W(s),children:s.is_active?"Active":"Inactive"})}),e.jsx(r,{children:s.events_found}),e.jsx(r,{children:s.last_scraped_at?new Date(s.last_scraped_at).toLocaleDateString():"Never"}),e.jsx(r,{children:e.jsxs(u,{size:"sm",variant:"outline",disabled:y===s.id,onClick:()=>K(s.id),children:[y===s.id?e.jsx(g,{className:"h-3 w-3 animate-spin"}):e.jsx(U,{className:"h-3 w-3"}),e.jsx("span",{className:"ml-1",children:"Scrape"})]})})]},s.id))})]})]})}export{ge 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.