PageSourceSearch

https://blueroots-production.up.railway.app/assets/domains-page-DkLb-_w-.js

js blueroots-production.up.railway.app collected 2026-10-03 12:12:17 UTC 12,157 bytes, 1 lines download raw bytes

1import{d as D,j as e,e as $,b as j}from"./tanstack-raftEBQU.js";import{r as L}from"./react-vendor-DG9jHnNQ.js";import{bk as q,bj as B,a8 as T,ah as b,p as h,q as p,aN as A,aP as F,aQ as v,aO as y,s as f,t as k,ak as M,d as E,bm as N,b0 as g,ag as K,af as R,i as x}from"./index-CwEfLZlp.js";import{L as z}from"./link-2-CYZaaWG9.js";import{T as Q}from"./triangle-alert-CxdbLZNa.js";import{C as w}from"./circle-check-BHqhkodH.js";import{R as _}from"./refresh-cw-CYTauMj1.js";import{T as G}from"./trash-2-D8NernoQ.js";import{C as H}from"./copy-DS2sWNpy.js";import"./radix-B0zOOFBK.js";import"./charts-ycOWY838.js";import"./dnd-IADusAtS.js";const C={pending:{label:"Waiting for DNS",cls:"bg-amber-100 text-amber-900 border-amber-300 dark:bg-amber-950 dark:text-amber-200 dark:border-amber-800"},dns_verified:{label:"DNS verified · activation pending",cls:"bg-sky-100 text-sky-900 border-sky-300 dark:bg-sky-950 dark:text-sky-200 dark:border-sky-800"},active:{label:"Active",cls:"bg-green-100 text-green-900 border-green-300 dark:bg-green-950 dark:text-green-200 dark:border-green-800"},failed:{label:"Failed",cls:"bg-red-100 text-red-900 border-red-300 dark:bg-red-950 dark:text-red-200 dark:border-red-800"}};function O({status:a}){const s=C[a]||C.pending;return e.jsx(E,{className:`border ${s.cls} whitespace-nowrap`,"data-testid":`badge-status-${a}`,children:s.label})}function U(a){if(!a)return"never";const s=Date.now()-new Date(a).getTime();return s<6e4?"just now":s<36e5?`${Math.floor(s/6e4)} min ago`:s<864e5?`${Math.floor(s/36e5)} hr ago`:`${Math.floor(s/864e5)} days ago`}function S({value:a,label:s}){const{toast:d}=N();return e.jsxs("div",{className:"flex items-center gap-2 min-w-0",children:[e.jsx("code",{className:"text-xs bg-muted rounded px-2 py-1 break-all min-w-0",children:a}),e.jsx(x,{type:"button",variant:"ghost",size:"icon",className:"h-7 w-7 shrink-0","aria-label":`Copy ${s}`,onClick:()=>{navigator.clipboard?.writeText(a),d({title:`${s} copied`})},children:e.jsx(H,{className:"h-3.5 w-3.5"})})]})}function V({campaignId:a,d:s,isMasterAdmin:d}){const i=$(),{toast:n}=N(),l=[`/api/campaigns/${a}/link-domains`],u=t=>n({title:"Something went wrong",description:t?.message,variant:"destructive"}),c=j({mutationFn:async()=>(await g("POST",`/api/campaigns/${a}/link-domains/${s.id}/verify`)).json(),onSuccess:t=>{i.invalidateQueries({queryKey:l}),n(t.domain.lastError?{title:"Not verified yet",description:t.domain.lastError}:{title:"DNS verified",description:`${s.domain} points to Blueroots.`})},onError:u}),o=j({mutationFn:async t=>(await g("POST",`/api/campaigns/${a}/link-domains/${s.id}/activate`,{active:t})).json(),onSuccess:()=>{i.invalidateQueries({queryKey:l}),n({title:"Domain updated"})},onError:u}),m=j({mutationFn:async()=>(await g("DELETE",`/api/campaigns/${a}/link-domains/${s.id}`)).json(),onSuccess:()=>{i.invalidateQueries({queryKey:l}),n({title:"Domain removed"})},onError:u});return e.jsxs(h,{className:"cc-card","data-testid":`card-link-domain-${s.id}`,children:[e.jsx(f,{className:"pb-3",children:e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(k,{className:"text-base break-all",children:s.domain}),e.jsx(O,{status:s.status}),e.jsxs("span",{className:"text-xs text-muted-foreground sm:ml-auto",children:["Last checked ",U(s.lastCheckedAt)]})]})}),e.jsxs(p,{className:"space-y-4",children:[s.status!=="active"&&e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-sm",children:"Add this record at your DNS provider (GoDaddy, Cloudflare, Squarespace, Namecheap, etc.):"}),e.jsx("div",{className:"rounded-md border divide-y",children:s.records.map(t=>e.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-[5rem_1fr_1fr] gap-2 p-3 text-sm",children:[e.jsxs("div",{children:[e.jsx("span",{className:"sm:hidden text-xs text-muted-foreground",children:"Type "}),e.jsx("span",{className:"font-medium",children:t.type})]}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("span",{className:"text-xs text-muted-foreground block mb-1",children:"Host / Name"}),e.jsx(S,{value:t.host.split(".")[0],label:"Host"})]}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("span",{className:"text-xs text-muted-foreground block mb-1",children:"Value / Points to"}),e.jsx(S,{value:t.value,label:"Value"})]})]},t.type+t.host))}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:["Most providers only want the first part of the host (",s.domain.split(".")[0],"). DNS changes usually appear within minutes but can take up to an hour. We re-check automatically every 10 minutes."]})]}),s.lastError&&e.jsxs("div",{className:"flex gap-2 rounded-md border border-amber-300 bg-amber-50 p-3 text-sm text-amber-900 dark:bg-amber-950 dar
1k:text-amber-200 dark:border-amber-800",children:[e.jsx(Q,{className:"h-4 w-4 shrink-0 mt-0.5"}),e.jsx("span",{children:s.lastError})]}),s.status==="dns_verified"&&e.jsxs("div",{className:"flex gap-2 rounded-md border p-3 text-sm",children:[e.jsx(w,{className:"h-4 w-4 shrink-0 mt-0.5 text-green-600"}),e.jsx("span",{children:"DNS is set up correctly. The Blueroots team is issuing the security certificate for this domain. Until then, texts keep using the shared short link domain."})]}),s.status==="active"&&e.jsxs("div",{className:"flex gap-2 rounded-md border p-3 text-sm",children:[e.jsx(w,{className:"h-4 w-4 shrink-0 mt-0.5 text-green-600"}),e.jsxs("span",{children:["New texts with links use ",e.jsxs("strong",{className:"break-all",children:["https://",s.domain,"/…"]})]})]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsxs(x,{variant:"outline",size:"sm",onClick:()=>c.mutate(),disabled:c.isPending,"data-testid":`button-verify-${s.id}`,children:[c.isPending?e.jsx(b,{className:"h-4 w-4 mr-1 animate-spin"}):e.jsx(_,{className:"h-4 w-4 mr-1"})," Check DNS now"]}),d&&s.status==="dns_verified"&&e.jsx(x,{size:"sm",onClick:()=>o.mutate(!0),disabled:o.isPending,"data-testid":`button-activate-${s.id}`,children:"Mark active (certificate issued)"}),d&&s.status==="active"&&e.jsx(x,{variant:"outline",size:"sm",onClick:()=>o.mutate(!1),disabled:o.isPending,children:"Stop using for new texts"}),(s.status!=="active"||d)&&e.jsxs(x,{variant:"ghost",size:"sm",className:"text-destructive sm:ml-auto",onClick:()=>{window.confirm(`Remove ${s.domain}?`)&&m.mutate()},disabled:m.isPending,"data-testid":`button-remove-${s.id}`,children:[e.jsx(G,{className:"h-4 w-4 mr-1"})," Remove"]})]})]})]})}function W({campaignId:a,isMasterAdmin:s}){const d=$(),{toast:i}=N(),[n,l]=L.useState(""),u=[`/api/campaigns/${a}/link-domains`],c=D({queryKey:u,queryFn:async()=>(await g("GET",`/api/campaigns/${a}/link-domains`)).json(),refetchInterval:6e4}),o=j({mutationFn:async()=>(await g("POST",`/api/campaigns/${a}/link-domains`,{domain:n})).json(),onSuccess:()=>{l(""),d.invalidateQueries({queryKey:u}),i({title:"Domain added",description:"Add the DNS record below, then check DNS."})},onError:r=>i({title:"Could not add domain",description:String(r?.message||"").replace(/^\d+:\s*/,""),variant:"destructive"})});if(c.isLoading)return e.jsxs("div",{className:"flex items-center gap-2 text-sm text-muted-foreground",children:[e.jsx(b,{className:"h-4 w-4 animate-spin"})," Loading"]});if(c.error)return e.jsx(h,{className:"cc-card",children:e.jsx(p,{className:"p-6 text-sm text-muted-foreground",children:"Could not load link domains."})});const m=c.data,t=m.domains.find(r=>r.status==="active"),P=m.sharedBase.replace(/^https?:\/\//,"");return e.jsxs("div",{className:"space-y-4",children:[e.jsxs(h,{className:"cc-card",children:[e.jsx(f,{className:"pb-2",children:e.jsxs(k,{className:"text-base flex items-center gap-2",children:[e.jsx(z,{className:"h-4 w-4"})," Links in your texts"]})}),e.jsxs(p,{className:"space-y-3 text-sm",children:[e.jsx("p",{children:"Links in texting blasts are shortened and tracked automatically. You'll see clicks for each blast, and ActBlue donations can be credited to the person who tapped the link."}),e.jsxs("div",{className:"rounded-md bg-muted/60 p-3 space-y-1",children:[e.jsx("div",{className:"text-xs text-muted-foreground",children:"Links currently look like"}),e.jsx("code",{className:"text-sm break-all","data-testid":"text-current-link-base",children:t?`https://${t.domain}/aB3xK9`:`${m.sharedBase}/aB3xK9`}),e.jsx("div",{className:"text-xs text-muted-foreground",children:t?"Your own link domain is active.":`Shared Blueroots link domain (${P}). Add your own below to brand your links.`})]})]})]}),e.jsxs(h,{className:"cc-card",children:[e.jsx(f,{className:"pb-2",children:e.jsxs(k,{className:"text-base flex items-center gap-2",children:[e.jsx(T,{className:"h-4 w-4"})," Use your own link domain"]})}),e.jsxs(p,{children:[e.jsxs("form",{className:"flex flex-col sm:flex-row gap-2 sm:items-end",onSubmit:r=>{r.preventDefault(),n.trim()&&o.mutate()},children:[e.jsxs("div",{className:"flex-1 space-y-1",children:[e.jsx(K,{htmlFor:"link-domain-in
1put",children:"Subdomain"}),e.jsx(R,{id:"link-domain-input",placeholder:"links.yourcampaign.com",value:n,onChange:r=>l(r.target.value),autoComplete:"off",inputMode:"url","data-testid":"input-link-domain"})]}),e.jsxs(x,{type:"submit",disabled:!n.trim()||o.isPending,"data-testid":"button-add-link-domain",children:[o.isPending&&e.jsx(b,{className:"h-4 w-4 mr-1 animate-spin"})," Add domain"]})]}),e.jsx("p",{className:"text-xs text-muted-foreground mt-2",children:"Use a subdomain of a site you already own, like links. or go. Your main website is not affected."})]})]}),m.domains.map(r=>e.jsx(V,{campaignId:a,d:r,isMasterAdmin:s},r.id))]})}function Y(){return e.jsxs(h,{className:"cc-card",children:[e.jsx(f,{className:"pb-2",children:e.jsxs(k,{className:"text-base flex items-center gap-2",children:[e.jsx(M,{className:"h-4 w-4"})," Email sending domains"]})}),e.jsxs(p,{className:"space-y-3 text-sm",children:[e.jsx("p",{children:"When native email sending turns on, you'll verify the domain you send from here. Blueroots will list the SPF, DKIM, and DMARC records to add, and check them automatically, the same way link domains work."}),e.jsxs("ul",{className:"list-disc pl-5 space-y-1 text-muted-foreground",children:[e.jsx("li",{children:"SPF: authorizes Blueroots to send on your domain's behalf"}),e.jsx("li",{children:"DKIM: signs each email so inboxes trust it"}),e.jsx("li",{children:"DMARC: tells inboxes what to do with unsigned mail"})]}),e.jsx(E,{variant:"secondary",children:"Not available yet"})]})]})}function le(){const{activeCampaign:a,selectedCampaign:s}=q(),{user:d}=B(),i=s?.id||a?.id,n=d?.role==="master_admin",l=D({queryKey:[`/api/campaigns/${i}/link-settings`],queryFn:async()=>(await g("GET",`/api/campaigns/${i}/link-settings`)).json(),enabled:!!i});return i?e.jsxs("div",{className:"p-4 sm:p-6 space-y-4 sm:space-y-6 overflow-y-auto h-full pb-24 sm:pb-6 relative z-[1] max-w-4xl","data-testid":"domains-page",children:[e.jsxs("div",{children:[e.jsxs("h1",{className:"cc-page-title flex items-center gap-2",children:[e.jsx(T,{className:"h-5 w-5"})," Domains"]}),e.jsx("p",{className:"text-sm text-muted-foreground mt-0.5",children:"Domains your campaign uses for tracked links and, soon, email."})]}),l.isLoading?e.jsxs("div",{className:"flex items-center gap-2 text-sm text-muted-foreground",children:[e.jsx(b,{className:"h-4 w-4 animate-spin"})," Loading"]}):l.data?.enabled?e.jsxs(A,{defaultValue:"links",children:[e.jsxs(F,{children:[e.jsx(v,{value:"links","data-testid":"tab-link-domains",children:"Link domains"}),e.jsx(v,{value:"email","data-testid":"tab-email-domains",children:"Email domains"})]}),e.jsx(y,{value:"links",className:"mt-4",children:e.jsx(W,{campaignId:i,isMasterAdmin:n})}),e.jsx(y,{value:"email",className:"mt-4",children:e.jsx(Y,{})})]}):e.jsx(h,{className:"cc-card",children:e.jsx(p,{className:"p-6 text-sm text-muted-foreground",children:"Tracked links are not turned on for this campaign yet. A platform admin can enable them in Campaign Features."})})]}):e.jsx("div",{className:"flex items-center justify-center h-full",children:e.jsx("p",{className:"text-muted-foreground",children:"Select a campaign to manage domains"})})}export{Y as EmailDomainsPlaceholder,W as LinkDomainsPanel,le 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.