PageSourceSearch

https://remindermedia.com/assets/experiments-BpY0Pyfc.js

js remindermedia.com collected 2026-10-09 22:16:32 UTC 10,330 bytes, 1 lines download raw bytes

1import{ak as T,r as s,j as e,ae as $,an as u,b as B}from"./index-8bceNMaj.js";import{A as R,F as D}from"./AdminLayout-DywuyU6G.js";import{a as i,A as E}from"./clerk-VNvb1lbB.js";import{T as M}from"./trophy-CvGExtDp.js";import"./index-CiBbbeOy.js";import"./theme-DYrjnAQF.js";import"./users-CBbLwnT_.js";import"./book-open-CRKK0van.js";const z=[["path",{d:"M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09z",key:"m3kijz"}],["path",{d:"m12 15-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2z",key:"1fmvmk"}],["path",{d:"M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0",key:"1f8sc4"}],["path",{d:"M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5",key:"qeys4"}]],P=T("rocket",z),G={draft:"bg-neutral-100 text-neutral-700 border-neutral-200 dark:bg-neutral-800 dark:text-neutral-300 dark:border-neutral-700",running:"bg-emerald-50 text-emerald-700 border-emerald-200 dark:bg-emerald-900/40 dark:text-emerald-300 dark:border-emerald-700",concluded:"bg-violet-50 text-violet-700 border-violet-200 dark:bg-violet-900/40 dark:text-violet-300 dark:border-violet-700"};function I({status:a}){return e.jsx("span",{className:`inline-flex items-center rounded-full border px-2 py-0.5 text-[11px] font-medium uppercase tracking-wider ${G[a]}`,children:a})}function U(a){if(!a)return"—";try{return new Date(a).toLocaleDateString()}catch{return a}}function F({v:a}){if(a.recommendation==="insufficient_data"||!a.leadingVariantKey)return e.jsxs("span",{className:"inline-flex items-center gap-1 rounded-full border border-neutral-200 bg-neutral-50 px-2 py-0.5 text-[11px] text-neutral-500 dark:border-neutral-700 dark:bg-neutral-800 dark:text-neutral-400",children:["gathering data (",a.totalExposures,")"]});const d=Math.round(a.probabilityToBeBest*100),l=a.recommendation==="ship_leader";return e.jsxs("span",{className:`inline-flex items-center gap-1 rounded-full border px-2 py-0.5 text-[11px] font-medium ${l?"border-emerald-200 bg-emerald-50 text-emerald-700 dark:border-emerald-700 dark:bg-emerald-900/40 dark:text-emerald-300":"border-amber-200 bg-amber-50 text-amber-800 dark:border-amber-700 dark:bg-amber-900/40 dark:text-amber-300"}`,children:[e.jsx(M,{className:"h-3 w-3"}),a.leadingVariantKey," (",d,"%)"]})}function Z(){const[a,d]=s.useState(null),[l,V]=s.useState([]),[p,h]=s.useState(null),[_,c]=s.useState(!1),[o,y]=s.useState(""),[b,f]=s.useState(""),[g,j]=s.useState("form_submit"),[m,k]=s.useState(!1),[N,v]=s.useState(null),[w,S]=s.useState(null),C=s.useMemo(()=>{const t=new Map;for(const r of l)t.set(r.experimentKey,r);return t},[l]);async function K(){try{h(null);const[t,r]=await Promise.all([i.listExperiments(),i.listExperimentVerdicts().catch(()=>({items:[]}))]);d(t),V(r.items)}catch(t){h(t instanceof Error?t.message:String(t))}}s.useEffect(()=>{K()},[]);async function A(t){const r=C.get(t.key);if(!r?.leadingVariantKey)return;const x=t.variants.find(n=>n.key===r.leadingVariantKey)?.label??r.leadingVariantKey;if(window.confirm(`Ship "${x}" as the winner of ${t.key}? This collapses traffic to 100% and concludes the test.`)){S(t.key);try{await i.shipExperiment(t.key,r.leadingVariantKey),await K()}catch(n){window.alert(n instanceof E?n.message:String(n))}finally{S(null)}}}async function L(){k(!0),v(null);try{const t=await i.createExperiment({key:o.trim(),description:b.trim()||null,goalEventKey:g.trim()||"form_submit",variants:[{key:"control",label:"Control",weight:50},{key:"variant",label:"Variant",weight:50}],audience:{},status:"draft"});c(!1),y(""),f(""),j("form_submit"),window.location.assign(`/admin/experiments/${encodeURIComponent(t.key)}`)}catch(t){const r=t instanceof E?t.message:String(t);v(r)}finally{k(!1)}}return e.jsx(R,{children:e.jsxs("div",{className:"px-6 py-10 max-w-6xl",children:[e.jsxs("header",{className:"mb-8 flex items-start justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"font-serif text-3xl tracking-tight text-neutral-900",children:"Experiments"}),e.jsx("p",{className:"mt-2 text-sm text-neutral-600",children:"Run split tests on copy, CTAs, and forms. Variants are assigned deterministically per visitor and stay sticky across sessions. Verdicts come from the nightly Bayesian evaluator and refresh once per day."})]}),e.jsxs("button",{type:"button",onClick:()=>c(!0),className:"inline-flex items-center gap-2 rounded-full bg-neutral-900 px-4 py-2 text-sm text-white hover:bg-neutral-800",children:[e.jsx($,{className:"h-4 w-4"}),"New experiment"]})]}),p&&e.jsx("div",{className:"mb-4 rounded-lg border border-rose-200 bg-rose-50 p-3 text-sm text-rose-800",children:p}),a?a.length===0?e.jsxs("div",{className:"rounded-2xl border border-dashed border-neutral-300 bg-white p-10 text-center",children:[e.jsx(D,{className:"mx-auto h-8 w-8 text-neutral-400"}),e.jsx("p",{className:"mt-3 text-sm font-medium text-neutral-900",children:"No experiments yet"}),e.jsx("p",{className:"mt-1 text-sm text-neutral-600",children:"Create your first split test — e.g. two hero headlines on the homepage measured against `form_submit`."})]}):e.jsx("div",{className:"overflow-hidden rounded-2xl border border-neutral-200 bg-white",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{className:"bg-neutral-50 text-left text-xs uppercase tracking-wider text-neutral-500",children:e.jsxs("tr",{children:[e.jsx("th",{className:"px-4 py-3 font-medium",children:"Key"}),e.jsx("th",{className:"px-4 py-3 font-medium",children:"Status"}),e.jsx("th",{className:"px-4 py-3 font-medium",children:"Verdict"}),e.jsx("th",{className:"px-4 py-3 font-medium",children:"Variants"}),e.jsx("th",{className:"px-4 py-3 font-medium",children:"Goal"}),e.jsx("th",{className:"px-4 py-3 font-medium",children:"Started"}),e.jsx("th",{className:"px-4 py-3 font-medium text-right",children:"Actions"})]})}),e.jsx("tbody",{className:"divide-y divide-neutral-100",children:a.map(t=>{const r=C.get(t.key),x=t.status==="running"&&r?.recommendation==="ship_leader"&&r.leadingVariantKey!=null;return e.jsxs("tr",{className:"hover:bg-neutral-50/50",children:[e.jsxs("td",{className:"px-4 py-3",children:[e.jsx(B,{href:`/admin/experiments/${encodeURIComponent(t.key)}`,children:e.jsx("a",{className:"font-mono text-[13px] text-neutral-900 hover:underline",children:t.key})}),t.description&&e.jsx("p",{className:"mt-0.5 text-xs text-neutral-500 line-clamp-1",children:t.description})]}),e.jsx("td",{className:"px-4 py-3",children:e.jsx(I,{status:t.status})}),e.jsx("td",{className:"px-4 py-3",children:t.status==="concluded"&&t.shippedVariantKey?e.jsxs("span",{className:"inline-flex items-center gap-1 rounded-full border border-violet-200 bg-vi
1olet-50 px-2 py-0.5 text-[11px] text-violet-700 dark:border-violet-700 dark:bg-violet-900/40 dark:text-violet-300",children:["shipped ",t.shippedVariantKey]}):r?e.jsx(F,{v:r}):e.jsx("span",{className:"text-[11px] text-neutral-400",children:"—"})}),e.jsx("td",{className:"px-4 py-3 text-neutral-700",children:t.variants.map(n=>`${n.label} (${n.weight}%)`).join(" · ")}),e.jsx("td",{className:"px-4 py-3 font-mono text-[12px] text-neutral-600",children:t.goalEventKey}),e.jsx("td",{className:"px-4 py-3 text-neutral-600",children:U(t.startedAt)}),e.jsx("td",{className:"px-4 py-3 text-right",children:x&&e.jsxs("button",{type:"button",onClick:()=>{A(t)},disabled:w===t.key,className:"inline-flex items-center gap-1 rounded-md border border-emerald-300 bg-emerald-50 px-2.5 py-1 text-xs font-medium text-emerald-800 hover:bg-emerald-100 disabled:opacity-50",children:[w===t.key?e.jsx(u,{className:"h-3 w-3 animate-spin"}):e.jsx(P,{className:"h-3 w-3"}),"Ship leader"]})})]},t.key)})})]})}):e.jsxs("div",{className:"flex items-center gap-2 text-sm text-neutral-500",children:[e.jsx(u,{className:"h-4 w-4 animate-spin"})," Loading…"]}),_&&e.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4",children:e.jsxs("div",{className:"w-full max-w-md rounded-2xl bg-white p-6 shadow-xl",children:[e.jsx("h2",{className:"font-serif text-xl tracking-tight text-neutral-900",children:"New experiment"}),e.jsx("p",{className:"mt-1 text-sm text-neutral-600",children:"Pick a stable key — it goes into the codebase and the admin URL. You'll set up variants on the next screen."}),e.jsxs("div",{className:"mt-5 space-y-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"text-[11px] uppercase tracking-wider text-neutral-500",children:"Key"}),e.jsx("input",{type:"text",value:o,onChange:t=>y(t.target.value.toLowerCase().replace(/[^a-z0-9_-]/g,"")),placeholder:"e.g. homepage_hero_headline",className:"mt-1 w-full rounded-md border border-neutral-300 px-3 py-2 text-sm focus:border-neutral-900 focus:outline-none"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"text-[11px] uppercase tracking-wider text-neutral-500",children:"Description"}),e.jsx("input",{type:"text",value:b,onChange:t=>f(t.target.value),placeholder:"What are you testing and why?",className:"mt-1 w-full rounded-md border border-neutral-300 px-3 py-2 text-sm focus:border-neutral-900 focus:outline-none"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"text-[11px] uppercase tracking-wider text-neutral-500",children:"Goal event key"}),e.jsx("input",{type:"text",value:g,onChange:t=>j(t.target.value),placeholder:"form_submit",className:"mt-1 w-full rounded-md border border-neutral-300 px-3 py-2 text-sm font-mono focus:border-neutral-900 focus:outline-none"}),e.jsxs("p",{className:"mt-1 text-xs text-neutral-500",children:["Any analytics event key — e.g. ",e.jsx("code",{children:"form_submit"}),","," ",e.jsx("code",{children:"cta_click"}),", or a custom one you fire via"," ",e.jsx("code",{children:"track()"}),"."]})]}),N&&e.jsx("p",{className:"text-sm text-rose-700",children:N})]}),e.jsxs("div",{className:"mt-6 flex items-center justify-end gap-2",children:[e.jsx("button",{type:"button",onClick:()=>c(!1),disabled:m,className:"rounded-md px-3 py-2 text-sm text-neutral-600 hover:bg-neutral-100",children:"Cancel"}),e.jsxs("button",{type:"button",onClick:()=>{L()},disabled:m||o.length<2,className:"inline-flex items-center gap-2 rounded-md bg-neutral-900 px-4 py-2 text-sm text-white hover:bg-neutral-800 disabled:opacity-50",children:[m&&e.jsx(u,{className:"h-4 w-4 animate-spin"}),"Create"]})]})]})})]})})}export{Z 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.