1import{r as i,s as c,j as e,C as g,c as j,d as y,P as U,n as D,e as p,B as o,v as m,I as v,q as a,k as us,l as xs,A as gs,bd as ae,bK as Me,Z as $e,a2 as re,G as ps,af as fs,a0 as js}from"./index-D6S94l3r.js";import{T as ys,a as vs,b as T,c as L}from"./tabs-BFGREGV3.js";import{i as Ns}from"./knownPaths-BTLtWSiT.js";import{C as _s}from"./circle-check-big-DB1_Tds_.js";import{C as ze}from"./circle-x-Biyh4d0H.js";import{R as Se}from"./refresh-cw-cPZ2haEo.js";import{E as ws}from"./eye-off-4uZXy-DR.js";import{E as bs}from"./eye-xwXaduU-.js";import{S as B}from"./save-t8jLgaQj.js";import{C as Ss}from"./circle-check-mazYLBU_.js";import{S as je,a as ye,b as ve,c as Ne,d as b}from"./select-BkXyGY_9.js";import{T as _e,a as we,b as K,c as u,d as be,e as x}from"./table-DNwFNVSx.js";import{P as X}from"./plus-BOxbBXe6.js";import"./index-BdQq_4o_.js";import"./chevron-down-0kA1qCjF.js";import"./chevron-up-D18T203o.js";function Cs(){const[P,A]=i.useState(!1),[S,C]=i.useState("unknown"),[w,q]=i.useState(null),[N,E]=i.useState(""),[k,R]=i.useState(""),[d,F]=i.useState(!1),[O,Y]=i.useState(!1);i.useEffect(()=>{H()},[]);const H=async()=>{const{data:h}=await c.from("site_settings").select("setting_key, setting_value").in("setting_key",["publer_api_key","publer_workspace_id"]);if(h)for(const f of h)f.setting_key==="publer_api_key"&&E(f.setting_value||""),f.setting_key==="publer_workspace_id"&&R(f.setting_value||"")},Z=async()=>{if(!N.trim()||!k.trim()){a.error("Both API Key and Workspace ID are required");return}F(!0);try{const h=new Date().toISOString(),{error:f}=await c.from("site_settings").upsert({setting_key:"publer_api_key",setting_value:N.trim(),description:"Publer API key for social media scheduling",updated_at:h},{onConflict:"setting_key"});if(f)throw f;const{error:W}=await c.from("site_settings").upsert({setting_key:"publer_workspace_id",setting_value:k.trim(),description:"Publer workspace ID",updated_at:h},{onConflict:"setting_key"});if(W)throw W;a.success("Publer settings saved")}catch(h){a.error("Failed to save: "+h.message)}finally{F(!1)}},G=async()=>{A(!0);try{const{data:h,error:f}=await c.functions.invoke("publer-api",{body:{action:"test-connection"}});if(f)throw f;h?.connected?(C("connected"),q(h.workspace||null),a.success("Publer connection is active")):(C("disconnected"),a.error("Publer connection failed: "+(h?.error||"Unknown error")))}catch(h){C("disconnected"),a.error("Test failed: "+h.message)}finally{A(!1)}};return e.jsxs(g,{children:[e.jsxs(j,{children:[e.jsxs(y,{className:"flex items-center gap-2",children:["Publer Integration",S==="connected"&&e.jsx(U,{variant:"default",children:"Connected"}),S==="disconnected"&&e.jsx(U,{variant:"destructive",children:"Disconnected"})]}),e.jsx(D,{children:"Connect to Publer for social media scheduling. Get your API key from Publer Settings > Access & Login > API Keys."})]}),e.jsxs(p,{className:"space-y-6",children:[e.jsxs("div",{className:"rounded-lg border p-4 space-y-3",children:[e.jsx("h3",{className:"font-medium",children:"Connection Status"}),S==="connected"&&e.jsxs("div",{className:"flex items-center gap-2 text-sm text-primary",children:[e.jsx(_s,{className:"h-4 w-4"}),e.jsxs("span",{children:["Publer API is responding",w?` (${w})`:""]})]}),S==="disconnected"&&e.jsxs("div",{className:"flex items-center gap-2 text-sm text-destructive",children:[e.jsx(ze,{className:"h-4 w-4"}),e.jsx("span",{children:"Publer API is not responding. Check your credentials below."})]}),e.jsxs(o,{variant:"outline",onClick:G,disabled:P,children:[e.jsx(Se,{className:`mr-2 h-4 w-4 ${P?"animate-spin":""}`}),P?"Testing...":"Test Connection"]})]}),e.jsxs("div",{className:"rounded-lg border p-4 space-y-4",children:[e.jsx("h3",{className:"font-medium",children:"Credentials"}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"publer-api-key",children:"API Key"}),e.jsx("div",{className:"flex gap-2",children:e.jsxs("div",{className:"relative flex-1",children:[e.jsx(v,{id:"publer-api-key",type:O?"text":"password",value:N,onChange:h=>E(h.target.value),placeholder:"Enter your Publer API key"}),e.jsx("button",{type:"button",className:"absolute right-2 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground",onClick:()=>Y(!O),children:O?e.jsx(ws,{className:"h-4 w-4"}):e.jsx(bs,{className:"h-4 w-4"})})]})}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Found in Publer > Settings > Access & Login > API Keys"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"publer-workspace-id",children:"Worksp
1ace ID"}),e.jsx(v,{id:"publer-workspace-id",value:k,onChange:h=>R(h.target.value),placeholder:"Enter your Publer workspace ID"}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:["Found in your Publer URL: app.publer.com/workspaces/",e.jsx("strong",{children:"your-workspace-id"})]})]}),e.jsxs(o,{onClick:Z,disabled:d,children:[e.jsx(B,{className:"mr-2 h-4 w-4"}),d?"Saving...":"Save Credentials"]})]})]})]})}function ks(){const[P,A]=i.useState(""),[S,C]=i.useState(!1),[w,q]=i.useState(!1),[N,E]=i.useState(null);i.useEffect(()=>{(async()=>{const{data:F}=await c.from("site_settings").select("setting_value").eq("setting_key","short_io_domain_id").maybeSingle();F?.setting_value&&A(F.setting_value)})()},[]);const k=async()=>{C(!0);try{const{error:d}=await c.from("site_settings").upsert({setting_key:"short_io_domain_id",setting_value:P.trim(),description:"Short.io domain ID for API calls",updated_at:new Date().toISOString()},{onConflict:"setting_key"});if(d)throw d;a.success("Domain ID saved")}catch(d){a.error("Failed to save: "+d.message)}finally{C(!1)}},R=async()=>{q(!0),E(null);try{const{data:d,error:F}=await c.functions.invoke("sync-short-urls",{body:{action:"test"}});if(F)throw F;E({success:!!d?.success,message:d?.message||d?.error||"Short.io test failed"})}catch(d){E({success:!1,message:d.message||"Short.io test failed"})}finally{q(!1)}};return e.jsxs(g,{children:[e.jsxs(j,{children:[e.jsx(y,{children:"Short.io Integration"}),e.jsx(D,{children:"Configure Short.io for tracking click statistics on your short URLs. The API Key and Domain are stored as Supabase secrets (SHORT_IO_API_KEY and SHORT_IO_DOMAIN)."})]}),e.jsxs(p,{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-sm text-muted-foreground",children:"API Key:"}),e.jsx(U,{variant:"outline",children:"Configured as secret"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-sm text-muted-foreground",children:"Domain:"}),e.jsx(U,{variant:"outline",children:"Configured as secret"})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"short-io-domain-id",children:"Domain ID"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Find this in your Short.io dashboard under Domain settings. It's the numeric ID used in API calls to list links."}),e.jsxs("div",{className:"flex gap-2 max-w-md",children:[e.jsx(v,{id:"short-io-domain-id",value:P,onChange:d=>A(d.target.value),placeholder:"e.g. 123456"}),e.jsxs(o,{onClick:k,disabled:S,children:[e.jsx(B,{className:"mr-2 h-4 w-4"}),S?"Saving...":"Save"]})]})]}),e.jsxs("div",{className:"border-t pt-4 space-y-3",children:[e.jsxs(o,{onClick:R,disabled:w,variant:"outline",children:[e.jsx(Se,{className:`mr-2 h-4 w-4 ${w?"animate-spin":""}`}),w?"Testing...":"Test Connection"]}),N&&e.jsx("div",{className:"flex items-center gap-2 text-sm",children:N.success?e.jsxs(e.Fragment,{children:[e.jsx(Ss,{className:"h-4 w-4 text-green-600"}),e.jsx("span",{className:"text-green-600",children:N.message})]}):e.jsxs(e.Fragment,{children:[e.jsx(ze,{className:"h-4 w-4 text-destructive"}),e.jsx("span",{className:"text-destructive",children:N.message})]})})]}),e.jsxs("div",{className:"border-t pt-4",children:[e.jsxs("p",{className:"text-sm text-muted-foreground",children:[e.jsx("strong",{children:"Note:"})," The SHORT_IO_API_KEY and SHORT_IO_DOMAIN secrets must be configured in your Supabase project's Edge Function secrets. The Domain ID above is stored in site settings and is used by the sync function to know which domain to query."]}),e.jsx("p",{className:"text-sm text-muted-foreground mt-2",children:"Currently, the sync function uses the SHORT_IO_DOMAIN secret directly. If your domain ID differs from your domain name, update the edge function configuration accordingly."})]})]})]})}const zs=()=>{const{user:P,isAdmin:A,loading:S}=us(),C=xs(),[w,q]=i.useState([]),[N,E]=i.useState([]),[k,R]=i.useState([]),[d,F]=i.useState(""),[O,Y]=i.useState(""),[H,Z]=i.useState(""),[G,h]=i.useState(""),[f,W]=i.useState(!1),[ie,Ce]=i.useState(!1),[ke,Ie]=i.useState(""),[Pe,Fe]=i.useState(""),[M,$]=i.useState(!1),[J,Ke]=i.useState([]),[ne,ce]=i.useState([]),[le,oe]=i.useState([]),[de,Ae]=i.useState(""),[me,Re]=i.useState(""),[He,he]=i.useState(!0),[We,ue]=i.useState(!1),[l,Te]=i.useState(null),[Le,Xe]=i.useState([]),[Is,Ye]=i.useState(null),[De,xe]=i.useState({}),[Q,Ze]=i.useState([]),[_,z]=i.useState({old_path:"",new_path:"",redirect_type:"301",notes:""}),[Ue,Ee]=i.useState(!1),[Oe,Je]=i.useState([]);i.useEffect(()=>{if(!S&&!P){C("/admin/login");return}if(!S&&!A){C("/admin");return}P&&A&&(ge(),se(),te(),rs(),ee(),Be(),as(),Ve())},[P,A,S]);const Ve=async()=>{const{data:s,error:t}=await c.from("social_media_links").select("*").order("display_order");if(!t&&s){Xe(s);const r={};
1s.forEach(n=>{r[n.id]={url:n.url,is_active:n.is_active}}),xe(r)}},Qe=async s=>{const t=De[s];if(!t)return;const{error:r}=await c.from("social_media_links").update({url:t.url,is_active:t.is_active}).eq("id",s);if(r){a.error("Failed to save social link");return}a.success("Social link saved"),Ye(null),Ve()},ee=async()=>{const{data:s,error:t}=await c.from("url_redirects").select("*").order("created_at",{ascending:!1});if(t){a.error("Failed to fetch URL redirects");return}Ze(s||[])},Be=async()=>{const{data:s,error:t}=await c.from("page_views").select("page_path, view_count").eq("page_type","other");if(t||!s)return;const r={};for(const I of s)r[I.page_path]=(r[I.page_path]||0)+I.view_count;const{data:n}=await c.from("url_redirects").select("old_path"),V=new Set((n||[]).map(I=>I.old_path.toLowerCase())),pe=Object.entries(r).filter(([I])=>!Ns(I)).map(([I,fe])=>({path:I,totalViews:fe,alreadyRedirected:V.has(I.toLowerCase())})).sort((I,fe)=>fe.totalViews-I.totalViews);Je(pe)},es=async()=>{if(!_.old_path.trim()||!_.new_path.trim()){a.error("Both old and new paths are required");return}Ee(!0);try{const{error:s}=await c.from("url_redirects").insert({old_path:_.old_path.trim(),new_path:_.new_path.trim(),redirect_type:_.redirect_type,notes:_.notes.trim()||null});if(s){if(s.code==="23505")a.error("A redirect for this old path already exists");else throw s;return}a.success("Redirect added"),z({old_path:"",new_path:"",redirect_type:"301",notes:""}),ee(),Be()}catch(s){a.error("Failed to add redirect: "+s.message)}finally{Ee(!1)}},ss=async(s,t)=>{const{error:r}=await c.from("url_redirects").update({is_active:!t}).eq("id",s);if(r){a.error("Failed to update redirect");return}ee()},ts=async s=>{const{error:t}=await c.from("url_redirects").delete().eq("id",s);if(t){a.error("Failed to delete redirect");return}a.success("Redirect deleted"),ee()},as=async()=>{const{data:s}=await c.from("user_profiles").select("id, email, first_name, last_name").order("last_name");Ke(s||[])},rs=async()=>{const{data:s,error:t}=await c.from("site_settings").select("*");if(!t&&s)for(const r of s)r.setting_key==="safeguarding_report_email"?Ie(r.setting_value||""):r.setting_key==="supabase_functions_base_url"?Fe(r.setting_value||""):r.setting_key==="volunteer_signup_notify_users"?ce(r.setting_value?r.setting_value.split(",").filter(Boolean):[]):r.setting_key==="member_signup_notify_users"?oe(r.setting_value?r.setting_value.split(",").filter(Boolean):[]):r.setting_key==="arts_directory_enabled"?he(r.setting_value!=="false"):r.setting_key==="volunteer_rota_enabled"&&ue(r.setting_value==="true")},qe=async(s,t,r)=>{$(!0);try{const{error:n}=await c.from("site_settings").upsert({setting_key:s,setting_value:t.join(","),description:r,updated_at:new Date().toISOString()},{onConflict:"setting_key"});if(n)throw n;a.success("Notification recipients saved")}catch(n){a.error("Failed to save: "+n.message)}finally{$(!1)}},is=async()=>{$(!0);try{const{error:s}=await c.from("site_settings").upsert({setting_key:"safeguarding_report_email",setting_value:ke.trim(),description:"Email address for safeguarding incident reports from user groups",updated_at:new Date().toISOString()},{onConflict:"setting_key"});if(s)throw s;a.success("Safeguarding email saved")}catch(s){a.error("Failed to save: "+s.message)}finally{$(!1)}},ns=async()=>{$(!0);try{const{error:s}=await c.from("site_settings").upsert({setting_key:"supabase_functions_base_url",setting_value:Pe.trim()||null,description:"Base URL used by database cron jobs to call edge functions",updated_at:new Date().toISOString()},{onConflict:"setting_key"});if(s)throw s;a.success("Functions base URL saved")}catch(s){a.error("Failed to save: "+s.message)}finally{$(!1)}},ge=async()=>{const{data:s,error:t}=await c.from("categories").select("*").order("display_order");if(t){a.error("Failed to fetch categories");return}q(s||[])},se=async()=>{const{data:s,error:t}=await c.from("genres").select("*").order("display_order");if(t){a.error("Failed to fetch genres");return}E(s||[])},cs=async()=>{if(!d.trim()){a.error("Category name is required");return}const s=d.trim(),t=s.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,""),{error:r}=await c.from("categories").insert({name:s,slug:t,display_order:w.length});if(r){a.error("Failed to add category");return}a.success("Category added"),F(""),ge()},ls=async s=>{const{error:t}=await c.from("categories").delete().eq("id",s);if(t){a.error("Failed to delete category");return}a.success("Category deleted"),ge(),se()},os=async()=>
1{if(!O.trim()){a.error("Genre name is required");return}if(!G){a.error("Please select a category");return}const s=O.trim(),t=s.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,""),{error:r}=await c.from("genres").insert({name:s,slug:t,category_id:G,display_order:N.filter(n=>n.category_id===G).length});if(r){a.error("Failed to add genre");return}a.success("Genre added"),Y(""),se()},ds=async s=>{const{error:t}=await c.from("genres").delete().eq("id",s);if(t){a.error("Failed to delete genre");return}a.success("Genre deleted"),se()},te=async()=>{const{data:s,error:t}=await c.from("marketing_platforms").select("*").order("display_order");if(t){a.error("Failed to fetch platforms");return}R(s||[])},ms=async()=>{if(!H.trim()){a.error("Platform name is required");return}const{error:s}=await c.from("marketing_platforms").insert({name:H.trim(),display_order:k.length});if(s){a.error("Failed to add platform");return}a.success("Platform added"),Z(""),te()},hs=async s=>{const{error:t}=await c.from("marketing_platforms").delete().eq("id",s);if(t){a.error("Failed to delete platform");return}a.success("Platform deleted"),te()},Ge=async(s=!1)=>{W(!0),Te(null);try{const{data:t,error:r}=await c.functions.invoke("verify-shopify-sync",{body:{autoCreate:s}});if(r)throw r;Te(t),s&&t.products.needsSync===0?a.success("All products created and synced"):t.products.errors.length===0&&t.discountCodes.errors.length===0?a.success("Sync complete"):a.warning("Sync complete with errors")}catch(t){a.error(`Sync failed: ${t.message}`)}finally{W(!1)}};return S||!P||!A?null:e.jsx("div",{className:"min-h-screen bg-background",children:e.jsxs("div",{className:"container mx-auto py-8 px-4",children:[e.jsxs("div",{className:"mb-6",children:[e.jsxs(o,{variant:"ghost",onClick:()=>C("/admin"),className:"mb-4",children:[e.jsx(gs,{className:"mr-2 h-4 w-4"}),"Back to Admin"]}),e.jsx("h1",{className:"text-3xl font-bold",children:"Configuration"}),e.jsx("p",{className:"text-muted-foreground mt-2",children:"Manage categories and genres for productions"})]}),e.jsxs(ys,{defaultValue:"categories",className:"space-y-6",children:[e.jsxs(vs,{className:"flex-wrap h-auto",children:[e.jsx(T,{value:"categories",children:"Categories"}),e.jsx(T,{value:"genres",children:"Genres"}),e.jsx(T,{value:"platforms",children:"Platforms"}),e.jsx(T,{value:"publer",children:"Publer"}),e.jsx(T,{value:"short-io",children:"Short.io"}),e.jsx(T,{value:"url-redirects",children:"URL Redirects"}),e.jsx(T,{value:"social-media",children:"Social Media"}),e.jsx(T,{value:"site-settings",children:"Site Settings"}),e.jsx(T,{value:"shopify",children:"Shopify Sync"})]}),e.jsx(L,{value:"publer",children:e.jsx(Cs,{})}),e.jsx(L,{value:"short-io",children:e.jsx(ks,{})}),e.jsx(L,{value:"social-media",children:e.jsxs(g,{children:[e.jsxs(j,{children:[e.jsx(y,{children:"Social Media Links"}),e.jsx(D,{children:"Configure which social media icons appear in the website footer. Toggle platforms on/off and set their URLs."})]}),e.jsx(p,{children:e.jsxs("div",{className:"space-y-4",children:[Le.map(s=>{const t=De[s.id];return e.jsxs("div",{className:"flex items-center gap-4 p-4 border border-border rounded-lg",children:[e.jsx("div",{className:"w-24 font-medium capitalize text-foreground",children:s.platform==="x"?"X (Twitter)":s.platform}),e.jsx("div",{className:"flex-1",children:e.jsx(v,{value:t?.url||"",onChange:r=>xe(n=>({...n,[s.id]:{...n[s.id],url:r.target.value}})),placeholder:`https://${s.platform}.com/your-page`})}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(m,{htmlFor:`social-active-${s.id}`,className:"text-sm text-muted-foreground",children:"Active"}),e.jsx(ae,{id:`social-active-${s.id}`,checked:t?.is_active||!1,onCheckedChange:r=>{xe(n=>({...n,[s.id]:{...n[s.id],is_active:r}}))}})]}),e.jsxs(o,{size:"sm",onClick:()=>Qe(s.id),disabled:t?.url===s.url&&t?.is_active===s.is_active,children:[e.jsx(B,{className:"h-4 w-4 mr-1"}),"Save"]})]},s.id)}),Le.length===0&&e.jsx("p",{className:"text-muted-foreground text-sm",children:"No social media platforms configured."})]})})]})}),e.jsx(L,{value:"site-settings",children:e.jsxs(g,{children:[e.jsxs(j,{children:[e.jsx(y,{children:"Site Settings"}),e.jsx(D,{children:"Configure email addresses and other site-wide settings"})]}),e.jsxs(p,{className:"space-y-6",children:[e.jsxs("div",{className:"space-y-3",children:[e.jsx(m,{className:"text-base font-semibold",children:"Feature Flags"}),e.jsxs("div",{className:"flex items-center justify-between max-w-md",children:[e.jsxs("div",{children:[e.jsx(m,{htmlFor:"arts-directory-toggle",children:"Arts Directory"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Show the Arts Directory in the navigation and allow public access to directory pages."})]}),e.jsx(ae,{id:"arts-directory-toggle",checked:He,onCheckedChange:async s=>{he(s);const{error:t}=await c.from("site_settings").upsert({setting_key:"arts_directory_enabled",setting_value:String(s),description:"Feature flag: show/hide the Arts Directory from navigation and public routes",updated_at:new Date().toISOString()},{onConflict:"setting_key"});t?(a.error("Failed to save"),he(!s)):(a.success(`Arts Directory ${s?"enabled":"disabled"}`),Me())}})]}),e.jsxs("div",{className:"flex items-center justify-between max-w-md",children:[e.jsxs("div",{children:[e.jsx(m,{htmlFor:"volunteer-rota-toggle",children:"Volunteer Rota"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Show the in-house volunteer rota to active volunteers. While off, only admins, trustees and marketing can see it (configure freely without exposing it)."})]}),e.jsx(ae,{id:"volunteer-rota-toggle",checked:We,onCheckedChange:async s=>{ue(s);const{error:t}=await c.from("site_settings").upsert({setting_key:"volunteer_rota_enabled",setting_value:String(s),description:"Feature flag: show the volunteer rota to active volunteers (admins/trustees/marketing always see it)",updated_at:new Date().toISOString()},{onConflict:"setting_key"});t?(a.error("Failed to save"),ue(!s)):(a.success(`Volunteer Rota ${s?"enabled":"disabled"}`),Me())}})]})]}),e.jsxs("div",{className:"border-t pt-4 space-y-2",children:[e.jsx(m,{className:"text-base font-semibold",children:"Volunteer Rota Configuration"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Manage shift types (categories) and skills used by the volunteer rota."}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsx(o,{variant:"outline",size:"sm",onClick:()=>C("/admin/volunteer-shift-types"),children:"Shift Types"}),e.jsx(o,{variant:"outline",size:"sm",onClick:()=>C("/admin/volunteer-skills"),children:"Skills"})]})]}),e.jsxs("div",{className:"border-t pt-4 space-y-2",children:[e.jsx(m,{htmlFor:"safeguarding-email",children:"Safeguarding Report Email"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Email address where user group safeguarding incident reports will be sent."}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(v,{id:"safeguarding-email",type:"email",value:ke,onChange:s=>Ie(s.target.value),placeholder:"[email protected]",className:"max-w-md"}),e.jsxs(o,{onClick:is,disabled:M,children:[e.jsx(B,{className:"mr-2 h-4 w-4"}),M?"Saving...":"Save"]})]})]}),e.jsxs("div",{className:"space-y-2 border-t pt-4",children:[e.jsx(m,{htmlFor:"supabase-functions-base-url",children:"Functions Base URL"}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Used by database cron jobs to call edge functions. For self
1-hosted production this should usually be",e.jsx("span",{className:"font-mono",children:" https://api.theabbeytheatre.com"}),"."]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(v,{id:"supabase-functions-base-url",type:"url",value:Pe,onChange:s=>Fe(s.target.value),placeholder:"https://api.theabbeytheatre.com",className:"max-w-md"}),e.jsxs(o,{onClick:ns,disabled:M,children:[e.jsx(B,{className:"mr-2 h-4 w-4"}),M?"Saving...":"Save"]})]})]}),e.jsxs("div",{className:"space-y-2 border-t pt-4",children:[e.jsx(m,{children:"Volunteer Signup Notifications"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Users to email when a new volunteer application is submitted."}),e.jsx("div",{className:"flex flex-wrap gap-2 mb-2",children:ne.map(s=>{const t=J.find(r=>r.id===s);return t?e.jsxs(U,{variant:"secondary",className:"gap-1",children:[t.first_name," ",t.last_name," (",t.email,")",e.jsx("button",{onClick:()=>ce(r=>r.filter(n=>n!==s)),className:"ml-1",children:e.jsx($e,{className:"h-3 w-3"})})]},s):null})}),e.jsx("div",{className:"flex gap-2 max-w-md",children:e.jsx(v,{placeholder:"Search users...",value:de,onChange:s=>Ae(s.target.value)})}),de.length>=2&&e.jsx("div",{className:"border rounded-md max-h-40 overflow-y-auto max-w-md",children:J.filter(s=>!ne.includes(s.id)).filter(s=>{const t=de.toLowerCase();return s.first_name?.toLowerCase().includes(t)||s.last_name?.toLowerCase().includes(t)||s.email.toLowerCase().includes(t)}).slice(0,10).map(s=>e.jsxs("button",{className:"w-full text-left px-3 py-2 text-sm hover:bg-muted transition-colors",onClick:()=>{ce(t=>[...t,s.id]),Ae("")},children:[s.first_name," ",s.last_name," â ",s.email]},s.id))}),e.jsxs(o,{onClick:()=>qe("volunteer_signup_notify_users",ne,"User IDs to notify on new volunteer signups"),disabled:M,size:"sm",children:[e.jsx(B,{className:"mr-2 h-4 w-4"}),"Save"]})]}),e.jsxs("div",{className:"space-y-2 border-t pt-4",children:[e.jsx(m,{children:"Member Signup Notifications"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Users to email when a new membership application is submitted."}),e.jsx("div",{className:"flex flex-wrap gap-2 mb-2",children:le.map(s=>{const t=J.find(r=>r.id===s);return t?e.jsxs(U,{variant:"secondary",className:"gap-1",children:[t.first_name," ",t.last_name," (",t.email,")",e.jsx("button",{onClick:()=>oe(r=>r.filter(n=>n!==s)),className:"ml-1",children:e.jsx($e,{className:"h-3 w-3"})})]},s):null})}),e.jsx("div",{className:"flex gap-2 max-w-md",children:e.jsx(v,{placeholder:"Search users...",value:me,onChange:s=>Re(s.target.value)})}),me.length>=2&&e.jsx("div",{className:"border rounded-md max-h-40 overflow-y-auto max-w-md",children:J.filter(s=>!le.includes(s.id)).filter(s=>{const t=me.toLowerCase();return s.first_name?.toLowerCase().includes(t)||s.last_name?.toLowerCase().includes(t)||s.email.toLowerCase().includes(t)}).slice(0,10).map(s=>e.jsxs("button",{className:"w-full text-left px-3 py-2 text-sm hover:bg-muted transition-colors",onClick:()=>{oe(t=>[...t,s.id]),Re("")},children:[s.first_name," ",s.last_name," â ",s.email]},s.id))}),e.jsxs(o,{onClick:()=>qe("member_signup_notify_users",le,"User IDs to notify on new member signups"),disabled:M,size:"sm",children:[e.jsx(B,{className:"mr-2 h-4 w-4"}),"Save"]})]})]})]})}),e.jsxs(L,{value:"categories",children:[e.jsxs(g,{children:[e.jsx(j,{children:e.jsx(y,{children:"Add Category"})}),e.jsx(p,{children:e.jsxs("div",{className:"flex gap-2",children:[e.jsxs("div",{className:"flex-1",children:[e.jsx(m,{htmlFor:"category-name",children:"Category Name"}),e.jsx(v,{id:"category-name",value:d,onChange:s=>F(s.target.value),placeholder:"e.g., Theatre, Music, Dance"})]}),e.jsxs(o,{onClick:cs,className:"mt-6",children:[e.jsx(X,{className:"mr-2 h-4 w-4"}),"Add"]})]})})]}),e.jsxs(g,{className:"mt-6",children:[e.jsx(j,{children:e.jsx(y,{children:"Categories"})}),e.jsx(p,{children:e.jsxs("div",{className:"space-y-2",children:[w.map(s=>e.jsxs("div",{className:"flex items-center justify-between p-3 border rounded-lg",children:[e.jsx("span",{className:"font-medium",children:s.name}),e.jsx(o,{variant:"destructive",size:"sm",onClick:()=>ls(s.id),children:e.jsx(re,{className:"h-4 w-4"})})]},s.id)),w.length===0&&e.jsx("p",{className:"text-muted-foreground text-center py-8",children:"No categories yet"})]})})]})]}),e.jsxs(L,{value:"genres",children:[e.jsxs(g,{children:[e.jsx(j,{children:e.jsx(y,{children:"Add Genre"})}),e.jsx(p,{children:e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx(m,{htmlFor:"genre-category",children:"Category"}),e.jsxs(je,{value:G,onValueChange:h,children:[e.jsx(ye,{id:"genre-category",children:e.jsx(ve,{placeholder:"Select category"})}),e.jsx(Ne,{children:w.map(s=>e.jsx(b,{value:s.id,children:s.name},s.id))})]})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs("div",{className:"flex-1",children:[e.jsx(m,{htmlFor:"genre-name",children:"Genre Name"}),e.jsx(v,{id:"genre-name",value:O,onChange:s=>Y(s.target.value),placeholder:"e.g., Drama, Comedy, Musical"})]}),e.jsxs(o,{onClick:os,className:"mt-6",children:[e.jsx(X,{className:"mr-2 h-4 w-4"}),"Add"]})]})]})})]}),e.jsxs(g,{className:"mt-6",children:[e.jsx(j,{children:e.jsx(y,{children:"Genres"})}),e.jsx(p,{children:w.filter(s=>N.some(t=>t.category_id===s.id)).length===0&&N.length===0?e.jsx("p",{className:"text-muted-foreground text-center py-8",children:"No genres yet"}):e.jsx("div",{className:"space-y-4",children:w.filter(s=>N.some(t=>t.category_id===s.id)).map(s=>e.jsxs("div",{children:[e.jsx("h3",{className:"font-semibold text-sm text-foreground mb-1.5",children:s.name}),e.jsx("div",{className:"space-y-1 ml-4 border-l-2 border-muted pl-3",children:N.filter(t=>t.category_id===s.id).map(t=>e.jsxs("div",{className:"flex items-center justify-between py-1.5",children:[e.jsx("span",{className:"text-sm",children:t.name}),e.jsx(o,{variant:"destructive",size:"sm",className:"h-7 w-7 p-0",onClick:()=>
1ds(t.id),children:e.jsx(re,{className:"h-3.5 w-3.5"})})]},t.id))})]},s.id))})})]})]}),e.jsxs(L,{value:"platforms",children:[e.jsxs(g,{children:[e.jsxs(j,{children:[e.jsx(y,{children:"Add Platform"}),e.jsx(D,{children:"Marketing platforms used for short URLs, blurbs, and Publer scheduling."})]}),e.jsx(p,{children:e.jsxs("div",{className:"flex gap-2",children:[e.jsxs("div",{className:"flex-1",children:[e.jsx(m,{htmlFor:"platform-name",children:"Platform Name"}),e.jsx(v,{id:"platform-name",value:H,onChange:s=>Z(s.target.value),placeholder:"e.g., Facebook, TikTok"})]}),e.jsxs(o,{onClick:ms,className:"mt-6",children:[e.jsx(X,{className:"mr-2 h-4 w-4"}),"Add"]})]})})]}),e.jsxs(g,{className:"mt-6",children:[e.jsx(j,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx(y,{children:"Platforms"}),e.jsx(D,{children:"Map platforms to Publer social network types and set character limits."})]}),e.jsxs(o,{variant:"outline",size:"sm",disabled:ie,onClick:async()=>{Ce(!0);const s=a.loading("Connecting to Publer...");try{const{data:t,error:r}=await c.functions.invoke("publer-api",{body:{action:"sync-accounts"}});if(r)throw r;if(t?.mappings)for(const n of t.mappings){const V=n.matched?`â ${n.publerNetwork}: Linked to ${n.accountName}`:`â ${n.publerNetwork}: No match found`;a.loading(V,{id:s}),await new Promise(pe=>setTimeout(pe,500))}a.success(`Synced: ${t.matchedCount}/${t.totalPlatforms} platforms matched`,{id:s}),te()}catch(t){a.error(`Sync failed: ${t.message}`,{id:s})}finally{Ce(!1)}},children:[e.jsx(Se,{className:ps("mr-2 h-4 w-4",ie&&"animate-spin")}),ie?"Syncing...":"Sync Publer Accounts"]})]})}),e.jsx(p,{children:k.length===0?e.jsx("p",{className:"text-muted-foreground text-center py-8",children:"No platforms yet"}):e.jsx("div",{className:"overflow-x-auto",children:e.jsxs(_e,{children:[e.jsx(we,{children:e.jsxs(K,{children:[e.jsx(u,{children:"Name"}),e.jsx(u,{children:"Publer Network"}),e.jsx(u,{children:"Publer Account"}),e.jsx(u,{children:"Char Limit"}),e.jsx(u,{children:"Supports Images"}),e.jsx(u,{className:"text-right",children:"Actions"})]})}),e.jsx(be,{children:k.map(s=>e.jsxs(K,{children:[e.jsx(x,{className:"font-medium",children:s.name}),e.jsx(x,{children:e.jsxs(je,{value:s.publer_network||"__none__",onValueChange:async t=>{const r=t==="__none__"?null:t,{error:n}=await c.from("marketing_platforms").update({publer_network:r}).eq("id",s.id);if(n){a.error("Failed to update");return}R(k.map(V=>V.id===s.id?{...V,publer_network:r}:V)),a.success("Updated")},children:[e.jsx(ye,{className:"w-[160px]",children:e.jsx(ve,{placeholder:"Not mapped"})}),e.jsxs(Ne,{children:[e.jsx(b,{value:"__none__",children:"Not mapped"}),e.jsx(b,{value:"facebook",children:"Facebook"}),e.jsx(b,{value:"instagram",children:"Instagram"}),e.jsx(b,{value:"twitter",children:"X / Twitter"}),e.jsx(b,{value:"linkedin",children:"LinkedIn"}),e.jsx(b,{value:"pinterest",children:"Pinterest"}),e.jsx(b,{value:"youtube",children:"YouTube"}),e.jsx(b,{value:"tiktok",children:"TikTok"}),e.jsx(b,{value:"google_business",children:"Google Business"}),e.jsx(b,{value:"mastodon",children:"Mastodon"})]})]})}),e.jsx(x,{children:s.publer_account_id?e.jsxs(U,{variant:"secondary",className:"text-xs font-mono truncate max-w-[140px]",children:[s.publer_account_id.substring(0,12),"â¦"]}):e.jsx("span",{className:"text-xs text-muted-foreground",children:"â"})}),e.jsx(x,{children:e.jsx(v,{type:"number",className:"w-[100px]",value:s.character_limit??"",placeholder:"â",onChange:async t=>{const r=t.target.value?parseInt(t.target.value):null;R(k.map(n=>n.id===s.id?{...n,character_limit:r}:n))},onBlur:async t=>{const r=t.target.value?parseInt(t.target.value):null,{error:n}=await c.from("marketing_platforms").update({character_limit:r}).eq("id",s.id);n&&a.error("Failed to save")}})}),e.jsx(x,{children:e.jsx("input",{type:"checkbox",checked:s.supports_images!==!1,onChange:async t=>{const{error:r}=await c.from("marketing_platforms").update({supports_images:t.target.checked}).eq("id",s.id);if(r){a.error("Failed to update");return}R(k.map(n=>n.id===s.id?{...n,supports_images:t.target.checked}:n))}})}),e.jsx(x,{className:"text-right",children:e.jsx(o,{variant:"destructive",size:"sm",onClick:()=>hs(s.id),children:e.jsx(re,{className:"h-4 w-4"})})})]},s.id))})]})})})]})]}),e.jsx(L,{value:"shopify",children:e.jsxs(g,{children:[e.jsx(j,{children:e.jsx(y,{children:"Shopify Sync"})}),e.jsxs(p,{className:"space-y-4",children:[e.jsx("p",{className:"text-muted-foreground",children:"Verify all products and discount codes are synchronized with Shopify"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(o,{onClick:()=>Ge(!1),disabled:f,variant:"outline",children:f?"Checking...":"Check Status"}),e.jsx(o,{onClick:()=>
1Ge(!0),disabled:f,children:f?"Syncing...":"Sync & Create Missing"})]}),l&&e.jsxs("div",{className:"space-y-6",children:[e.jsx(g,{className:"border-2",children:e.jsx(p,{className:"pt-6",children:e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx("span",{className:l.products.needsSync===0&&l.products.errors.length===0?"text-green-600":"text-amber-600",children:l.products.needsSync===0&&l.products.errors.length===0?"â":"â "}),e.jsxs("div",{className:"flex-1",children:[e.jsxs("p",{className:"font-medium",children:["Products: ",l.products.synced,"/",l.products.total," synced"]}),l.products.needsSync>0&&e.jsxs("p",{className:"text-sm text-amber-600 mt-1",children:[l.products.needsSync," showtime pricing combination(s) need Shopify products created"]}),l.products.errors.length>0&&e.jsx("div",{className:"mt-2 space-y-1",children:l.products.errors.map((s,t)=>e.jsxs("p",{className:"text-sm text-destructive",children:["⢠",s.id,": ",s.message]},t))})]})]}),e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx("span",{className:l.discountCodes.needsSync===0&&l.discountCodes.errors.length===0?"text-green-600":"text-amber-600",children:l.discountCodes.needsSync===0&&l.discountCodes.errors.length===0?"â":"â "}),e.jsxs("div",{className:"flex-1",children:[e.jsxs("p",{className:"font-medium",children:["Discount Codes: ",l.discountCodes.synced,"/",l.discountCodes.total," synced"]}),l.discountCodes.needsSync>0&&e.jsxs("p",{className:"text-sm text-amber-600 mt-1",children:[l.discountCodes.needsSync," discount code(s) not yet synced to Shopify"]}),l.discountCodes.errors.length>0&&e.jsx("div",{className:"mt-2 space-y-1",children:l.discountCodes.errors.map((s,t)=>e.jsxs("p",{className:"text-sm text-destructive",children:["⢠",s.id,": ",s.message]},t))})]})]}),l.products.needsSync===0&&l.products.errors.length===0&&l.discountCodes.needsSync===0&&l.discountCodes.errors.length===0&&e.jsx("p",{className:"text-sm text-green-600",children:"â All items synchronized successfully"})]})})}),e.jsxs(g,{children:[e.jsx(j,{children:e.jsx(y,{className:"text-lg",children:"Discount Code Compatibility"})}),e.jsxs(p,{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx("h4",{className:"font-medium text-sm mb-2",children:"Supported Features:"}),e.jsx("ul",{className:"text-sm text-muted-foreground space-y-1",children:l.discountCompatibility.supported.map((s,t)=>e.jsxs("li",{children:["â ",s]},t))})]}),e.jsxs("div",{children:[e.jsx("h4",{className:"font-medium text-sm mb-2 text-amber-600",children:"Limitations:"}),e.jsx("ul",{className:"text-sm text-muted-foreground space-y-1",children:l.discountCompatibility.limitations.map((s,t)=>e.jsxs("li",{children:["â ",s]},t))})]})]})]})]})]})]})}),e.jsxs(L,{value:"url-redirects",className:"space-y-6",children:[Oe.length>0&&e.jsxs(g,{className:"border-amber-500/40",children:[e.jsxs(j,{children:[e.jsxs(y,{className:"flex items-center gap-2",children:[e.jsx(fs,{className:"h-5 w-5 text-amber-500"}),"Suggested Redirects"]}),e.jsx(D,{children:"These paths are receiving traffic but don't match any known page â they're likely 404 errors. Consider creating redirects for them."})]}),e.jsx(p,{children:e.jsx("div",{className:"overflow-x-auto",children:e.jsxs(_e,{children:[e.jsx(we,{children:e.jsxs(K,{children:[e.jsx(u,{children:"404 Path"}),e.jsx(u,{className:"text-right",children:"Views"}),e.jsx(u,{className:"text-center",children:"Status"}),e.jsx(u,{className:"text-right",children:"Action"})]})}),e.jsx(be,{children:Oe.slice(0,20).map(s=>e.jsxs(K,{children:[e.jsx(x,{className:"font-mono text-sm",children:s.path}),e.jsx(x,{className:"text-right font-medium",children:s.totalViews.toLocaleString()}),e.jsx(x,{className:"text-center",children:s.alreadyRedirected?e.jsx(U,{variant:"outline",children:"Redirected"}):e.jsx(U,{variant:"destructive",children:"No redirect"})}),e.jsx(x,{className:"text-right",children:!s.alreadyRedirected&&e.jsxs(o,{variant:"outline",size:"sm",onClick:()=>{z({old_path:s.path,new_path:"",redirect_type:"301",notes:"From 404 analytics suggestion"}),document.getElementById("add-redirect-card")?.scrollIntoView({behavior:"smooth"})},children:[e.jsx(X,{className:"mr-1 h-3 w-3"}),"Create"]})})]},s.path))})]})})})]}),e.jsxs(g,{id:"add-redirect-card",children:[e.jsxs(j,{children:[e.jsx(y,{children:"Add URL Redirect"}),e.jsx(D,{children:"Redirect old URLs (e.g., from the previous website) to new pages"})]}),e.jsxs(p,{className:"space-y-4",children:[e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"old-path",children:"Old Path"}),e.jsx(v,{id:"old-path",value:_.old_path,onChange:s=>
1z({..._,old_path:s.target.value}),placeholder:"/3amigos"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"new-path",children:"New Path"}),e.jsx(v,{id:"new-path",value:_.new_path,onChange:s=>z({..._,new_path:s.target.value}),placeholder:"/shows/three-amigos"})]})]}),e.jsxs("div",{className:"grid gap-4 sm:grid-cols-2",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"redirect-type",children:"Redirect Type"}),e.jsxs(je,{value:_.redirect_type,onValueChange:s=>z({..._,redirect_type:s}),children:[e.jsx(ye,{id:"redirect-type",children:e.jsx(ve,{})}),e.jsxs(Ne,{children:[e.jsx(b,{value:"301",children:"301 (Permanent)"}),e.jsx(b,{value:"302",children:"302 (Temporary)"})]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(m,{htmlFor:"redirect-notes",children:"Notes (optional)"}),e.jsx(v,{id:"redirect-notes",value:_.notes,onChange:s=>z({..._,notes:s.target.value}),placeholder:"From old website"})]})]}),e.jsxs(o,{onClick:es,disabled:Ue,children:[e.jsx(X,{className:"mr-2 h-4 w-4"}),Ue?"Adding...":"Add Redirect"]})]})]}),e.jsxs(g,{className:"mt-6",children:[e.jsxs(j,{children:[e.jsx(y,{children:"Existing Redirects"}),e.jsxs(D,{children:[Q.length," redirect",Q.length!==1?"s":""," configured"]})]}),e.jsx(p,{children:Q.length===0?e.jsx("p",{className:"text-muted-foreground text-center py-8",children:"No redirects configured yet"}):e.jsx("div",{className:"overflow-x-auto",children:e.jsxs(_e,{children:[e.jsx(we,{children:e.jsxs(K,{children:[e.jsx(u,{children:"Old Path"}),e.jsx(u,{children:"New Path"}),e.jsx(u,{className:"text-center",children:"Type"}),e.jsx(u,{className:"text-center",children:"Hits"}),e.jsx(u,{className:"text-center",children:"Active"}),e.jsx(u,{className:"text-right",children:"Actions"})]})}),e.jsx(be,{children:Q.map(s=>e.jsxs(K,{children:[e.jsx(x,{className:"font-mono text-sm",children:s.old_path}),e.jsx(x,{children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"font-mono text-sm",children:s.new_path}),e.jsx("a",{href:s.new_path,target:"_blank",rel:"noopener noreferrer",className:"text-muted-foreground hover:text-foreground",children:e.jsx(js,{className:"h-3 w-3"})})]})}),e.jsx(x,{className:"text-center",children:s.redirect_type}),e.jsxs(x,{className:"text-center",children:[s.hit_count,s.last_used_at&&e.jsxs("span",{className:"block text-xs text-muted-foreground",children:["Last: ",new Date(s.last_used_at).toLocaleDateString()]})]}),e.jsx(x,{className:"text-center",children:e.jsx(ae,{checked:s.is_active,onCheckedChange:()=>ss(s.id,s.is_active)})}),e.jsx(x,{className:"text-right",children:e.jsx(o,{variant:"destructive",size:"sm",onClick:()=>ts(s.id),children:e.jsx(re,{className:"h-4 w-4"})})})]},s.id))})]})})})]})]})]})]})})};export{zs 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.