PageSourceSearch

https://novaco.ai/assets/DemoAdmin-CYdzNASn.js

js novaco.ai collected 2026-10-05 12:44:54 UTC 7,754 bytes, 1 lines download raw bytes

1import{r,j as e,N as D,L as z,s as x,h as c}from"./index-Be_2bHJP.js";import{F as A}from"./Footer-DydoStv_.js";import{P as F}from"./plus-IV4fWgEX.js";import{C as L}from"./check-C3aNFezU.js";import{C as T}from"./copy-DynWS-TK.js";import{E as U}from"./external-link-Cpr-W2jr.js";import{P as q,T as R}from"./trash-2-dik4pVU8.js";async function _(l){const p=new TextEncoder().encode(l),g=await crypto.subtle.digest("SHA-256",p);return Array.from(new Uint8Array(g)).map(m=>m.toString(16).padStart(2,"0")).join("")}const y={slug:"",org_name:"",script_code:"",password:"",is_active:!0},K=()=>{const[l,j]=r.useState([]),[p,g]=r.useState(!0),[o,m]=r.useState(null),[v,h]=r.useState(!1),[t,a]=r.useState(y),[N,u]=r.useState(!1),[k,w]=r.useState(null),f=async()=>{const{data:s}=await x.from("demo_pages").select("*").order("created_at",{ascending:!1});j(s||[]),g(!1)};r.useEffect(()=>{f()},[]);const b=()=>{a(y),m(null),h(!1)},C=s=>{a({slug:s.slug,org_name:s.org_name,script_code:s.script_code,password:"",is_active:s.is_active}),m(s.id),h(!0)},S=async s=>{confirm("Delete this demo page?")&&(await x.from("demo_pages").delete().eq("id",s),c.success("Demo page deleted"),f())},E=async s=>{s.preventDefault(),u(!0);const i=t.slug.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"");if(!i||!t.org_name||!t.script_code){c.error("Please fill in all required fields"),u(!1);return}try{if(o){const n={slug:i,org_name:t.org_name,script_code:t.script_code,is_active:t.is_active};t.password&&(n.password_hash=await _(t.password));const{error:d}=await x.from("demo_pages").update(n).eq("id",o);if(d)throw d;c.success("Demo page updated")}else{if(!t.password){c.error("Password is required for new pages"),u(!1);return}const n=await _(t.password),{error:d}=await x.from("demo_pages").insert({slug:i,org_name:t.org_name,script_code:t.script_code,password_hash:n,is_active:t.is_active});if(d)throw d;c.success("Demo page created")}b(),f()}catch(n){c.error(n.message||"Something went wrong")}u(!1)},P=s=>{const i=`${window.location.origin}/demo/${s}`;navigator.clipboard.writeText(i),w(s),setTimeout(()=>w(null),2e3)};return e.jsxs("div",{className:"min-h-screen",children:[e.jsx(D,{}),e.jsx("section",{className:"pt-32 pb-24 px-6",children:e.jsxs("div",{className:"container mx-auto max-w-4xl",children:[e.jsxs("div",{className:"flex items-center justify-between mb-8",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-3 mb-2",children:[e.jsx("p",{className:"text-sm font-semibold uppercase tracking-widest text-accent",children:"Novaco Insights"}),e.jsx(z,{to:"/admin/roadmap",className:"text-xs text-muted-foreground hover:text-foreground transition-colors",children:"Roadmap →"})]}),e.jsx("h1",{className:"font-display text-3xl font-bold",children:"Client Demo Pages"}),e.jsx("p",{className:"text-muted-foreground mt-1 text-sm",children:"Create password-protected test pages for clients with their own Nova assistant."})]}),!v&&e.jsxs("button",{onClick:()=>{b(),h(!0)},className:"btn-accent-glass inline-flex items-center gap-2 rounded-xl px-5 py-2.5 text-sm font-semibold text-accent-foreground",children:[e.jsx(F,{size:16})," New page"]})]}),v&&e.jsxs("form",{onSubmit:E,className:"glass-card rounded-2xl p-8 mb-8 space-y-5",children:[e.jsx("h2",{className:"font-display text-lg font-bold",children:o?"Edit demo page":"Create demo page"}),e.jsxs("div",{className:"grid sm:grid-cols-2 gap-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"text-xs font-medium text-muted-foreground mb-1 block",children:"Organisation name *"}),e.jsx("input",{value:t.org_name,onChange:s=>a({...t,org_name:s.target.value}),className:"w-full rounded-lg border border-border/50 bg-background px-4 py-2.5 text-sm outline-none focus:border-accent transition-colors",placeholder:"Broekhuis"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"text-xs font-medium text-muted-foreground mb-1 block",children:"URL slug *"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-xs text-muted-foreground whitespace-nowrap",children:"/demo/"}),e.jsx("input",{value:t.slug,onChange:s=>a({...t,slug:s.target.value}),className:"w-full rounded-lg border border-border/50 bg-background px-4 py-2.5 text-sm outline-none focus:border-accent transition-colors",placeholder:"broekhuis"})]})]})]}),e.jsxs("div",{children:[e.jsxs("label",{className:"text-xs font-medium text-muted-foreground mb-1 block",children:["Password ",o?"(leave empty to keep current)":"*"]}),e.jsx("input",{type:"text",value:t.password,onChange:s=>a({...t,password:s.target.value}),className:"w-full rounded-lg border border-border/50 bg-background px-4 py-2.5 text-sm outline-none focus:border-accent transition-colors",placeholder:"Enter password for client"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"text-xs font-medium text-muted-foreground mb-1 block",children:"Nova / AutoChat script *"}),e.jsx("textarea",{value:t.script_code,onChange:s=>a({...t,script_code:s.target.value}),rows:4,className:"w-full rounded-lg border border-border/50 bg-background px-4 py-2.5 text-sm font-mono outline-none focus:border-accent transition-colors resize-y",placeholder:'<script src="https://app.autochat.ai/widget/..." async><\/script>'})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("input",{type:"checkbox",id:"is_active",checked:t.is_active,onChange:s=>a({...t,is_active:s.target.checked}),className:"accent-accent"}),e.jsx("label",{htmlFor:"is_active",className:"text-sm",children:"Active"})]}),e.jsxs("div",{className:"flex gap-3 pt-2",children:[e.jsx("button",{type:"submit",disabled:N,className:"btn-accent-glass inline-flex items-center gap-2 rounded-xl px-6 py-2.5 text-sm font-semibold text-accent-foreground disabled:opacity-50",children:N?"Saving…":o?"Update":"Create"}),e.jsx("button",{type:"button",onClick:b,className:"glass-card rounded-xl px-6 py-2.5 text-sm font-semibold text-foreground",children:"Cancel"})]})]}),p?e.jsx("div",{className:"text-muted-foreground text-center py-12",children:"Loading…"}):l.length===0?e.jsx("div",{className:"glass-card rounded-2xl p-12 text-center",children:e.jsx("p",{className:"text-muted-foreground",children:"No demo pages yet. Create your first one."})}):e.jsx("div",{className:"space-y-3",children:l.map(s=>e.jsxs("div",{className:"glass-card rounded-xl p-5 flex items-center gap-4",children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[e.jsx("h3",{className:"font-semibold truncate",children:s.org_name}),!s.is_active&&e.jsx("span",{className:"text-[10px] bg-muted px-2 py-0.5 rounded-full text-muted-foreground",children:"Inactive"})]}),e.jsxs("p",{className:"text-xs text-muted-foreground truncate",children:["/demo/",s.slug]})]}),e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx("button",{onClick:()=>P(s.slug),className:"p-2 rounded-lg hover:bg-accent/10 transition-colors text-muted-foreground hover:text-accent",title:"Copy URL",children:k===s.slug?e.jsx(L,{size:16}):e.jsx(T,{size:16})}),e.jsx("a",{href:`/demo/${s.slug}`,target:"_blank",rel:"noopener noreferrer",className:"p-2 rounded-lg hover:bg-accent/10 transition-colors text-muted-foreground hover:text-accent",title:"Open demo",children:e.jsx(U,{size:16})}),e.jsx("button",{onClick:()=>C(s),className:"p-2 rounded-lg hover:bg-accent/10 transition-colors text-muted-foreground hover:text-accent",title:"Edit",children:e.jsx(q,{size:16})}),e.jsx("button",{onClick:()=>S(s.id),className:"p-2 rounded-lg hover:bg-red-500/10 transition-colors text-muted-foreground hover:text-red-500",title:"Delete",children:e.jsx(R,{size:16})})]})]},s.id))})]})}),e.jsx(A,{})]})};export{K 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.