@mamiy/chatbot 1.0.0

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.
@@ -0,0 +1,12 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ type Props = {
4
+ businessId: string;
5
+ icon?: string;
6
+ bgColor?: string;
7
+ textColor?: string;
8
+ apiUrl?: string;
9
+ };
10
+ declare function Chatbot({ businessId, icon, bgColor, textColor, apiUrl, }: Props): react_jsx_runtime.JSX.Element;
11
+
12
+ export { Chatbot };
@@ -0,0 +1,12 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ type Props = {
4
+ businessId: string;
5
+ icon?: string;
6
+ bgColor?: string;
7
+ textColor?: string;
8
+ apiUrl?: string;
9
+ };
10
+ declare function Chatbot({ businessId, icon, bgColor, textColor, apiUrl, }: Props): react_jsx_runtime.JSX.Element;
11
+
12
+ export { Chatbot };
package/dist/index.js ADDED
@@ -0,0 +1,236 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ Chatbot: () => Chatbot
24
+ });
25
+ module.exports = __toCommonJS(index_exports);
26
+
27
+ // src/Chatbot.tsx
28
+ var import_react = require("react");
29
+ var import_jsx_runtime = require("react/jsx-runtime");
30
+ function Chatbot({
31
+ businessId,
32
+ icon = "\u{1F5E8}\uFE0F",
33
+ bgColor = "#000000",
34
+ textColor = "#ffffff",
35
+ apiUrl = "http://localhost:3000/api/chat"
36
+ }) {
37
+ const [isOpen, setIsOpen] = (0, import_react.useState)(false);
38
+ const [messages, setMessages] = (0, import_react.useState)([
39
+ { text: "Hi \u{1F44B} How can we help you today?", sender: "ai" }
40
+ ]);
41
+ const [input, setInput] = (0, import_react.useState)("");
42
+ const [loading, setLoading] = (0, import_react.useState)(false);
43
+ const messagesEndRef = (0, import_react.useRef)(null);
44
+ (0, import_react.useEffect)(() => {
45
+ messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
46
+ }, [messages]);
47
+ async function handleSend() {
48
+ if (!input.trim() || loading) return;
49
+ const userMessage = input;
50
+ setMessages((prev) => [...prev, { text: userMessage, sender: "user" }]);
51
+ setInput("");
52
+ setLoading(true);
53
+ try {
54
+ const res = await fetch(apiUrl, {
55
+ method: "POST",
56
+ headers: { "Content-Type": "application/json" },
57
+ body: JSON.stringify({
58
+ message: userMessage,
59
+ businessId
60
+ })
61
+ });
62
+ const data = await res.json();
63
+ setMessages((prev) => [
64
+ ...prev,
65
+ {
66
+ text: data?.answer || "Please contact support",
67
+ sender: "ai"
68
+ }
69
+ ]);
70
+ } catch {
71
+ setMessages((prev) => [
72
+ ...prev,
73
+ { text: "Network error. Please contact support", sender: "ai" }
74
+ ]);
75
+ } finally {
76
+ setLoading(false);
77
+ }
78
+ }
79
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
80
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
81
+ "button",
82
+ {
83
+ onClick: () => setIsOpen(!isOpen),
84
+ style: {
85
+ position: "fixed",
86
+ bottom: "40px",
87
+ right: "40px",
88
+ width: "50px",
89
+ height: "50px",
90
+ borderRadius: "50%",
91
+ border: "none",
92
+ cursor: "pointer",
93
+ fontSize: "24px",
94
+ backgroundColor: bgColor,
95
+ color: textColor,
96
+ boxShadow: "0 4px 12px rgba(0,0,0,0.2)",
97
+ zIndex: 999999
98
+ },
99
+ children: icon
100
+ }
101
+ ),
102
+ isOpen && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
103
+ "div",
104
+ {
105
+ style: {
106
+ position: "fixed",
107
+ width: "320px",
108
+ height: "420px",
109
+ borderRadius: "16px",
110
+ bottom: "100px",
111
+ right: "40px",
112
+ border: "1px solid #e5e5e5",
113
+ background: "#ffffff",
114
+ boxShadow: "0 12px 32px rgba(0,0,0,0.18)",
115
+ display: "flex",
116
+ flexDirection: "column",
117
+ overflow: "hidden",
118
+ fontFamily: "Arial, sans-serif",
119
+ zIndex: 999999
120
+ },
121
+ children: [
122
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
123
+ "div",
124
+ {
125
+ style: {
126
+ padding: "14px",
127
+ display: "flex",
128
+ justifyContent: "space-between",
129
+ background: bgColor,
130
+ color: textColor
131
+ },
132
+ children: [
133
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "Customer Support" }),
134
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { cursor: "pointer" }, onClick: () => setIsOpen(false), children: "\u2715" })
135
+ ]
136
+ }
137
+ ),
138
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
139
+ "div",
140
+ {
141
+ style: {
142
+ flex: 1,
143
+ padding: "12px",
144
+ overflowY: "auto",
145
+ background: "#f5f7fb",
146
+ display: "flex",
147
+ flexDirection: "column",
148
+ gap: "8px",
149
+ fontSize: "14px"
150
+ },
151
+ children: [
152
+ messages.map((msg, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
153
+ "div",
154
+ {
155
+ style: {
156
+ alignSelf: msg.sender === "user" ? "flex-end" : "flex-start",
157
+ background: msg.sender === "user" ? bgColor : "#e9eef6",
158
+ color: msg.sender === "user" ? "#fff" : "#333",
159
+ padding: "10px 12px",
160
+ borderRadius: "14px",
161
+ maxWidth: "75%"
162
+ },
163
+ children: msg.text
164
+ },
165
+ i
166
+ )),
167
+ loading && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
168
+ "div",
169
+ {
170
+ style: {
171
+ alignSelf: "flex-start",
172
+ background: "#e9eef6",
173
+ padding: "8px 12px",
174
+ borderRadius: "14px"
175
+ },
176
+ children: "Typing..."
177
+ }
178
+ ),
179
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { ref: messagesEndRef })
180
+ ]
181
+ }
182
+ ),
183
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
184
+ "div",
185
+ {
186
+ style: {
187
+ display: "flex",
188
+ padding: "10px",
189
+ borderTop: "1px solid #e5e5e5"
190
+ },
191
+ children: [
192
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
193
+ "input",
194
+ {
195
+ value: input,
196
+ onChange: (e) => setInput(e.target.value),
197
+ onKeyDown: (e) => e.key === "Enter" && handleSend(),
198
+ placeholder: "Type your message...",
199
+ style: {
200
+ flex: 1,
201
+ padding: "8px 10px",
202
+ border: "1px solid #ddd",
203
+ borderRadius: "8px",
204
+ outline: "none"
205
+ }
206
+ }
207
+ ),
208
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
209
+ "button",
210
+ {
211
+ onClick: handleSend,
212
+ disabled: loading,
213
+ style: {
214
+ marginLeft: "8px",
215
+ padding: "8px 12px",
216
+ border: "none",
217
+ borderRadius: "8px",
218
+ cursor: "pointer",
219
+ background: bgColor,
220
+ color: textColor
221
+ },
222
+ children: "Send"
223
+ }
224
+ )
225
+ ]
226
+ }
227
+ )
228
+ ]
229
+ }
230
+ )
231
+ ] });
232
+ }
233
+ // Annotate the CommonJS export names for ESM import in node:
234
+ 0 && (module.exports = {
235
+ Chatbot
236
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,209 @@
1
+ // src/Chatbot.tsx
2
+ import { useState, useRef, useEffect } from "react";
3
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
+ function Chatbot({
5
+ businessId,
6
+ icon = "\u{1F5E8}\uFE0F",
7
+ bgColor = "#000000",
8
+ textColor = "#ffffff",
9
+ apiUrl = "http://localhost:3000/api/chat"
10
+ }) {
11
+ const [isOpen, setIsOpen] = useState(false);
12
+ const [messages, setMessages] = useState([
13
+ { text: "Hi \u{1F44B} How can we help you today?", sender: "ai" }
14
+ ]);
15
+ const [input, setInput] = useState("");
16
+ const [loading, setLoading] = useState(false);
17
+ const messagesEndRef = useRef(null);
18
+ useEffect(() => {
19
+ messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
20
+ }, [messages]);
21
+ async function handleSend() {
22
+ if (!input.trim() || loading) return;
23
+ const userMessage = input;
24
+ setMessages((prev) => [...prev, { text: userMessage, sender: "user" }]);
25
+ setInput("");
26
+ setLoading(true);
27
+ try {
28
+ const res = await fetch(apiUrl, {
29
+ method: "POST",
30
+ headers: { "Content-Type": "application/json" },
31
+ body: JSON.stringify({
32
+ message: userMessage,
33
+ businessId
34
+ })
35
+ });
36
+ const data = await res.json();
37
+ setMessages((prev) => [
38
+ ...prev,
39
+ {
40
+ text: data?.answer || "Please contact support",
41
+ sender: "ai"
42
+ }
43
+ ]);
44
+ } catch {
45
+ setMessages((prev) => [
46
+ ...prev,
47
+ { text: "Network error. Please contact support", sender: "ai" }
48
+ ]);
49
+ } finally {
50
+ setLoading(false);
51
+ }
52
+ }
53
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
54
+ /* @__PURE__ */ jsx(
55
+ "button",
56
+ {
57
+ onClick: () => setIsOpen(!isOpen),
58
+ style: {
59
+ position: "fixed",
60
+ bottom: "40px",
61
+ right: "40px",
62
+ width: "50px",
63
+ height: "50px",
64
+ borderRadius: "50%",
65
+ border: "none",
66
+ cursor: "pointer",
67
+ fontSize: "24px",
68
+ backgroundColor: bgColor,
69
+ color: textColor,
70
+ boxShadow: "0 4px 12px rgba(0,0,0,0.2)",
71
+ zIndex: 999999
72
+ },
73
+ children: icon
74
+ }
75
+ ),
76
+ isOpen && /* @__PURE__ */ jsxs(
77
+ "div",
78
+ {
79
+ style: {
80
+ position: "fixed",
81
+ width: "320px",
82
+ height: "420px",
83
+ borderRadius: "16px",
84
+ bottom: "100px",
85
+ right: "40px",
86
+ border: "1px solid #e5e5e5",
87
+ background: "#ffffff",
88
+ boxShadow: "0 12px 32px rgba(0,0,0,0.18)",
89
+ display: "flex",
90
+ flexDirection: "column",
91
+ overflow: "hidden",
92
+ fontFamily: "Arial, sans-serif",
93
+ zIndex: 999999
94
+ },
95
+ children: [
96
+ /* @__PURE__ */ jsxs(
97
+ "div",
98
+ {
99
+ style: {
100
+ padding: "14px",
101
+ display: "flex",
102
+ justifyContent: "space-between",
103
+ background: bgColor,
104
+ color: textColor
105
+ },
106
+ children: [
107
+ /* @__PURE__ */ jsx("span", { children: "Customer Support" }),
108
+ /* @__PURE__ */ jsx("span", { style: { cursor: "pointer" }, onClick: () => setIsOpen(false), children: "\u2715" })
109
+ ]
110
+ }
111
+ ),
112
+ /* @__PURE__ */ jsxs(
113
+ "div",
114
+ {
115
+ style: {
116
+ flex: 1,
117
+ padding: "12px",
118
+ overflowY: "auto",
119
+ background: "#f5f7fb",
120
+ display: "flex",
121
+ flexDirection: "column",
122
+ gap: "8px",
123
+ fontSize: "14px"
124
+ },
125
+ children: [
126
+ messages.map((msg, i) => /* @__PURE__ */ jsx(
127
+ "div",
128
+ {
129
+ style: {
130
+ alignSelf: msg.sender === "user" ? "flex-end" : "flex-start",
131
+ background: msg.sender === "user" ? bgColor : "#e9eef6",
132
+ color: msg.sender === "user" ? "#fff" : "#333",
133
+ padding: "10px 12px",
134
+ borderRadius: "14px",
135
+ maxWidth: "75%"
136
+ },
137
+ children: msg.text
138
+ },
139
+ i
140
+ )),
141
+ loading && /* @__PURE__ */ jsx(
142
+ "div",
143
+ {
144
+ style: {
145
+ alignSelf: "flex-start",
146
+ background: "#e9eef6",
147
+ padding: "8px 12px",
148
+ borderRadius: "14px"
149
+ },
150
+ children: "Typing..."
151
+ }
152
+ ),
153
+ /* @__PURE__ */ jsx("div", { ref: messagesEndRef })
154
+ ]
155
+ }
156
+ ),
157
+ /* @__PURE__ */ jsxs(
158
+ "div",
159
+ {
160
+ style: {
161
+ display: "flex",
162
+ padding: "10px",
163
+ borderTop: "1px solid #e5e5e5"
164
+ },
165
+ children: [
166
+ /* @__PURE__ */ jsx(
167
+ "input",
168
+ {
169
+ value: input,
170
+ onChange: (e) => setInput(e.target.value),
171
+ onKeyDown: (e) => e.key === "Enter" && handleSend(),
172
+ placeholder: "Type your message...",
173
+ style: {
174
+ flex: 1,
175
+ padding: "8px 10px",
176
+ border: "1px solid #ddd",
177
+ borderRadius: "8px",
178
+ outline: "none"
179
+ }
180
+ }
181
+ ),
182
+ /* @__PURE__ */ jsx(
183
+ "button",
184
+ {
185
+ onClick: handleSend,
186
+ disabled: loading,
187
+ style: {
188
+ marginLeft: "8px",
189
+ padding: "8px 12px",
190
+ border: "none",
191
+ borderRadius: "8px",
192
+ cursor: "pointer",
193
+ background: bgColor,
194
+ color: textColor
195
+ },
196
+ children: "Send"
197
+ }
198
+ )
199
+ ]
200
+ }
201
+ )
202
+ ]
203
+ }
204
+ )
205
+ ] });
206
+ }
207
+ export {
208
+ Chatbot
209
+ };
package/package.json ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "@mamiy/chatbot",
3
+ "version": "1.0.0",
4
+ "description": "Embeddable React chatbot widget",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "files": ["dist"],
9
+ "scripts": {
10
+ "build": "tsup src/index.ts --format esm,cjs --dts"
11
+ },
12
+ "keywords": ["chatbot", "react", "widget", "support"],
13
+ "author": "Your Name",
14
+ "license": "MIT",
15
+ "peerDependencies": {
16
+ "react": "^18 || ^19",
17
+ "react-dom": "^18 || ^19"
18
+ },
19
+ "devDependencies": {
20
+ "@types/react": "^19.2.14",
21
+ "@types/react-dom": "^19.2.3",
22
+ "tsup": "^8.5.1",
23
+ "typescript": "^5.9.3"
24
+ }
25
+ }