UNPKG

@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
"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