@jutech-devs/agent-sdk
Version:
Modern embeddable AI agent chat widget with voice support and payment integration
1,249 lines (1,235 loc) • 192 kB
JavaScript
"use strict";
var AgentSDK = (() => {
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// node_modules/react/cjs/react.production.min.js
var require_react_production_min = __commonJS({
"node_modules/react/cjs/react.production.min.js"(exports) {
"use strict";
var l = Symbol.for("react.element");
var n = Symbol.for("react.portal");
var p = Symbol.for("react.fragment");
var q = Symbol.for("react.strict_mode");
var r = Symbol.for("react.profiler");
var t = Symbol.for("react.provider");
var u = Symbol.for("react.context");
var v = Symbol.for("react.forward_ref");
var w = Symbol.for("react.suspense");
var x = Symbol.for("react.memo");
var y = Symbol.for("react.lazy");
var z = Symbol.iterator;
function A(a) {
if (null === a || "object" !== typeof a) return null;
a = z && a[z] || a["@@iterator"];
return "function" === typeof a ? a : null;
}
var B = { isMounted: function() {
return false;
}, enqueueForceUpdate: function() {
}, enqueueReplaceState: function() {
}, enqueueSetState: function() {
} };
var C = Object.assign;
var D = {};
function E(a, b, e) {
this.props = a;
this.context = b;
this.refs = D;
this.updater = e || B;
}
E.prototype.isReactComponent = {};
E.prototype.setState = function(a, b) {
if ("object" !== typeof a && "function" !== typeof a && null != a) throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");
this.updater.enqueueSetState(this, a, b, "setState");
};
E.prototype.forceUpdate = function(a) {
this.updater.enqueueForceUpdate(this, a, "forceUpdate");
};
function F() {
}
F.prototype = E.prototype;
function G(a, b, e) {
this.props = a;
this.context = b;
this.refs = D;
this.updater = e || B;
}
var H = G.prototype = new F();
H.constructor = G;
C(H, E.prototype);
H.isPureReactComponent = true;
var I = Array.isArray;
var J = Object.prototype.hasOwnProperty;
var K = { current: null };
var L = { key: true, ref: true, __self: true, __source: true };
function M(a, b, e) {
var d, c = {}, k = null, h = null;
if (null != b) for (d in void 0 !== b.ref && (h = b.ref), void 0 !== b.key && (k = "" + b.key), b) J.call(b, d) && !L.hasOwnProperty(d) && (c[d] = b[d]);
var g = arguments.length - 2;
if (1 === g) c.children = e;
else if (1 < g) {
for (var f = Array(g), m = 0; m < g; m++) f[m] = arguments[m + 2];
c.children = f;
}
if (a && a.defaultProps) for (d in g = a.defaultProps, g) void 0 === c[d] && (c[d] = g[d]);
return { $$typeof: l, type: a, key: k, ref: h, props: c, _owner: K.current };
}
function N(a, b) {
return { $$typeof: l, type: a.type, key: b, ref: a.ref, props: a.props, _owner: a._owner };
}
function O(a) {
return "object" === typeof a && null !== a && a.$$typeof === l;
}
function escape(a) {
var b = { "=": "=0", ":": "=2" };
return "$" + a.replace(/[=:]/g, function(a2) {
return b[a2];
});
}
var P = /\/+/g;
function Q(a, b) {
return "object" === typeof a && null !== a && null != a.key ? escape("" + a.key) : b.toString(36);
}
function R(a, b, e, d, c) {
var k = typeof a;
if ("undefined" === k || "boolean" === k) a = null;
var h = false;
if (null === a) h = true;
else switch (k) {
case "string":
case "number":
h = true;
break;
case "object":
switch (a.$$typeof) {
case l:
case n:
h = true;
}
}
if (h) return h = a, c = c(h), a = "" === d ? "." + Q(h, 0) : d, I(c) ? (e = "", null != a && (e = a.replace(P, "$&/") + "/"), R(c, b, e, "", function(a2) {
return a2;
})) : null != c && (O(c) && (c = N(c, e + (!c.key || h && h.key === c.key ? "" : ("" + c.key).replace(P, "$&/") + "/") + a)), b.push(c)), 1;
h = 0;
d = "" === d ? "." : d + ":";
if (I(a)) for (var g = 0; g < a.length; g++) {
k = a[g];
var f = d + Q(k, g);
h += R(k, b, e, f, c);
}
else if (f = A(a), "function" === typeof f) for (a = f.call(a), g = 0; !(k = a.next()).done; ) k = k.value, f = d + Q(k, g++), h += R(k, b, e, f, c);
else if ("object" === k) throw b = String(a), Error("Objects are not valid as a React child (found: " + ("[object Object]" === b ? "object with keys {" + Object.keys(a).join(", ") + "}" : b) + "). If you meant to render a collection of children, use an array instead.");
return h;
}
function S(a, b, e) {
if (null == a) return a;
var d = [], c = 0;
R(a, d, "", "", function(a2) {
return b.call(e, a2, c++);
});
return d;
}
function T(a) {
if (-1 === a._status) {
var b = a._result;
b = b();
b.then(function(b2) {
if (0 === a._status || -1 === a._status) a._status = 1, a._result = b2;
}, function(b2) {
if (0 === a._status || -1 === a._status) a._status = 2, a._result = b2;
});
-1 === a._status && (a._status = 0, a._result = b);
}
if (1 === a._status) return a._result.default;
throw a._result;
}
var U = { current: null };
var V = { transition: null };
var W = { ReactCurrentDispatcher: U, ReactCurrentBatchConfig: V, ReactCurrentOwner: K };
function X() {
throw Error("act(...) is not supported in production builds of React.");
}
exports.Children = { map: S, forEach: function(a, b, e) {
S(a, function() {
b.apply(this, arguments);
}, e);
}, count: function(a) {
var b = 0;
S(a, function() {
b++;
});
return b;
}, toArray: function(a) {
return S(a, function(a2) {
return a2;
}) || [];
}, only: function(a) {
if (!O(a)) throw Error("React.Children.only expected to receive a single React element child.");
return a;
} };
exports.Component = E;
exports.Fragment = p;
exports.Profiler = r;
exports.PureComponent = G;
exports.StrictMode = q;
exports.Suspense = w;
exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = W;
exports.act = X;
exports.cloneElement = function(a, b, e) {
if (null === a || void 0 === a) throw Error("React.cloneElement(...): The argument must be a React element, but you passed " + a + ".");
var d = C({}, a.props), c = a.key, k = a.ref, h = a._owner;
if (null != b) {
void 0 !== b.ref && (k = b.ref, h = K.current);
void 0 !== b.key && (c = "" + b.key);
if (a.type && a.type.defaultProps) var g = a.type.defaultProps;
for (f in b) J.call(b, f) && !L.hasOwnProperty(f) && (d[f] = void 0 === b[f] && void 0 !== g ? g[f] : b[f]);
}
var f = arguments.length - 2;
if (1 === f) d.children = e;
else if (1 < f) {
g = Array(f);
for (var m = 0; m < f; m++) g[m] = arguments[m + 2];
d.children = g;
}
return { $$typeof: l, type: a.type, key: c, ref: k, props: d, _owner: h };
};
exports.createContext = function(a) {
a = { $$typeof: u, _currentValue: a, _currentValue2: a, _threadCount: 0, Provider: null, Consumer: null, _defaultValue: null, _globalName: null };
a.Provider = { $$typeof: t, _context: a };
return a.Consumer = a;
};
exports.createElement = M;
exports.createFactory = function(a) {
var b = M.bind(null, a);
b.type = a;
return b;
};
exports.createRef = function() {
return { current: null };
};
exports.forwardRef = function(a) {
return { $$typeof: v, render: a };
};
exports.isValidElement = O;
exports.lazy = function(a) {
return { $$typeof: y, _payload: { _status: -1, _result: a }, _init: T };
};
exports.memo = function(a, b) {
return { $$typeof: x, type: a, compare: void 0 === b ? null : b };
};
exports.startTransition = function(a) {
var b = V.transition;
V.transition = {};
try {
a();
} finally {
V.transition = b;
}
};
exports.unstable_act = X;
exports.useCallback = function(a, b) {
return U.current.useCallback(a, b);
};
exports.useContext = function(a) {
return U.current.useContext(a);
};
exports.useDebugValue = function() {
};
exports.useDeferredValue = function(a) {
return U.current.useDeferredValue(a);
};
exports.useEffect = function(a, b) {
return U.current.useEffect(a, b);
};
exports.useId = function() {
return U.current.useId();
};
exports.useImperativeHandle = function(a, b, e) {
return U.current.useImperativeHandle(a, b, e);
};
exports.useInsertionEffect = function(a, b) {
return U.current.useInsertionEffect(a, b);
};
exports.useLayoutEffect = function(a, b) {
return U.current.useLayoutEffect(a, b);
};
exports.useMemo = function(a, b) {
return U.current.useMemo(a, b);
};
exports.useReducer = function(a, b, e) {
return U.current.useReducer(a, b, e);
};
exports.useRef = function(a) {
return U.current.useRef(a);
};
exports.useState = function(a) {
return U.current.useState(a);
};
exports.useSyncExternalStore = function(a, b, e) {
return U.current.useSyncExternalStore(a, b, e);
};
exports.useTransition = function() {
return U.current.useTransition();
};
exports.version = "18.3.1";
}
});
// node_modules/react/index.js
var require_react = __commonJS({
"node_modules/react/index.js"(exports, module) {
"use strict";
if (true) {
module.exports = require_react_production_min();
} else {
module.exports = null;
}
}
});
// node_modules/react/cjs/react-jsx-runtime.production.min.js
var require_react_jsx_runtime_production_min = __commonJS({
"node_modules/react/cjs/react-jsx-runtime.production.min.js"(exports) {
"use strict";
var f = require_react();
var k = Symbol.for("react.element");
var l = Symbol.for("react.fragment");
var m = Object.prototype.hasOwnProperty;
var n = f.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner;
var p = { key: true, ref: true, __self: true, __source: true };
function q(c, a, g) {
var b, d = {}, e = null, h = null;
void 0 !== g && (e = "" + g);
void 0 !== a.key && (e = "" + a.key);
void 0 !== a.ref && (h = a.ref);
for (b in a) m.call(a, b) && !p.hasOwnProperty(b) && (d[b] = a[b]);
if (c && c.defaultProps) for (b in a = c.defaultProps, a) void 0 === d[b] && (d[b] = a[b]);
return { $$typeof: k, type: c, key: e, ref: h, props: d, _owner: n.current };
}
exports.Fragment = l;
exports.jsx = q;
exports.jsxs = q;
}
});
// node_modules/react/jsx-runtime.js
var require_jsx_runtime = __commonJS({
"node_modules/react/jsx-runtime.js"(exports, module) {
"use strict";
if (true) {
module.exports = require_react_jsx_runtime_production_min();
} else {
module.exports = null;
}
}
});
// src/index.ts
var index_exports = {};
__export(index_exports, {
AgentWidget: () => AgentWidget,
ChatbotEmbed: () => ChatbotEmbed
});
// src/AgentWidget.tsx
var import_react9 = __toESM(require_react());
// src/components/ChatBubble.tsx
var import_jsx_runtime = __toESM(require_jsx_runtime());
function ChatBubble({ isOpen, onClick, primaryColor = "#3b82f6", unreadCount = 0, position = "bottom-right" }) {
const adjustColor = (color, percent) => {
const num = parseInt(color.replace("#", ""), 16);
const amt = Math.round(2.55 * percent);
const R = (num >> 16) + amt;
const G = (num >> 8 & 255) + amt;
const B = (num & 255) + amt;
return "#" + (16777216 + (R < 255 ? R < 1 ? 0 : R : 255) * 65536 + (G < 255 ? G < 1 ? 0 : G : 255) * 256 + (B < 255 ? B < 1 ? 0 : B : 255)).toString(16).slice(1);
};
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
"button",
{
onClick,
style: {
position: "fixed",
bottom: position.includes("bottom") ? "20px" : "auto",
top: position.includes("top") ? "20px" : "auto",
right: position.includes("right") ? "20px" : "auto",
left: position.includes("left") ? "20px" : "auto",
width: "60px",
height: "60px",
borderRadius: "50%",
backgroundColor: primaryColor,
color: "white",
border: "none",
cursor: "pointer",
display: "flex",
alignItems: "center",
justifyContent: "center",
fontSize: "24px",
boxShadow: "0 10px 15px -3px rgba(0, 0, 0, 0.1)",
zIndex: 9999,
transition: "all 0.2s ease"
},
onMouseEnter: (e) => {
e.currentTarget.style.backgroundColor = adjustColor(primaryColor, -10);
e.currentTarget.style.transform = "scale(1.05)";
},
onMouseLeave: (e) => {
e.currentTarget.style.backgroundColor = primaryColor;
e.currentTarget.style.transform = "scale(1)";
},
"aria-label": "Open chat",
children: [
unreadCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: {
position: "absolute",
top: "-2px",
right: "-2px",
background: "linear-gradient(135deg, #ef4444, #dc2626)",
color: "white",
borderRadius: "50%",
minWidth: "20px",
height: "20px",
display: "flex",
alignItems: "center",
justifyContent: "center",
fontSize: "11px",
fontWeight: "600",
padding: "0 4px",
border: "2px solid white"
}, children: unreadCount > 9 ? "9+" : unreadCount }),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
"svg",
{
width: "24",
height: "24",
fill: "none",
stroke: "currentColor",
viewBox: "0 0 24 24",
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
"path",
{
strokeLinecap: "round",
strokeLinejoin: "round",
strokeWidth: 2.5,
d: "M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"
}
)
}
)
]
}
);
}
// src/components/ChatWindow.tsx
var import_react4 = __toESM(require_react());
// src/components/MessageList.tsx
var import_jsx_runtime2 = __toESM(require_jsx_runtime());
function MessageList({
messages,
primaryColor,
isLoading = false,
onEndConversation,
onShowProducts,
onShowServices,
onShowBookingForm,
onShowPaymentOptions,
onShowInvoice,
onRequestFeedback,
onShowCart
}) {
const adjustColor = (color, percent) => {
const num = parseInt(color.replace("#", ""), 16);
const amt = Math.round(2.55 * percent);
const R = (num >> 16) + amt;
const G = (num >> 8 & 255) + amt;
const B = (num & 255) + amt;
return "#" + (16777216 + (R < 255 ? R < 1 ? 0 : R : 255) * 65536 + (G < 255 ? G < 1 ? 0 : G : 255) * 256 + (B < 255 ? B < 1 ? 0 : B : 255)).toString(16).slice(1);
};
const buttonStyle = {
padding: "8px 16px",
backgroundColor: primaryColor,
color: "white",
border: "none",
borderRadius: "16px",
fontSize: "13px",
fontWeight: "500",
cursor: "pointer",
display: "inline-flex",
alignItems: "center",
gap: "6px",
transition: "all 0.2s ease"
};
const ThinkingIndicator = () => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: {
marginBottom: "16px",
display: "flex",
gap: "8px",
justifyContent: "flex-start",
alignItems: "flex-end"
}, children: [
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: {
width: "28px",
height: "28px",
borderRadius: "50%",
display: "flex",
alignItems: "center",
justifyContent: "center",
fontSize: "12px",
flexShrink: 0,
background: `linear-gradient(135deg, ${primaryColor}, ${adjustColor(primaryColor, -10)})`,
color: "white",
marginBottom: "2px"
}, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { width: "14", height: "14", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" }) }) }),
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: {
maxWidth: "85%",
padding: "12px 16px",
borderRadius: "16px",
borderBottomLeftRadius: "4px",
fontSize: "14px",
lineHeight: "1.5",
backgroundColor: "#f8f9fa",
color: "#1f2937",
boxShadow: "0 1px 2px rgba(0, 0, 0, 0.1)",
display: "flex",
alignItems: "center",
gap: "8px"
}, children: [
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: {
display: "flex",
gap: "4px",
alignItems: "center"
}, children: [
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: {
width: "8px",
height: "8px",
borderRadius: "50%",
backgroundColor: "#6b7280",
animation: "typing 1.4s infinite ease-in-out"
} }),
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: {
width: "8px",
height: "8px",
borderRadius: "50%",
backgroundColor: "#6b7280",
animation: "typing 1.4s infinite ease-in-out",
animationDelay: "0.2s"
} }),
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: {
width: "8px",
height: "8px",
borderRadius: "50%",
backgroundColor: "#6b7280",
animation: "typing 1.4s infinite ease-in-out",
animationDelay: "0.4s"
} })
] }),
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { color: "#6b7280", fontSize: "13px" }, children: "AI is thinking..." })
] })
] });
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "16px" }, children: [
messages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
"div",
{
style: {
display: "flex",
justifyContent: message.role === "user" ? "flex-end" : "flex-start",
marginBottom: "16px",
alignItems: "flex-end",
gap: "8px"
},
children: [
message.role === "assistant" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: {
width: "28px",
height: "28px",
borderRadius: "50%",
display: "flex",
alignItems: "center",
justifyContent: "center",
fontSize: "12px",
flexShrink: 0,
background: `linear-gradient(135deg, ${primaryColor}, ${adjustColor(primaryColor, -10)})`,
color: "white",
marginBottom: "2px"
}, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { width: "14", height: "14", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" }) }) }),
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: {
maxWidth: "85%",
padding: "12px 16px",
borderRadius: "16px",
borderBottomLeftRadius: message.role === "assistant" ? "4px" : "16px",
borderBottomRightRadius: message.role === "user" ? "4px" : "16px",
fontSize: "14px",
lineHeight: "1.5",
wordWrap: "break-word",
backgroundColor: message.role === "assistant" ? "#f8f9fa" : primaryColor,
color: message.role === "assistant" ? "#1f2937" : "white",
boxShadow: "0 1px 2px rgba(0, 0, 0, 0.1)",
marginLeft: message.role === "user" ? "auto" : "0"
}, children: [
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
message.content || (message.isStreaming ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: {
display: "flex",
gap: "4px",
padding: "8px 0",
alignItems: "center"
}, children: [
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: {
width: "8px",
height: "8px",
borderRadius: "50%",
backgroundColor: "#6b7280",
animation: "typing 1.4s infinite ease-in-out"
} }),
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: {
width: "8px",
height: "8px",
borderRadius: "50%",
backgroundColor: "#6b7280",
animation: "typing 1.4s infinite ease-in-out",
animationDelay: "0.2s"
} }),
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: {
width: "8px",
height: "8px",
borderRadius: "50%",
backgroundColor: "#6b7280",
animation: "typing 1.4s infinite ease-in-out",
animationDelay: "0.4s"
} })
] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: {
display: "flex",
gap: "4px",
padding: "8px 0",
alignItems: "center"
}, children: [
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: {
width: "8px",
height: "8px",
borderRadius: "50%",
backgroundColor: "#6b7280",
animation: "typing 1.4s infinite ease-in-out"
} }),
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: {
width: "8px",
height: "8px",
borderRadius: "50%",
backgroundColor: "#6b7280",
animation: "typing 1.4s infinite ease-in-out",
animationDelay: "0.2s"
} }),
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: {
width: "8px",
height: "8px",
borderRadius: "50%",
backgroundColor: "#6b7280",
animation: "typing 1.4s infinite ease-in-out",
animationDelay: "0.4s"
} })
] })),
message.role === "assistant" && message.metadata && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { marginTop: "12px", display: "flex", flexWrap: "wrap", gap: "8px" }, children: [
message.metadata.showProducts && onShowProducts && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { onClick: onShowProducts, style: buttonStyle, children: "\u{1F6CD}\uFE0F View Products" }),
message.metadata.showServices && onShowServices && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { onClick: onShowServices, style: buttonStyle, children: "\u{1F6CE}\uFE0F View Services" }),
message.metadata.showBookingForm && onShowBookingForm && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { onClick: onShowBookingForm, style: buttonStyle, children: "\u{1F4C5} Book Now" }),
message.metadata.showPaymentOptions && onShowPaymentOptions && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { onClick: onShowPaymentOptions, style: buttonStyle, children: "\u{1F4B3} Payment Options" }),
message.metadata.showInvoice && onShowInvoice && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { onClick: onShowInvoice, style: buttonStyle, children: "\u{1F9FE} View Invoice" }),
message.metadata.requestFeedback && onRequestFeedback && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { onClick: onRequestFeedback, style: buttonStyle, children: "\u2B50 Rate Experience" }),
message.metadata.showCart && onShowCart && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { onClick: onShowCart, style: buttonStyle, children: "\u{1F6D2} View Cart" }),
message.metadata.showEndButton && onEndConversation && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { onClick: onEndConversation, style: buttonStyle, children: "\u2705 End Conversation" })
] })
] }),
message.timestamp && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: {
fontSize: "10px",
color: message.role === "assistant" ? "#9ca3af" : "rgba(255,255,255,0.7)",
marginTop: "6px",
textAlign: message.role === "user" ? "right" : "left"
}, children: new Date(message.timestamp).toLocaleTimeString([], {
hour: "2-digit",
minute: "2-digit"
}) })
] }),
message.role === "user" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: {
width: "28px",
height: "28px",
borderRadius: "50%",
display: "flex",
alignItems: "center",
justifyContent: "center",
fontSize: "12px",
flexShrink: 0,
background: "linear-gradient(135deg, #6b7280, #4b5563)",
color: "white",
marginBottom: "2px"
}, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { width: "14", height: "14", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" }) }) })
]
},
message.id
)),
isLoading && !messages.some((msg) => msg.isStreaming) && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ThinkingIndicator, {})
] });
}
// src/hooks/useVoice.ts
var import_react = __toESM(require_react());
function useVoice({ onTranscript, enabled = true }) {
const [isListening, setIsListening] = (0, import_react.useState)(false);
const [isSupported, setIsSupported] = (0, import_react.useState)(() => {
if (typeof window !== "undefined") {
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
return !!SpeechRecognition && enabled;
}
return false;
});
const recognitionRef = (0, import_react.useRef)(null);
const createRecognition = (0, import_react.useCallback)(() => {
if (typeof window === "undefined") return null;
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
if (!SpeechRecognition) return null;
const recognition = new SpeechRecognition();
recognition.continuous = false;
recognition.interimResults = false;
recognition.lang = "en-US";
recognition.maxAlternatives = 1;
recognition.onstart = () => {
console.log("Speech recognition started");
setIsListening(true);
};
recognition.onresult = (event) => {
console.log("Speech recognition result:", event);
console.log("Results length:", event.results.length);
for (let i = 0; i < event.results.length; i++) {
const result = event.results[i];
console.log(`Result ${i}:`, result);
console.log(`Result ${i} transcript:`, result[0]?.transcript);
if (result[0]?.transcript) {
const transcript = result[0].transcript.trim();
console.log("Final transcript:", transcript);
onTranscript(transcript);
setIsListening(false);
return;
}
}
};
recognition.onend = () => {
console.log("Speech recognition ended");
setIsListening(false);
};
recognition.onerror = (event) => {
console.error("Speech recognition error:", event.error);
setIsListening(false);
};
return recognition;
}, [onTranscript]);
const startListening = (0, import_react.useCallback)(() => {
console.log("Starting voice recognition...");
if (recognitionRef.current) {
recognitionRef.current.abort();
}
const recognition = createRecognition();
if (!recognition) {
console.error("Speech recognition not supported");
return;
}
recognitionRef.current = recognition;
try {
recognition.start();
} catch (error) {
console.error("Failed to start recognition:", error);
setIsListening(false);
}
}, [createRecognition]);
const stopListening = (0, import_react.useCallback)(() => {
console.log("Stopping voice recognition...");
if (recognitionRef.current) {
recognitionRef.current.stop();
recognitionRef.current = null;
}
setIsListening(false);
}, []);
const speak = (0, import_react.useCallback)((text) => {
if (typeof window !== "undefined" && window.speechSynthesis && enabled) {
window.speechSynthesis.cancel();
const utterance = new SpeechSynthesisUtterance(text);
utterance.rate = 0.9;
utterance.pitch = 1;
utterance.volume = 0.8;
window.speechSynthesis.speak(utterance);
}
}, [enabled]);
return {
isListening,
isSupported,
startListening,
stopListening,
speak
};
}
// src/components/MessageInput.tsx
var import_jsx_runtime3 = __toESM(require_jsx_runtime());
function MessageInput({ value, onChange, onSend, isLoading, placeholder, primaryColor, voiceEnabled = false }) {
const { isListening, isSupported, startListening, stopListening } = useVoice({
onTranscript: (text) => {
console.log("MessageInput received transcript:", text);
onChange(text);
console.log("MessageInput onChange called with:", text);
},
enabled: voiceEnabled
});
const handleKeyPress = (e) => {
if (e.key === "Enter" && !e.shiftKey) {
e.preventDefault();
onSend();
}
};
const handleVoiceToggle = () => {
console.log("Voice toggle clicked, isListening:", isListening);
if (isListening) {
console.log("Stopping voice recognition");
stopListening();
} else {
console.log("Starting voice recognition");
startListening();
}
};
const adjustColor = (color, percent) => {
const num = parseInt(color.replace("#", ""), 16);
const amt = Math.round(2.55 * percent);
const R = (num >> 16) + amt;
const G = (num >> 8 & 255) + amt;
const B = (num & 255) + amt;
return "#" + (16777216 + (R < 255 ? R < 1 ? 0 : R : 255) * 65536 + (G < 255 ? G < 1 ? 0 : G : 255) * 256 + (B < 255 ? B < 1 ? 0 : B : 255)).toString(16).slice(1);
};
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: {
padding: "16px",
borderTop: "1px solid #e5e7eb",
backgroundColor: "white"
}, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: {
display: "flex",
gap: "8px",
alignItems: "flex-end"
}, children: [
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
"textarea",
{
value,
onChange: (e) => onChange(e.target.value),
onKeyPress: handleKeyPress,
placeholder,
disabled: isLoading,
rows: 1,
style: {
flex: 1,
border: "1px solid #e5e7eb",
borderRadius: "20px",
padding: "12px 16px",
fontSize: "14px",
outline: "none",
resize: "none",
overflow: "hidden",
minHeight: "44px",
maxHeight: "120px",
backgroundColor: "white",
color: "#1f2937",
fontFamily: "inherit"
},
onFocus: (e) => {
e.target.style.borderColor = primaryColor;
e.target.style.boxShadow = `0 0 0 3px ${primaryColor}20`;
},
onBlur: (e) => {
e.target.style.borderColor = "#e5e7eb";
e.target.style.boxShadow = "none";
},
onInput: (e) => {
const target = e.target;
target.style.height = "auto";
target.style.height = Math.min(target.scrollHeight, 120) + "px";
}
}
),
voiceEnabled && !value.trim() ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
"button",
{
onClick: handleVoiceToggle,
disabled: !isSupported,
style: {
background: isListening ? `linear-gradient(135deg, #ef4444, #dc2626)` : `linear-gradient(135deg, ${primaryColor}, ${adjustColor(primaryColor, -10)})`,
color: "white",
border: "none",
borderRadius: "50%",
width: "44px",
height: "44px",
display: "flex",
alignItems: "center",
justifyContent: "center",
cursor: !isSupported ? "not-allowed" : "pointer",
opacity: !isSupported ? 0.5 : 1,
transition: "all 0.2s ease",
animation: isListening ? "pulse 1.5s infinite" : "none"
},
onMouseEnter: (e) => {
if (isSupported) {
e.currentTarget.style.transform = "scale(1.05)";
}
},
onMouseLeave: (e) => {
e.currentTarget.style.transform = "scale(1)";
},
"aria-label": isListening ? "Stop recording" : "Start voice recording",
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { width: "16", height: "16", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2.5, d: "M19 11a7 7 0 01-7 7m0 0a7 7 0 01-7-7m7 7v4m0 0H8m4 0h4m-4-8a3 3 0 01-3-3V5a3 3 0 116 0v6a3 3 0 01-3 3z" }) })
}
) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
"button",
{
onClick: onSend,
disabled: !value.trim() || isLoading,
style: {
background: `linear-gradient(135deg, ${primaryColor}, ${adjustColor(primaryColor, -10)})`,
color: "white",
border: "none",
borderRadius: "50%",
width: "44px",
height: "44px",
display: "flex",
alignItems: "center",
justifyContent: "center",
cursor: !value.trim() || isLoading ? "not-allowed" : "pointer",
opacity: !value.trim() || isLoading ? 0.5 : 1,
transition: "all 0.2s ease"
},
onMouseEnter: (e) => {
if (!(!value.trim() || isLoading)) {
e.currentTarget.style.transform = "scale(1.05)";
}
},
onMouseLeave: (e) => {
e.currentTarget.style.transform = "scale(1)";
},
"aria-label": "Send message",
children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: {
width: "20px",
height: "20px",
border: "2px solid transparent",
borderTop: "2px solid currentColor",
borderRadius: "50%",
animation: "spin 1s linear infinite"
} }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { width: "16", height: "16", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2.5, d: "M12 19l9 2-9-18-9 18 9-2zm0 0v-8" }) })
}
)
] }) });
}
// src/components/ProductCard.tsx
var import_jsx_runtime4 = __toESM(require_jsx_runtime());
function ProductCard({ product, onBuyNow, primaryColor }) {
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
"div",
{
style: {
border: "1px solid #e5e7eb",
borderRadius: "8px",
padding: "16px",
margin: "8px 0",
backgroundColor: "#ffffff"
},
children: [
(product.imageUrl || product.images?.[0]) && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
"img",
{
src: product.imageUrl || product.images[0],
alt: product.name,
style: {
width: "100%",
height: "120px",
objectFit: "cover",
borderRadius: "6px",
marginBottom: "12px"
}
}
),
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
"h3",
{
style: {
fontSize: "16px",
fontWeight: "600",
margin: "0 0 8px 0",
color: "#1f2937"
},
children: product.name
}
),
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
"p",
{
style: {
fontSize: "14px",
color: "#6b7280",
margin: "0 0 12px 0",
lineHeight: "1.4"
},
children: product.description
}
),
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
"div",
{
style: {
display: "flex",
justifyContent: "space-between",
alignItems: "center"
},
children: [
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
"span",
{
style: {
fontSize: "18px",
fontWeight: "700",
color: primaryColor
},
children: [
product.currency,
" ",
product.price
]
}
),
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
"button",
{
onClick: () => onBuyNow(product),
style: {
backgroundColor: primaryColor,
color: "white",
border: "none",
borderRadius: "6px",
padding: "8px 16px",
fontSize: "14px",
fontWeight: "500",
cursor: "pointer"
},
children: "Buy Now"
}
)
]
}
)
]
}
);
}
// src/components/OrdersView.tsx
var import_jsx_runtime5 = __toESM(require_jsx_runtime());
function OrdersView({ orders, onClose, onPayOrder }) {
const formatDate = (dateString) => {
return new Date(dateString).toLocaleDateString("en-US", {
year: "numeric",
month: "short",
day: "numeric",
hour: "2-digit",
minute: "2-digit"
});
};
const getStatusColor = (status) => {
switch (status) {
case "completed":
return "#10b981";
case "processing":
return "#3b82f6";
case "shipped":
return "#8b5cf6";
case "delivered":
return "#059669";
case "pending":
return "#f59e0b";
case "failed":
return "#ef4444";
case "cancelled":
return "#6b7280";
default:
return "#6b7280";
}
};
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { padding: "20px" }, children: [
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: {
display: "flex",
justifyContent: "space-between",
alignItems: "center",
marginBottom: "20px"
}, children: [
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h3", { style: {
fontSize: "18px",
fontWeight: "600",
margin: 0,
color: "#1f2937"
}, children: "My Orders" }),
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
"button",
{
onClick: onClose,
style: {
background: "none",
border: "none",
fontSize: "24px",
cursor: "pointer",
color: "#6b7280",
padding: "4px"
},
children: "\xD7"
}
)
] }),
orders.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: {
textAlign: "center",
padding: "40px 20px",
color: "#6b7280"
}, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { children: "No orders found" }) }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: orders.map((order) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
"div",
{
style: {
border: "1px solid #e5e7eb",
borderRadius: "8px",
padding: "16px",
backgroundColor: "#ffffff"
},
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { display: "flex", gap: "12px" }, children: [
order.productId && order.productId.imageUrl && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
"img",
{
src: order.productId.imageUrl,
alt: order.productId.name,
style: {
width: "60px",
height: "60px",
objectFit: "cover",
borderRadius: "6px"
}
}
),
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { flex: 1 }, children: [
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h4", { style: {
fontSize: "16px",
fontWeight: "600",
margin: "0 0 4px 0",
color: "#1f2937"
}, children: order.productId ? order.productId.name : order.itemName || "Service Order" }),
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { style: {
fontSize: "14px",
color: "#6b7280",
margin: "0 0 8px 0"
}, children: order.productId ? order.productId.description : "Service booking order" }),
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: {
display: "flex",
justifyContent: "space-between",
alignItems: "center"
}, children: [
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { style: {
fontSize: "16px",
fontWeight: "600",
color: "#1f2937"
}, children: [
order.currency,
" ",
order.amount
] }),
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { style: {
fontSize: "12px",
padding: "4px 8px",
borderRadius: "12px",
backgroundColor: `${getStatusColor(order.status)}20`,
color: getStatusColor(order.status),
fontWeight: "500",
textTransform: "capitalize"
}, children: order.status })
] }),
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { style: {
fontSize: "12px",
color: "#9ca3af",
margin: "8px 0 0 0"
}, children: formatDate(order.createdAt) }),
order.trackingNumber && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { style: {
fontSize: "12px",
color: "#3b82f6",
margin: "4px 0 0 0",
fontWeight: "500"
}, children: [
"Tracking: ",
order.trackingNumber
] }),
order.deliveryAddress && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { style: {
fontSize: "12px",
color: "#6b7280",
margin: "4px 0 0 0"
}, children: [
order.deliveryAddress.street,
", ",
order.deliveryAddress.city,
", ",
order.deliveryAddress.state,
" ",
order.deliveryAddress.zipCode
] }),
order.status === "pending" && onPayOrder && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
"button",
{
onClick: () => onPayOrder(order),
style: {
marginTop: "8px",
padding: "6px 12px",
backgroundColor: "#3b82f6",
color: "white",
border: "none",
borderRadius: "4px",
fontSize: "12px",
fontWeight: "500",
cursor: "pointer"
},
children: "Pay Now"
}
)
] })
] })
},
order._id
)) })
] });
}
// src/components/ServiceCard.tsx
var import_jsx_runtime6 = __toESM(require_jsx_runtime());
function ServiceCard({ service, onBook }) {
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
"div",
{
style: {
border: "1px solid #e5e7eb",
borderRadius: "8px",
padding: "16px",
backgroundColor: "white",
boxShadow: "0 1px 3px rgba(0, 0, 0, 0.1)"
},
children: [
service.imageUrl && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
"img",
{
src: service.imageUrl,
alt: service.name,
style: {
width