PageSourceSearch

https://closehaulcapital.ai/assets/AzulSettings-CzWCjZSt.js

js closehaulcapital.ai collected 2026-10-05 15:00:09 UTC 9,881 bytes, 1 lines download raw bytes

1import{j as e}from"./ui-CMTTTAxa.js";import{a as l}from"./vendor-BDindXV3.js";import{u as T,t as f,L as z}from"./index-Bqrg_C6x.js";import{a as _,A as a,d as N}from"./azul-Bv1oKUU-.js";import{g as $,j as E,A as F,u as C,k as L}from"./azulApi-D7SxfMYj.js";import{G as O}from"./grip-vertical-CXLhDFIX.js";import{X as B}from"./x-YAgHnB88.js";import{P as M}from"./plus-WgQwEo1z.js";import{S as W}from"./save-diDkHLBf.js";import"./supabase-Czj9ajwo.js";function te(){const{user:s}=T(),[t,n]=l.useState(!0),[i,r]=l.useState(null),[u,m]=l.useState([]),d=l.useCallback(async()=>{n(!0);const[p,g]=await Promise.all([$(),E()]);p.error?f.error(`Couldn’t load settings — ${p.error.message}`):r(p.data),g.error?f.error(`Couldn’t load team — ${g.error.message}`):m(g.data),n(!1)},[]);return l.useEffect(()=>{d()},[d]),t?e.jsx("div",{style:{display:"flex",justifyContent:"center",padding:"60px 0"},children:e.jsx(z,{size:22,className:"animate-spin",style:{color:_[400]}})}):e.jsxs("div",{children:[e.jsx("p",{style:{margin:0,fontSize:11,color:a.ink2},children:"Azul Interactiv · workspace"}),e.jsx("h1",{style:{margin:"2px 0 0",fontSize:20,fontWeight:500,color:a.ink},children:"Settings"}),e.jsx("p",{style:{margin:"2px 0 20px",fontSize:13,color:a.ink2},children:"Control the workspace, team, pipeline, and health rules."}),e.jsxs("div",{style:{display:"grid",gridTemplateColumns:"repeat(2, minmax(0, 1fr))",gap:16,alignItems:"start"},className:"azul-settings-grid",children:[e.jsx(U,{settings:i,userId:s==null?void 0:s.id,onSaved:r}),e.jsx(P,{members:u,onSaved:d}),e.jsx(Z,{settings:i,userId:s==null?void 0:s.id,onSaved:r}),e.jsx(G,{settings:i,userId:s==null?void 0:s.id,onSaved:r})]}),e.jsx("style",{children:"@media (max-width: 900px){ .azul-settings-grid{ grid-template-columns: 1fr !important; } }"})]})}function U({settings:s,userId:t,onSaved:n}){const[i,r]=l.useState(s.workspace_name||""),[u,m]=l.useState(s.sender_domain||""),[d,p]=l.useState(!1),g=i!==s.workspace_name||u!==s.sender_domain;async function o(){if(!i.trim()){f.error("Workspace name can’t be empty");return}p(!0);const{data:y,error:j}=await C({workspace_name:i.trim(),sender_domain:u.trim()},t);if(p(!1),j){f.error(`Save failed — ${j.message}`);return}n(y),f.success("Workspace saved")}return e.jsxs(k,{title:"Workspace",desc:"Identity used across the workspace and outbound email.",children:[e.jsx(b,{label:"Workspace name",children:e.jsx("input",{value:i,onChange:y=>r(y.target.value),style:v})}),e.jsx(b,{label:"Email sender domain",hint:"Outbound Azul email sends from this domain for both members.",children:e.jsx("input",{value:u,onChange:y=>m(y.target.value),placeholder:"azulinteractiv.com",style:v})}),e.jsx(A,{dirty:g,saving:d,onSave:o})]})}function P({members:s,onSaved:t}){return e.jsxs(k,{title:"Team & access",desc:"Only these people can open the Azul workspace. Each sends outbound email as their Azul identity.",children:[e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:10},children:s.map(n=>e.jsx(D,{member:n,onSaved:t},n.id))}),e.jsxs("p",{style:{margin:"12px 0 0",fontSize:11.5,color:a.ink3},children:["Adding or removing members is managed in the schema for now — this list mirrors ",e.jsx("code",{style:{fontSize:11},children:"azul_members"}),"."]})]})}function D({member:s,onSaved:t}){const[n,i]=l.useState(s.role),[r,u]=l.useState(s.send_as_email||""),[m,d]=l.useState(!1),p=n!==s.role||r!==(s.send_as_email||"");async function g(){d(!0);const{error:o}=await L(s.id,{role:n,send_as_email:r.trim()||null});if(d(!1),o){f.error(`Save failed — ${o.message}`);return}f.success(`${s.full_name||"Member"} updated`),t()}return e.jsxs("div",{style:{border:`1px solid ${a.border}`,borderRadius:14,padding:14,background:a.panel2},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:11,marginBottom:12},children:[e.jsx("div",{style:{width:34,height:34,borderRadius:999,background:_[900],color:"#fff",fontSize:12,fontWeight:500,display:"flex",alignItems:"center",justifyContent:"center",flexShrink:0},children:(s.full_name||s.email||"?").split(/\s+/).map(o=>o[0]).slice(0,2).join("").toUpperCase()}),e.jsxs("div",{style:{minWidth:0},children:[e.jsx("div",{style:{fontSize:13.5,fontWeight:500,color:a.ink},children:s.full_name||"—"}),e.jsx("div",{style:{fontSize:12,color:a.ink2,overflow:"hidden",textOverflow:"ellipsis"},children:s.email})]})]}),e.jsxs("div",{style:{display:"grid",gridTemplateColumns:"140px 1fr",gap:10},children:[e.jsx(b,{label:"Role",bare:!0,children:e.jsxs("select",{value:n,onChange:o=>i(o.target.value),style:{...v,background:"#fff"},children:[e.jsx("option",{value:"owner",children:"Owner"}),e.jsx("option",{value:"member",children:"Member"})]})}),e.jsx(b,{label:"Sends email as",bare:!0,children:e.jsx("input",{value:r,onChange:o=>u(o.target.value),placeholder:"[email protected]",style:{...v,background:"#fff"}})})]}),e.jsx("div",{style:{display:"flex",justifyContent:"flex-end",marginTop:12},children:e.jsxs("button",{onClick:g,disabled:!p||m,style:I(p,m),children:[m?e.jsx(z,{size:14,className:"animate-spin"}):e.jsx(W,{size:14})," Save"]})})]})}function Z({settings:s,userId:t,onSaved:n}){var j;const[i,r]=l.useState((j=s.stages)!=null&&j.length?s.stages:F.stages),[u,m]=l.useState(!1),d=JSON.stringify(i)!==JSON.stringify(s.stages),p=(c,h)=>r(x=>x.map((S,R)=>R===c?h:S)),g=c=>r(h=>h.filter((x,S)=>S!==c)),o=()=>r(c=>[...c,""]);async function y(){const c=i.map(S=>
1S.trim()).filter(Boolean);if(c.length<2){f.error("Keep at least two stages");return}m(!0);const{data:h,error:x}=await C({stages:c},t);if(m(!1),x){f.error(`Save failed — ${x.message}`);return}n(h),r(c),f.success("Pipeline stages saved")}return e.jsxs(k,{title:"Pipeline stages",desc:"The ordered stages a deal moves through. Order here is the pipeline order everywhere.",children:[e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:8},children:i.map((c,h)=>e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8},children:[e.jsx(O,{size:15,style:{color:a.ink3,flexShrink:0}}),e.jsx("span",{style:{width:18,fontSize:12,color:a.ink3,flexShrink:0},children:h+1}),e.jsx("input",{value:c,onChange:x=>p(h,x.target.value),placeholder:"Stage name",style:v}),e.jsx("button",{onClick:()=>g(h),"aria-label":"Remove stage",style:{width:34,height:38,flexShrink:0,borderRadius:10,border:`1px solid ${a.border}`,background:"#fff",color:N.dangerText,cursor:"pointer",display:"inline-flex",alignItems:"center",justifyContent:"center"},children:e.jsx(B,{size:15})})]},h))}),e.jsxs("button",{onClick:o,style:{display:"inline-flex",alignItems:"center",gap:6,marginTop:10,height:34,padding:"0 13px",borderRadius:999,border:`1px solid ${a.border}`,background:"#fff",color:a.ink,cursor:"pointer",fontFamily:"inherit",fontSize:12.5,fontWeight:500},children:[e.jsx(M,{size:14})," Add stage"]}),e.jsx(A,{dirty:d,saving:u,onSave:y})]})}function G({settings:s,userId:t,onSaved:n}){const[i,r]=l.useState(s.stale_touch_days),[u,m]=l.useState(s.stalled_proposal_days),[d,p]=l.useState(s.renewal_window_days),[g,o]=l.useState(!1),y=i!==s.stale_touch_days||u!==s.stalled_proposal_days||d!==s.renewal_window_days;async function j(){const c={stale_touch_days:+i,stalled_proposal_days:+u,renewal_window_days:+d};if(Object.values(c).some(S=>!Number.isFinite(S)||S<1)){f.error("Use whole numbers of days (1+)");return}o(!0);const{data:h,error:x}=await C(c,t);if(o(!1),x){f.error(`Save failed — ${x.message}`);return}n(h),f.success("Health rules saved")}return e.jsxs(k,{title:"Health rules",desc:"When a client gets flagged. Fewer flags = Strong, one = Watch, two or more = At risk.",children:[e.jsxs("div",{style:{display:"grid",gridTemplateColumns:"repeat(3, 1fr)",gap:12},className:"azul-health-grid",children:[e.jsx(w,{label:"Stale touch",hint:"days since last activity",value:i,onChange:r}),e.jsx(w,{label:"Stalled proposal",hint:"days a proposal sits open",value:u,onChange:m}),e.jsx(w,{label:"Renewal window",hint:"days out counts as upcoming",value:d,onChange:p})]}),e.jsx(A,{dirty:y,saving:g,onSave:j}),e.jsx("style",{children:"@media (max-width: 640px){ .azul-health-grid{ grid-template-columns: 1fr !important; } }"})]})}function k({title:s,desc:t,children:n}){return e.jsxs("div",{style:{background:"#fff",border:`1px solid ${a.border}`,borderRadius:20,padding:20},children:[e.jsx("h2",{style:{margin:0,fontSize:15,fontWeight:500,color:a.ink},children:s}),t&&e.jsx("p",{style:{margin:"3px 0 16px",fontSize:12.5,color:a.ink2},children:t}),n]})}function b({label:s,hint:t,children:n,bare:i}){return e.jsxs("div",{style:{marginBottom:i?0:14},children:[e.jsx("label",{style:{display:"block",fontSize:11,fontWeight:500,color:a.ink2,marginBottom:5},children:s}),n,t&&e.jsx("p",{style:{margin:"5px 0 0",fontSize:11,color:a.ink3},children:t})]})}function w({label:s,hint:t,value:n,onChange:i}){return e.jsxs("div",{children:[e.jsx("label",{style:{display:"block",fontSize:11,fontWeight:500,color:a.ink2,marginBottom:5},children:s}),e.jsx("input",{type:"number",min:1,value:n,onChange:r=>i(r.target.value),style:v}),t&&e.jsx("p",{style:{margin:"5px 0 0",fontSize:11,color:a.ink3},children:t})]})}function A({dirty:s,saving:t,onSave:n}){return e.jsx("div",{style:{display:"flex",justifyContent:"flex-end",marginTop:18},children:e.jsxs("button",{onClick:n,disabled:!s||t,style:I(s,t),children:[t?e.jsx(z,{size:14,className:"animate-spin"}):e.jsx(W,{size:14})," Save changes"]})})}const v={width:"100%",height:38,padding:"0 12px",boxSizing:"border-box",borderRadius:10,border:`1px solid ${a.border}`,background:"#fff",color:a.ink,fontSize:13,fontFamily:"inherit",outline:"none"};function I(s,t){return{display:"inline-flex",alignItems:"center",gap:7,height:38,padding:"0 16px",borderRadius:999,border:"none",cursor:s&&!t?"pointer":"default",fontFamily:"inherit",fontSize:13,fontWeight:500,background:s?_[900]:a.panel2,color:s?"#fff":a.ink3,opacity:t?.7:1}}export{te 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.