PageSourceSearch

https://callflow.dev/assets/AdminBookings-DzXzx7Yn.js

js callflow.dev collected 2026-10-08 05:58:12 UTC 14,437 bytes, 12 lines download raw bytes

1import{r as d,j as e}from"./vendor-react-BejaPDzU.js";import{A as Z,q as J}from"./AppLayout-Nsg2RFJV.js";import{C as f,d as _,a as K,b as Q}from"./card-Dl5bEXx2.js";import{m as I,B as u,s as c}from"./index-B6Tyvt9P.js";import{B as ee}from"./badge-OW0agykM.js";import{T as te,a as se,b as S,c as T}from"./tabs-MFdBz91_.js";import{I as h}from"./input-BwU7N1FI.js";import{L as x}from"./label-offiFfzP.js";import{T as ie}from"./textarea-AWnqC42P.js";import{S as P}from"./switch--U7-R_xr.js";import{D as M,e as q,a as F,b as R,c as U,f as ae}from"./dialog-BuASFBqZ.js";import{S as ne,a as le,b as re,c as oe,d as b}from"./select-lfjxjYVy.js";import{T as ce,a as de,b as N,c as v,d as me,e as g}from"./table-33DvqWg9.js";import{t as j}from"./use-toast-BTyiUUGD.js";import{C as xe}from"./clock-BJ14rlqt.js";import{C as ue}from"./circle-check-C0t50smJ.js";import{M as he}from"./mail-Do-P7hm5.js";import{B as pe}from"./building-2-DRIne6JZ.js";import{C as ge}from"./circle-x-KjexKQES.js";import{P as je}from"./plus-DQHF1DnE.js";import{T as ve}from"./trash-2-Cfn7t_UC.js";import"./crown-DuK_wRJT.js";import"./shield-BrfVeZWH.js";import"./user-CI3eJVPv.js";import"./credit-card-BNCInpWV.js";import"./lock-CIxnjdoP.js";import"./check-5ruikr_P.js";import"./trending-down-Dfyj699h.js";import"./index-BuVK54E4.js";import"./index-DrBC9ePF.js";import"./index-BAQWsOKG.js";import"./vendor-supabase-FIOcN6HE.js";import"./index-aOMPTBki.js";import"./index-BLB-hL8W.js";import"./circle-DpCXuugA.js";import"./trophy-Chv8EbjU.js";import"./award-ZjIN6ZhU.js";import"./phone-qf_RBItm.js";import"./graduation-cap-CXdt3xTa.js";import"./file-text-BuwfvdQT.js";import"./chart-column-BhxPBFDw.js";import"./settings-wilwGLPn.js";import"./dollar-sign-xW6zi3JC.js";import"./message-square-DDNSefya.js";import"./users-C4L8Xy2y.js";import"./briefcase-3QIVXJHg.js";import"./target-Ch3VcIky.js";import"./send-CfoUftgC.js";import"./zap-C3cOGATG.js";import"./search-Ct9P-NMr.js";import"./paintbrush-bnC3_emt.js";import"./vendor-query-DdyZXiDU.js";import"./vendor-ui--X5BZniO.js";import"./index-BH3fl-Co.js";import"./index-BdQq_4o_.js";/**
2 * @license lucide-react v0.462.0 - ISC
3 *
4 * This source code is licensed under the ISC license.
5 * See the LICENSE file in the root directory of this source tree.
6 */const fe=I("Link",[["path",{d:"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71",key:"1cjeqo"}],["path",{d:"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71",key:"19qd67"}]]);/**
7 * @license lucide-react v0.462.0 - ISC
8 *
9 * This source code is licensed under the ISC license.
10 * See the LICENSE file in the root directory of this source tree.
11 */const _e=I("PenLine",[["path",{d:"M12 20h9",key:"t2du7b"}],["path",{d:"M16.376 3.622a1 1 0 0 1 3.002 3.002L7.368 18.635a2 2 0 0 1-.855.506l-2.872.838a.5.5 0 0 1-.62-.62l.838-2.872a2 2 0 0 1 .506-.854z",key:"1ykcvy"}]]),ye=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"];function Ct(){const[n,m]=d.useState([]),[s,o]=d.useState([]),[a,W]=d.useState([]),[D,E]=d.useState(!0),[B,k]=d.useState(null),[H,w]=d.useState(!1),[$,y]=d.use
11State(null),p=async()=>{E(!0),k(null);try{const[t,i,l]=await Promise.all([c.from("bookings").select("*, booking_event_types(title, slug)").order("scheduled_at",{ascending:!0}).limit(200),c.from("booking_event_types").select("*").order("created_at",{ascending:!0}),c.from("booking_availability").select("*").order("day_of_week",{ascending:!0})]),r=t.error||i.error||l.error;r&&k(r.message),m(t.data||[]),o(i.data||[]),W(l.data||[])}catch(t){k(t?.message||"Failed to load bookings")}finally{E(!1)}};d.useEffect(()=>{p()},[]);const z=n.filter(t=>t.status==="confirmed"&&t.scheduled_at&&new Date(t.scheduled_at)>=new Date),V=z.filter(t=>new Date(t.scheduled_at)<=new Date(Date.now()+7*864e5)),A=async(t,i)=>{await c.from("bookings").update({status:i,cancelled_at:i==="cancelled"?new Date().toISOString():null}).eq("id",t),j({title:`Booking ${i}`}),p()},G=async t=>{const i={title:t.title,slug:t.slug,description:t.description||null,duration_minutes:Number(t.duration_minutes)||15,location_type:t.location_type||"google_meet",location_details:t.location_details||null,buffer_minutes:Number(t.buffer_minutes)||0,max_per_day:Number(t.max_per_day)||20,is_active:t.is_active??!0}
11,l=t.id?c.from("booking_event_types").update(i).eq("id",t.id):c.from("booking_event_types").insert(i),{error:r}=await l;if(r){j({title:"Save failed",description:r.message,variant:"destructive"});return}j({title:"Saved"}),w(!1),y(null),p()},O=async t=>{if(!confirm("Delete this event type? Existing bookings remain."))return;const{error:i}=await c.from("booking_event_types").delete().eq("id",t);if(i){j({title:"Delete failed",description:i.message,variant:"destructive"});return}j({title:"Deleted"}),p()},Y=async(t,i)=>{i?await c.from("booking_availability").update({is_active:!i.is_active}).eq("id",i.id):await c.from("booking_availability").insert({day_of_week:t,start_time:"09:00",end_time:"17:00",timezone:"America/New_York",is_active:!0}),p()},C=async(t,i)=>{await c.from("booking_availability").update(i).eq("id",t),p()},X=t=>{const i=`${window.location.origin}/book/${t}`;navigator.clipboard.writeText(i),j({title:"Link copied",description:i})};return e.jsx(Z,{children:e.jsxs("div",{className:"p-6 max-w-7xl mx-auto space-y-6",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-bold text-foreground",children:"Bookings"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Manage appointments, event types, and availability."})]}),B&&e.jsx(f,{className:"border-destructive/40",children:e.jsxs(_,{className:"p-4 flex items-center justify-between gap-3",children:[e.jsxs("p",{className:"text-sm text-destructive",children:["Could not load bookings: ",B]}),e.jsx(u,{size:"sm",variant:"outline",onClick:p,children:"Retry"})]})}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-4",children:[e.jsx(L,{icon:e.jsx(J,{className:"w-4 h-4"}),label:"Upcoming",value:z.length}),e.jsx(L,{icon:e.jsx(xe,{className:"w-4 h-4"}),label:"This week",value:V.length}),e.jsx(L,{icon:e.jsx(ue,{className:"w-4 h-4"}),label:"Active event types",value:s.filter(t=>t.is_active).length})]}),e.jsxs(te,{defaultValue:"upcoming",children:[e.jsxs(se,{children:[e.jsx(S,{value:"upcoming",children:"Upcoming"}),e.jsx(S,{value:"event-types",children:"Event Types"}),e.jsx(S,{value:"availability",children:"Availability"})]}),e.jsx(T,{value:"upcoming",children:e.jsx(f,{children:e.jsx(_,{className:"p-0",children:e.jsxs(ce,{children:[e.jsx(de,{children:e.jsxs(N,{children:[e.jsx(v,{children:"When"}),e.jsx(v,{children:"Guest"}),e.jsx(v,{children:"Meeting"}),e.jsx(v,{children:"Status"}),e.jsx(v,{className:"text-right",children:"Actions"})]})}),e.jsxs(me,{children:[D&&e.jsx(N,{children:e.jsx(g,{colSpan:5,className:"text-center text-muted-foreground py-8",children:"Loading…"})}),!D&&n.length===0&&e.jsx(N,{children:e.jsx(g,{colSpan:5,className:"text-center text-muted-foreground py-8",children:"No bookings yet."})}),n.map(t=>e.jsxs(N,{children:[e.jsxs(g,{children:[e.jsx("div",{className:"text-sm font-medium",children:be(t.scheduled_at)}),e.jsxs("div",{className:"text-xs text-muted-foreground",children:[t.duration_minutes," min"]})]}),e.jsxs(g,{children:[e.jsx("div",{className:"text-sm font-medium",children:t.guest_name||"Unknown"}),e.jsxs("div",{className:"text-xs text-muted-foreground flex items-center gap-1",children:[e.jsx(he,{className:"w-3 h-3"}),t.guest_email||"-"]}),t.guest_company&&e.jsxs("div",{className:"text-xs text-muted-foreground flex items-center gap-1",children:[e.jsx(pe,{className:"w-3 h-3"}),t.guest_company]})]}),e.jsx(g,{className:"text-sm",children:t.booking_event_types?.title||"—"}),e.jsx(g,{children:e.jsx(Ne,{status:t.status})}),e.jsxs(g,{className:"text-right space-x-1",children:[t.notes&&e.jsxs(M,{children:[e.jsx(q,{asChild:!0,children:e.jsx(u,{size:"sm",variant:"ghost",children:"Notes"})}),e.jsxs(F,{children:[e.jsx(R,{children:e.jsxs(U,{children:["Notes from ",t.guest_name]})}),e.jsx("p",{className:"whitespace-pre-wrap text-sm",children:t.notes})]})]}),t.status==="confirmed"&&e.jsxs(e.Fragment,{children:[e.jsx(u,{size:"sm",variant:"outline",onClick:()=>A(t.id,"completed"),children:"Complete"}),e.jsx(u,{size:"sm",variant:"ghost",onClick:()=>A(t.id,"cancelled"),children:e.jsx(ge,{className:"w-4 h-4"})})]})]})]},t.id))]})]})})})}),e.jsxs(T,{value:"event-types",children:[e.jsx("div",{className:"flex justify-end mb-3",children:e.jsxs(M,{open:H,onOpenChange:t=>{w(t),t||y(null)},children:[e.jsx(q,{asChild:!0,children:e.jsxs(u,{onClick:()=>y(null),children:[e.jsx(je,{className:"w-4 h-4 mr-1"})," New event type"]})}),e.jsx(ke,{initial:$,onSave:G})]})}),e.jsxs("div",{className:"grid gap-3",children:[s.map(t=>e.jsx(f,{children:e.jsxs(_,{className:"p-4 flex items-center justify-between",children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("h3",{className:"font-semibold text-foreground",children:t.title}),!t.is_active&&e.jsx(ee,{variant:"secondary",children:"Inactive"})]}),e.jsxs("p",{className:"text-sm text-muted-foreground mt-1",children:[t.duration_minutes," min · ",(t.location_type||"").replace("_"," ")," · /book/",t.slug]})]}),e.jsxs("div",{className:"flex gap-1",children:[e.jsx(u,{size:"sm",variant:"ghost",onClick:()=>X(t.slug),children:e.jsx(fe,{className:"w-4 h-4"})}),e.jsx(u,{size:"sm",variant:"ghost",onClick:()=>{y(t),w(!0)},children:e.jsx(_e,{className:"w-4 h-4"})}),e.jsx(u,{size:"sm",variant:"ghost",onClick:()=>O(t.id),children:e.jsx(ve,{className:"w-4 h-4 text-destructive"})})]})]})},t.id)),!s.length&&e.jsx("p",{className:"text-sm text-muted-foreground text-center py-8",children:"No event types yet."})]})]}),e.jsx(T,{value:"availability",children:e.jsxs(f,{children:[e.jsx(K,{children:e.jsx(Q,{className:"text-base",children:"Weekly schedule"})}),e.jsx(_,{className:"space-y-3",children:ye.map((t,i)=>{const l=a.find(r=>r.day_of_week===i);return e.jsxs("div",{className:"flex items-center gap-3 py-2 border-b border-border last:border-0",children:[e.jsx("div",{className:"w-16",children:e.jsx(P,{checked:!!l?.is_active,onCheckedChange:()=>Y(i,l)})}),e.jsx("div",{className:"w-12 text-sm font-medium",children:t}),l?.is_active?e.jsxs("div",{className:"flex items-center gap-2 flex-1",children:[e.jsx(h,{type:"time",value:(l.start_time||"09:00").slice(0,5),className:"w-32",onChange:r=>C(l.id,{start_time:r.target.value})}),e.jsx("span",{className:"text-sm text-muted-foreground",children:"to"}),e.jsx(h,{type:"time",value:(l.end_time||"17:00").slice(0,5),className:"w-32",onChange:r=>C(l.id,{end_time:r.target.value})}
11),e.jsx(h,{value:l.timezone||"",className:"w-48",onChange:r=>C(l.id,{timezone:r.target.value})})]}):e.jsx("div",{className:"text-sm text-muted-foreground",children:"Unavailable"})]},i)})})]})})]})]})})}function L({icon:n,label:m,value:s}){return e.jsx(f,{children:e.jsxs(_,{className:"p-5",children:[e.jsxs("div",{className:"flex items-center gap-2 text-muted-foreground text-xs uppercase tracking-wide",children:[n,m]}),e.jsx("div",{className:"text-2xl font-bold mt-2 text-foreground",children:s})]})})}function be(n){if(!n)return"-";const m=new Date(n);return isNaN(m.getTime())?"-":m.toLocaleString([],{weekday:"short",month:"short",day:"numeric",hour:"numeric",minute:"2-digit"})}function Ne({status:n}){const s={confirmed:{label:"Confirmed",cls:"bg-secondary/15 text-secondary"},cancelled:{label:"Cancelled",cls:"bg-destructive/15 text-destructive"},completed:{label:"Completed",cls:"bg-primary/15 text-primary"},no_show:{label:"No-show",cls:"bg-muted text-muted-foreground"}}[n]||{label:n,cls:"bg-muted"};return e.jsx("span",{className:`inline-flex items-center px-2 py-0.5 rounded-md text-xs font-medium ${s.cls}`,children:s.label})}function ke({initial:n,onSave:m}){const[s,o]=d.useState(n||{title:"",slug:"",description:"",duration_minutes:15,location_type:"google_meet",location_details:"",buffer_minutes:5,max_per_day:20,is_active:!0});return d.useEffect(()=>{o(n||{title:"",slug:"",description:"",duration_minutes:15,location_type:"google_meet",location_details:"",buffer_minutes:5,max_per_day:20,is_active:!0})},[n]),e.jsxs(F,{className:"max-w-lg",children:[e.jsx(R,{children:e.jsx(U,{children:n?"Edit event type":"New event type"})}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{children:[e.jsx(x,{children:"Title"}),e.jsx(h,{value:s.title||"",onChange:a=>o({...s,title:a.target.value}),maxLength:100})]}),e.jsxs("div",{children:[e.jsxs(x,{children:["Slug (URL: /book/",e.jsx("em",{children:"slug"}),")"]}),e.jsx(h,{value:s.slug||"",onChange:a=>o({...s,slug:a.target.value.toLowerCase().replace(/[^a-z0-9-]/g,"-")}),maxLength:60})]}),e.jsxs("div",{children:[e.jsx(x,{children:"Description"}),e.jsx(ie,{value:s.description||"",onChange:a=>o({...s,description:a.target.value}),rows:2,maxLength:500})]}),e.jsxs("div",{className:"grid grid-cols-3 gap-3",children:[e.jsxs("div",{children:[e.jsx(x,{children:"Duration (min)"}),e.jsx(h,{type:"number",min:5,value:s.duration_minutes||15,onChange:a=>o({...s,duration_minutes:Number(a.target.value)})})]}),e.jsxs("div",{children:[e.jsx(x,{children:"Buffer (min)"}),e.jsx(h,{type:"number",min:0,value:s.buffer_minutes||0,onChange:a=>o({...s,buffer_minutes:Number(a.target.value)})})]}),e.jsxs("div",{children:[e.jsx(x,{children:"Max/day"}),e.jsx(h,{type:"number",min:1,value:s.max_per_day||20,onChange:a=>o({...s,max_per_day:Number(a.target.value)})})]})]}),e.jsxs("div",{children:[e.jsx(x,{children:"Location"}),e.jsxs(ne,{value:s.location_type||"google_meet",onValueChange:a=>o({...s,location_type:a}),children:[e.jsx(le,{children:e.jsx(re,{})}),e.jsxs(oe,{children:[e.jsx(b,{value:"google_meet",children:"Google Meet"}),e.jsx(b,{value:"zoom",children:"Zoom"}),e.jsx(b,{value:"phone",children:"Phone"}),e.jsx(b,{value:"in_person",children:"In person"})]})]})]}),e.jsxs("div",{children:[e.jsx(x,{children:"Location details (link / address / phone)"}),e.jsx(h,{value:s.location_details||"",onChange:a=>o({...s,location_details:a.target.value}),placeholder:"https://meet.google.com/..."})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(P,{checked:s.is_active??!0,onCheckedChange:a=>o({...s,is_active:a})}),e.jsx(x,{children:"Active"})]})]}),e.jsx(ae,{children:e.jsx(u,{onClick:()=>m({...s,id:n?.id}),disabled:!s.title||!s.slug,children:"Save"})})]})}export{Ct as default};
12//# sourceMappingURL=AdminBookings-DzXzx7Yn.js.map

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.