1import{z as k,D as _,E as S,au as q,e as j,f as z,r as g,j as e,C as B,a as V,b as D,c as W,B as o,bm as J,d as H,h as N,ab as L,ac as P,ad as F,ae as M,af as w,I as ee,ay as se,N as K,aU as ae,aV as te,aW as f,aX as l,aY as ne,aZ as i,bi as re,k as ie,cg as ce,aN as le,aJ as oe,t as h,cV as R,P as de,az as me,aA as he,aB as u,aC as x,cW as ue,cX as xe,cY as ve}from"./index-DHwBXtP2.js";const ge=k({method:"POST"}).middleware([_]).handler(S("src_lib_capi-custom-conversions_functions_ts--listCustomConversions_createServerFn_handler")),fe=k({method:"POST"}).middleware([_]).handler(S("src_lib_capi-custom-conversions_functions_ts--saveCustomConversion_createServerFn_handler")),pe=k({method:"POST"}).middleware([_]).handler(S("src_lib_capi-custom-conversions_functions_ts--deleteCustomConversion_createServerFn_handler")),C=[{key:"form_submit",label:"Landing page form submitted",desc:"Someone fills in a form on a Brain landing page or embedded form.",standardEvent:"Lead"},{key:"lead_magnet",label:"Lead magnet claimed",desc:"Someone opts in on a lead-magnet page or claims a PDF.",standardEvent:"Lead"},{key:"booking",label:"Call booked",desc:"Someone books an appointment on your calendar.",standardEvent:"Schedule"},{key:"purchase",label:"Payment taken",desc:"An invoice or checkout is paid.",standardEvent:"Purchase"}];function je(n){return C.find(t=>t.key===n)?.label??n}function O(n){return C.find(t=>t.key===n)?.standardEvent??"Lead"}function Ce(n){const t=n.trim();return t.length>=1&&t.length<=60&&/^[A-Za-z0-9_][A-Za-z0-9_ .-]*$/.test(t)}const p="__all__";function be({workspaceId:n}){const t=q(),d=j(ge),b=j(fe),y=j(pe),r=z({queryKey:["capi-custom-conversions",n],queryFn:()=>d({data:{workspaceId:n}})}),[a,c]=g.useState(null),[T,I]=g.useState(!1),[E,Q]=g.useState(null),A=r.data?.rows??[],G=r.data?.offers??[];function U(){c({offerId:p,trigger:"form_submit",eventName:"",active:!0})}function Y(s){c({id:s.id,offerId:s.offer_id??p,trigger:s.trigger,eventName:s.event_name,active:s.active})}async function Z(){if(a){if(!Ce(a.eventName)){h.error("Use letters, numbers, spaces, dots, dashes or underscores (up to 60).");return}I(!0);try{await b({data:{workspaceId:n,id:a.id,offerId:a.offerId===p?null:a.offerId,trigger:a.trigger,eventName:a.eventName,active:a.active}}),h.success("Saved. New conversions will report this name."),c(null),t.invalidateQueries({queryKey:["capi-custom-conversions",n]})}catch(s){h.error(s.message)}finally{I(!1)}}}async function X(s){try{await y({data:{workspaceId:n,id:s}}),h.success("Removed. That milestone goes back to its standard name."),t.invalidateQueries({queryKey:["capi-custom-conversions",n]})}catch(m){h.error(m.message)}}return e.jsxs(B,{children:[e.jsxs(V,{className:"flex flex-row items-start justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx(D,{className:"text-base",children:"Custom conversions"}),e.jsxs(W,{children:["Choose the name Facebook receives for each milestone, per offer â for example",e.jsx("span",{className:"font-mono",children:" lead_fractional_team"})," instead of",e.jsx("span",{className:"font-mono",children:" Lead"}),". Anything you don't set here keeps sending the standard name. You still create the custom conversion itself once in Facebook Events Manager, as a rule on the name you type here."]})]}),e.jsxs(o,{size:"sm",onClick:U,children:[e.jsx(J,{className:"mr-1 h-4 w-4"})," Add"]})]}
1),e.jsxs(H,{className:"space-y-4",children:[a?e.jsxs("div",{className:"grid gap-3 rounded-lg border bg-muted/30 p-4 md:grid-cols-4",children:[e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(N,{children:"When this happens"}),e.jsxs(L,{value:a.trigger,onValueChange:s=>c({...a,trigger:s}),children:[e.jsx(P,{children:e.jsx(F,{})}),e.jsx(M,{children:C.map(s=>e.jsx(w,{value:s.key,children:s.label},s.key))})]}),e.jsx("p",{className:"text-xs text-muted-foreground",children:C.find(s=>s.key===a.trigger)?.desc})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(N,{children:"For this offer"}),e.jsxs(L,{value:a.offerId,onValueChange:s=>c({...a,offerId:s}),children:[e.jsx(P,{children:e.jsx(F,{})}),e.jsxs(M,{children:[e.jsx(w,{value:p,children:"Every offer"}),G.map(s=>e.jsx(w,{value:s.id,children:s.name},s.id))]})]})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx(N,{children:"Send this event name"}),e.jsx(ee,{value:a.eventName,placeholder:`${O(a.trigger).toLowerCase()}_my_offer`,onChange:s=>c({...a,eventName:s.target.value})}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:["Standard name today: ",O(a.trigger)]})]}),e.jsxs("div",{className:"flex flex-col justify-between gap-3",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(se,{checked:a.active,onCheckedChange:s=>c({...a,active:s})}),e.jsx("span",{className:"text-sm",children:"On"})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(o,{size:"sm",onClick:Z,disabled:T,children:T?"Savingâ¦":"Save"}),e.jsx(o,{size:"sm",variant:"ghost",onClick:()=>c(null),children:"Cancel"})]})]})]}):null,r.isLoading?e.jsx(K,{className:"h-24 w-full"}):A.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"Nothing set up yet, so form fills report Lead, booked calls report Schedule and payments report Purchase."}):e.jsxs(ae,{children:[e.jsx(te,{children:e.jsxs(f,{children:[e.jsx(l,{children:"When this happens"}),e.jsx(l,{children:"Offer"}),e.jsx(l,{children:"Event sent to Facebook"}),e.jsx(l,{children:"Times fired"}),e.jsx(l,{children:"Last fired"}),e.jsx(l,{children:"Status"}),e.jsx(l,{className:"w-24"})]})}),e.jsx(ne,{children:A.map(s=>e.jsxs(g.Fragment,{children:[e.jsxs(f,{children:[e.jsx(i,{children:je(s.trigger)}),e.jsx(i,{children:s.offer_name??"Every offer"}),e.jsx(i,{className:"font-mono text-xs",children:s.event_name}),e.jsx(i,{children:s.fired_count>0?e.jsxs(o,{size:"sm",variant:"ghost",className:"h-7 px-2",onClick:()=>Q(E===s.id?null:s.id),children:[s.fired_count," ",e.jsx(re,{className:"ml-1 h-3 w-3"})]}):e.jsx("span",{className:"text-muted-foreground",children:"0"})}),e.jsx(i,{className:"text-xs text-muted-foreground",children:s.last_fired_at?new Date(s.last_fired_at).toLocaleString():"â"}),e.jsx(i,{children:e.jsx(ie,{variant:s.active?"default":"secondary",children:s.active?"On":"Off"})}),e.jsxs(i,{className:"text-right",children:[e.jsx(o,{size:"icon",variant:"ghost",onClick:()=>Y(s),title:"Edit",children:e.jsx(ce,{className:"h-4 w-4"})}),e.jsx(o,{size:"icon",variant:"ghost",onClick:()=>X(s.id),title:"Remove",children:e.jsx(le,{className:"h-4 w-4"})})]})]}),s.warning?e.jsx(f,{children:e.jsx(i,{colSpan:7,className:"pt-0",children:e.jsxs("p",{className:"flex items-start gap-2 text-xs text-destructive",children:[e.jsx(oe,{className:"mt-0.5 h-3.5 w-3.5 shrink-0"}),s.warning]})})}):null,E===s.id?e.jsx(f,{children:e.jsx(i,{colSpan:7,className:"pt-0",children:e.jsxs("div",{className:"rounded-md border bg-muted/30 p-3",children:[e.jsx("p",{className:"mb-2 text-xs font-medium",children:"Most recent people this fired for"}),e.jsx("ul",{className:"space-y-1 text-xs",children:s.recent.map((m,$)=>
1e.jsxs("li",{className:"flex justify-between gap-4",children:[e.jsx("span",{children:m.name||m.email||"Unnamed contact"}),e.jsx("span",{className:"text-muted-foreground",children:new Date(m.at).toLocaleString()})]},$))})]})})}):null]},s.id))})]})]})]})}function Ne(){const{tab:n}=R.useSearch(),t=R.useNavigate(),d=q(),b=j(de),{data:y}=z({queryKey:["workspaces"],queryFn:()=>b({})}),r=y?.[0];return e.jsxs("div",{className:"mx-auto max-w-7xl space-y-6 px-4 py-6",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-semibold tracking-tight",children:"Tracking & attribution"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"One place for landing-page message match, Meta â CRM event reconciliation, CAPI delivery, and the AI-classified mappings that wire it all together."})]}),r?e.jsxs(me,{value:n,onValueChange:a=>t({search:{tab:a},replace:!0}),children:[e.jsxs(he,{children:[e.jsx(u,{value:"overview",children:"Overview"}),e.jsx(u,{value:"lp",children:"LP audit"}),e.jsx(u,{value:"capi",children:"CAPI feed"}),e.jsx(u,{value:"conversions",children:"Custom conversions"}),e.jsx(u,{value:"match",children:"Message match"})]}),e.jsx(x,{value:"overview",className:"mt-4 space-y-4",children:e.jsxs(B,{children:[e.jsxs(V,{children:[e.jsx(D,{className:"text-base",children:"What lives here"}),e.jsx(W,{children:'Everything that answers "is my data flowing correctly from ad â landing page â CRM â Meta?"'})]}
1),e.jsxs(H,{className:"grid gap-3 sm:grid-cols-2",children:[e.jsx(v,{title:"LP audit",desc:"Side-by-side: how many leads Meta counted vs how many your CRM actually received. AI flags pixel gaps and missing stages.",onClick:()=>t({search:{tab:"lp"},replace:!0})}),e.jsx(v,{title:"CAPI feed",desc:"Every event Brain sends to Meta's Conversions API â coverage per event, success rate, top failures, live feed.",onClick:()=>t({search:{tab:"capi"},replace:!0})}),e.jsx(v,{title:"Message match",desc:"AI scores how well each landing page matches the ad that drove the click. Catches the high-CTR / low-conversion leak.",onClick:()=>t({search:{tab:"match"},replace:!0})}),e.jsx(v,{title:"CRM mappings",desc:"AI-classified mappings from your CRM stage names to Meta CAPI events. Override or re-run from the CAPI feed tab.",onClick:()=>t({search:{tab:"capi"},replace:!0})}),e.jsx(v,{title:"Custom conversions",desc:"Give each offer its own event name for form fills, booked calls and payments â so every campaign optimises toward its own outcome.",onClick:()=>t({search:{tab:"conversions"},replace:!0})})]})]})}),e.jsx(x,{value:"lp",className:"mt-4",children:e.jsx(ue,{workspaceId:r.id})}),e.jsx(x,{value:"capi",className:"mt-4",children:e.jsx(xe,{workspaceId:r.id})}),e.jsx(x,{value:"conversions",className:"mt-4",children:e.jsx(be,{workspaceId:r.id})}),e.jsx(x,{value:"match",className:"mt-4",children:e.jsx(ve,{workspaceId:r.id,qc:d})})]}):e.jsx(K,{className:"h-96 w-full"})]})}function v({title:n,desc:t,onClick:d}){return e.jsxs("button",{type:"button",onClick:d,className:"rounded-lg border bg-card p-4 text-left transition hover:border-primary hover:bg-accent/30",children:[e.jsx("div",{className:"font-medium",children:n}),e.jsx("p",{className:"mt-1 text-xs text-muted-foreground",children:t})]})}export{Ne as component};
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.