1import{r,j as e,m as N,I as C,Y as U,W as P,g as H,s as T,C as S,w as A,x as D,a9 as W,b as B,e as Y,B as F,d as $,K as z,U as K,u as G,aj as M,ak as q,al as O,am as X}from"./index-C_-x7ftU.js";import{I as R,S as J}from"./ImageUpload-DfVNwKiN.js";import{A as Q}from"./AgencyPageHeader-ijjgL7is.js";import{P as Z}from"./PanelState-XISNzZje.js";const V=/^#[0-9a-fA-F]{6}$/;function w(x){let m=x.trim().replace(/^#/,"");return/^[0-9a-fA-F]{3}$/.test(m)&&(m=m.split("").map(u=>u+u).join("")),/^[0-9a-fA-F]{6}$/.test(m)?`#${m.toUpperCase()}`:null}function ee({label:x,hint:m,value:u,onChange:p,onValidityChange:h}){const[o,a]=r.useState(u),[f,y]=r.useState(!1);r.useEffect(()=>{a(u),y(!1)},[u]);const c=w(o),_=f&&c===null;r.useEffect(()=>{h==null||h(c!==null)},[c,h]);function v(){c&&(p(c),a(c),y(!1))}return e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx("input",{type:"color",value:V.test(u)?u:"#000000",onChange:g=>{const k=g.target.value.toUpperCase();a(k),p(k)},className:"h-9 w-14 shrink-0 rounded border border-input bg-background p-1 cursor-pointer","aria-label":x}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx(N,{children:x}),m&&e.jsx("p",{className:"text-xs text-muted-foreground",children:m}),_&&e.jsxs("p",{className:"text-xs text-destructive mt-1",children:["Needs 6 hex digits, like ",e.jsx("code",{className:"font-mono",children:"#8B5CC8"})]})]}),e.jsx(C,{value:o,onChange:g=>{a(g.target.value),y(!0)},onBlur:v,onKeyDown:g=>{g.key==="Enter"&&v()},spellCheck:!1,maxLength:7,className:U("w-28 font-mono text-xs shrink-0",_&&"border-destructive")}
1)]})}const ae={pending_dns:{label:"Waiting for DNS",tone:"wait",hint:"Add the record below with your DNS provider."},verifying:{label:"Checking DNS",tone:"wait",hint:"We can see the record and are confirming it."},dns_verified:{label:"DNS confirmed",tone:"wait",hint:"Issuing your certificate â usually a few minutes."},cert_pending:{label:"Issuing certificate",tone:"wait",hint:"Almost there. No action needed."},issued:{label:"Live",tone:"ok",hint:"Your clients can use this address."},failed:{label:"Failed",tone:"bad",hint:"Check the DNS record matches exactly, then contact us."},expired:{label:"Expired",tone:"bad",hint:"The certificate lapsed. Contact us â clients will see a warning."}},se={capability_denied:"Only an agency owner can add a domain.",invalid_hostname:"That does not look like a hostname. Use something like app.youragency.com",reserved_hostname:"That hostname is not available.",hostname_taken:"That hostname is already in use.",not_a_live_agency:"This agency is not active.",domains_not_available:"Custom domains aren't available yet."};function te(){const{agency:x,caps:m}=P(),{toast:u}=H(),[p,h]=r.useState([]),[o,a]=r.useState(!0),[f,y]=r.useState(!1),[c,_]=r.useState(""),[v,g]=r.useState(!1),[k,E]=r.useState(null),[j,I]=r.useState(null),b=x==null?void 0:x.organization_id,s=r.useCallback(async()=>{if(!b)return;a(!0),y(!1);const{data:t,error:l}=await T.rpc("agency_list_domains",{p_agency_org_id:b});l?(console.error("[DomainsCard]",l),y(!0),h([])):h(t??[]);const{data:n}=await T.rpc("agency_domains_available");I(n===!0),a(!1)},[b]);r.useEffect(()=>{s()},[s]);async function d(){if(!b||!c.trim())return;g(!0);const{data:t,error:l}=await T.rpc("agency_add_domain",{p_agency_org_id:b,p_hostname:c.trim()});g(!1);const n=t;if(l||!(n!=null&&n.ok)){u({title:"Could not add that domain",description:se[(n==null?void 0:n.error)??""]??(l==null?void 0:l.message)??"Unknown error",variant:"destructive"});return}_(""),u({title:"Domain added",description:"Add the DNS record shown, then we take it from there."}),s()}async function i(t,l){try{await navigator.clipboard.writeText(t),E(l),setTimeout(()=>E(null),2e3)}catch{}}const L=m.can("brand.manage");return e.jsxs(S,{children:[e.jsx(A,{className:"pb-3",children:e.jsxs(D,{className:"text-base flex items-center gap-2",children:[e.jsx(W,{className:"h-4 w-4 text-primary"})," Your own domain"]})}),e.jsxs(B,{className:"space-y-4",children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:"Put the app on your address instead of ours, so your clients only ever see your domain."}),e.jsx(Z,{loading:o,error:f||void 0,empty:!o&&!f&&p.length===0,emptyTitle:"No domain yet",emptyHint:"Add one below. You will need access to your DNS settings.",onRetry:s,skeletonRows:1}),!o&&!f&&p.length>0&&e.jsx("div",{className:"space-y-3",children:p.map(t=>{const l=ae[t.status]??{label:t.status,tone:"wait",hint:""},n=t.dns_instructions;return e.jsxs("div",{className:"rounded-lg border border-border p-3.5",children:[e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[e.jsx("code",{className:"text-sm font-medium",children:t.hostname}),e.jsx(Y,{variant:"outline",className:l.tone==="ok"?"border-success/40 text-success":l.tone==="bad"?"border-destructive/40 text-destructive":"border-warning/40 text-warning",children:l.label})]}),l.hint&&e.jsx("p",{className:"text-xs text-muted-foreground mt-1.5",children:l.hint}),(n==null?void 0:n.value)&&t.status!=="issued"&&e.jsxs("div",{className:"mt-3 rounded-md bg-muted/50 p-2.5 text-xs space-y-1.5",children:[e.jsx("div",{className:"font-medium",children:"Add this record with your DNS provider:"}),e.jsxs("div",{className:"grid grid-cols-[auto_1fr_auto] gap-2 items-center font-mono",children:[e.jsx("span",{className:"text-muted-foreground",children:n.type}),e.jsxs("span",{className:"truncate",children:[n.name," â ",n.value]}),e.jsx(F,{size:"sm",variant:"ghost",className:"h-7","aria-label":"Copy DNS re
1cord value",onClick:()=>i(n.value,t.id),children:k===t.id?e.jsx($,{className:"h-3.5 w-3.5"}):e.jsx(z,{className:"h-3.5 w-3.5"})})]})]})]},t.id)})}),j===!1?e.jsx("div",{className:"rounded-lg border border-border bg-muted/30 p-3.5 text-xs text-muted-foreground",children:"Custom domains are coming soon â you'll be able to point your own address here once it's switched on."}):L?e.jsxs("div",{className:"flex items-end gap-2 pt-1",children:[e.jsxs("div",{className:"flex-1",children:[e.jsx(N,{htmlFor:"dom-host",children:"Add a domain"}),e.jsx(C,{id:"dom-host",value:c,placeholder:"app.youragency.com",onChange:t=>_(t.target.value),onKeyDown:t=>{t.key==="Enter"&&d()}})]}),e.jsxs(F,{onClick:d,disabled:v||!c.trim(),children:[v&&e.jsx(K,{className:"h-4 w-4 mr-2 animate-spin"})," Add"]})]}):e.jsx("p",{className:"text-xs text-muted-foreground",children:"Only an agency owner can add a domain."})]})]})}const re=[{key:"color_primary",label:"Primary",hint:"Buttons, links, focus rings"},{key:"color_primary_glow",label:"Primary glow",hint:"Gradient end, shadows"},{key:"color_accent",label:"Accent",hint:"Secondary highlights"},{key:"color_ring",label:"Focus ring",hint:"Keyboard focus outline"}];function ce(){const{user:x,loading:m}=G(),{loading:u,isAgency:p}=M(),{toast:h}=H(),{agency:o}=P(),[a,f]=r.useState(null),[y,c]=r.useState(!0),[_,v]=r.useState(!1),[g,k]=r.useState({}),E=Object.values(g).some(Boolean);r.useEffect(()=>{if(!(o!=null&&o.brand_id)){c(!1);return}let s=!1;return T.from("brands").select("id, display_name, tagline, wordmark_text, logo_url, favicon_url, color_primary, color_primary_glow, color_accent, color_ring, color_background, color_foreground, support_url, marketing_url, status").eq("id",o.brand_id).maybeSingle().then(({data:d,error:i})=>{s||(i&&console.error("[AgencyBrandSettings]",i),f(d??null),c(!1))}),()=>{s=!0}},[o==null?void 0:o.brand_id]);const j=(s,d)=>f(i=>i&&{...i,[s]:d}),I=r.useMemo(()=>a?q(a):void 0,[a==null?void 0:a.color_primary,a==null?void 0:a.color_primary_glow,a==null?void 0:a.color_accent,a==null?void 0:a.color_ring,a==null?void 0:a.color_background,a==null?void 0:a.color_foreground]);async function b(){if(!a)return;const s={color_primary:w(a.color_primary),color_primary_glow:w(a.color_primary_glow),color_accent:w(a.color_accent),color_ring:w(a.color_ring),color_background:w(a.color_background),color_foreground:w(a.color_foreground)},d=Object.entries(s).filter(([,t])=>t===null).map(([t])=>t);if(d.length>0){h({title:"Fix the colours first",description:`${d.join(", ")} must be 6 hex digits, like #8B5CC8.`,variant:"destructive"});return}v(!0);const{data:i,error:L}=await T.from("brands").update({display_name:a.display_name,tagline:a.tagline,wordmark_text:a.wordmark_text,logo_url:a.logo_url,favicon_url:a.favicon_url,color_primary:s.color_primary,color_primary_glow:s.color_primary_glow,color_accent:s.color_accent,color_ring:s.color_ring,color_background:s.color_background,color_foreground:s.color_foreground,support_url:a.support_url,marketing_url:a.marketing_url,updated_at:new Date().toISOString()}).eq("id",a.id).select("id");if(v(!1),L){h({title:"Could not save",description:L.message,variant:"destructive"});return}if(!i||i.length===0){h({title:"You do not have permission to change the brand",description:"Ask an owner or admin of your agency to make this change.",variant:"destructive"});return}X(),h({title:"Brand saved",description:"Applied â your clients see it now."})}return m||u||y?e.jsx("div",{className:"py-16 text-muted-foreground",children:"Loadingâ¦"}):x?p?a?e.jsxs(e.Fragment,{children:[e.jsx(Q,{title:"Brand",subtitle:"What your clients see. Colours apply across the whole app at runtime."}),e.jsxs("div",{className:"max-w-3xl space-y-6",children:[e.jsxs(S,{children:[e.jsx(A,{className:"pb-3",children:e.jsx(D,{className:"text-base",children:"Identity"})}),e.jsxs(B,{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx(N,{htmlFor:"display_name",children:"Display name"}),e.jsx(C,{id:"display_name",value:a.display_name,onChange:s=>j("display_name",s.target.value)})]}),e.jsxs("div",{children:[e.jsx(N,{htmlFor:"wordmark",children:"Wordmark text"}),e.jsx(C,{id:"wordmark",value:a.wordmark_text??"",placeholder:a.display_name,onChange:s=>j("wordmark_text",s.target.value)}),e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"Shown in the header when no logo is uploaded."})]}),e.jsxs("div",{children:[e.jsx(N,{htmlFor:"tagline",children:"Tagline"}),e.jsx(C,{id:"tagline",value:a.tagline??"",onChange:s=>j("tagline",s.target.value)})]})]})]}),e.jsxs(S,{children:[e.jsx(A,{className:"pb-3",children:e.jsx(D,{className:"text-base",children:"Logo"})}),e.jsxs(B,{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx(N,{className:"mb-2 block",children:"Header logo"}),e.jsx(R,{value:a.logo_url??"",onChange:s=>j("logo_url",s),bucket:"brand-assets",folder:o.organization_id})]}),e.jsxs("div",{children:[e.jsx(N,{className:"mb-2 block",children:"Favicon"}),e.jsx(R,{value:a.favicon_url??"",onChange:s=>j("favicon_url",s),bucket:"brand-assets",folder:o.organization_id})]})]})]}),e.jsxs(S,{children:[e.jsx(A,{className:"pb-3",children:e.jsx(D,{className:"text-base",children:"Colours"})}),e.jsxs(B,{className:"space-y-4",children:[re.map(s=>e.jsx(ee,{label:s.label,hint:s.hint,value:a[s.key],onChange:d=>j(s.key,d),onValidityChange:d=>k(i=>i[s.key]===!d?i:{...i,[s.key]:!d})},s.key)),e.jsx("p",{className:"text-xs text-muted-foreground pt-2 border-t border-border",children:'Status colours (success, warning, error) are fixed platform-wide. Green means "winning variant" regardless of brand â repainting them would make a losing test look like a winning one.'})]})]}),e.jsxs(S,{children:[e.jsx(A,{className:"pb-3",children:e.jsx(D,{className:"text-base",children:"Live preview"})}),e.jsxs(B,{children:[e.jsxs("div",{style:I,className:"rounded-lg border border-border p-5 space-y-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx(F,{children:"Primary button"}),e.jsx(F,{variant:"outline",children:"Secondary"}),e.jsx("a",{href:"#",onClick:s=>s.preventDefault(),className:"text-primary underline text-sm",children:"A link"}),e.jsx("span",{className:"inline-flex items-center rounded-full bg-accent px-2.5 py-0.5 text-xs font-medium text-accent-foreground",children:"Accent"})]}),e.jsx(C,{placeholder:"Click here to see your focus ring"})]}),e.jsx("p",{className:"text-xs text-muted-foreground mt-3",children:"Sample chrome â how your brand colours look on buttons, links and focus rings. Changes here preview instantly; Save applies them for your clients."})]})]}),e.jsx(te,{}),e.jsx("div",{className:"flex items-center justify-end gap-3",children:e.jsxs(F,{onClick:b,disabled:_||E,children:[e.jsx(J,{className:"h-4 w-4 mr-2"}),_?"Savingâ¦":"Save brand"]})})]})]}):e.jsx("div",{className:"py-16",children:e.jsx("p",{className:"text-muted-foreground",children:"No brand is attached to this agency. Re-run provisioning, or contact support."})}):e.jsx(O,{to:"/app",replace:!0}):e.jsx(O,{to:"/",replace:!0})}export{ce 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.