@gropulse/booking-widget 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +2 -1
- package/dist/index.js +137 -125
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),w=require("react");function v(g){const{apiBaseUrl:o,context:r,onBookingConfirmed:t}=g,[s,b]=w.useState([]),[d,n]=w.useState(null),[f,i]=w.useState(null),[u,x]=w.useState(!1),[j,p]=w.useState(null),h=w.useCallback(async l=>{const a={...r,timezone:r.timezone??Intl.DateTimeFormat().resolvedOptions().timeZone},c=await fetch(`${o}/api/chat`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({messages:l,context:a})});if(!c.ok){const m=await c.text();throw new Error(`Chat API error ${c.status}: ${m}`)}return await c.json()},[o,r]),y=w.useCallback(l=>{b(a=>[...a,{role:"assistant",content:l.message}]),l.action==="show_slots"&&l.slots&&n(l.slots),l.action==="booking_confirmed"&&l.booking&&(i(l.booking),n(null),t==null||t(l.booking))},[t]),k=w.useCallback(async()=>{if(!(s.length>0||u)){x(!0),p(null);try{const a=await h([{role:"user",content:"__START__"}]);b([{role:"assistant",content:a.message}]),a.action==="show_slots"&&a.slots&&n(a.slots),a.action==="booking_confirmed"&&a.booking&&(i(a.booking),t==null||t(a.booking))}catch(l){p(l.message)}finally{x(!1)}}},[s.length,u,h,t]),N=w.useCallback(async l=>{const a=l.trim();if(!a||u)return;const c=[...s,{role:"user",content:a}];b(c),x(!0),p(null);try{const m=await h(c);y(m)}catch(m){p(m.message)}finally{x(!1)}},[s,u,h,y]),S=w.useCallback(async l=>{if(u)return;const a=new Date(l.time).toLocaleString(void 0,{weekday:"short",month:"short",day:"numeric",hour:"numeric",minute:"2-digit"}),c=[...s,{role:"user",content:`I'll take ${a} (${l.time})`}];b(c),n(null),x(!0),p(null);try{const m=await h(c);y(m)}catch(m){p(m.message)}finally{x(!1)}},[s,u,h,y]);return{messages:s,slots:d,booking:f,isLoading:u,error:j,sendMessage:N,pickSlot:S,start:k}}function C(g){return g.split(`
|
|
2
|
+
`).flatMap((o,r,t)=>{const s=[],b=o.split(/(\*\*[^*]+\*\*|\*[^*]+\*)/g);for(let d=0;d<b.length;d++){const n=b[d];n.startsWith("**")&&n.endsWith("**")?s.push(e.jsx("strong",{children:n.slice(2,-2)},`${r}-${d}`)):n.startsWith("*")&&n.endsWith("*")?s.push(e.jsx("em",{children:n.slice(1,-1)},`${r}-${d}`)):s.push(n)}return r<t.length-1&&s.push(e.jsx("br",{},`br-${r}`)),s})}function L({message:g}){const o=g.role==="user";return e.jsx("div",{className:`gbw-flex ${o?"gbw-justify-end":"gbw-justify-start"} gbw-mb-2`,children:e.jsx("div",{className:o?"gbw-max-w-[80%] gbw-rounded-2xl gbw-rounded-br-sm gbw-bg-gropulse-navy gbw-px-3.5 gbw-py-2 gbw-text-sm gbw-text-white":"gbw-max-w-[80%] gbw-rounded-2xl gbw-rounded-bl-sm gbw-bg-gropulse-bg gbw-px-3.5 gbw-py-2 gbw-text-sm gbw-text-gropulse-text gbw-border gbw-border-gropulse-border",children:o?g.content:C(g.content)})})}function $({messages:g,isLoading:o}){const r=w.useRef(null);return w.useEffect(()=>{var t;(t=r.current)==null||t.scrollIntoView({behavior:"smooth",block:"end"})},[g,o]),e.jsxs("div",{className:"gbw-flex-1 gbw-overflow-y-auto gbw-px-4 gbw-py-3",children:[g.map((t,s)=>e.jsx(L,{message:t},s)),o?e.jsx(B,{}):null,e.jsx("div",{ref:r})]})}function B(){return e.jsx("div",{className:"gbw-flex gbw-justify-start gbw-mb-2",children:e.jsx("div",{className:"gbw-rounded-2xl gbw-rounded-bl-sm gbw-bg-gropulse-bg gbw-border gbw-border-gropulse-border gbw-px-3.5 gbw-py-2.5",children:e.jsxs("div",{className:"gbw-flex gbw-gap-1",children:[e.jsx("span",{className:"gbw-typing-dot gbw-h-1.5 gbw-w-1.5 gbw-rounded-full gbw-bg-gropulse-muted gbw-inline-block"}),e.jsx("span",{className:"gbw-typing-dot gbw-h-1.5 gbw-w-1.5 gbw-rounded-full gbw-bg-gropulse-muted gbw-inline-block"}),e.jsx("span",{className:"gbw-typing-dot gbw-h-1.5 gbw-w-1.5 gbw-rounded-full gbw-bg-gropulse-muted gbw-inline-block"})]})})})}function T({onSend:g,disabled:o,placeholder:r}){const[t,s]=w.useState(""),b=()=>{const n=t.trim();!n||o||(g(n),s(""))},d=n=>{n.key==="Enter"&&!n.shiftKey&&(n.preventDefault(),b())};return e.jsx("div",{className:"gbw-border-t gbw-border-gropulse-border gbw-bg-white gbw-p-3",children:e.jsxs("div",{className:"gbw-flex gbw-items-end gbw-gap-2",children:[e.jsx("textarea",{value:t,onChange:n=>s(n.target.value),onKeyDown:d,disabled:o,rows:1,placeholder:r??"Type a message…",className:"gbw-flex-1 gbw-resize-none gbw-rounded-xl gbw-border gbw-border-gropulse-border gbw-bg-white gbw-px-3 gbw-py-2 gbw-text-sm gbw-outline-none focus:gbw-border-gropulse-navy focus:gbw-ring-2 focus:gbw-ring-gropulse-navy/10 disabled:gbw-bg-gropulse-bg disabled:gbw-text-gropulse-muted",style:{maxHeight:120}}),e.jsx("button",{type:"button",onClick:b,disabled:o||!t.trim(),className:"gbw-shrink-0 gbw-rounded-xl gbw-bg-gropulse-navy gbw-px-4 gbw-py-2 gbw-text-sm gbw-font-medium gbw-text-white gbw-transition hover:gbw-bg-gropulse-navyHover disabled:gbw-opacity-40",children:"Send"})]})})}function M({slots:g,onPick:o,disabled:r}){const t=w.useMemo(()=>D(g),[g]);return g.length===0?e.jsx("div",{className:"gbw-mx-4 gbw-mb-3 gbw-rounded-xl gbw-border gbw-border-gropulse-border gbw-bg-gropulse-bg gbw-px-3 gbw-py-2 gbw-text-sm gbw-text-gropulse-muted",children:"No slots available right now — try again in a moment."}):e.jsxs("div",{className:"gbw-mx-4 gbw-mb-3 gbw-rounded-xl gbw-border gbw-border-gropulse-border gbw-bg-white gbw-p-3",children:[e.jsx("div",{className:"gbw-mb-2 gbw-text-xs gbw-font-medium gbw-uppercase gbw-tracking-wide gbw-text-gropulse-muted",children:"Pick a time that works"}),e.jsx("div",{className:"gbw-flex gbw-flex-col gbw-gap-3 gbw-max-h-60 gbw-overflow-y-auto",children:t.map(s=>e.jsxs("div",{children:[e.jsx("div",{className:"gbw-mb-1.5 gbw-text-xs gbw-font-semibold gbw-text-gropulse-text",children:s.dayLabel}),e.jsx("div",{className:"gbw-grid gbw-grid-cols-3 gbw-gap-1.5",children:s.slots.map(b=>e.jsx("button",{type:"button",disabled:r,onClick:()=>o(b),className:"gbw-rounded-lg gbw-border gbw-border-gropulse-border gbw-bg-white gbw-px-2 gbw-py-1.5 gbw-text-xs gbw-font-medium gbw-text-gropulse-text gbw-transition hover:gbw-border-gropulse-navy hover:gbw-bg-gropulse-navy hover:gbw-text-white disabled:gbw-opacity-40",children:W(b.time)},b.time))})]},s.dayLabel))})]})}function D(g){const o=new Map;for(const r of g){const s=new Date(r.time).toLocaleDateString(void 0,{weekday:"short",month:"short",day:"numeric"}),b=o.get(s);b?b.push(r):o.set(s,[r])}return Array.from(o.entries()).map(([r,t])=>({dayLabel:r,slots:t}))}function W(g){return new Date(g).toLocaleTimeString(void 0,{hour:"numeric",minute:"2-digit",timeZoneName:"short"})}function _(g){const{apiBaseUrl:o,context:r,trigger:t="button",buttonLabel:s="Book Free Strategy Call",onBookingConfirmed:b,className:d}=g,[n,f]=w.useState(t==="auto"),i=v({apiBaseUrl:o,context:r,onBookingConfirmed:b});return w.useEffect(()=>{n&&i.messages.length===0&&!i.isLoading&&i.start()},[n,i]),e.jsxs("div",{className:`gbw-root ${d??""}`,children:[t==="button"?e.jsxs("button",{type:"button",onClick:()=>f(u=>!u),className:"gbw-inline-flex gbw-items-center gbw-gap-2 gbw-rounded-xl gbw-bg-gropulse-navy gbw-px-4 gbw-py-2.5 gbw-text-sm gbw-font-medium gbw-text-white gbw-shadow-sm gbw-transition hover:gbw-bg-gropulse-navyHover",children:[e.jsx("span",{className:"gbw-h-2 gbw-w-2 gbw-rounded-full gbw-bg-gropulse-accent"}),s]}):null,n?e.jsxs("div",{className:"gbw-fixed gbw-inset-0 gbw-z-[9999] gbw-flex gbw-items-end gbw-justify-end gbw-p-0 sm:gbw-p-4",children:[e.jsx("div",{className:"gbw-absolute gbw-inset-0 gbw-bg-black/20",onClick:()=>f(!1)}),e.jsxs("div",{className:"gbw-relative gbw-flex gbw-h-full gbw-w-full gbw-flex-col gbw-overflow-hidden gbw-bg-white gbw-shadow-panel sm:gbw-h-[620px] sm:gbw-w-[400px] sm:gbw-rounded-2xl",children:[e.jsx(P,{ownerName:r.ownerName,onClose:()=>f(!1)}),e.jsx($,{messages:i.messages,isLoading:i.isLoading}),i.slots&&!i.booking?e.jsx(M,{slots:i.slots,onPick:i.pickSlot,disabled:i.isLoading}):null,i.error?e.jsx("div",{className:"gbw-mx-4 gbw-mb-2 gbw-rounded-lg gbw-border gbw-border-red-200 gbw-bg-red-50 gbw-px-3 gbw-py-2 gbw-text-xs gbw-text-red-700",children:i.error}):null,i.booking?e.jsx(R,{}):e.jsx(T,{onSend:i.sendMessage,disabled:i.isLoading,placeholder:"Reply…"})]})]}):null]})}function P({ownerName:g,onClose:o}){return e.jsxs("div",{className:"gbw-flex gbw-items-center gbw-justify-between gbw-border-b gbw-border-gropulse-border gbw-bg-gropulse-navy gbw-px-4 gbw-py-3 gbw-text-white",children:[e.jsxs("div",{children:[e.jsx("div",{className:"gbw-text-sm gbw-font-semibold",children:"Gropulse Growth Strategy"}),e.jsxs("div",{className:"gbw-text-xs gbw-text-white/70",children:["Hey ",g.split(" ")[0]," — let’s find a time."]})]}),e.jsx("button",{type:"button",onClick:o,"aria-label":"Close",className:"gbw-rounded-md gbw-p-1 gbw-text-white/80 gbw-transition hover:gbw-bg-white/10 hover:gbw-text-white",children:e.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[e.jsx("path",{d:"M18 6 6 18"}),e.jsx("path",{d:"m6 6 12 12"})]})})]})}function R(){return e.jsx("div",{className:"gbw-border-t gbw-border-gropulse-border gbw-bg-gropulse-bg gbw-px-4 gbw-py-3 gbw-text-center gbw-text-xs gbw-text-gropulse-muted",children:"Calendar invite on its way. You can close this window."})}exports.BookingWidget=_;exports.useBookingChat=v;
|
package/dist/index.js
CHANGED
|
@@ -1,131 +1,142 @@
|
|
|
1
1
|
import { jsx as e, jsxs as a } from "react/jsx-runtime";
|
|
2
|
-
import { useState as
|
|
3
|
-
function
|
|
4
|
-
const { apiBaseUrl:
|
|
5
|
-
async (
|
|
6
|
-
const
|
|
7
|
-
...
|
|
8
|
-
timezone:
|
|
9
|
-
},
|
|
2
|
+
import { useState as p, useCallback as v, useRef as j, useEffect as N, useMemo as T } from "react";
|
|
3
|
+
function B(g) {
|
|
4
|
+
const { apiBaseUrl: s, context: r, onBookingConfirmed: t } = g, [o, b] = p([]), [d, n] = p(null), [y, i] = p(null), [u, h] = p(!1), [C, f] = p(null), x = v(
|
|
5
|
+
async (l) => {
|
|
6
|
+
const w = {
|
|
7
|
+
...r,
|
|
8
|
+
timezone: r.timezone ?? Intl.DateTimeFormat().resolvedOptions().timeZone
|
|
9
|
+
}, c = await fetch(`${s}/api/chat`, {
|
|
10
10
|
method: "POST",
|
|
11
11
|
headers: { "Content-Type": "application/json" },
|
|
12
|
-
body: JSON.stringify({ messages:
|
|
12
|
+
body: JSON.stringify({ messages: l, context: w })
|
|
13
13
|
});
|
|
14
|
-
if (!
|
|
15
|
-
const
|
|
16
|
-
throw new Error(`Chat API error ${
|
|
14
|
+
if (!c.ok) {
|
|
15
|
+
const m = await c.text();
|
|
16
|
+
throw new Error(`Chat API error ${c.status}: ${m}`);
|
|
17
17
|
}
|
|
18
|
-
return await
|
|
18
|
+
return await c.json();
|
|
19
19
|
},
|
|
20
|
-
[
|
|
21
|
-
), k =
|
|
22
|
-
(
|
|
23
|
-
|
|
20
|
+
[s, r]
|
|
21
|
+
), k = v(
|
|
22
|
+
(l) => {
|
|
23
|
+
b((w) => [...w, { role: "assistant", content: l.message }]), l.action === "show_slots" && l.slots && n(l.slots), l.action === "booking_confirmed" && l.booking && (i(l.booking), n(null), t == null || t(l.booking));
|
|
24
24
|
},
|
|
25
25
|
[t]
|
|
26
|
-
), L =
|
|
27
|
-
if (!(
|
|
28
|
-
|
|
26
|
+
), L = v(async () => {
|
|
27
|
+
if (!(o.length > 0 || u)) {
|
|
28
|
+
h(!0), f(null);
|
|
29
29
|
try {
|
|
30
|
-
const
|
|
30
|
+
const w = await x([{
|
|
31
31
|
role: "user",
|
|
32
32
|
content: "__START__"
|
|
33
33
|
}]);
|
|
34
|
-
|
|
35
|
-
} catch (
|
|
36
|
-
|
|
34
|
+
b([{ role: "assistant", content: w.message }]), w.action === "show_slots" && w.slots && n(w.slots), w.action === "booking_confirmed" && w.booking && (i(w.booking), t == null || t(w.booking));
|
|
35
|
+
} catch (l) {
|
|
36
|
+
f(l.message);
|
|
37
37
|
} finally {
|
|
38
|
-
|
|
38
|
+
h(!1);
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
|
-
}, [
|
|
42
|
-
async (
|
|
43
|
-
const
|
|
44
|
-
if (!
|
|
45
|
-
const
|
|
46
|
-
|
|
41
|
+
}, [o.length, u, x, t]), S = v(
|
|
42
|
+
async (l) => {
|
|
43
|
+
const w = l.trim();
|
|
44
|
+
if (!w || u) return;
|
|
45
|
+
const c = [...o, { role: "user", content: w }];
|
|
46
|
+
b(c), h(!0), f(null);
|
|
47
47
|
try {
|
|
48
|
-
const
|
|
49
|
-
k(
|
|
50
|
-
} catch (
|
|
51
|
-
|
|
48
|
+
const m = await x(c);
|
|
49
|
+
k(m);
|
|
50
|
+
} catch (m) {
|
|
51
|
+
f(m.message);
|
|
52
52
|
} finally {
|
|
53
|
-
|
|
53
|
+
h(!1);
|
|
54
54
|
}
|
|
55
55
|
},
|
|
56
|
-
[
|
|
57
|
-
),
|
|
58
|
-
async (
|
|
59
|
-
if (
|
|
60
|
-
const
|
|
56
|
+
[o, u, x, k]
|
|
57
|
+
), $ = v(
|
|
58
|
+
async (l) => {
|
|
59
|
+
if (u) return;
|
|
60
|
+
const w = new Date(l.time).toLocaleString(void 0, {
|
|
61
61
|
weekday: "short",
|
|
62
62
|
month: "short",
|
|
63
63
|
day: "numeric",
|
|
64
64
|
hour: "numeric",
|
|
65
65
|
minute: "2-digit"
|
|
66
|
-
}),
|
|
67
|
-
...
|
|
68
|
-
{ role: "user", content: `I'll take ${
|
|
66
|
+
}), c = [
|
|
67
|
+
...o,
|
|
68
|
+
{ role: "user", content: `I'll take ${w} (${l.time})` }
|
|
69
69
|
];
|
|
70
|
-
|
|
70
|
+
b(c), n(null), h(!0), f(null);
|
|
71
71
|
try {
|
|
72
|
-
const
|
|
73
|
-
k(
|
|
74
|
-
} catch (
|
|
75
|
-
|
|
72
|
+
const m = await x(c);
|
|
73
|
+
k(m);
|
|
74
|
+
} catch (m) {
|
|
75
|
+
f(m.message);
|
|
76
76
|
} finally {
|
|
77
|
-
|
|
77
|
+
h(!1);
|
|
78
78
|
}
|
|
79
79
|
},
|
|
80
|
-
[
|
|
80
|
+
[o, u, x, k]
|
|
81
81
|
);
|
|
82
|
-
return { messages:
|
|
82
|
+
return { messages: o, slots: d, booking: y, isLoading: u, error: C, sendMessage: S, pickSlot: $, start: L };
|
|
83
|
+
}
|
|
84
|
+
function D(g) {
|
|
85
|
+
return g.split(`
|
|
86
|
+
`).flatMap((s, r, t) => {
|
|
87
|
+
const o = [], b = s.split(/(\*\*[^*]+\*\*|\*[^*]+\*)/g);
|
|
88
|
+
for (let d = 0; d < b.length; d++) {
|
|
89
|
+
const n = b[d];
|
|
90
|
+
n.startsWith("**") && n.endsWith("**") ? o.push(/* @__PURE__ */ e("strong", { children: n.slice(2, -2) }, `${r}-${d}`)) : n.startsWith("*") && n.endsWith("*") ? o.push(/* @__PURE__ */ e("em", { children: n.slice(1, -1) }, `${r}-${d}`)) : o.push(n);
|
|
91
|
+
}
|
|
92
|
+
return r < t.length - 1 && o.push(/* @__PURE__ */ e("br", {}, `br-${r}`)), o;
|
|
93
|
+
});
|
|
83
94
|
}
|
|
84
|
-
function
|
|
85
|
-
const
|
|
86
|
-
return /* @__PURE__ */ e("div", { className: `gbw-flex ${
|
|
95
|
+
function M({ message: g }) {
|
|
96
|
+
const s = g.role === "user";
|
|
97
|
+
return /* @__PURE__ */ e("div", { className: `gbw-flex ${s ? "gbw-justify-end" : "gbw-justify-start"} gbw-mb-2`, children: /* @__PURE__ */ e(
|
|
87
98
|
"div",
|
|
88
99
|
{
|
|
89
|
-
className:
|
|
90
|
-
children: g.content
|
|
100
|
+
className: s ? "gbw-max-w-[80%] gbw-rounded-2xl gbw-rounded-br-sm gbw-bg-gropulse-navy gbw-px-3.5 gbw-py-2 gbw-text-sm gbw-text-white" : "gbw-max-w-[80%] gbw-rounded-2xl gbw-rounded-bl-sm gbw-bg-gropulse-bg gbw-px-3.5 gbw-py-2 gbw-text-sm gbw-text-gropulse-text gbw-border gbw-border-gropulse-border",
|
|
101
|
+
children: s ? g.content : D(g.content)
|
|
91
102
|
}
|
|
92
103
|
) });
|
|
93
104
|
}
|
|
94
|
-
function
|
|
95
|
-
const
|
|
105
|
+
function _({ messages: g, isLoading: s }) {
|
|
106
|
+
const r = j(null);
|
|
96
107
|
return N(() => {
|
|
97
108
|
var t;
|
|
98
|
-
(t =
|
|
99
|
-
}, [g,
|
|
100
|
-
g.map((t,
|
|
101
|
-
|
|
102
|
-
/* @__PURE__ */ e("div", { ref:
|
|
109
|
+
(t = r.current) == null || t.scrollIntoView({ behavior: "smooth", block: "end" });
|
|
110
|
+
}, [g, s]), /* @__PURE__ */ a("div", { className: "gbw-flex-1 gbw-overflow-y-auto gbw-px-4 gbw-py-3", children: [
|
|
111
|
+
g.map((t, o) => /* @__PURE__ */ e(M, { message: t }, o)),
|
|
112
|
+
s ? /* @__PURE__ */ e(W, {}) : null,
|
|
113
|
+
/* @__PURE__ */ e("div", { ref: r })
|
|
103
114
|
] });
|
|
104
115
|
}
|
|
105
|
-
function
|
|
116
|
+
function W() {
|
|
106
117
|
return /* @__PURE__ */ e("div", { className: "gbw-flex gbw-justify-start gbw-mb-2", children: /* @__PURE__ */ e("div", { className: "gbw-rounded-2xl gbw-rounded-bl-sm gbw-bg-gropulse-bg gbw-border gbw-border-gropulse-border gbw-px-3.5 gbw-py-2.5", children: /* @__PURE__ */ a("div", { className: "gbw-flex gbw-gap-1", children: [
|
|
107
118
|
/* @__PURE__ */ e("span", { className: "gbw-typing-dot gbw-h-1.5 gbw-w-1.5 gbw-rounded-full gbw-bg-gropulse-muted gbw-inline-block" }),
|
|
108
119
|
/* @__PURE__ */ e("span", { className: "gbw-typing-dot gbw-h-1.5 gbw-w-1.5 gbw-rounded-full gbw-bg-gropulse-muted gbw-inline-block" }),
|
|
109
120
|
/* @__PURE__ */ e("span", { className: "gbw-typing-dot gbw-h-1.5 gbw-w-1.5 gbw-rounded-full gbw-bg-gropulse-muted gbw-inline-block" })
|
|
110
121
|
] }) }) });
|
|
111
122
|
}
|
|
112
|
-
function
|
|
113
|
-
const [t,
|
|
114
|
-
const
|
|
115
|
-
!
|
|
123
|
+
function z({ onSend: g, disabled: s, placeholder: r }) {
|
|
124
|
+
const [t, o] = p(""), b = () => {
|
|
125
|
+
const n = t.trim();
|
|
126
|
+
!n || s || (g(n), o(""));
|
|
116
127
|
};
|
|
117
128
|
return /* @__PURE__ */ e("div", { className: "gbw-border-t gbw-border-gropulse-border gbw-bg-white gbw-p-3", children: /* @__PURE__ */ a("div", { className: "gbw-flex gbw-items-end gbw-gap-2", children: [
|
|
118
129
|
/* @__PURE__ */ e(
|
|
119
130
|
"textarea",
|
|
120
131
|
{
|
|
121
132
|
value: t,
|
|
122
|
-
onChange: (
|
|
123
|
-
onKeyDown: (
|
|
124
|
-
|
|
133
|
+
onChange: (n) => o(n.target.value),
|
|
134
|
+
onKeyDown: (n) => {
|
|
135
|
+
n.key === "Enter" && !n.shiftKey && (n.preventDefault(), b());
|
|
125
136
|
},
|
|
126
|
-
disabled:
|
|
137
|
+
disabled: s,
|
|
127
138
|
rows: 1,
|
|
128
|
-
placeholder:
|
|
139
|
+
placeholder: r ?? "Type a message…",
|
|
129
140
|
className: "gbw-flex-1 gbw-resize-none gbw-rounded-xl gbw-border gbw-border-gropulse-border gbw-bg-white gbw-px-3 gbw-py-2 gbw-text-sm gbw-outline-none focus:gbw-border-gropulse-navy focus:gbw-ring-2 focus:gbw-ring-gropulse-navy/10 disabled:gbw-bg-gropulse-bg disabled:gbw-text-gropulse-muted",
|
|
130
141
|
style: { maxHeight: 120 }
|
|
131
142
|
}
|
|
@@ -134,107 +145,108 @@ function $({ onSend: g, disabled: o, placeholder: n }) {
|
|
|
134
145
|
"button",
|
|
135
146
|
{
|
|
136
147
|
type: "button",
|
|
137
|
-
onClick:
|
|
138
|
-
disabled:
|
|
148
|
+
onClick: b,
|
|
149
|
+
disabled: s || !t.trim(),
|
|
139
150
|
className: "gbw-shrink-0 gbw-rounded-xl gbw-bg-gropulse-navy gbw-px-4 gbw-py-2 gbw-text-sm gbw-font-medium gbw-text-white gbw-transition hover:gbw-bg-gropulse-navyHover disabled:gbw-opacity-40",
|
|
140
151
|
children: "Send"
|
|
141
152
|
}
|
|
142
153
|
)
|
|
143
154
|
] }) });
|
|
144
155
|
}
|
|
145
|
-
function
|
|
146
|
-
const t =
|
|
156
|
+
function H({ slots: g, onPick: s, disabled: r }) {
|
|
157
|
+
const t = T(() => P(g), [g]);
|
|
147
158
|
return g.length === 0 ? /* @__PURE__ */ e("div", { className: "gbw-mx-4 gbw-mb-3 gbw-rounded-xl gbw-border gbw-border-gropulse-border gbw-bg-gropulse-bg gbw-px-3 gbw-py-2 gbw-text-sm gbw-text-gropulse-muted", children: "No slots available right now — try again in a moment." }) : /* @__PURE__ */ a("div", { className: "gbw-mx-4 gbw-mb-3 gbw-rounded-xl gbw-border gbw-border-gropulse-border gbw-bg-white gbw-p-3", children: [
|
|
148
159
|
/* @__PURE__ */ e("div", { className: "gbw-mb-2 gbw-text-xs gbw-font-medium gbw-uppercase gbw-tracking-wide gbw-text-gropulse-muted", children: "Pick a time that works" }),
|
|
149
|
-
/* @__PURE__ */ e("div", { className: "gbw-flex gbw-flex-col gbw-gap-3 gbw-max-h-60 gbw-overflow-y-auto", children: t.map((
|
|
150
|
-
/* @__PURE__ */ e("div", { className: "gbw-mb-1.5 gbw-text-xs gbw-font-semibold gbw-text-gropulse-text", children:
|
|
151
|
-
/* @__PURE__ */ e("div", { className: "gbw-grid gbw-grid-cols-3 gbw-gap-1.5", children:
|
|
160
|
+
/* @__PURE__ */ e("div", { className: "gbw-flex gbw-flex-col gbw-gap-3 gbw-max-h-60 gbw-overflow-y-auto", children: t.map((o) => /* @__PURE__ */ a("div", { children: [
|
|
161
|
+
/* @__PURE__ */ e("div", { className: "gbw-mb-1.5 gbw-text-xs gbw-font-semibold gbw-text-gropulse-text", children: o.dayLabel }),
|
|
162
|
+
/* @__PURE__ */ e("div", { className: "gbw-grid gbw-grid-cols-3 gbw-gap-1.5", children: o.slots.map((b) => /* @__PURE__ */ e(
|
|
152
163
|
"button",
|
|
153
164
|
{
|
|
154
165
|
type: "button",
|
|
155
|
-
disabled:
|
|
156
|
-
onClick: () =>
|
|
166
|
+
disabled: r,
|
|
167
|
+
onClick: () => s(b),
|
|
157
168
|
className: "gbw-rounded-lg gbw-border gbw-border-gropulse-border gbw-bg-white gbw-px-2 gbw-py-1.5 gbw-text-xs gbw-font-medium gbw-text-gropulse-text gbw-transition hover:gbw-border-gropulse-navy hover:gbw-bg-gropulse-navy hover:gbw-text-white disabled:gbw-opacity-40",
|
|
158
|
-
children:
|
|
169
|
+
children: R(b.time)
|
|
159
170
|
},
|
|
160
|
-
|
|
171
|
+
b.time
|
|
161
172
|
)) })
|
|
162
|
-
] },
|
|
173
|
+
] }, o.dayLabel)) })
|
|
163
174
|
] });
|
|
164
175
|
}
|
|
165
|
-
function
|
|
166
|
-
const
|
|
167
|
-
for (const
|
|
168
|
-
const
|
|
176
|
+
function P(g) {
|
|
177
|
+
const s = /* @__PURE__ */ new Map();
|
|
178
|
+
for (const r of g) {
|
|
179
|
+
const o = new Date(r.time).toLocaleDateString(void 0, {
|
|
169
180
|
weekday: "short",
|
|
170
181
|
month: "short",
|
|
171
182
|
day: "numeric"
|
|
172
|
-
}),
|
|
173
|
-
|
|
183
|
+
}), b = s.get(o);
|
|
184
|
+
b ? b.push(r) : s.set(o, [r]);
|
|
174
185
|
}
|
|
175
|
-
return Array.from(
|
|
186
|
+
return Array.from(s.entries()).map(([r, t]) => ({ dayLabel: r, slots: t }));
|
|
176
187
|
}
|
|
177
|
-
function
|
|
188
|
+
function R(g) {
|
|
178
189
|
return new Date(g).toLocaleTimeString(void 0, {
|
|
179
190
|
hour: "numeric",
|
|
180
|
-
minute: "2-digit"
|
|
191
|
+
minute: "2-digit",
|
|
192
|
+
timeZoneName: "short"
|
|
181
193
|
});
|
|
182
194
|
}
|
|
183
195
|
function A(g) {
|
|
184
196
|
const {
|
|
185
|
-
apiBaseUrl:
|
|
186
|
-
context:
|
|
197
|
+
apiBaseUrl: s,
|
|
198
|
+
context: r,
|
|
187
199
|
trigger: t = "button",
|
|
188
|
-
buttonLabel:
|
|
189
|
-
onBookingConfirmed:
|
|
190
|
-
className:
|
|
191
|
-
} = g, [
|
|
200
|
+
buttonLabel: o = "Book Free Strategy Call",
|
|
201
|
+
onBookingConfirmed: b,
|
|
202
|
+
className: d
|
|
203
|
+
} = g, [n, y] = p(t === "auto"), i = B({ apiBaseUrl: s, context: r, onBookingConfirmed: b });
|
|
192
204
|
return N(() => {
|
|
193
|
-
|
|
194
|
-
}, [
|
|
205
|
+
n && i.messages.length === 0 && !i.isLoading && i.start();
|
|
206
|
+
}, [n, i]), /* @__PURE__ */ a("div", { className: `gbw-root ${d ?? ""}`, children: [
|
|
195
207
|
t === "button" ? /* @__PURE__ */ a(
|
|
196
208
|
"button",
|
|
197
209
|
{
|
|
198
210
|
type: "button",
|
|
199
|
-
onClick: () =>
|
|
211
|
+
onClick: () => y((u) => !u),
|
|
200
212
|
className: "gbw-inline-flex gbw-items-center gbw-gap-2 gbw-rounded-xl gbw-bg-gropulse-navy gbw-px-4 gbw-py-2.5 gbw-text-sm gbw-font-medium gbw-text-white gbw-shadow-sm gbw-transition hover:gbw-bg-gropulse-navyHover",
|
|
201
213
|
children: [
|
|
202
214
|
/* @__PURE__ */ e("span", { className: "gbw-h-2 gbw-w-2 gbw-rounded-full gbw-bg-gropulse-accent" }),
|
|
203
|
-
|
|
215
|
+
o
|
|
204
216
|
]
|
|
205
217
|
}
|
|
206
218
|
) : null,
|
|
207
|
-
|
|
219
|
+
n ? /* @__PURE__ */ a("div", { className: "gbw-fixed gbw-inset-0 gbw-z-[9999] gbw-flex gbw-items-end gbw-justify-end gbw-p-0 sm:gbw-p-4", children: [
|
|
208
220
|
/* @__PURE__ */ e(
|
|
209
221
|
"div",
|
|
210
222
|
{
|
|
211
223
|
className: "gbw-absolute gbw-inset-0 gbw-bg-black/20",
|
|
212
|
-
onClick: () =>
|
|
224
|
+
onClick: () => y(!1)
|
|
213
225
|
}
|
|
214
226
|
),
|
|
215
227
|
/* @__PURE__ */ a("div", { className: "gbw-relative gbw-flex gbw-h-full gbw-w-full gbw-flex-col gbw-overflow-hidden gbw-bg-white gbw-shadow-panel sm:gbw-h-[620px] sm:gbw-w-[400px] sm:gbw-rounded-2xl", children: [
|
|
216
228
|
/* @__PURE__ */ e(
|
|
217
|
-
|
|
229
|
+
E,
|
|
218
230
|
{
|
|
219
|
-
ownerName:
|
|
220
|
-
onClose: () =>
|
|
231
|
+
ownerName: r.ownerName,
|
|
232
|
+
onClose: () => y(!1)
|
|
221
233
|
}
|
|
222
234
|
),
|
|
223
|
-
/* @__PURE__ */ e(
|
|
224
|
-
|
|
225
|
-
|
|
235
|
+
/* @__PURE__ */ e(_, { messages: i.messages, isLoading: i.isLoading }),
|
|
236
|
+
i.slots && !i.booking ? /* @__PURE__ */ e(
|
|
237
|
+
H,
|
|
226
238
|
{
|
|
227
|
-
slots:
|
|
228
|
-
onPick:
|
|
229
|
-
disabled:
|
|
239
|
+
slots: i.slots,
|
|
240
|
+
onPick: i.pickSlot,
|
|
241
|
+
disabled: i.isLoading
|
|
230
242
|
}
|
|
231
243
|
) : null,
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
244
|
+
i.error ? /* @__PURE__ */ e("div", { className: "gbw-mx-4 gbw-mb-2 gbw-rounded-lg gbw-border gbw-border-red-200 gbw-bg-red-50 gbw-px-3 gbw-py-2 gbw-text-xs gbw-text-red-700", children: i.error }) : null,
|
|
245
|
+
i.booking ? /* @__PURE__ */ e(I, {}) : /* @__PURE__ */ e(
|
|
246
|
+
z,
|
|
235
247
|
{
|
|
236
|
-
onSend:
|
|
237
|
-
disabled:
|
|
248
|
+
onSend: i.sendMessage,
|
|
249
|
+
disabled: i.isLoading,
|
|
238
250
|
placeholder: "Reply…"
|
|
239
251
|
}
|
|
240
252
|
)
|
|
@@ -242,7 +254,7 @@ function A(g) {
|
|
|
242
254
|
] }) : null
|
|
243
255
|
] });
|
|
244
256
|
}
|
|
245
|
-
function
|
|
257
|
+
function E({ ownerName: g, onClose: s }) {
|
|
246
258
|
return /* @__PURE__ */ a("div", { className: "gbw-flex gbw-items-center gbw-justify-between gbw-border-b gbw-border-gropulse-border gbw-bg-gropulse-navy gbw-px-4 gbw-py-3 gbw-text-white", children: [
|
|
247
259
|
/* @__PURE__ */ a("div", { children: [
|
|
248
260
|
/* @__PURE__ */ e("div", { className: "gbw-text-sm gbw-font-semibold", children: "Gropulse Growth Strategy" }),
|
|
@@ -256,7 +268,7 @@ function R({ ownerName: g, onClose: o }) {
|
|
|
256
268
|
"button",
|
|
257
269
|
{
|
|
258
270
|
type: "button",
|
|
259
|
-
onClick:
|
|
271
|
+
onClick: s,
|
|
260
272
|
"aria-label": "Close",
|
|
261
273
|
className: "gbw-rounded-md gbw-p-1 gbw-text-white/80 gbw-transition hover:gbw-bg-white/10 hover:gbw-text-white",
|
|
262
274
|
children: /* @__PURE__ */ a(
|
|
@@ -280,10 +292,10 @@ function R({ ownerName: g, onClose: o }) {
|
|
|
280
292
|
)
|
|
281
293
|
] });
|
|
282
294
|
}
|
|
283
|
-
function
|
|
295
|
+
function I() {
|
|
284
296
|
return /* @__PURE__ */ e("div", { className: "gbw-border-t gbw-border-gropulse-border gbw-bg-gropulse-bg gbw-px-4 gbw-py-3 gbw-text-center gbw-text-xs gbw-text-gropulse-muted", children: "Calendar invite on its way. You can close this window." });
|
|
285
297
|
}
|
|
286
298
|
export {
|
|
287
299
|
A as BookingWidget,
|
|
288
|
-
|
|
300
|
+
B as useBookingChat
|
|
289
301
|
};
|
package/package.json
CHANGED