PageSourceSearch

https://advisor.tv/assets/hosts-c8vb7Vhn.js

js advisor.tv collected 2026-09-25 14:40:19 UTC 14,861 bytes, 1 lines download raw bytes

1import{bt as L,bu as B,bv as G,bw as O,bx as P,o as R,r as o,j as e,a as D,by as E,X as w}from"./index-BZRo-bYt.js";import{u as N}from"./useServerFn-CLUwdsxf.js";const W=[{key:"mon",label:"Monday"},{key:"tue",label:"Tuesday"},{key:"wed",label:"Wednesday"},{key:"thu",label:"Thursday"},{key:"fri",label:"Friday"},{key:"sat",label:"Saturday"},{key:"sun",label:"Sunday"}],I="inline-flex items-center justify-center gap-1.5 rounded-full bg-black px-4 py-2 text-sm font-medium text-white shadow-sm transition-all duration-200 hover:bg-text hover:-translate-y-0.5 hover:shadow-md active:translate-y-0",k="inline-flex items-center justify-center gap-1.5 rounded-full border border-black/15 bg-white px-4 py-2 text-sm font-medium text-text transition-all duration-200 hover:bg-black/[0.04] hover:-translate-y-0.5",K="inline-flex items-center justify-center rounded-full px-3 py-1.5 text-xs font-medium text-rose-600 transition-all duration-200 hover:bg-rose-50 hover:text-rose-700";function U(){const t=N(L),i=N(B),h=N(G),d=N(O),p=N(P),c=R({queryKey:["admin-hosts"],queryFn:()=>t()}),[x,r]=o.useState(null),[g,l]=o.useState(!1),[m,f]=o.useState(null),[C,_]=o.useState({}),S=async(s,a)=>{confirm(`Disconnect ${a}?`)&&(await d({data:{hostId:s,googleEmail:a}}),c.refetch())},v=async s=>{if(confirm("Delete this host? Their calendar links will also be removed."))try{await h({data:{id:s}}),c.refetch()}catch(a){f(a.message)}},A=async s=>{try{const{url:a,emailed:u,claimed:b}=await p({data:{hostId:s,origin:window.location.origin,sendEmail:!0}});_(z=>({...z,[s]:a}));try{await navigator.clipboard.writeText(a)}catch{}u?w.success("Invite email sent",{description:"Also copied to your clipboard."}):b?w.success("Sign-in link copied",{description:"This host already claimed their account."}):w.success("Invite link copied",{description:"Couldn't send email — share the link manually."}),c.refetch()}catch(a){w.error("Couldn't create invite",{description:a.message})}},y=c.data??[],j=y.filter(s=>s.is_required),n=y.filter(s=>!s.is_required);return e.jsx("main",{className:"min-h-screen bg-[#fafaf7]",children:e.jsxs("div",{className:"mx-auto max-w-5xl px-6 py-10",children:[e.jsxs("div",{className:"flex flex-wrap items-end justify-between gap-4",children:[e.jsxs("div",{children:[e.jsxs(D,{to:"/dashboard",className:"inline-flex items-center gap-1 text-sm text-text-2 transition-all duration-200 hover:-translate-x-0.5 hover:text-text",children:[e.jsx("span",{"aria-hidden":!0,children:"←"})," Back to dashboard"]}),e.jsx("div",{className:"mt-3 text-xs uppercase tracking-[0.18em] text-text-2",children:"Admin"}),e.jsx("h1",{className:"font-display text-4xl text-text mt-1",children:"Hosts & calendars"}),e.jsx("p",{className:"mt-2 text-sm text-text-2 max-w-xl",children:"Connect Google calendars so the public booking page can find open slots. The videographer’s calendar is required for every show; show hosts are optional for now."})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(D,{to:"/admin/calendar",className:k,children:"Episode calendar"}),e.jsxs("button",{onClick:()=>{l(!0),r(null)},className:I,children:[e.jsx("span",{className:"text-lg leading-none",children:"+"})," Add host"]})]})]}),m&&e.jsxs("div",{className:"mt-6 rounded-lg border border-rose-200 bg-rose-50 px-4 py-3 text-sm text-rose-800",children:[m,e.jsx("button",{onClick:()=>f(null),className:"ml-3 underline hover:no-underline",children:"dismiss"})]}),c.isLoading&&e.jsx("div",{className:"mt-10 text-sm text-text-2",children:"Loading hosts…"}),c.error&&e.jsx("div",{className:"mt-10 text-sm text-rose-700",children:c.error.message}),j.length>0&&e.jsxs("section",{className:"mt-10",children:[e.jsx(H,{children:"Required for every booking"}),e.jsx("div",{className:"mt-3 space-y-3",children:j.map(s=>e.jsx(T,{host:s,inviteLink:C[s.id]??null,onDisconnect:a=>S(s.id,a),onEdit:()=>{r(s),l(!1)},onDelete:()=>v(s.id),onInvite:()=>A(s.id)},s.id))})]}),e.jsxs("section",{className:"mt-10",children:[e.jsx(H,{children:"Show hosts (optional for now)"}),n.length===0?e.jsxs("div",{className:"mt-3 rounded-xl border border-dashed border-black/15 bg-white px-6 py-10 text-center",children:[e.jsx("p",{className:"text-sm text-text-2",children:"No show hosts yet. Bookings work with just the videographer."}),e.jsx("button",{onClick:()=>{l(!0),r(null)},className:`${k} mt-4`,children:"+ Add a show host"})]}):e.jsx("div",{className:"mt-3 space-y-3",children:n.map(s=>e.jsx(T,{host:s,inviteLink:C[s.id]??null,onDisconnect:a=>S(s.id,a),onEdit:()=>{r(s),l(!1)},onDelete:()=>v(s.id),onInvite:()=>A(s.id)},s.id))})]}),(x||g)&&e.jsx(Y,{host:x,onClose:()=>{r(null),l(!1)},onSave:async s=>{try{await i({data:s}),r(null),l(!1),c.refetch()}catch(a){f(a.message)}}})]})})}function H({children:t}){return e.jsx("h2",{className:"text-xs uppercase tracking-[0.18em] text-text-2",children:t})}function T({host:t,inviteLink:i,onDisconnect:h,onEdit:d,onDelete:p,onInvite:c}){const x=t.calendars.length>0,r=!!t.claimed_at&&!!t.user_id,g=!!t.invite_token;return e.jsxs("article",{className:"group rounded-xl border border-black/10 bg-white p-5 shadow-[0_1px_2px_rgba(0,0,0,0.04)] transition-all duration-200 hover:border-black/20 hover:shadow-[0_8px_24px_-12px_rgba(0,0,0,0.15)]",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-4",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[e.jsx("h3",{className:"font-display text-xl text-text",children:t.full_name}),t.is_required&&e.jsx("span",{className:"text-[10px] font-medium uppercase tracking-wider bg-amber-100 text-amber-900 border border-amber-200 px-2 py-0.5 rounded-full",children:"Always required"}),!t.active&&e.jsx("span",{className:"text-[10px] font-medium uppercase tracking-wider bg-black/5 text-text-2 px-2 py-0.5 rounded-full",children:"Inactive"}),e.jsxs("span",{className:`inline-flex items-center gap-1.5 text-[11px] font-medium px-2 py-0.5 rounded-full border ${x?"bg-emerald-50 text-emerald-800 border-emerald-200":"bg-amber-50 text-amber-900 border-amber-200"}`,children:[e.jsx("span",{className:`h-1.5 w-1.5 rounded-full ${x?"bg-emerald-500":"bg-amber-500"}`}),x?`${t.calendars.length} calendar${t.calendars.length>
11?"s":""} connected`:"No calendars connected"]}),e.jsx("span",{className:`inline-flex items-center gap-1.5 text-[11px] font-medium px-2 py-0.5 rounded-full border ${r?"bg-emerald-50 text-emerald-800 border-emerald-200":g?"bg-sky-50 text-sky-900 border-sky-200":"bg-black/[0.04] text-text-2 border-black/10"}`,title:r?"Host has claimed their account":g?"Invite created — not yet claimed":"No invite sent yet",children:r?"Account claimed":g?"Invite pending":"No invite"})]}),e.jsx("div",{className:"mt-1 text-sm text-text-2",children:t.email}),e.jsxs("dl",{className:"mt-3 grid grid-cols-2 sm:grid-cols-3 gap-x-6 gap-y-1 text-xs text-text-2",children:[e.jsxs("div",{children:[e.jsx("dt",{className:"text-[10px] uppercase tracking-wider text-text-2/70",children:"Shows"}),e.jsx("dd",{className:"text-text",children:t.is_required?"All shows":t.show_slugs.length?t.show_slugs.map(l=>E.find(m=>m.slug===l)?.name??l).join(", "):"—"})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-[10px] uppercase tracking-wider text-text-2/70",children:"Timezone"}),e.jsx("dd",{className:"text-text",children:t.timezone})]}),e.jsxs("div",{children:[e.jsx("dt",{className:"text-[10px] uppercase tracking-wider text-text-2/70",children:"Buffer"}),e.jsxs("dd",{className:"text-text",children:[t.buffer_minutes," min"]})]})]}),x&&e.jsx("ul",{className:"mt-3 space-y-1.5",children:t.calendars.map(l=>e.jsxs("li",{className:"flex items-center gap-2 text-sm",children:[e.jsx("span",{className:"inline-flex h-5 w-5 items-center justify-center rounded-full bg-emerald-100 text-emerald-700 text-[10px]",children:"✓"}),e.jsx("span",{className:"text-text",children:l.google_email}),e.jsx("button",{onClick:()=>h(l.google_email),className:"text-[11px] text-text-2 hover:text-rose-600 transition-colors",children:"disconnect"})]},l.google_email))})]}),e.jsxs("div",{className:"flex flex-col items-stretch gap-2 shrink-0 w-full sm:w-auto",children:[!t.is_required&&e.jsx("button",{onClick:c,className:k,type:"button",children:r?"Copy sign-in link":g?"Copy invite link":"Invite to sign in"}),e.jsx("button",{type:"button",onClick:()=>{const l=t.full_name.normalize("NFKD").replace(/[\u0300-\u036f]/g,"").toLowerCase().replace(/[^a-z0-9\s-]/g,"").trim().replace(/\s+/g,"-"),m=`${window.location.origin}/h/${l}`;navigator.clipboard?.writeText(m),w.success("Landing page link copied",{description:m}),window.open(m,"_blank","noopener,noreferrer")},className:k,children:"Copy landing page link"}),e.jsx("a",{href:`/admin/connect-calendar/${t.id}`,target:"_blank",rel:"noopener noreferrer",className:I,children:x?"Connect another calendar":"Connect Google Calendar"}),e.jsx("button",{onClick:d,className:k,children:"Edit details"}),e.jsx("button",{onClick:p,className:K,children:"Delete host"})]})]}),i&&e.jsxs("div",{className:"mt-4 rounded-lg border border-black/10 bg-black/[0.03] p-3",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-wider text-text-2",children:"Invite link"}),e.jsxs("div",{className:"mt-1 flex flex-wrap items-center gap-2",children:[e.jsx("code",{className:"flex-1 min-w-0 truncate text-xs text-text",children:i}),e.jsx("button",{type:"button",onClick:()=>navigator.clipboard?.writeText(i),className:"rounded-full border border-black/15 bg-white px-3 py-1 text-[11px] font-medium hover:bg-black/[0.04]",children:"Copy again"})]}),e.jsxs("p",{className:"mt-2 text-[11px] text-text-2",children:["Anyone with this link can claim the host account. Share only with ",t.full_name,"."]})]})]})}function Y({host:t,onClose:i,onSave:h}){const[d,p]=o.useState(t?.full_name??""),[c,x]=o.useState(t?.email??""),[r,g]=o.useState(t?.show_slugs??[]),[l,m]=o.useState(t?.is_required??!1),[f,C]=o.useState(t?.buffer_minutes??15),[_,S]=o.useState(t?.timezone??"America/New_York"),[v,A]=o.useState(t?.active??!0),[y,j]=o.useState(t?.working_hours??{mon:["09:00","17:00"],tue:["09:00","17:00"],wed:["09:00","17:00"],thu:["09:00","17:00"],fri:["09:00","17:00"]});return e.jsx("div",{className:"fixed inset-0 bg-black/40 backdrop-blur-sm flex items-center justify-center p-4 z-50 animate-fade-in",onClick:i,children:e.jsxs("div",{onClick:n=>n.stopPropagation(),className:"bg-white border border-black/10 rounded-2xl shadow-2xl p-6 max-w-xl w-full max-h-[90vh] overflow-y-auto animate-scale-in",children:[e.jsxs("div",{className:"flex items-start justify-between mb-5",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"font-display text-2xl text-text",children:t?"Edit host":"Add host"}),e.jsx("p",{className:"text-xs text-text-2 mt-1",children:"Hosts can have one or more Google calendars connected."})]}),e.jsx("button",{onClick:i,"aria-label":"Close",className:"h-8 w-8 rounded-full text-text-2 hover:bg-black/5 hover:text-text transition-colors",children:"✕"})]}),e.jsxs("div",{className:"space-y-4",children:[e.jsx(q,{label:"Full name",value:d,onChange:p}),e.jsx(q,{label:"Email",value:c,onChange:x,type:"email"}),e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsx(q,{label:"Timezone (IANA)",value:_,onCh
1ange:S}),e.jsx(q,{label:"Buffer between bookings (min)",type:"number",value:String(f),onChange:n=>C(parseInt(n)||0)})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-3 pt-1",children:[e.jsx($,{checked:l,onChange:m,label:"Always required",hint:"Videographer attends every show"}),e.jsx($,{checked:v,onChange:A,label:"Active",hint:"Show this host in bookings"})]}),!l&&e.jsxs("div",{children:[e.jsx(F,{children:"Assigned shows"}),e.jsx("div",{className:"mt-2 grid grid-cols-2 gap-2",children:E.map(n=>{const s=r.includes(n.slug);return e.jsxs("label",{className:`flex items-center gap-2 text-sm rounded-lg border px-3 py-2 cursor-pointer transition-all duration-150 ${s?"border-black bg-black/[0.04]":"border-black/10 hover:border-black/30"}`,children:[e.jsx("input",{type:"checkbox",className:"accent-black",checked:s,onChange:a=>g(u=>a.target.checked?[...u,n.slug]:u.filter(b=>b!==n.slug))}),e.jsx("span",{className:"text-text",children:n.name})]},n.slug)})})]}),e.jsxs("div",{children:[e.jsx(F,{children:"Working hours (in host’s timezone)"}),e.jsx("div",{className:"mt-2 space-y-1.5",children:W.map(n=>{const s=y[n.key],a=!!s;return e.jsxs("div",{className:"flex items-center gap-3 text-sm rounded-lg border border-black/10 px-3 py-2",children:[e.jsxs("label",{className:"flex items-center gap-2 w-32 cursor-pointer",children:[e.jsx("input",{type:"checkbox",className:"accent-black",checked:a,onChange:u=>j(b=>({...b,[n.key]:u.target.checked?["09:00","17:00"]:null}))}),e.jsx("span",{className:"text-text",children:n.label})]}),a&&s?e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("input",{type:"time",value:s[0],onChange:u=>j(b=>({...b,[n.key]:[u.target.value,s[1]]})),className:"bg-white border border-black/15 rounded-md px-2 py-1 text-text"}),e.jsx("span",{className:"text-text-2",children:"to"}),e.jsx("input",{type:"time",value:s[1],onChange:u=>j(b=>({...b,[n.key]:[s[0],u.target.value]})),className:"bg-white border border-black/15 rounded-md px-2 py-1 text-text"})]}):e.jsx("span",{className:"text-xs text-text-2",children:"Off"})]},n.key)})})]})]}),e.jsxs("div",{className:"mt-6 flex justify-end gap-2",children:[e.jsx("button",{onClick:i,className:k,children:"Cancel"}),e.jsx("button",{onClick:()=>{const n={};for(const[s,a]of Object.entries(y))a&&(n[s]=a);h({id:t?.id,full_name:d,email:c,show_slugs:l?[]:r,is_required:l,buffer_minutes:f,timezone:_,active:v,working_hours:n})},className:I,children:"Save host"})]})]})})}function F({children:t}){return e.jsx("div",{className:"text-[11px] uppercase tracking-wider text-text-2",children:t})}function q({label:t,value:i,onChange:h,type:d="text"}){return e.jsxs("label",{className:"block text-sm",children:[e.jsx("span",{className:"text-[11px] uppercase tracking-wider text-text-2 block mb-1",children:t}),e.jsx("input",{type:d,value:i,onChange:p=>h(p.target.value),className:"w-full bg-white border border-black/15 rounded-lg px-3 py-2 text-text transition-colors focus:outline-none focus:border-black/40 focus:ring-2 focus:ring-black/5"})]})}function $({checked:t,onChange:i,label:h,hint:d}){return e.jsxs("label",{className:`flex items-start gap-3 rounded-lg border px-3 py-2.5 cursor-pointer transition-all duration-150 ${t?"border-black bg-black/[0.04]":"border-black/10 hover:border-black/30"}`,children:[e.jsx("input",{type:"checkbox",className:"accent-black mt-0.5",checked:t,onChange:p=>i(p.target.checked)}),e.jsxs("span",{children:[e.jsx("span",{className:"block text-sm text-text",children:h}),d&&e.jsx("span",{className:"block text-[11px] text-text-2",children:d})]})]})}export{U 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.