dinesh-ai-chat-widget 1.0.13 → 1.0.15

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/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # Floating AI Chat Widget
2
2
 
3
- A floating, customizable chat widget for React and Next.js. Demo replies are built-in. Easily connect your own backend API for custom AI-driven conversations.
3
+ A floating, customizable chat widget for React and Next.js. Includes demo replies out of the box—just add your API key and backend URL to connect your own AI for real conversations.
4
4
 
5
5
  ## Installation
6
6
 
7
- Install the widget package and its peer dependency:
7
+ Install the package and its peer dependency:
8
8
 
9
9
  ```bash
10
10
  npm install dinesh-ai-chat-widget lucide-react
@@ -12,7 +12,7 @@ npm install dinesh-ai-chat-widget lucide-react
12
12
 
13
13
  ## Basic Usage (Next.js Example)
14
14
 
15
- Place the widget in your `app/layout.tsx`:
15
+ Add the widget to your layout, just before the closing `</body>` tag (e.g., in `app/layout.tsx`):
16
16
 
17
17
  ```tsx
18
18
  import { ChatWidget } from "dinesh-ai-chat-widget";
@@ -27,7 +27,8 @@ export default function RootLayout({
27
27
  <body>
28
28
  {children}
29
29
  <ChatWidget
30
- key="YOUR-API-KEY"
30
+ apiKey="YOUR-API-KEY"
31
+ apiUrl="YOUR-API-URL"
31
32
  title="Support Assistant"
32
33
  subtitle="Online · Ask us anything"
33
34
  primaryColor="#2563eb"
@@ -40,11 +41,21 @@ export default function RootLayout({
40
41
 
41
42
  ## Configuration Options
42
43
 
43
- You can configure the widget with these optional props:
44
+ The widget accepts the following props:
44
45
 
46
+ | Prop | Type | Default | Description |
47
+ |----------------|----------|-----------------|-------------------------------------------------------|
48
+ | `apiKey` | string | — | **Required** to enable the chat widget |
49
+ | `apiUrl` | string | http://localhost:8000 | API endpoint URL for your backend |
50
+ | `title` | string | "AI Assistant" | Widget header title |
51
+ | `subtitle` | string | "Online · Ready to help" | Widget header subtitle |
52
+ | `primaryColor` | string | "#2563eb" | Primary theme color (hex, rgb, etc.) |
53
+
54
+ **Example:**
45
55
  ```tsx
46
56
  <ChatWidget
47
- key="YOUR-API-KEY"
57
+ apiKey="YOUR-API-KEY"
58
+ apiUrl="YOUR-API-URL"
48
59
  title="Support Assistant"
49
60
  subtitle="Online · Ask us anything"
50
61
  primaryColor="#2563eb"
@@ -55,19 +66,24 @@ You can configure the widget with these optional props:
55
66
 
56
67
  ## API Integration
57
68
 
58
- When the user sends a message, the widget issues a `POST` request formatted like this:
69
+ When a user sends a message, the widget makes a `POST` request to your backend like:
59
70
 
60
71
  ```json
61
72
  {
62
- "message": "Hello",
73
+ "title": "Hello",
63
74
  "key": "YOUR-API-KEY"
64
75
  }
65
76
  ```
66
77
 
67
- Your backend should return a JSON response with a reply:
78
+ Your backend should respond with a JSON object containing a reply. Example:
68
79
 
69
80
  ```json
70
81
  {
71
82
  "reply": "Hello! How can I help?"
72
83
  }
73
84
  ```
85
+
86
+ - The widget also accepts `"response"` or `"message"` if `"reply"` is missing.
87
+ - To use demo replies, omit the `apiKey` prop.
88
+
89
+ For more details and advanced integration, please refer to the [documentation](#).
@@ -1,8 +1,9 @@
1
1
  export type ChatWidgetProps = {
2
- key?: string;
2
+ apiKey?: string;
3
+ apiUrl?: string;
3
4
  title?: string;
4
5
  subtitle?: string;
5
6
  primaryColor?: string;
6
7
  };
7
- export default function ChatWidget({ key, title, subtitle, primaryColor, }: ChatWidgetProps): "" | import('react').JSX.Element;
8
+ export default function ChatWidget({ apiKey, apiUrl, title, subtitle, primaryColor, }: ChatWidgetProps): import('react').JSX.Element | null;
8
9
  //# sourceMappingURL=ChatWidget.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ChatWidget.d.ts","sourceRoot":"","sources":["../src/ChatWidget.tsx"],"names":[],"mappings":"AAEA,OAAO,eAAe,CAAC;AAYvB,MAAM,MAAM,eAAe,GAAG;IAC5B,GAAG,CAAC,EAAC,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAmCF,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,EACjC,GAAG,EACH,KAAsB,EACtB,QAAmC,EACnC,YAAwB,GACzB,EAAE,eAAe,oCA0LjB"}
1
+ {"version":3,"file":"ChatWidget.d.ts","sourceRoot":"","sources":["../src/ChatWidget.tsx"],"names":[],"mappings":"AAMA,OAAO,eAAe,CAAC;AASvB,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,CAAC,EAAC,MAAM,CAAC;IACf,MAAM,CAAC,EAAC,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAmCF,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,EACjC,MAAM,EACN,MAAgC,EAChC,KAAsB,EACtB,QAAmC,EACnC,YAAwB,GACzB,EAAE,eAAe,sCAiMjB"}
package/dist/index.cjs CHANGED
@@ -1,9 +1,3 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,s)=>(s=n==null?{}:e(i(n)),o(r||!n||!n.__esModule||!a.call(n,`default`)?t(s,`default`,{value:n,enumerable:!0}):s,n));let c=require("react"),l=require("lucide-react"),u=require("dayjs");u=s(u);let d=require("react/jsx-runtime");var f=[`Check vehicle status`,`Schedule maintenance`,`Pricing information`],p=[{id:1,role:`assistant`,text:`Hello! 👋 I'm your AI assistant. How can I help you today?`,time:`Just now`}];function m(e){let t=e.toLowerCase();return t.includes(`vehicle`)||t.includes(`status`)?`I can help check vehicle status. Please provide the vehicle number plate, such as VDR6117.`:t.includes(`maintenance`)||t.includes(`repair`)?`I can help with maintenance! Please describe the vehicle issue, and I'll suggest the next steps.`:t.includes(`price`)||t.includes(`cost`)?`Pricing depends on your requirements. Tell me which service you're interested in, and I'll help estimate the cost.`:t.includes(`hello`)||t.includes(`hi`)?`Hello! 😊 What would you like help with today?`:`Thanks for your message: "${e}". This is a demo response. Configure apiUrl to connect your AI backend.`}function h({key:e,title:t=`AI Assistant`,subtitle:n=`Online · Ready to help`,primaryColor:r=`#2563eb`}){let[i,a]=(0,c.useState)(!1),[o,s]=(0,c.useState)(!1),[h,g]=(0,c.useState)(``),[_,v]=(0,c.useState)(!1),[y,b]=(0,c.useState)(p),x=(0,c.useRef)(null),S=(0,c.useRef)(null),[C,w]=(0,c.useState)(null);(0,c.useEffect)(()=>{x.current?.scrollIntoView({behavior:`smooth`})},[y,_,i,o]),(0,c.useEffect)(()=>{i&&!o&&S.current?.focus()},[i,o]);let T=process.env.NEXT_PUBLIC_API_URL;if(!T||!e)return``;async function E(t=h){let n=t.trim();if(!n||_)return;let r=(0,u.default)().format(`HH:mm`);b(e=>[...e,{id:Date.now(),role:`user`,text:n,time:r}]),g(``),v(!0),w(null);try{let t;if(T){let r;try{r=await fetch(T,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({message:n,key:e})})}catch(e){throw w(`Failed to fetch.
2
-
3
- Possible Reasons:
4
-
5
- - CORS
6
- - Network Failure
7
- - URL scheme must be "http" or "https" for CORS request.`),e}if(!r.ok)throw w(`Failed to fetch.\n\nPossible Reasons:\n\n- CORS\n- Network Failure\n- URL scheme must be "http" or "https" for CORS request.\n\nChat API returned ${r.status}`),Error(`Chat API returned ${r.status}`);let i=await r.json();t=i.reply??i.response??i.message??`I received a response, but it did not include a reply field.`}else await new Promise(e=>setTimeout(e,700)),t=m(n);b(e=>[...e,{id:Date.now()+1,role:`assistant`,text:t,time:(0,u.default)().format(`HH:mm`)}])}catch{b(e=>[...e,{id:Date.now()+1,role:`assistant`,text:C||`Sorry, I couldn't reach the chat service. Please try again.`,time:(0,u.default)().format(`HH:mm`)}])}finally{v(!1)}}return(0,d.jsxs)(`div`,{className:`acw-root`,style:{"--acw-primary":r},children:[i&&(0,d.jsxs)(`section`,{className:`acw-panel ${o?`acw-minimized`:``}`,"aria-label":`AI chat assistant`,children:[(0,d.jsxs)(`header`,{className:`acw-header`,children:[(0,d.jsx)(`div`,{className:`acw-brand-icon`,children:(0,d.jsx)(l.Bot,{size:23})}),(0,d.jsxs)(`div`,{className:`acw-heading`,children:[(0,d.jsx)(`h2`,{children:t}),(0,d.jsxs)(`p`,{children:[(0,d.jsx)(`span`,{className:`acw-online-dot`}),n]})]}),(0,d.jsx)(`button`,{className:`acw-header-button`,onClick:()=>s(!o),"aria-label":`Minimize chat`,children:(0,d.jsx)(l.Minimize2,{size:17})}),(0,d.jsx)(`button`,{className:`acw-header-button`,onClick:()=>a(!1),"aria-label":`Close chat`,children:(0,d.jsx)(l.X,{size:19})})]}),!o&&(0,d.jsxs)(d.Fragment,{children:[(0,d.jsxs)(`div`,{className:`acw-messages`,children:[y.map((e,t)=>(0,d.jsxs)(`div`,{className:`acw-message-row ${e.role===`user`?`acw-user-row`:``}`,children:[e.role===`assistant`&&(0,d.jsx)(`div`,{className:`acw-avatar acw-bot-avatar`,children:(0,d.jsx)(l.Bot,{size:17})}),(0,d.jsxs)(`div`,{className:`acw-message-content`,children:[(0,d.jsx)(`div`,{className:`acw-bubble ${e.role===`user`?`acw-user-bubble`:`acw-assistant-bubble`}`,children:e.text.split(`
8
- `).map((t,n)=>(0,d.jsxs)(`span`,{children:[t,n<e.text.split(`
9
- `).length-1&&(0,d.jsx)(`br`,{})]},n))}),(0,d.jsx)(`span`,{className:`acw-time`,children:e.time})]}),e.role===`user`&&(0,d.jsx)(`div`,{className:`acw-avatar acw-user-avatar`,children:(0,d.jsx)(l.User,{size:17})})]},e.id)),_&&(0,d.jsxs)(`div`,{className:`acw-message-row`,children:[(0,d.jsx)(`div`,{className:`acw-avatar acw-bot-avatar`,children:(0,d.jsx)(l.Bot,{size:17})}),(0,d.jsxs)(`div`,{className:`acw-typing`,"aria-label":`Assistant is typing`,children:[(0,d.jsx)(`span`,{}),(0,d.jsx)(`span`,{}),(0,d.jsx)(`span`,{})]})]}),(0,d.jsx)(`div`,{ref:x})]}),y.length===1&&(0,d.jsxs)(`div`,{className:`acw-suggestions`,children:[(0,d.jsxs)(`p`,{children:[(0,d.jsx)(l.Sparkles,{size:13}),` Suggested questions`]}),(0,d.jsx)(`div`,{className:`acw-suggestion-list`,children:f.map(e=>(0,d.jsx)(`button`,{onClick:()=>void E(e),children:e},e))})]}),(0,d.jsxs)(`form`,{className:`acw-composer`,onSubmit:e=>{e.preventDefault(),E()},children:[(0,d.jsx)(`input`,{ref:S,value:h,onChange:e=>g(e.target.value),placeholder:`Type your message...`,"aria-label":`Type your message`}),(0,d.jsx)(`button`,{type:`submit`,disabled:!h.trim()||_,"aria-label":`Send message`,children:(0,d.jsx)(l.Send,{size:18})})]}),(0,d.jsx)(`p`,{className:`acw-footer`,children:T?`Powered by your AI service`:`Demo mode · Connect your AI API`})]})]}),(0,d.jsxs)(`button`,{className:`acw-launcher`,onClick:()=>{a(!i),s(!1)},"aria-label":i?`Close chat widget`:`Open chat widget`,"aria-expanded":i,children:[!i&&(0,d.jsx)(`span`,{className:`acw-notification-dot`}),i?(0,d.jsx)(l.X,{size:25}):(0,d.jsx)(l.MessageCircle,{size:26})]})]})}exports.ChatWidget=h;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t,t.exports),e=null),t.exports),s=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},c=(n,r,o)=>(o=n==null?{}:e(i(n)),s(r||!n||!n.__esModule||!a.call(n,`default`)?t(o,`default`,{value:n,enumerable:!0}):o,n));let l=require("react"),u=require("react/jsx-runtime");var d=e=>e.replace(/([a-z0-9])([A-Z])/g,`$1-$2`).toLowerCase(),f=e=>e.replace(/^([A-Z])|[\s-_]+(\w)/g,(e,t,n)=>n?n.toUpperCase():t.toLowerCase()),p=e=>{let t=f(e);return t.charAt(0).toUpperCase()+t.slice(1)},m=(...e)=>e.filter((e,t,n)=>!!e&&e.trim()!==``&&n.indexOf(e)===t).join(` `).trim(),h=e=>{for(let t in e)if(t.startsWith(`aria-`)||t===`role`||t===`title`)return!0},g={xmlns:`http://www.w3.org/2000/svg`,width:24,height:24,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:2,strokeLinecap:`round`,strokeLinejoin:`round`},_=(0,l.forwardRef)(({color:e=`currentColor`,size:t=24,strokeWidth:n=2,absoluteStrokeWidth:r,className:i=``,children:a,iconNode:o,...s},c)=>(0,l.createElement)(`svg`,{ref:c,...g,width:t,height:t,stroke:e,strokeWidth:r?Number(n)*24/Number(t):n,className:m(`lucide`,i),...!a&&!h(s)&&{"aria-hidden":`true`},...s},[...o.map(([e,t])=>(0,l.createElement)(e,t)),...Array.isArray(a)?a:[a]])),v=(e,t)=>{let n=(0,l.forwardRef)(({className:n,...r},i)=>(0,l.createElement)(_,{ref:i,iconNode:t,className:m(`lucide-${d(p(e))}`,`lucide-${e}`,n),...r}));return n.displayName=p(e),n},y=v(`bot`,[[`path`,{d:`M12 8V4H8`,key:`hb8ula`}],[`rect`,{width:`16`,height:`12`,x:`4`,y:`8`,rx:`2`,key:`enze0r`}],[`path`,{d:`M2 14h2`,key:`vft8re`}],[`path`,{d:`M20 14h2`,key:`4cs60a`}],[`path`,{d:`M15 13v2`,key:`1xurst`}],[`path`,{d:`M9 13v2`,key:`rq6x2g`}]]),b=v(`message-circle`,[[`path`,{d:`M7.9 20A9 9 0 1 0 4 16.1L2 22Z`,key:`vv11sd`}]]),x=v(`minimize-2`,[[`path`,{d:`m14 10 7-7`,key:`oa77jy`}],[`path`,{d:`M20 10h-6V4`,key:`mjg0md`}],[`path`,{d:`m3 21 7-7`,key:`tjx5ai`}],[`path`,{d:`M4 14h6v6`,key:`rmj7iw`}]]),S=v(`send`,[[`path`,{d:`M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z`,key:`1ffxy3`}],[`path`,{d:`m21.854 2.147-10.94 10.939`,key:`12cjpa`}]]),C=v(`sparkles`,[[`path`,{d:`M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z`,key:`4pj2yx`}],[`path`,{d:`M20 3v4`,key:`1olli1`}],[`path`,{d:`M22 5h-4`,key:`1gvqau`}],[`path`,{d:`M4 17v2`,key:`vumght`}],[`path`,{d:`M5 18H3`,key:`zchphs`}]]),w=v(`user`,[[`path`,{d:`M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2`,key:`975kel`}],[`circle`,{cx:`12`,cy:`7`,r:`4`,key:`17ys0d`}]]),T=v(`x`,[[`path`,{d:`M18 6 6 18`,key:`1bl5f8`}],[`path`,{d:`m6 6 12 12`,key:`d8bk6v`}]]),E=c(o(((e,t,n)=>{(function(n,r){typeof e==`object`&&t!==void 0?t.exports=r():typeof define==`function`&&define.amd?define(r):(n=typeof globalThis<`u`?globalThis:n||self).dayjs=r()})(n,(function(){"use strict";var e=1e3,t=6e4,n=36e5,r=`millisecond`,i=`second`,a=`minute`,o=`hour`,s=`day`,c=`week`,l=`month`,u=`quarter`,d=`year`,f=`date`,p=`Invalid Date`,m=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,h=/\[([^\]]+)]|YYYY|YY|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,g={name:`en`,weekdays:`Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday`.split(`_`),months:`January_February_March_April_May_June_July_August_September_October_November_December`.split(`_`),ordinal:function(e){var t=[`th`,`st`,`nd`,`rd`],n=e%100;return`[`+e+(t[(n-20)%10]||t[n]||t[0])+`]`}},_=function(e,t,n){var r=String(e);return!r||r.length>=t?e:``+Array(t+1-r.length).join(n)+e},v={s:_,z:function(e){var t=-e.utcOffset(),n=Math.abs(t),r=Math.floor(n/60),i=n%60;return(t<=0?`+`:`-`)+_(r,2,`0`)+`:`+_(i,2,`0`)},m:function e(t,n){if(t.date()<n.date())return-e(n,t);var r=12*(n.year()-t.year())+(n.month()-t.month()),i=t.clone().add(r,l),a=n-i<0,o=t.clone().add(r+(a?-1:1),l);return+(-(r+(n-i)/(a?i-o:o-i))||0)},a:function(e){return e<0?Math.ceil(e)||0:Math.floor(e)},p:function(e){return{M:l,y:d,w:c,d:s,D:f,h:o,m:a,s:i,ms:r,Q:u}[e]||String(e||``).toLowerCase().replace(/s$/,``)},u:function(e){return e===void 0}},y=`en`,b={};b[y]=g;var x=`$isDayjsObject`,S=function(e){return e instanceof E||!(!e||!e[x])},C=function e(t,n,r){var i;if(!t)return y;if(typeof t==`string`){var a=t.toLowerCase();b[a]&&(i=a),n&&(b[a]=n,i=a);var o=t.split(`-`);if(!i&&o.length>1)return e(o[0])}else{var s=t.name;b[s]=t,i=s}return!r&&i&&(y=i),i||!r&&y},w=function(e,t){if(S(e))return e.clone();var n=typeof t==`object`?t:{};return n.date=e,n.args=arguments,new E(n)},T=v;T.l=C,T.i=S,T.w=function(e,t){return w(e,{locale:t.$L,utc:t.$u,x:t.$x,$offset:t.$offset})};var E=function(){function g(e){this.$L=C(e.locale,null,!0),this.parse(e),this.$x=this.$x||e.x||{},this[x]=!0}var _=g.prototype;return _.parse=function(e){this.$d=function(e){var t=e.date,n=e.utc;if(t===null)return new Date(NaN);if(T.u(t))return new Date;if(t instanceof Date)return new Date(t);if(typeof t==`string`&&!/Z$/i.test(t)){var r=t.match(m);if(r){var i=r[2]-1||0,a=(r[7]||`0`).substring(0,3);return n?new Date(Date.UTC(r[1],i,r[3]||1,r[4]||0,r[5]||0,r[6]||0,a)):new Date(r[1],i,r[3]||1,r[4]||0,r[5]||0,r[6]||0,a)}}return new Date(t)}(e),this.init()},_.init=function(){var e=this.$d;this.$y=e.getFullYear(),this.$M=e.getMonth(),this.$D=e.getDate(),this.$W=e.getDay(),this.$H=e.getHours(),this.$m=e.getMinutes(),this.$s=e.getSeconds(),this.$ms=e.getMilliseconds()},_.$utils=function(){return T},_.isValid=function(){return this.$d.toString()!==p},_.isSame=function(e,t){var n=w(e);return this.startOf(t)<=n&&n<=this.endOf(t)},_.isAfter=function(e,t){return w(e)<this.startOf(t)},_.isBefore=function(e,t){return this.endOf(t)<w(e)},_.$g=function(e,t,n){return T.u(e)?this[t]:this.set(n,e)},_.unix=function(){return Math.floor(this.valueOf()/1e3)},_.valueOf=function(){return this.$d.getTime()},_.startOf=function(e,t){var n=this,r=!!T.u(t)||t,u=T.p(e),p=function(e,t){var i=T.w(n.$u?Date.UTC(n.$y,t,e):new Date(n.$y,t,e),n);return r?i:i.endOf(s)},m=function(e,t){return T.w(n.toDate()[e].apply(n.toDate(`s`),(r?[0,0,0,0]:[23,59,59,999]).slice(t)),n)},h=this.$W,g=this.$M,_=this.$D,v=`set`+(this.$u?`UTC`:``);switch(u){case d:return r?p(1,0):p(31,11);case l:return r?p(1,g):p(0,g+1);case c:var y=this.$locale().weekStart||0,b=(h<y?h+7:h)-y;return p(r?_-b:_+(6-b),g);case s:case f:return m(v+`Hours`,0);case o:return m(v+`Minutes`,1);case a:return m(v+`Seconds`,2);case i:return m(v+`Milliseconds`,3);default:return this.clone()}},_.endOf=function(e){return this.startOf(e,!1)},_.$set=function(e,t){var n,c=T.p(e),u=`set`+(this.$u?`UTC`:``),p=(n={},n[s]=u+`Date`,n[f]=u+`Date`,n[l]=u+`Month`,n[d]=u+`FullYear`,n[o]=u+`Hours`,n[a]=u+`Minutes`,n[i]=u+`Seconds`,n[r]=u+`Milliseconds`,n)[c],m=c===s?this.$D+(t-this.$W):t;if(c===l||c===d){var h=this.clone().set(f,1);h.$d[p](m),h.init(),this.$d=h.set(f,Math.min(this.$D,h.daysInMonth())).$d}else p&&this.$d[p](m);return this.init(),this},_.set=function(e,t){return this.clone().$set(e,t)},_.get=function(e){return this[T.p(e)]()},_.add=function(r,u){var f,p=this;r=Number(r);var m=T.p(u),h=function(e){var t=w(p);return T.w(t.date(t.date()+Math.round(e*r)),p)};if(m===l)return this.set(l,this.$M+r);if(m===d)return this.set(d,this.$y+r);if(m===s)return h(1);if(m===c)return h(7);var g=(f={},f[a]=t,f[o]=n,f[i]=e,f)[m]||1,_=this.$d.getTime()+r*g;return T.w(_,this)},_.subtract=function(e,t){return this.add(-1*e,t)},_.format=function(e){var t=this,n=this.$locale();if(!this.isValid())return n.invalidDate||p;var r=e||`YYYY-MM-DDTHH:mm:ssZ`,i=T.z(this),a=this.$H,o=this.$m,s=this.$M,c=n.weekdays,l=n.months,u=n.meridiem,d=function(e,n,i,a){return e&&(e[n]||e(t,r))||i[n].slice(0,a)},f=function(e){return T.s(a%12||12,e,`0`)},m=u||function(e,t,n){var r=e<12?`AM`:`PM`;return n?r.toLowerCase():r};return r.replace(h,(function(e,r){return r||function(e){switch(e){case`YY`:return String(t.$y).slice(-2);case`YYYY`:return T.s(t.$y,4,`0`);case`M`:return s+1;case`MM`:return T.s(s+1,2,`0`);case`MMM`:return d(n.monthsShort,s,l,3);case`MMMM`:return d(l,s);case`D`:return t.$D;case`DD`:return T.s(t.$D,2,`0`);case`d`:return String(t.$W);case`dd`:return d(n.weekdaysMin,t.$W,c,2);case`ddd`:return d(n.weekdaysShort,t.$W,c,3);case`dddd`:return c[t.$W];case`H`:return String(a);case`HH`:return T.s(a,2,`0`);case`h`:return f(1);case`hh`:return f(2);case`a`:return m(a,o,!0);case`A`:return m(a,o,!1);case`m`:return String(o);case`mm`:return T.s(o,2,`0`);case`s`:return String(t.$s);case`ss`:return T.s(t.$s,2,`0`);case`SSS`:return T.s(t.$ms,3,`0`);case`Z`:return i}return null}(e)||i.replace(`:`,``)}))},_.utcOffset=function(){return 15*-Math.round(this.$d.getTimezoneOffset()/15)},_.diff=function(r,f,p){var m,h=this,g=T.p(f),_=w(r),v=(_.utcOffset()-this.utcOffset())*t,y=this-_,b=function(){return T.m(h,_)};switch(g){case d:m=b()/12;break;case l:m=b();break;case u:m=b()/3;break;case c:m=(y-v)/6048e5;break;case s:m=(y-v)/864e5;break;case o:m=y/n;break;case a:m=y/t;break;case i:m=y/e;break;default:m=y}return p?m:T.a(m)},_.daysInMonth=function(){return this.endOf(l).$D},_.$locale=function(){return b[this.$L]},_.locale=function(e,t){if(!e)return this.$L;var n=this.clone(),r=C(e,t,!0);return r&&(n.$L=r),n},_.clone=function(){return T.w(this.$d,this)},_.toDate=function(){return new Date(this.valueOf())},_.toJSON=function(){return this.isValid()?this.toISOString():null},_.toISOString=function(){return this.$d.toISOString()},_.toString=function(){return this.$d.toUTCString()},g}(),D=E.prototype;return w.prototype=D,[[`$ms`,r],[`$s`,i],[`$m`,a],[`$H`,o],[`$W`,s],[`$M`,l],[`$y`,d],[`$D`,f]].forEach((function(e){D[e[1]]=function(t){return this.$g(t,e[0],e[1])}})),w.extend=function(e,t){return e.$i||=(e(t,E,w),!0),w},w.locale=C,w.isDayjs=S,w.unix=function(e){return w(1e3*e)},w.en=b[y],w.Ls=b,w.p={},w}))}))()),D=[`Check vehicle status`,`Schedule maintenance`,`Pricing information`],O=[{id:1,role:`assistant`,text:`Hello! 👋 I'm your AI assistant. How can I help you today?`,time:`Just now`}];function k(e){let t=e.toLowerCase();return t.includes(`vehicle`)||t.includes(`status`)?`I can help check vehicle status. Please provide the vehicle number plate, such as VDR6117.`:t.includes(`maintenance`)||t.includes(`repair`)?`I can help with maintenance! Please describe the vehicle issue, and I'll suggest the next steps.`:t.includes(`price`)||t.includes(`cost`)?`Pricing depends on your requirements. Tell me which service you're interested in, and I'll help estimate the cost.`:t.includes(`hello`)||t.includes(`hi`)?`Hello! 😊 What would you like help with today?`:`Thanks for your message: "${e}". This is a demo response. Configure apiUrl to connect your AI backend.`}function A({apiKey:e,apiUrl:t=`http://localhost:8000`,title:n=`AI Assistant`,subtitle:r=`Online · Ready to help`,primaryColor:i=`#2563eb`}){let[a,o]=(0,l.useState)(!1),[s,c]=(0,l.useState)(!1),[d,f]=(0,l.useState)(``),[p,m]=(0,l.useState)(!1),[h,g]=(0,l.useState)(O),_=(0,l.useRef)(null),v=(0,l.useRef)(null),[A,j]=(0,l.useState)(null);if((0,l.useEffect)(()=>{_.current?.scrollIntoView({behavior:`smooth`})},[h,p,a,s]),(0,l.useEffect)(()=>{a&&!s&&v.current?.focus()},[a,s]),console.log(t,e,`dinesh1`),!e)return null;async function M(n=d){let r=n.trim();if(!r||p)return;let i=(0,E.default)().format(`HH:mm`);g(e=>[...e,{id:Date.now(),role:`user`,text:r,time:i}]),f(``),m(!0),j(null);try{let n;if(t){let i;try{i=await fetch(t+`/chats`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({title:r,key:e})})}catch(e){throw j(`Failed to fetch.\n\nPossible Reasons:\n\n- CORS\n- Network Failure\n- URL scheme must be "http" or "https" for CORS request.\n\nError: ${e instanceof Error?e.message:String(e)}`),e}if(!i.ok)throw j(`Failed to fetch.\n\nPossible Reasons:\n\n- CORS\n- Network Failure\n- URL scheme must be "http" or "https" for CORS request.\n\nChat API returned ${i.status}`),Error(`Chat API returned ${i.status}`);let a=await i.json();n=a.reply??a.response??a.message??`I received a response, but it did not include a reply field.`}else await new Promise(e=>setTimeout(e,700)),n=k(r);g(e=>[...e,{id:Date.now()+1,role:`assistant`,text:n,time:(0,E.default)().format(`HH:mm`)}])}catch{g(e=>[...e,{id:Date.now()+1,role:`assistant`,text:A||`Sorry, I couldn't reach the chat service. Please try again.`,time:(0,E.default)().format(`HH:mm`)}])}finally{m(!1)}}return(0,u.jsxs)(`div`,{className:`acw-root`,style:{"--acw-primary":i},children:[a&&(0,u.jsxs)(`section`,{className:`acw-panel ${s?`acw-minimized`:``}`,"aria-label":`AI chat assistant`,children:[(0,u.jsxs)(`header`,{className:`acw-header`,children:[(0,u.jsx)(`div`,{className:`acw-brand-icon`,children:(0,u.jsx)(y,{size:23})}),(0,u.jsxs)(`div`,{className:`acw-heading`,children:[(0,u.jsx)(`h2`,{children:n}),(0,u.jsxs)(`p`,{children:[(0,u.jsx)(`span`,{className:`acw-online-dot`}),r]})]}),(0,u.jsx)(`button`,{className:`acw-header-button`,onClick:()=>c(!s),"aria-label":`Minimize chat`,children:(0,u.jsx)(x,{size:17})}),(0,u.jsx)(`button`,{className:`acw-header-button`,onClick:()=>o(!1),"aria-label":`Close chat`,children:(0,u.jsx)(T,{size:19})})]}),!s&&(0,u.jsxs)(u.Fragment,{children:[(0,u.jsxs)(`div`,{className:`acw-messages`,children:[h.map((e,t)=>(0,u.jsxs)(`div`,{className:`acw-message-row ${e.role===`user`?`acw-user-row`:``}`,children:[e.role===`assistant`&&(0,u.jsx)(`div`,{className:`acw-avatar acw-bot-avatar`,children:(0,u.jsx)(y,{size:17})}),(0,u.jsxs)(`div`,{className:`acw-message-content`,children:[(0,u.jsx)(`div`,{className:`acw-bubble ${e.role===`user`?`acw-user-bubble`:`acw-assistant-bubble`}`,children:e.text.split(`
2
+ `).map((t,n)=>(0,u.jsxs)(`span`,{children:[t,n<e.text.split(`
3
+ `).length-1&&(0,u.jsx)(`br`,{})]},n))}),(0,u.jsx)(`span`,{className:`acw-time`,children:e.time})]}),e.role===`user`&&(0,u.jsx)(`div`,{className:`acw-avatar acw-user-avatar`,children:(0,u.jsx)(w,{size:17})})]},e.id)),p&&(0,u.jsxs)(`div`,{className:`acw-message-row`,children:[(0,u.jsx)(`div`,{className:`acw-avatar acw-bot-avatar`,children:(0,u.jsx)(y,{size:17})}),(0,u.jsxs)(`div`,{className:`acw-typing`,"aria-label":`Assistant is typing`,children:[(0,u.jsx)(`span`,{}),(0,u.jsx)(`span`,{}),(0,u.jsx)(`span`,{})]})]}),(0,u.jsx)(`div`,{ref:_})]}),h.length===1&&(0,u.jsxs)(`div`,{className:`acw-suggestions`,children:[(0,u.jsxs)(`p`,{children:[(0,u.jsx)(C,{size:13}),` Suggested questions`]}),(0,u.jsx)(`div`,{className:`acw-suggestion-list`,children:D.map(e=>(0,u.jsx)(`button`,{onClick:()=>void M(e),children:e},e))})]}),(0,u.jsxs)(`form`,{className:`acw-composer`,onSubmit:e=>{e.preventDefault(),M()},children:[(0,u.jsx)(`input`,{ref:v,value:d,onChange:e=>f(e.target.value),placeholder:`Type your message...`,"aria-label":`Type your message`}),(0,u.jsx)(`button`,{type:`submit`,disabled:!d.trim()||p,"aria-label":`Send message`,children:(0,u.jsx)(S,{size:18})})]}),(0,u.jsx)(`p`,{className:`acw-footer`,children:t?`Powered by your AI service`:`Demo mode · Connect your AI API`})]})]}),(0,u.jsxs)(`button`,{className:`acw-launcher`,onClick:()=>{o(!a),c(!1)},"aria-label":a?`Close chat widget`:`Open chat widget`,"aria-expanded":a,children:[!a&&(0,u.jsx)(`span`,{className:`acw-notification-dot`}),a?(0,u.jsx)(T,{size:25}):(0,u.jsx)(b,{size:26})]})]})}exports.ChatWidget=A;
package/dist/index.js CHANGED
@@ -1,200 +1,622 @@
1
- import { useEffect as e, useRef as t, useState as n } from "react";
2
- import { Bot as r, MessageCircle as i, Minimize2 as a, Send as o, Sparkles as s, User as c, X as l } from "lucide-react";
3
- import u from "dayjs";
4
- import { Fragment as d, jsx as f, jsxs as p } from "react/jsx-runtime";
5
- // src/ChatWidget.tsx
6
- var m = [
1
+ import { createElement as e, forwardRef as t, useEffect as n, useRef as r, useState as i } from "react";
2
+ import { Fragment as a, jsx as o, jsxs as s } from "react/jsx-runtime";
3
+ // \0rolldown/runtime.js
4
+ var c = Object.create, l = Object.defineProperty, u = Object.getOwnPropertyDescriptor, d = Object.getOwnPropertyNames, f = Object.getPrototypeOf, p = Object.prototype.hasOwnProperty, m = (e, t) => () => (t || (e((t = { exports: {} }).exports, t, t.exports), e = null), t.exports), h = (e, t, n, r) => {
5
+ if (t && typeof t == "object" || typeof t == "function") for (var i = d(t), a = 0, o = i.length, s; a < o; a++) s = i[a], !p.call(e, s) && s !== n && l(e, s, {
6
+ get: ((e) => t[e]).bind(null, s),
7
+ enumerable: !(r = u(t, s)) || r.enumerable
8
+ });
9
+ return e;
10
+ }, g = (e, t, n) => (n = e == null ? {} : c(f(e)), h(t || !e || !e.__esModule || !p.call(e, "default") ? l(n, "default", {
11
+ value: e,
12
+ enumerable: !0
13
+ }) : n, e)), _ = (e) => e.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(), v = (e) => e.replace(/^([A-Z])|[\s-_]+(\w)/g, (e, t, n) => n ? n.toUpperCase() : t.toLowerCase()), y = (e) => {
14
+ let t = v(e);
15
+ return t.charAt(0).toUpperCase() + t.slice(1);
16
+ }, b = (...e) => e.filter((e, t, n) => !!e && e.trim() !== "" && n.indexOf(e) === t).join(" ").trim(), x = (e) => {
17
+ for (let t in e) if (t.startsWith("aria-") || t === "role" || t === "title") return !0;
18
+ }, S = {
19
+ xmlns: "http://www.w3.org/2000/svg",
20
+ width: 24,
21
+ height: 24,
22
+ viewBox: "0 0 24 24",
23
+ fill: "none",
24
+ stroke: "currentColor",
25
+ strokeWidth: 2,
26
+ strokeLinecap: "round",
27
+ strokeLinejoin: "round"
28
+ }, C = t(({ color: t = "currentColor", size: n = 24, strokeWidth: r = 2, absoluteStrokeWidth: i, className: a = "", children: o, iconNode: s, ...c }, l) => e("svg", {
29
+ ref: l,
30
+ ...S,
31
+ width: n,
32
+ height: n,
33
+ stroke: t,
34
+ strokeWidth: i ? Number(r) * 24 / Number(n) : r,
35
+ className: b("lucide", a),
36
+ ...!o && !x(c) && { "aria-hidden": "true" },
37
+ ...c
38
+ }, [...s.map(([t, n]) => e(t, n)), ...Array.isArray(o) ? o : [o]])), w = (n, r) => {
39
+ let i = t(({ className: t, ...i }, a) => e(C, {
40
+ ref: a,
41
+ iconNode: r,
42
+ className: b(`lucide-${_(y(n))}`, `lucide-${n}`, t),
43
+ ...i
44
+ }));
45
+ return i.displayName = y(n), i;
46
+ }, T = w("bot", [
47
+ ["path", {
48
+ d: "M12 8V4H8",
49
+ key: "hb8ula"
50
+ }],
51
+ ["rect", {
52
+ width: "16",
53
+ height: "12",
54
+ x: "4",
55
+ y: "8",
56
+ rx: "2",
57
+ key: "enze0r"
58
+ }],
59
+ ["path", {
60
+ d: "M2 14h2",
61
+ key: "vft8re"
62
+ }],
63
+ ["path", {
64
+ d: "M20 14h2",
65
+ key: "4cs60a"
66
+ }],
67
+ ["path", {
68
+ d: "M15 13v2",
69
+ key: "1xurst"
70
+ }],
71
+ ["path", {
72
+ d: "M9 13v2",
73
+ key: "rq6x2g"
74
+ }]
75
+ ]), E = w("message-circle", [["path", {
76
+ d: "M7.9 20A9 9 0 1 0 4 16.1L2 22Z",
77
+ key: "vv11sd"
78
+ }]]), D = w("minimize-2", [
79
+ ["path", {
80
+ d: "m14 10 7-7",
81
+ key: "oa77jy"
82
+ }],
83
+ ["path", {
84
+ d: "M20 10h-6V4",
85
+ key: "mjg0md"
86
+ }],
87
+ ["path", {
88
+ d: "m3 21 7-7",
89
+ key: "tjx5ai"
90
+ }],
91
+ ["path", {
92
+ d: "M4 14h6v6",
93
+ key: "rmj7iw"
94
+ }]
95
+ ]), O = w("send", [["path", {
96
+ d: "M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z",
97
+ key: "1ffxy3"
98
+ }], ["path", {
99
+ d: "m21.854 2.147-10.94 10.939",
100
+ key: "12cjpa"
101
+ }]]), k = w("sparkles", [
102
+ ["path", {
103
+ d: "M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z",
104
+ key: "4pj2yx"
105
+ }],
106
+ ["path", {
107
+ d: "M20 3v4",
108
+ key: "1olli1"
109
+ }],
110
+ ["path", {
111
+ d: "M22 5h-4",
112
+ key: "1gvqau"
113
+ }],
114
+ ["path", {
115
+ d: "M4 17v2",
116
+ key: "vumght"
117
+ }],
118
+ ["path", {
119
+ d: "M5 18H3",
120
+ key: "zchphs"
121
+ }]
122
+ ]), A = w("user", [["path", {
123
+ d: "M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2",
124
+ key: "975kel"
125
+ }], ["circle", {
126
+ cx: "12",
127
+ cy: "7",
128
+ r: "4",
129
+ key: "17ys0d"
130
+ }]]), j = w("x", [["path", {
131
+ d: "M18 6 6 18",
132
+ key: "1bl5f8"
133
+ }], ["path", {
134
+ d: "m6 6 12 12",
135
+ key: "d8bk6v"
136
+ }]]), M = /* @__PURE__ */ g((/* @__PURE__ */ m(((e, t, n) => {
137
+ (function(n, r) {
138
+ typeof e == "object" && t !== void 0 ? t.exports = r() : typeof define == "function" && define.amd ? define(r) : (n = typeof globalThis < "u" ? globalThis : n || self).dayjs = r();
139
+ })(n, (function() {
140
+ var e = 1e3, t = 6e4, n = 36e5, r = "millisecond", i = "second", a = "minute", o = "hour", s = "day", c = "week", l = "month", u = "quarter", d = "year", f = "date", p = "Invalid Date", m = /^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/, h = /\[([^\]]+)]|YYYY|YY|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g, g = {
141
+ name: "en",
142
+ weekdays: "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),
143
+ months: "January_February_March_April_May_June_July_August_September_October_November_December".split("_"),
144
+ ordinal: function(e) {
145
+ var t = [
146
+ "th",
147
+ "st",
148
+ "nd",
149
+ "rd"
150
+ ], n = e % 100;
151
+ return "[" + e + (t[(n - 20) % 10] || t[n] || t[0]) + "]";
152
+ }
153
+ }, _ = function(e, t, n) {
154
+ var r = String(e);
155
+ return !r || r.length >= t ? e : "" + Array(t + 1 - r.length).join(n) + e;
156
+ }, v = {
157
+ s: _,
158
+ z: function(e) {
159
+ var t = -e.utcOffset(), n = Math.abs(t), r = Math.floor(n / 60), i = n % 60;
160
+ return (t <= 0 ? "+" : "-") + _(r, 2, "0") + ":" + _(i, 2, "0");
161
+ },
162
+ m: function e(t, n) {
163
+ if (t.date() < n.date()) return -e(n, t);
164
+ var r = 12 * (n.year() - t.year()) + (n.month() - t.month()), i = t.clone().add(r, l), a = n - i < 0, o = t.clone().add(r + (a ? -1 : 1), l);
165
+ return +(-(r + (n - i) / (a ? i - o : o - i)) || 0);
166
+ },
167
+ a: function(e) {
168
+ return e < 0 ? Math.ceil(e) || 0 : Math.floor(e);
169
+ },
170
+ p: function(e) {
171
+ return {
172
+ M: l,
173
+ y: d,
174
+ w: c,
175
+ d: s,
176
+ D: f,
177
+ h: o,
178
+ m: a,
179
+ s: i,
180
+ ms: r,
181
+ Q: u
182
+ }[e] || String(e || "").toLowerCase().replace(/s$/, "");
183
+ },
184
+ u: function(e) {
185
+ return e === void 0;
186
+ }
187
+ }, y = "en", b = {};
188
+ b[y] = g;
189
+ var x = "$isDayjsObject", S = function(e) {
190
+ return e instanceof E || !(!e || !e[x]);
191
+ }, C = function e(t, n, r) {
192
+ var i;
193
+ if (!t) return y;
194
+ if (typeof t == "string") {
195
+ var a = t.toLowerCase();
196
+ b[a] && (i = a), n && (b[a] = n, i = a);
197
+ var o = t.split("-");
198
+ if (!i && o.length > 1) return e(o[0]);
199
+ } else {
200
+ var s = t.name;
201
+ b[s] = t, i = s;
202
+ }
203
+ return !r && i && (y = i), i || !r && y;
204
+ }, w = function(e, t) {
205
+ if (S(e)) return e.clone();
206
+ var n = typeof t == "object" ? t : {};
207
+ return n.date = e, n.args = arguments, new E(n);
208
+ }, T = v;
209
+ T.l = C, T.i = S, T.w = function(e, t) {
210
+ return w(e, {
211
+ locale: t.$L,
212
+ utc: t.$u,
213
+ x: t.$x,
214
+ $offset: t.$offset
215
+ });
216
+ };
217
+ var E = function() {
218
+ function g(e) {
219
+ this.$L = C(e.locale, null, !0), this.parse(e), this.$x = this.$x || e.x || {}, this[x] = !0;
220
+ }
221
+ var _ = g.prototype;
222
+ return _.parse = function(e) {
223
+ this.$d = function(e) {
224
+ var t = e.date, n = e.utc;
225
+ if (t === null) return /* @__PURE__ */ new Date(NaN);
226
+ if (T.u(t)) return /* @__PURE__ */ new Date();
227
+ if (t instanceof Date) return new Date(t);
228
+ if (typeof t == "string" && !/Z$/i.test(t)) {
229
+ var r = t.match(m);
230
+ if (r) {
231
+ var i = r[2] - 1 || 0, a = (r[7] || "0").substring(0, 3);
232
+ return n ? new Date(Date.UTC(r[1], i, r[3] || 1, r[4] || 0, r[5] || 0, r[6] || 0, a)) : new Date(r[1], i, r[3] || 1, r[4] || 0, r[5] || 0, r[6] || 0, a);
233
+ }
234
+ }
235
+ return new Date(t);
236
+ }(e), this.init();
237
+ }, _.init = function() {
238
+ var e = this.$d;
239
+ this.$y = e.getFullYear(), this.$M = e.getMonth(), this.$D = e.getDate(), this.$W = e.getDay(), this.$H = e.getHours(), this.$m = e.getMinutes(), this.$s = e.getSeconds(), this.$ms = e.getMilliseconds();
240
+ }, _.$utils = function() {
241
+ return T;
242
+ }, _.isValid = function() {
243
+ return this.$d.toString() !== p;
244
+ }, _.isSame = function(e, t) {
245
+ var n = w(e);
246
+ return this.startOf(t) <= n && n <= this.endOf(t);
247
+ }, _.isAfter = function(e, t) {
248
+ return w(e) < this.startOf(t);
249
+ }, _.isBefore = function(e, t) {
250
+ return this.endOf(t) < w(e);
251
+ }, _.$g = function(e, t, n) {
252
+ return T.u(e) ? this[t] : this.set(n, e);
253
+ }, _.unix = function() {
254
+ return Math.floor(this.valueOf() / 1e3);
255
+ }, _.valueOf = function() {
256
+ return this.$d.getTime();
257
+ }, _.startOf = function(e, t) {
258
+ var n = this, r = !!T.u(t) || t, u = T.p(e), p = function(e, t) {
259
+ var i = T.w(n.$u ? Date.UTC(n.$y, t, e) : new Date(n.$y, t, e), n);
260
+ return r ? i : i.endOf(s);
261
+ }, m = function(e, t) {
262
+ return T.w(n.toDate()[e].apply(n.toDate("s"), (r ? [
263
+ 0,
264
+ 0,
265
+ 0,
266
+ 0
267
+ ] : [
268
+ 23,
269
+ 59,
270
+ 59,
271
+ 999
272
+ ]).slice(t)), n);
273
+ }, h = this.$W, g = this.$M, _ = this.$D, v = "set" + (this.$u ? "UTC" : "");
274
+ switch (u) {
275
+ case d: return r ? p(1, 0) : p(31, 11);
276
+ case l: return r ? p(1, g) : p(0, g + 1);
277
+ case c:
278
+ var y = this.$locale().weekStart || 0, b = (h < y ? h + 7 : h) - y;
279
+ return p(r ? _ - b : _ + (6 - b), g);
280
+ case s:
281
+ case f: return m(v + "Hours", 0);
282
+ case o: return m(v + "Minutes", 1);
283
+ case a: return m(v + "Seconds", 2);
284
+ case i: return m(v + "Milliseconds", 3);
285
+ default: return this.clone();
286
+ }
287
+ }, _.endOf = function(e) {
288
+ return this.startOf(e, !1);
289
+ }, _.$set = function(e, t) {
290
+ var n, c = T.p(e), u = "set" + (this.$u ? "UTC" : ""), p = (n = {}, n[s] = u + "Date", n[f] = u + "Date", n[l] = u + "Month", n[d] = u + "FullYear", n[o] = u + "Hours", n[a] = u + "Minutes", n[i] = u + "Seconds", n[r] = u + "Milliseconds", n)[c], m = c === s ? this.$D + (t - this.$W) : t;
291
+ if (c === l || c === d) {
292
+ var h = this.clone().set(f, 1);
293
+ h.$d[p](m), h.init(), this.$d = h.set(f, Math.min(this.$D, h.daysInMonth())).$d;
294
+ } else p && this.$d[p](m);
295
+ return this.init(), this;
296
+ }, _.set = function(e, t) {
297
+ return this.clone().$set(e, t);
298
+ }, _.get = function(e) {
299
+ return this[T.p(e)]();
300
+ }, _.add = function(r, u) {
301
+ var f, p = this;
302
+ r = Number(r);
303
+ var m = T.p(u), h = function(e) {
304
+ var t = w(p);
305
+ return T.w(t.date(t.date() + Math.round(e * r)), p);
306
+ };
307
+ if (m === l) return this.set(l, this.$M + r);
308
+ if (m === d) return this.set(d, this.$y + r);
309
+ if (m === s) return h(1);
310
+ if (m === c) return h(7);
311
+ var g = (f = {}, f[a] = t, f[o] = n, f[i] = e, f)[m] || 1, _ = this.$d.getTime() + r * g;
312
+ return T.w(_, this);
313
+ }, _.subtract = function(e, t) {
314
+ return this.add(-1 * e, t);
315
+ }, _.format = function(e) {
316
+ var t = this, n = this.$locale();
317
+ if (!this.isValid()) return n.invalidDate || p;
318
+ var r = e || "YYYY-MM-DDTHH:mm:ssZ", i = T.z(this), a = this.$H, o = this.$m, s = this.$M, c = n.weekdays, l = n.months, u = n.meridiem, d = function(e, n, i, a) {
319
+ return e && (e[n] || e(t, r)) || i[n].slice(0, a);
320
+ }, f = function(e) {
321
+ return T.s(a % 12 || 12, e, "0");
322
+ }, m = u || function(e, t, n) {
323
+ var r = e < 12 ? "AM" : "PM";
324
+ return n ? r.toLowerCase() : r;
325
+ };
326
+ return r.replace(h, (function(e, r) {
327
+ return r || function(e) {
328
+ switch (e) {
329
+ case "YY": return String(t.$y).slice(-2);
330
+ case "YYYY": return T.s(t.$y, 4, "0");
331
+ case "M": return s + 1;
332
+ case "MM": return T.s(s + 1, 2, "0");
333
+ case "MMM": return d(n.monthsShort, s, l, 3);
334
+ case "MMMM": return d(l, s);
335
+ case "D": return t.$D;
336
+ case "DD": return T.s(t.$D, 2, "0");
337
+ case "d": return String(t.$W);
338
+ case "dd": return d(n.weekdaysMin, t.$W, c, 2);
339
+ case "ddd": return d(n.weekdaysShort, t.$W, c, 3);
340
+ case "dddd": return c[t.$W];
341
+ case "H": return String(a);
342
+ case "HH": return T.s(a, 2, "0");
343
+ case "h": return f(1);
344
+ case "hh": return f(2);
345
+ case "a": return m(a, o, !0);
346
+ case "A": return m(a, o, !1);
347
+ case "m": return String(o);
348
+ case "mm": return T.s(o, 2, "0");
349
+ case "s": return String(t.$s);
350
+ case "ss": return T.s(t.$s, 2, "0");
351
+ case "SSS": return T.s(t.$ms, 3, "0");
352
+ case "Z": return i;
353
+ }
354
+ return null;
355
+ }(e) || i.replace(":", "");
356
+ }));
357
+ }, _.utcOffset = function() {
358
+ return 15 * -Math.round(this.$d.getTimezoneOffset() / 15);
359
+ }, _.diff = function(r, f, p) {
360
+ var m, h = this, g = T.p(f), _ = w(r), v = (_.utcOffset() - this.utcOffset()) * t, y = this - _, b = function() {
361
+ return T.m(h, _);
362
+ };
363
+ switch (g) {
364
+ case d:
365
+ m = b() / 12;
366
+ break;
367
+ case l:
368
+ m = b();
369
+ break;
370
+ case u:
371
+ m = b() / 3;
372
+ break;
373
+ case c:
374
+ m = (y - v) / 6048e5;
375
+ break;
376
+ case s:
377
+ m = (y - v) / 864e5;
378
+ break;
379
+ case o:
380
+ m = y / n;
381
+ break;
382
+ case a:
383
+ m = y / t;
384
+ break;
385
+ case i:
386
+ m = y / e;
387
+ break;
388
+ default: m = y;
389
+ }
390
+ return p ? m : T.a(m);
391
+ }, _.daysInMonth = function() {
392
+ return this.endOf(l).$D;
393
+ }, _.$locale = function() {
394
+ return b[this.$L];
395
+ }, _.locale = function(e, t) {
396
+ if (!e) return this.$L;
397
+ var n = this.clone(), r = C(e, t, !0);
398
+ return r && (n.$L = r), n;
399
+ }, _.clone = function() {
400
+ return T.w(this.$d, this);
401
+ }, _.toDate = function() {
402
+ return new Date(this.valueOf());
403
+ }, _.toJSON = function() {
404
+ return this.isValid() ? this.toISOString() : null;
405
+ }, _.toISOString = function() {
406
+ return this.$d.toISOString();
407
+ }, _.toString = function() {
408
+ return this.$d.toUTCString();
409
+ }, g;
410
+ }(), D = E.prototype;
411
+ return w.prototype = D, [
412
+ ["$ms", r],
413
+ ["$s", i],
414
+ ["$m", a],
415
+ ["$H", o],
416
+ ["$W", s],
417
+ ["$M", l],
418
+ ["$y", d],
419
+ ["$D", f]
420
+ ].forEach((function(e) {
421
+ D[e[1]] = function(t) {
422
+ return this.$g(t, e[0], e[1]);
423
+ };
424
+ })), w.extend = function(e, t) {
425
+ return e.$i ||= (e(t, E, w), !0), w;
426
+ }, w.locale = C, w.isDayjs = S, w.unix = function(e) {
427
+ return w(1e3 * e);
428
+ }, w.en = b[y], w.Ls = b, w.p = {}, w;
429
+ }));
430
+ })))()), N = [
7
431
  "Check vehicle status",
8
432
  "Schedule maintenance",
9
433
  "Pricing information"
10
- ], h = [{
434
+ ], P = [{
11
435
  id: 1,
12
436
  role: "assistant",
13
437
  text: "Hello! 👋 I'm your AI assistant. How can I help you today?",
14
438
  time: "Just now"
15
439
  }];
16
- function g(e) {
440
+ function F(e) {
17
441
  let t = e.toLowerCase();
18
442
  return t.includes("vehicle") || t.includes("status") ? "I can help check vehicle status. Please provide the vehicle number plate, such as VDR6117." : t.includes("maintenance") || t.includes("repair") ? "I can help with maintenance! Please describe the vehicle issue, and I'll suggest the next steps." : t.includes("price") || t.includes("cost") ? "Pricing depends on your requirements. Tell me which service you're interested in, and I'll help estimate the cost." : t.includes("hello") || t.includes("hi") ? "Hello! 😊 What would you like help with today?" : `Thanks for your message: "${e}". This is a demo response. Configure apiUrl to connect your AI backend.`;
19
443
  }
20
- function _({ key: _, title: v = "AI Assistant", subtitle: y = "Online · Ready to help", primaryColor: b = "#2563eb" }) {
21
- let [x, S] = n(!1), [C, w] = n(!1), [T, E] = n(""), [D, O] = n(!1), [k, A] = n(h), j = t(null), M = t(null), [N, P] = n(null);
22
- e(() => {
23
- j.current?.scrollIntoView({ behavior: "smooth" });
444
+ function I({ apiKey: e, apiUrl: t = "http://localhost:8000", title: c = "AI Assistant", subtitle: l = "Online · Ready to help", primaryColor: u = "#2563eb" }) {
445
+ let [d, f] = i(!1), [p, m] = i(!1), [h, g] = i(""), [_, v] = i(!1), [y, b] = i(P), x = r(null), S = r(null), [C, w] = i(null);
446
+ if (n(() => {
447
+ x.current?.scrollIntoView({ behavior: "smooth" });
24
448
  }, [
25
- k,
26
- D,
27
- x,
28
- C
29
- ]), e(() => {
30
- x && !C && M.current?.focus();
31
- }, [x, C]);
32
- let F = process.env.NEXT_PUBLIC_API_URL;
33
- if (!F || !_) return "";
34
- async function I(e = T) {
35
- let t = e.trim();
36
- if (!t || D) return;
37
- let n = u().format("HH:mm");
38
- A((e) => [...e, {
449
+ y,
450
+ _,
451
+ d,
452
+ p
453
+ ]), n(() => {
454
+ d && !p && S.current?.focus();
455
+ }, [d, p]), console.log(t, e, "dinesh1"), !e) return null;
456
+ async function I(n = h) {
457
+ let r = n.trim();
458
+ if (!r || _) return;
459
+ let i = (0, M.default)().format("HH:mm");
460
+ b((e) => [...e, {
39
461
  id: Date.now(),
40
462
  role: "user",
41
- text: t,
42
- time: n
43
- }]), E(""), O(!0), P(null);
463
+ text: r,
464
+ time: i
465
+ }]), g(""), v(!0), w(null);
44
466
  try {
45
- let e;
46
- if (F) {
47
- let n;
467
+ let n;
468
+ if (t) {
469
+ let i;
48
470
  try {
49
- n = await fetch(F, {
471
+ i = await fetch(t + "/chats", {
50
472
  method: "POST",
51
473
  headers: { "Content-Type": "application/json" },
52
474
  body: JSON.stringify({
53
- message: t,
54
- key: _
475
+ title: r,
476
+ key: e
55
477
  })
56
478
  });
57
479
  } catch (e) {
58
- throw P("Failed to fetch.\n\nPossible Reasons:\n\n- CORS\n- Network Failure\n- URL scheme must be \"http\" or \"https\" for CORS request."), e;
480
+ throw w(`Failed to fetch.\n\nPossible Reasons:\n\n- CORS\n- Network Failure\n- URL scheme must be "http" or "https" for CORS request.\n\nError: ${e instanceof Error ? e.message : String(e)}`), e;
59
481
  }
60
- if (!n.ok) throw P(`Failed to fetch.\n\nPossible Reasons:\n\n- CORS\n- Network Failure\n- URL scheme must be "http" or "https" for CORS request.\n\nChat API returned ${n.status}`), Error(`Chat API returned ${n.status}`);
61
- let r = await n.json();
62
- e = r.reply ?? r.response ?? r.message ?? "I received a response, but it did not include a reply field.";
63
- } else await new Promise((e) => setTimeout(e, 700)), e = g(t);
64
- A((t) => [...t, {
482
+ if (!i.ok) throw w(`Failed to fetch.\n\nPossible Reasons:\n\n- CORS\n- Network Failure\n- URL scheme must be "http" or "https" for CORS request.\n\nChat API returned ${i.status}`), Error(`Chat API returned ${i.status}`);
483
+ let a = await i.json();
484
+ n = a.reply ?? a.response ?? a.message ?? "I received a response, but it did not include a reply field.";
485
+ } else await new Promise((e) => setTimeout(e, 700)), n = F(r);
486
+ b((e) => [...e, {
65
487
  id: Date.now() + 1,
66
488
  role: "assistant",
67
- text: e,
68
- time: u().format("HH:mm")
489
+ text: n,
490
+ time: (0, M.default)().format("HH:mm")
69
491
  }]);
70
492
  } catch {
71
- A((e) => [...e, {
493
+ b((e) => [...e, {
72
494
  id: Date.now() + 1,
73
495
  role: "assistant",
74
- text: N || "Sorry, I couldn't reach the chat service. Please try again.",
75
- time: u().format("HH:mm")
496
+ text: C || "Sorry, I couldn't reach the chat service. Please try again.",
497
+ time: (0, M.default)().format("HH:mm")
76
498
  }]);
77
499
  } finally {
78
- O(!1);
500
+ v(!1);
79
501
  }
80
502
  }
81
- return /* @__PURE__ */ p("div", {
503
+ return /* @__PURE__ */ s("div", {
82
504
  className: "acw-root",
83
- style: { "--acw-primary": b },
84
- children: [x && /* @__PURE__ */ p("section", {
85
- className: `acw-panel ${C ? "acw-minimized" : ""}`,
505
+ style: { "--acw-primary": u },
506
+ children: [d && /* @__PURE__ */ s("section", {
507
+ className: `acw-panel ${p ? "acw-minimized" : ""}`,
86
508
  "aria-label": "AI chat assistant",
87
- children: [/* @__PURE__ */ p("header", {
509
+ children: [/* @__PURE__ */ s("header", {
88
510
  className: "acw-header",
89
511
  children: [
90
- /* @__PURE__ */ f("div", {
512
+ /* @__PURE__ */ o("div", {
91
513
  className: "acw-brand-icon",
92
- children: /* @__PURE__ */ f(r, { size: 23 })
514
+ children: /* @__PURE__ */ o(T, { size: 23 })
93
515
  }),
94
- /* @__PURE__ */ p("div", {
516
+ /* @__PURE__ */ s("div", {
95
517
  className: "acw-heading",
96
- children: [/* @__PURE__ */ f("h2", { children: v }), /* @__PURE__ */ p("p", { children: [/* @__PURE__ */ f("span", { className: "acw-online-dot" }), y] })]
518
+ children: [/* @__PURE__ */ o("h2", { children: c }), /* @__PURE__ */ s("p", { children: [/* @__PURE__ */ o("span", { className: "acw-online-dot" }), l] })]
97
519
  }),
98
- /* @__PURE__ */ f("button", {
520
+ /* @__PURE__ */ o("button", {
99
521
  className: "acw-header-button",
100
- onClick: () => w(!C),
522
+ onClick: () => m(!p),
101
523
  "aria-label": "Minimize chat",
102
- children: /* @__PURE__ */ f(a, { size: 17 })
524
+ children: /* @__PURE__ */ o(D, { size: 17 })
103
525
  }),
104
- /* @__PURE__ */ f("button", {
526
+ /* @__PURE__ */ o("button", {
105
527
  className: "acw-header-button",
106
- onClick: () => S(!1),
528
+ onClick: () => f(!1),
107
529
  "aria-label": "Close chat",
108
- children: /* @__PURE__ */ f(l, { size: 19 })
530
+ children: /* @__PURE__ */ o(j, { size: 19 })
109
531
  })
110
532
  ]
111
- }), !C && /* @__PURE__ */ p(d, { children: [
112
- /* @__PURE__ */ p("div", {
533
+ }), !p && /* @__PURE__ */ s(a, { children: [
534
+ /* @__PURE__ */ s("div", {
113
535
  className: "acw-messages",
114
536
  children: [
115
- k.map((e, t) => /* @__PURE__ */ p("div", {
537
+ y.map((e, t) => /* @__PURE__ */ s("div", {
116
538
  className: `acw-message-row ${e.role === "user" ? "acw-user-row" : ""}`,
117
539
  children: [
118
- e.role === "assistant" && /* @__PURE__ */ f("div", {
540
+ e.role === "assistant" && /* @__PURE__ */ o("div", {
119
541
  className: "acw-avatar acw-bot-avatar",
120
- children: /* @__PURE__ */ f(r, { size: 17 })
542
+ children: /* @__PURE__ */ o(T, { size: 17 })
121
543
  }),
122
- /* @__PURE__ */ p("div", {
544
+ /* @__PURE__ */ s("div", {
123
545
  className: "acw-message-content",
124
- children: [/* @__PURE__ */ f("div", {
546
+ children: [/* @__PURE__ */ o("div", {
125
547
  className: `acw-bubble ${e.role === "user" ? "acw-user-bubble" : "acw-assistant-bubble"}`,
126
- children: e.text.split("\n").map((t, n) => /* @__PURE__ */ p("span", { children: [t, n < e.text.split("\n").length - 1 && /* @__PURE__ */ f("br", {})] }, n))
127
- }), /* @__PURE__ */ f("span", {
548
+ children: e.text.split("\n").map((t, n) => /* @__PURE__ */ s("span", { children: [t, n < e.text.split("\n").length - 1 && /* @__PURE__ */ o("br", {})] }, n))
549
+ }), /* @__PURE__ */ o("span", {
128
550
  className: "acw-time",
129
551
  children: e.time
130
552
  })]
131
553
  }),
132
- e.role === "user" && /* @__PURE__ */ f("div", {
554
+ e.role === "user" && /* @__PURE__ */ o("div", {
133
555
  className: "acw-avatar acw-user-avatar",
134
- children: /* @__PURE__ */ f(c, { size: 17 })
556
+ children: /* @__PURE__ */ o(A, { size: 17 })
135
557
  })
136
558
  ]
137
559
  }, e.id)),
138
- D && /* @__PURE__ */ p("div", {
560
+ _ && /* @__PURE__ */ s("div", {
139
561
  className: "acw-message-row",
140
- children: [/* @__PURE__ */ f("div", {
562
+ children: [/* @__PURE__ */ o("div", {
141
563
  className: "acw-avatar acw-bot-avatar",
142
- children: /* @__PURE__ */ f(r, { size: 17 })
143
- }), /* @__PURE__ */ p("div", {
564
+ children: /* @__PURE__ */ o(T, { size: 17 })
565
+ }), /* @__PURE__ */ s("div", {
144
566
  className: "acw-typing",
145
567
  "aria-label": "Assistant is typing",
146
568
  children: [
147
- /* @__PURE__ */ f("span", {}),
148
- /* @__PURE__ */ f("span", {}),
149
- /* @__PURE__ */ f("span", {})
569
+ /* @__PURE__ */ o("span", {}),
570
+ /* @__PURE__ */ o("span", {}),
571
+ /* @__PURE__ */ o("span", {})
150
572
  ]
151
573
  })]
152
574
  }),
153
- /* @__PURE__ */ f("div", { ref: j })
575
+ /* @__PURE__ */ o("div", { ref: x })
154
576
  ]
155
577
  }),
156
- k.length === 1 && /* @__PURE__ */ p("div", {
578
+ y.length === 1 && /* @__PURE__ */ s("div", {
157
579
  className: "acw-suggestions",
158
- children: [/* @__PURE__ */ p("p", { children: [/* @__PURE__ */ f(s, { size: 13 }), " Suggested questions"] }), /* @__PURE__ */ f("div", {
580
+ children: [/* @__PURE__ */ s("p", { children: [/* @__PURE__ */ o(k, { size: 13 }), " Suggested questions"] }), /* @__PURE__ */ o("div", {
159
581
  className: "acw-suggestion-list",
160
- children: m.map((e) => /* @__PURE__ */ f("button", {
582
+ children: N.map((e) => /* @__PURE__ */ o("button", {
161
583
  onClick: () => void I(e),
162
584
  children: e
163
585
  }, e))
164
586
  })]
165
587
  }),
166
- /* @__PURE__ */ p("form", {
588
+ /* @__PURE__ */ s("form", {
167
589
  className: "acw-composer",
168
590
  onSubmit: (e) => {
169
591
  e.preventDefault(), I();
170
592
  },
171
- children: [/* @__PURE__ */ f("input", {
172
- ref: M,
173
- value: T,
174
- onChange: (e) => E(e.target.value),
593
+ children: [/* @__PURE__ */ o("input", {
594
+ ref: S,
595
+ value: h,
596
+ onChange: (e) => g(e.target.value),
175
597
  placeholder: "Type your message...",
176
598
  "aria-label": "Type your message"
177
- }), /* @__PURE__ */ f("button", {
599
+ }), /* @__PURE__ */ o("button", {
178
600
  type: "submit",
179
- disabled: !T.trim() || D,
601
+ disabled: !h.trim() || _,
180
602
  "aria-label": "Send message",
181
- children: /* @__PURE__ */ f(o, { size: 18 })
603
+ children: /* @__PURE__ */ o(O, { size: 18 })
182
604
  })]
183
605
  }),
184
- /* @__PURE__ */ f("p", {
606
+ /* @__PURE__ */ o("p", {
185
607
  className: "acw-footer",
186
- children: F ? "Powered by your AI service" : "Demo mode · Connect your AI API"
608
+ children: t ? "Powered by your AI service" : "Demo mode · Connect your AI API"
187
609
  })
188
610
  ] })]
189
- }), /* @__PURE__ */ p("button", {
611
+ }), /* @__PURE__ */ s("button", {
190
612
  className: "acw-launcher",
191
613
  onClick: () => {
192
- S(!x), w(!1);
614
+ f(!d), m(!1);
193
615
  },
194
- "aria-label": x ? "Close chat widget" : "Open chat widget",
195
- "aria-expanded": x,
196
- children: [!x && /* @__PURE__ */ f("span", { className: "acw-notification-dot" }), x ? /* @__PURE__ */ f(l, { size: 25 }) : /* @__PURE__ */ f(i, { size: 26 })]
616
+ "aria-label": d ? "Close chat widget" : "Open chat widget",
617
+ "aria-expanded": d,
618
+ children: [!d && /* @__PURE__ */ o("span", { className: "acw-notification-dot" }), d ? /* @__PURE__ */ o(j, { size: 25 }) : /* @__PURE__ */ o(E, { size: 26 })]
197
619
  })]
198
620
  });
199
621
  }
200
- export { _ as ChatWidget };
622
+ export { I as ChatWidget };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dinesh-ai-chat-widget",
3
- "version": "1.0.13",
3
+ "version": "1.0.15",
4
4
  "description": "Reusable floating AI chat widget for React and Next.js",
5
5
  "license": "MIT",
6
6
  "main": "./dist/index.cjs",
File without changes