@contenify/chatbot 0.1.2 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -19,6 +19,9 @@ var __spreadValues = (a, b) => {
19
19
  };
20
20
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
21
21
 
22
+ // src/index.tsx
23
+ import { useEffect as useEffect8 } from "react";
24
+
22
25
  // contexts/PreferencesContext.tsx
23
26
  import { createContext, useContext, useState, useEffect } from "react";
24
27
 
@@ -26,12 +29,22 @@ import { createContext, useContext, useState, useEffect } from "react";
26
29
  import axios from "axios";
27
30
 
28
31
  // lib/config.ts
32
+ var _apiUrl = process.env.NEXT_PUBLIC_CONTENIFY_API_URL || "http://localhost:8080/api";
33
+ var _apiKey = process.env.NEXT_PUBLIC_API_KEY || "";
34
+ var _domain = process.env.NEXT_PUBLIC_DOMAIN || "";
35
+ function setConfig(config) {
36
+ if (config.apiUrl) _apiUrl = config.apiUrl;
37
+ if (config.apiKey) _apiKey = config.apiKey;
38
+ if (config.domain) _domain = config.domain;
39
+ }
29
40
  function getApiBaseUrl() {
30
- return process.env.NEXT_PUBLIC_CONTENIFY_API_URL || DEFAULT_API_BASE_URL;
41
+ return _apiUrl;
31
42
  }
32
43
  function getServerBaseUrl() {
33
- const apiUrl = getApiBaseUrl();
34
- return apiUrl.replace(/\/api\/?$/, "");
44
+ return _apiUrl.replace(/\/api\/?$/, "");
45
+ }
46
+ function getApiKey() {
47
+ return _apiKey;
35
48
  }
36
49
 
37
50
  // lib/api.ts
@@ -44,7 +57,7 @@ var api = axios.create({
44
57
  });
45
58
  api.interceptors.request.use(
46
59
  (config) => {
47
- const apiKey = process.env.NEXT_PUBLIC_API_KEY;
60
+ const apiKey = getApiKey();
48
61
  if (apiKey) {
49
62
  config.headers["x-api-key"] = apiKey;
50
63
  }
@@ -67,6 +80,88 @@ var getMyPreferencesApi = async () => {
67
80
  const { data } = await api_default.get("/preferences/me");
68
81
  return data.data;
69
82
  };
83
+ var savePreferencesApi = async ({
84
+ botName,
85
+ logo,
86
+ state,
87
+ cities,
88
+ primaryColor,
89
+ secondaryColor,
90
+ theme,
91
+ language,
92
+ showSidebar,
93
+ showHeader,
94
+ activeThemePreset,
95
+ showNewsPanel,
96
+ tone,
97
+ style,
98
+ wordCount,
99
+ includeQuotes,
100
+ includeFAQ,
101
+ targetAudience
102
+ }) => {
103
+ const formData = new FormData();
104
+ if (botName) {
105
+ formData.append("botName", botName);
106
+ }
107
+ if (logo) {
108
+ formData.append("logo", logo);
109
+ }
110
+ if (state) {
111
+ formData.append("state", state);
112
+ }
113
+ if (cities) {
114
+ formData.append("cities", JSON.stringify(cities));
115
+ }
116
+ if (primaryColor) {
117
+ formData.append("primaryColor", primaryColor);
118
+ }
119
+ if (secondaryColor) {
120
+ formData.append("secondaryColor", secondaryColor);
121
+ }
122
+ if (theme) {
123
+ formData.append("theme", theme);
124
+ }
125
+ if (language) {
126
+ formData.append("language", language);
127
+ }
128
+ if (showSidebar !== void 0) {
129
+ formData.append("showSidebar", String(showSidebar));
130
+ }
131
+ if (showHeader !== void 0) {
132
+ formData.append("showHeader", String(showHeader));
133
+ }
134
+ if (activeThemePreset !== void 0) {
135
+ formData.append("activeThemePreset", activeThemePreset != null ? activeThemePreset : "");
136
+ }
137
+ if (showNewsPanel !== void 0) {
138
+ formData.append("showNewsPanel", String(showNewsPanel));
139
+ }
140
+ if (tone) {
141
+ formData.append("tone", tone);
142
+ }
143
+ if (style) {
144
+ formData.append("style", style);
145
+ }
146
+ if (wordCount) {
147
+ formData.append("wordCount", wordCount);
148
+ }
149
+ if (includeQuotes !== void 0) {
150
+ formData.append("includeQuotes", String(includeQuotes));
151
+ }
152
+ if (includeFAQ !== void 0) {
153
+ formData.append("includeFAQ", String(includeFAQ));
154
+ }
155
+ if (targetAudience !== void 0) {
156
+ formData.append("targetAudience", targetAudience);
157
+ }
158
+ const { data } = await api_default.put("/preferences", formData, {
159
+ headers: {
160
+ "Content-Type": "multipart/form-data"
161
+ }
162
+ });
163
+ return data.data;
164
+ };
70
165
 
71
166
  // contexts/PreferencesContext.tsx
72
167
  import { jsx } from "react/jsx-runtime";
@@ -169,60 +264,7 @@ function usePreferences() {
169
264
  }
170
265
 
171
266
  // components/chatbot/ChatBot.tsx
172
- import { useState as useState8, useCallback as useCallback3 } from "react";
173
-
174
- // components/chatbot/ArticleModal.tsx
175
- import { jsx as jsx2, jsxs } from "react/jsx-runtime";
176
- function ArticleModal({
177
- article,
178
- onClose,
179
- onRecreate
180
- }) {
181
- return /* @__PURE__ */ jsx2("div", { className: "fixed inset-0 z-50 bg-black/50 backdrop-blur-sm flex items-center justify-center px-4", children: /* @__PURE__ */ jsxs("div", { className: "relative w-full max-w-3xl bg-white rounded-xl shadow-card border border-gray-200 animate-in fade-in zoom-in", children: [
182
- /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between px-6 py-4 border-b border-gray-300", children: [
183
- /* @__PURE__ */ jsxs("div", { children: [
184
- /* @__PURE__ */ jsx2("p", { className: "text-xs text-gray-500 mb-1", children: "Source Article" }),
185
- /* @__PURE__ */ jsx2("h2", { className: "text-lg font-semibold text-gray-900 leading-snug", children: article.title })
186
- ] }),
187
- /* @__PURE__ */ jsx2(
188
- "button",
189
- {
190
- onClick: onClose,
191
- className: "text-gray-400 hover:text-gray-700 transition",
192
- "aria-label": "Close modal",
193
- children: "\u2715"
194
- }
195
- )
196
- ] }),
197
- /* @__PURE__ */ jsx2("div", { className: "px-6 py-5 max-h-[65vh] overflow-y-auto", children: /* @__PURE__ */ jsx2("div", { className: "prose prose-sm max-w-none text-gray-800", children: article.content }) }),
198
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-6 py-4 border-t bg-gray-50 rounded-b-xl", children: [
199
- /* @__PURE__ */ jsx2("span", { className: "text-xs text-gray-400", children: "This content will be recreated using AI" }),
200
- /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
201
- /* @__PURE__ */ jsx2(
202
- "button",
203
- {
204
- onClick: onClose,
205
- className: "px-4 py-2 text-sm rounded-md border border-gray-300 text-gray-700 hover:bg-gray-100 transition",
206
- children: "Cancel"
207
- }
208
- ),
209
- /* @__PURE__ */ jsx2(
210
- "button",
211
- {
212
- onClick: () => onRecreate({
213
- title: article.title,
214
- content: article.content,
215
- id: article._id
216
- // Include article ID when available
217
- }),
218
- className: "px-4 py-2 text-sm rounded-md bg-gray-900 text-white hover:bg-black transition",
219
- children: "Recreate Article"
220
- }
221
- )
222
- ] })
223
- ] })
224
- ] }) });
225
- }
267
+ import { useState as useState7 } from "react";
226
268
 
227
269
  // util/util.ts
228
270
  function extractArticleContent(raw) {
@@ -275,7 +317,7 @@ import {
275
317
  Pilcrow
276
318
  } from "lucide-react";
277
319
  import { useEffect as useEffect2 } from "react";
278
- import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
320
+ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
279
321
  function RichTextEditor({
280
322
  content,
281
323
  onChange,
@@ -297,7 +339,7 @@ function RichTextEditor({
297
339
  content,
298
340
  editorProps: {
299
341
  attributes: {
300
- class: "prose prose-sm max-w-none focus:outline-none min-h-[350px] p-4"
342
+ class: "ProseMirror"
301
343
  }
302
344
  },
303
345
  onUpdate: ({ editor: editor2 }) => {
@@ -310,96 +352,96 @@ function RichTextEditor({
310
352
  }
311
353
  }, [content, editor]);
312
354
  if (!editor) {
313
- return /* @__PURE__ */ jsx3("div", { className: "w-full h-[400px] border border-gray-300 rounded-lg flex items-center justify-center text-gray-400", children: "Loading editor..." });
355
+ return /* @__PURE__ */ jsx2("div", { className: "cnfy-editor-loading", children: "Loading editor..." });
314
356
  }
315
- return /* @__PURE__ */ jsxs2("div", { className: "w-full border border-gray-300 rounded-lg overflow-hidden", children: [
316
- /* @__PURE__ */ jsxs2("div", { className: "flex flex-wrap items-center gap-1 p-2 border-b border-gray-200 bg-gray-50", children: [
317
- /* @__PURE__ */ jsx3(
357
+ return /* @__PURE__ */ jsxs("div", { className: "cnfy-editor", children: [
358
+ /* @__PURE__ */ jsxs("div", { className: "cnfy-toolbar", children: [
359
+ /* @__PURE__ */ jsx2(
318
360
  ToolbarButton,
319
361
  {
320
362
  onClick: () => editor.chain().focus().toggleHeading({ level: 1 }).run(),
321
363
  isActive: editor.isActive("heading", { level: 1 }),
322
364
  title: "Heading 1",
323
- children: /* @__PURE__ */ jsx3(Heading1, { size: 18 })
365
+ children: /* @__PURE__ */ jsx2(Heading1, { size: 18 })
324
366
  }
325
367
  ),
326
- /* @__PURE__ */ jsx3(
368
+ /* @__PURE__ */ jsx2(
327
369
  ToolbarButton,
328
370
  {
329
371
  onClick: () => editor.chain().focus().toggleHeading({ level: 2 }).run(),
330
372
  isActive: editor.isActive("heading", { level: 2 }),
331
373
  title: "Heading 2",
332
- children: /* @__PURE__ */ jsx3(Heading2, { size: 18 })
374
+ children: /* @__PURE__ */ jsx2(Heading2, { size: 18 })
333
375
  }
334
376
  ),
335
- /* @__PURE__ */ jsx3(
377
+ /* @__PURE__ */ jsx2(
336
378
  ToolbarButton,
337
379
  {
338
380
  onClick: () => editor.chain().focus().setParagraph().run(),
339
381
  isActive: editor.isActive("paragraph"),
340
382
  title: "Paragraph",
341
- children: /* @__PURE__ */ jsx3(Pilcrow, { size: 18 })
383
+ children: /* @__PURE__ */ jsx2(Pilcrow, { size: 18 })
342
384
  }
343
385
  ),
344
- /* @__PURE__ */ jsx3("div", { className: "w-px h-6 bg-gray-300 mx-1" }),
345
- /* @__PURE__ */ jsx3(
386
+ /* @__PURE__ */ jsx2("div", { className: "cnfy-toolbar-divider" }),
387
+ /* @__PURE__ */ jsx2(
346
388
  ToolbarButton,
347
389
  {
348
390
  onClick: () => editor.chain().focus().toggleBold().run(),
349
391
  isActive: editor.isActive("bold"),
350
392
  title: "Bold",
351
- children: /* @__PURE__ */ jsx3(Bold, { size: 18 })
393
+ children: /* @__PURE__ */ jsx2(Bold, { size: 18 })
352
394
  }
353
395
  ),
354
- /* @__PURE__ */ jsx3(
396
+ /* @__PURE__ */ jsx2(
355
397
  ToolbarButton,
356
398
  {
357
399
  onClick: () => editor.chain().focus().toggleItalic().run(),
358
400
  isActive: editor.isActive("italic"),
359
401
  title: "Italic",
360
- children: /* @__PURE__ */ jsx3(Italic, { size: 18 })
402
+ children: /* @__PURE__ */ jsx2(Italic, { size: 18 })
361
403
  }
362
404
  ),
363
- /* @__PURE__ */ jsx3("div", { className: "w-px h-6 bg-gray-300 mx-1" }),
364
- /* @__PURE__ */ jsx3(
405
+ /* @__PURE__ */ jsx2("div", { className: "cnfy-toolbar-divider" }),
406
+ /* @__PURE__ */ jsx2(
365
407
  ToolbarButton,
366
408
  {
367
409
  onClick: () => editor.chain().focus().toggleBulletList().run(),
368
410
  isActive: editor.isActive("bulletList"),
369
411
  title: "Bullet List",
370
- children: /* @__PURE__ */ jsx3(List, { size: 18 })
412
+ children: /* @__PURE__ */ jsx2(List, { size: 18 })
371
413
  }
372
414
  ),
373
- /* @__PURE__ */ jsx3(
415
+ /* @__PURE__ */ jsx2(
374
416
  ToolbarButton,
375
417
  {
376
418
  onClick: () => editor.chain().focus().toggleOrderedList().run(),
377
419
  isActive: editor.isActive("orderedList"),
378
420
  title: "Numbered List",
379
- children: /* @__PURE__ */ jsx3(ListOrdered, { size: 18 })
421
+ children: /* @__PURE__ */ jsx2(ListOrdered, { size: 18 })
380
422
  }
381
423
  ),
382
- /* @__PURE__ */ jsx3("div", { className: "w-px h-6 bg-gray-300 mx-1" }),
383
- /* @__PURE__ */ jsx3(
424
+ /* @__PURE__ */ jsx2("div", { className: "cnfy-toolbar-divider" }),
425
+ /* @__PURE__ */ jsx2(
384
426
  ToolbarButton,
385
427
  {
386
428
  onClick: () => editor.chain().focus().undo().run(),
387
429
  disabled: !editor.can().undo(),
388
430
  title: "Undo",
389
- children: /* @__PURE__ */ jsx3(Undo, { size: 18 })
431
+ children: /* @__PURE__ */ jsx2(Undo, { size: 18 })
390
432
  }
391
433
  ),
392
- /* @__PURE__ */ jsx3(
434
+ /* @__PURE__ */ jsx2(
393
435
  ToolbarButton,
394
436
  {
395
437
  onClick: () => editor.chain().focus().redo().run(),
396
438
  disabled: !editor.can().redo(),
397
439
  title: "Redo",
398
- children: /* @__PURE__ */ jsx3(Redo, { size: 18 })
440
+ children: /* @__PURE__ */ jsx2(Redo, { size: 18 })
399
441
  }
400
442
  )
401
443
  ] }),
402
- /* @__PURE__ */ jsx3(EditorContent, { editor, className: "min-h-[350px]" })
444
+ /* @__PURE__ */ jsx2(EditorContent, { editor, className: "cnfy-editor-content" })
403
445
  ] });
404
446
  }
405
447
  function ToolbarButton({
@@ -409,13 +451,13 @@ function ToolbarButton({
409
451
  title,
410
452
  children
411
453
  }) {
412
- return /* @__PURE__ */ jsx3(
454
+ return /* @__PURE__ */ jsx2(
413
455
  "button",
414
456
  {
415
457
  onClick,
416
458
  disabled,
417
459
  title,
418
- className: `p-2 rounded hover:bg-gray-200 transition-colors ${isActive ? "bg-gray-200 text-emerald-600" : "text-gray-600"} ${disabled ? "opacity-40 cursor-not-allowed" : ""}`,
460
+ className: `cnfy-toolbar-btn ${isActive ? "cnfy-toolbar-btn--active" : ""} ${disabled ? "cnfy-toolbar-btn--disabled" : ""}`,
419
461
  children
420
462
  }
421
463
  );
@@ -440,7 +482,7 @@ function useTheme() {
440
482
  }
441
483
 
442
484
  // components/chatbot/EditModal.tsx
443
- import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
485
+ import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
444
486
  function EditModal({
445
487
  isOpen,
446
488
  initialContent,
@@ -499,30 +541,30 @@ function EditModal({
499
541
  }
500
542
  };
501
543
  if (!isOpen) return null;
502
- return /* @__PURE__ */ jsxs3("div", { className: "fixed inset-0 z-50 flex items-center justify-center", children: [
503
- /* @__PURE__ */ jsx4(
544
+ return /* @__PURE__ */ jsxs2("div", { className: "cnfy-edit-modal-overlay", children: [
545
+ /* @__PURE__ */ jsx3(
504
546
  "div",
505
547
  {
506
- className: "absolute inset-0 bg-black/50",
548
+ className: "cnfy-edit-modal-backdrop",
507
549
  onClick: onClose
508
550
  }
509
551
  ),
510
- /* @__PURE__ */ jsxs3("div", { className: "relative w-full h-full max-w-5xl max-h-[90vh] m-4 bg-white rounded-xl shadow-2xl flex flex-col overflow-hidden", children: [
511
- /* @__PURE__ */ jsxs3("div", { className: "flex items-center justify-between px-6 py-4 border-b", children: [
512
- /* @__PURE__ */ jsx4("h2", { className: "text-xl font-semibold text-gray-900", children: "Edit Article" }),
513
- /* @__PURE__ */ jsx4(
552
+ /* @__PURE__ */ jsxs2("div", { className: "cnfy-edit-modal", children: [
553
+ /* @__PURE__ */ jsxs2("div", { className: "cnfy-edit-modal-header", children: [
554
+ /* @__PURE__ */ jsx3("h2", { className: "cnfy-edit-modal-title", children: "Edit Article" }),
555
+ /* @__PURE__ */ jsx3(
514
556
  "button",
515
557
  {
516
558
  onClick: onClose,
517
- className: "p-2 rounded-full hover:bg-gray-100 transition-colors",
518
- children: /* @__PURE__ */ jsx4(X, { size: 20, className: "text-gray-500" })
559
+ className: "cnfy-edit-modal-close-btn",
560
+ children: /* @__PURE__ */ jsx3(X, { size: 20, className: "cnfy-edit-modal-close-icon" })
519
561
  }
520
562
  )
521
563
  ] }),
522
- /* @__PURE__ */ jsxs3("div", { className: "flex-1 overflow-y-auto p-6 space-y-6", children: [
523
- /* @__PURE__ */ jsxs3("div", { children: [
524
- /* @__PURE__ */ jsx4("label", { className: "block text-sm font-medium text-gray-700 mb-2", children: "Article Content" }),
525
- /* @__PURE__ */ jsx4(
564
+ /* @__PURE__ */ jsxs2("div", { className: "cnfy-edit-modal-body", children: [
565
+ /* @__PURE__ */ jsxs2("div", { children: [
566
+ /* @__PURE__ */ jsx3("label", { className: "cnfy-edit-label", children: "Article Content" }),
567
+ /* @__PURE__ */ jsx3(
526
568
  RichTextEditor,
527
569
  {
528
570
  content,
@@ -531,29 +573,29 @@ function EditModal({
531
573
  }
532
574
  )
533
575
  ] }),
534
- /* @__PURE__ */ jsxs3("div", { children: [
535
- /* @__PURE__ */ jsx4("label", { className: "block text-sm font-medium text-gray-700 mb-2", children: "Meta Keywords" }),
536
- /* @__PURE__ */ jsx4("div", { className: "flex flex-wrap gap-2 mb-3", children: keywords.map((keyword, index) => /* @__PURE__ */ jsxs3(
576
+ /* @__PURE__ */ jsxs2("div", { children: [
577
+ /* @__PURE__ */ jsx3("label", { className: "cnfy-edit-label", children: "Meta Keywords" }),
578
+ /* @__PURE__ */ jsx3("div", { className: "cnfy-keyword-list", children: keywords.map((keyword, index) => /* @__PURE__ */ jsxs2(
537
579
  "span",
538
580
  {
539
- className: "inline-flex items-center gap-1 px-3 py-1 bg-gray-100 text-gray-700 rounded-full text-sm",
581
+ className: "cnfy-keyword-tag",
540
582
  children: [
541
583
  "#",
542
584
  keyword,
543
- /* @__PURE__ */ jsx4(
585
+ /* @__PURE__ */ jsx3(
544
586
  "button",
545
587
  {
546
588
  onClick: () => handleRemoveKeyword(index),
547
- className: "ml-1 text-gray-400 hover:text-gray-600",
548
- children: /* @__PURE__ */ jsx4(X, { size: 14 })
589
+ className: "cnfy-keyword-remove-btn",
590
+ children: /* @__PURE__ */ jsx3(X, { size: 14 })
549
591
  }
550
592
  )
551
593
  ]
552
594
  },
553
595
  index
554
596
  )) }),
555
- /* @__PURE__ */ jsxs3("div", { className: "flex gap-2", children: [
556
- /* @__PURE__ */ jsx4(
597
+ /* @__PURE__ */ jsxs2("div", { className: "cnfy-keyword-input-row", children: [
598
+ /* @__PURE__ */ jsx3(
557
599
  "input",
558
600
  {
559
601
  type: "text",
@@ -561,42 +603,42 @@ function EditModal({
561
603
  onChange: (e) => setNewKeyword(e.target.value),
562
604
  onKeyDown: handleKeyDown,
563
605
  placeholder: "Add a keyword...",
564
- className: "flex-1 px-3 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-emerald-500 focus:border-emerald-500"
606
+ className: "cnfy-keyword-input"
565
607
  }
566
608
  ),
567
- /* @__PURE__ */ jsx4(
609
+ /* @__PURE__ */ jsx3(
568
610
  "button",
569
611
  {
570
612
  onClick: handleAddKeyword,
571
- className: "px-4 py-2 bg-gray-100 text-gray-700 rounded-lg text-sm font-medium hover:bg-gray-200 transition-colors",
613
+ className: "cnfy-btn-add-keyword",
572
614
  children: "Add"
573
615
  }
574
616
  )
575
617
  ] })
576
618
  ] })
577
619
  ] }),
578
- /* @__PURE__ */ jsxs3("div", { className: "flex items-center justify-end gap-3 px-6 py-4 border-t bg-gray-50", children: [
579
- /* @__PURE__ */ jsx4(
620
+ /* @__PURE__ */ jsxs2("div", { className: "cnfy-edit-modal-footer", children: [
621
+ /* @__PURE__ */ jsx3(
580
622
  "button",
581
623
  {
582
624
  onClick: onClose,
583
- className: "px-4 py-2 text-gray-700 text-sm font-medium hover:bg-gray-100 rounded-lg transition-colors",
625
+ className: "cnfy-btn-footer-cancel",
584
626
  children: "Cancel"
585
627
  }
586
628
  ),
587
- /* @__PURE__ */ jsx4(
629
+ /* @__PURE__ */ jsx3(
588
630
  "button",
589
631
  {
590
632
  onClick: () => onSaveDraft(content, keywords),
591
- className: "px-4 py-2 bg-gray-200 text-gray-800 text-sm font-medium rounded-lg hover:bg-gray-300 transition-colors",
633
+ className: "cnfy-btn-save-draft",
592
634
  children: "Save Draft"
593
635
  }
594
636
  ),
595
- /* @__PURE__ */ jsx4(
637
+ /* @__PURE__ */ jsx3(
596
638
  "button",
597
639
  {
598
640
  onClick: () => onPost(content, keywords),
599
- className: "px-4 py-2 bg-emerald-600 text-white text-sm font-medium rounded-lg hover:bg-emerald-700 transition-colors",
641
+ className: "cnfy-btn-post-article",
600
642
  style: { backgroundColor: primaryColor, color: "#fff" },
601
643
  children: "Post"
602
644
  }
@@ -609,7 +651,7 @@ function EditModal({
609
651
  // components/news/NewsList.tsx
610
652
  import { useState as useState3 } from "react";
611
653
  import { Eye, RefreshCcw } from "lucide-react";
612
- import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
654
+ import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
613
655
  var dateFormatter = new Intl.DateTimeFormat("en-GB", {
614
656
  day: "2-digit",
615
657
  month: "short",
@@ -651,22 +693,22 @@ function NewsList({
651
693
  b = Math.round(b + (255 - b) * (percent / 100));
652
694
  return `rgb(${r}, ${g}, ${b})`;
653
695
  };
654
- return /* @__PURE__ */ jsx5("div", { className: "p-4 space-y-3", children: news.flatMap((item) => {
696
+ return /* @__PURE__ */ jsx4("div", { className: "cnfy-news-list", children: news.flatMap((item) => {
655
697
  const publishedDate = new Date(item.publishedAt);
656
698
  const links = extractLinksFromContent(item.content);
657
699
  if (links.length > 0) {
658
- return links.map((link, idx) => /* @__PURE__ */ jsxs4(
700
+ return links.map((link, idx) => /* @__PURE__ */ jsxs3(
659
701
  "div",
660
702
  {
661
- className: "flex items-start justify-between gap-3 rounded-lg border border-gray-200 bg-white p-3 text-sm hover:bg-gray-50 transition",
703
+ className: "cnfy-news-card",
662
704
  children: [
663
- /* @__PURE__ */ jsxs4("div", { className: "min-w-0", children: [
664
- /* @__PURE__ */ jsx5("p", { className: "font-bold text-gray-900 line-clamp-2", children: link.title }),
665
- /* @__PURE__ */ jsxs4("div", { className: "flex flex-wrap items-center gap-2 mt-2 text-xs text-gray-500", children: [
666
- /* @__PURE__ */ jsx5(
705
+ /* @__PURE__ */ jsxs3("div", { className: "cnfy-news-card-content", children: [
706
+ /* @__PURE__ */ jsx4("p", { className: "cnfy-news-card-title", children: link.title }),
707
+ /* @__PURE__ */ jsxs3("div", { className: "cnfy-news-card-meta", children: [
708
+ /* @__PURE__ */ jsx4(
667
709
  "span",
668
710
  {
669
- className: "inline-flex items-center rounded-full px-2 py-0.5 font-medium border",
711
+ className: "cnfy-news-badge",
670
712
  style: {
671
713
  backgroundColor: lightenColor(primaryColorState, 95),
672
714
  color: primaryColor,
@@ -675,38 +717,37 @@ function NewsList({
675
717
  children: link.source || item.sourceName
676
718
  }
677
719
  ),
678
- /* @__PURE__ */ jsx5("span", { children: "\u2022" }),
679
- /* @__PURE__ */ jsx5("span", { className: "capitalize", children: item.category }),
680
- /* @__PURE__ */ jsx5("span", { children: "\u2022" }),
681
- /* @__PURE__ */ jsxs4("span", { children: [
720
+ /* @__PURE__ */ jsx4("span", { children: "\u2022" }),
721
+ /* @__PURE__ */ jsx4("span", { className: "cnfy-news-card-category", children: item.category }),
722
+ /* @__PURE__ */ jsx4("span", { children: "\u2022" }),
723
+ /* @__PURE__ */ jsxs3("span", { children: [
682
724
  dateFormatter.format(publishedDate),
683
725
  " ",
684
726
  timeFormatter.format(publishedDate)
685
727
  ] })
686
728
  ] })
687
729
  ] }),
688
- /* @__PURE__ */ jsxs4("div", { className: "flex flex-col gap-2 shrink-0", children: [
689
- /* @__PURE__ */ jsx5(
730
+ /* @__PURE__ */ jsxs3("div", { className: "cnfy-news-card-actions", children: [
731
+ /* @__PURE__ */ jsx4(
690
732
  "button",
691
733
  {
692
734
  onClick: () => window.open(link.url, "_blank"),
693
- className: "p-1 text-gray-400 hover:text-gray-700",
735
+ className: "cnfy-news-action-btn",
694
736
  title: "View",
695
- children: /* @__PURE__ */ jsx5(Eye, { size: 16 })
737
+ children: /* @__PURE__ */ jsx4(Eye, { size: 16 })
696
738
  }
697
739
  ),
698
- /* @__PURE__ */ jsx5(
740
+ /* @__PURE__ */ jsx4(
699
741
  "button",
700
742
  {
701
743
  onClick: () => onRecreate({
702
744
  title: link.title,
703
745
  content: link.title,
704
746
  id: item._id
705
- // Include article ID
706
747
  }),
707
- className: "p-1 text-gray-400 hover:text-gray-700",
748
+ className: "cnfy-news-action-btn",
708
749
  title: "Recreate",
709
- children: /* @__PURE__ */ jsx5(RefreshCcw, { size: 16 })
750
+ children: /* @__PURE__ */ jsx4(RefreshCcw, { size: 16 })
710
751
  }
711
752
  )
712
753
  ] })
@@ -715,18 +756,18 @@ function NewsList({
715
756
  `${item._id}-link-${idx}`
716
757
  ));
717
758
  }
718
- return /* @__PURE__ */ jsxs4(
759
+ return /* @__PURE__ */ jsxs3(
719
760
  "div",
720
761
  {
721
- className: "flex items-start justify-between gap-3 rounded-lg border border-gray-200 bg-white p-3 text-sm hover:bg-gray-50 transition",
762
+ className: "cnfy-news-card",
722
763
  children: [
723
- /* @__PURE__ */ jsxs4("div", { className: "min-w-0", children: [
724
- /* @__PURE__ */ jsx5("p", { className: "font-bold text-gray-900 line-clamp-2", children: item.title }),
725
- /* @__PURE__ */ jsxs4("div", { className: "flex flex-wrap items-center gap-2 mt-2 text-xs text-gray-500", children: [
726
- /* @__PURE__ */ jsx5(
764
+ /* @__PURE__ */ jsxs3("div", { className: "cnfy-news-card-content", children: [
765
+ /* @__PURE__ */ jsx4("p", { className: "cnfy-news-card-title", children: item.title }),
766
+ /* @__PURE__ */ jsxs3("div", { className: "cnfy-news-card-meta", children: [
767
+ /* @__PURE__ */ jsx4(
727
768
  "span",
728
769
  {
729
- className: "inline-flex items-center rounded-full px-2 py-0.5 font-medium border",
770
+ className: "cnfy-news-badge",
730
771
  style: {
731
772
  backgroundColor: lightenColor(primaryColorState, 95),
732
773
  color: primaryColor,
@@ -735,38 +776,37 @@ function NewsList({
735
776
  children: item.sourceName
736
777
  }
737
778
  ),
738
- /* @__PURE__ */ jsx5("span", { children: "\u2022" }),
739
- /* @__PURE__ */ jsx5("span", { className: "capitalize", children: item.category }),
740
- /* @__PURE__ */ jsx5("span", { children: "\u2022" }),
741
- /* @__PURE__ */ jsxs4("span", { children: [
779
+ /* @__PURE__ */ jsx4("span", { children: "\u2022" }),
780
+ /* @__PURE__ */ jsx4("span", { className: "cnfy-news-card-category", children: item.category }),
781
+ /* @__PURE__ */ jsx4("span", { children: "\u2022" }),
782
+ /* @__PURE__ */ jsxs3("span", { children: [
742
783
  dateFormatter.format(publishedDate),
743
784
  " ",
744
785
  timeFormatter.format(publishedDate)
745
786
  ] })
746
787
  ] })
747
788
  ] }),
748
- /* @__PURE__ */ jsxs4("div", { className: "flex flex-col gap-2 shrink-0", children: [
749
- /* @__PURE__ */ jsx5(
789
+ /* @__PURE__ */ jsxs3("div", { className: "cnfy-news-card-actions", children: [
790
+ /* @__PURE__ */ jsx4(
750
791
  "button",
751
792
  {
752
793
  onClick: () => onView(item),
753
- className: "p-1 text-gray-400 hover:text-gray-700",
794
+ className: "cnfy-news-action-btn",
754
795
  title: "View",
755
- children: /* @__PURE__ */ jsx5(Eye, { size: 16 })
796
+ children: /* @__PURE__ */ jsx4(Eye, { size: 16 })
756
797
  }
757
798
  ),
758
- /* @__PURE__ */ jsx5(
799
+ /* @__PURE__ */ jsx4(
759
800
  "button",
760
801
  {
761
802
  onClick: () => onRecreate({
762
803
  title: item.title,
763
804
  content: item.content || item.title,
764
805
  id: item._id
765
- // Include article ID
766
806
  }),
767
- className: "p-1 text-gray-400 hover:text-gray-700",
807
+ className: "cnfy-news-action-btn",
768
808
  title: "Recreate",
769
- children: /* @__PURE__ */ jsx5(RefreshCcw, { size: 16 })
809
+ children: /* @__PURE__ */ jsx4(RefreshCcw, { size: 16 })
770
810
  }
771
811
  )
772
812
  ] })
@@ -797,7 +837,7 @@ var getNewsBySource = async (sourceId) => {
797
837
 
798
838
  // components/chatbot/ChatWindow.tsx
799
839
  import Select from "react-select";
800
- import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
840
+ import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
801
841
  var ACTION_ICONS = {
802
842
  recreate_article: RefreshCcw2,
803
843
  create_summary: ListChecks,
@@ -973,59 +1013,59 @@ function ChatWindow({
973
1013
  });
974
1014
  return { blocks, metaKeywords };
975
1015
  }
976
- return /* @__PURE__ */ jsxs5("div", { className: "h-full flex w-full flex-col", children: [
977
- /* @__PURE__ */ jsx6("div", { className: "flex-1 px-4 py-6", children: /* @__PURE__ */ jsxs5("div", { className: "max-w-3xl chat-scroll mx-auto space-y-6", children: [
1016
+ return /* @__PURE__ */ jsxs4("div", { className: "cnfy-chat", children: [
1017
+ /* @__PURE__ */ jsx5("div", { className: "cnfy-chat-area", children: /* @__PURE__ */ jsxs4("div", { className: "cnfy-chat-scroll", children: [
978
1018
  messages.map((msg) => {
979
1019
  var _a2;
980
1020
  const parsed = formatAIContent(msg.content);
981
- return /* @__PURE__ */ jsxs5("div", { className: "flex gap-3", children: [
982
- /* @__PURE__ */ jsx6("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsx6(
1021
+ return /* @__PURE__ */ jsxs4("div", { className: "cnfy-msg", children: [
1022
+ /* @__PURE__ */ jsx5("div", { className: "cnfy-msg-avatar-wrap", children: /* @__PURE__ */ jsx5(
983
1023
  "div",
984
1024
  {
985
- className: "h-8 w-8 rounded-full flex items-center justify-center text-xs font-semibold text-white",
1025
+ className: "cnfy-msg-avatar",
986
1026
  style: {
987
1027
  backgroundColor: msg.role === "assistant" ? primaryColor : "#1f2937"
988
1028
  },
989
1029
  children: msg.role === "assistant" ? "AI" : "You"
990
1030
  }
991
1031
  ) }),
992
- /* @__PURE__ */ jsxs5("div", { className: "flex-1 text-sm space-y-3 leading-relaxed", children: [
993
- msg.role === "assistant" && parsed.blocks.length > 0 && /* @__PURE__ */ jsx6("div", { className: "flex justify-end -mt-1 mb-2", children: /* @__PURE__ */ jsx6(
1032
+ /* @__PURE__ */ jsxs4("div", { className: "cnfy-msg-body", children: [
1033
+ msg.role === "assistant" && parsed.blocks.length > 0 && /* @__PURE__ */ jsx5("div", { className: "cnfy-msg-copy-row", children: /* @__PURE__ */ jsx5(
994
1034
  "button",
995
1035
  {
996
1036
  onClick: () => handleCopy(parsed.blocks, msg.id),
997
- className: "p-1.5 rounded-md hover:bg-gray-100 transition-colors text-gray-400 hover:text-gray-600",
1037
+ className: "cnfy-copy-btn",
998
1038
  title: "Copy to clipboard",
999
- children: copiedId === msg.id ? /* @__PURE__ */ jsx6(Check, { size: 16, className: "text-emerald-600" }) : /* @__PURE__ */ jsx6(Copy, { size: 16 })
1039
+ children: copiedId === msg.id ? /* @__PURE__ */ jsx5(Check, { size: 16, className: "cnfy-copy-icon--copied" }) : /* @__PURE__ */ jsx5(Copy, { size: 16 })
1000
1040
  }
1001
1041
  ) }),
1002
1042
  parsed.blocks.map((block, idx) => {
1003
1043
  if (block.type === "h1") {
1004
- return /* @__PURE__ */ jsx6(
1044
+ return /* @__PURE__ */ jsx5(
1005
1045
  "h1",
1006
1046
  {
1007
- className: "text-sm font-semibold",
1047
+ className: "cnfy-block-h1",
1008
1048
  children: block.text
1009
1049
  },
1010
1050
  idx
1011
1051
  );
1012
1052
  }
1013
1053
  if (block.type === "h2") {
1014
- return /* @__PURE__ */ jsx6(
1054
+ return /* @__PURE__ */ jsx5(
1015
1055
  "h2",
1016
1056
  {
1017
- className: "text-base font-semibold mt-4",
1057
+ className: "cnfy-block-h2",
1018
1058
  children: block.text
1019
1059
  },
1020
1060
  idx
1021
1061
  );
1022
1062
  }
1023
- return /* @__PURE__ */ jsx6("p", { className: "text-gray-800", children: block.text }, idx);
1063
+ return /* @__PURE__ */ jsx5("p", { className: "cnfy-block-p", children: block.text }, idx);
1024
1064
  }),
1025
- parsed.metaKeywords.length > 0 && /* @__PURE__ */ jsx6("div", { className: "pt-4 border-t mt-6", children: /* @__PURE__ */ jsx6("div", { className: "flex flex-wrap gap-2", children: parsed.metaKeywords.map((tag, i) => /* @__PURE__ */ jsxs5(
1065
+ parsed.metaKeywords.length > 0 && /* @__PURE__ */ jsx5("div", { className: "cnfy-msg-keywords", children: /* @__PURE__ */ jsx5("div", { className: "cnfy-msg-keywords-list", children: parsed.metaKeywords.map((tag, i) => /* @__PURE__ */ jsxs4(
1026
1066
  "span",
1027
1067
  {
1028
- className: "text-xs px-3 py-1 rounded-full bg-gray-100 text-gray-700",
1068
+ className: "cnfy-msg-keyword-tag",
1029
1069
  children: [
1030
1070
  "#",
1031
1071
  tag
@@ -1033,41 +1073,41 @@ function ChatWindow({
1033
1073
  },
1034
1074
  i
1035
1075
  )) }) }),
1036
- msg.role === "assistant" && (analyzedData == null ? void 0 : analyzedData.messageId) === msg.id && analyzedData.options.length > 0 && /* @__PURE__ */ jsx6("div", { className: "flex flex-wrap gap-2 pt-4 mt-2", children: analyzedData.options.map((option) => {
1076
+ msg.role === "assistant" && (analyzedData == null ? void 0 : analyzedData.messageId) === msg.id && analyzedData.options.length > 0 && /* @__PURE__ */ jsx5("div", { className: "cnfy-action-options", children: analyzedData.options.map((option) => {
1037
1077
  const IconComponent = ACTION_ICONS[option.id] || FileText;
1038
- return /* @__PURE__ */ jsxs5(
1078
+ return /* @__PURE__ */ jsxs4(
1039
1079
  "button",
1040
1080
  {
1041
1081
  onClick: () => onSelectAction == null ? void 0 : onSelectAction(option.id, analyzedData.url, analyzedData.content),
1042
- className: "flex items-center gap-2 px-4 py-2 border border-gray-200 rounded-lg text-sm font-medium text-gray-700 hover:bg-gray-50 hover:border-gray-300 transition-colors",
1082
+ className: "cnfy-action-btn",
1043
1083
  children: [
1044
- /* @__PURE__ */ jsx6(IconComponent, { size: 16 }),
1084
+ /* @__PURE__ */ jsx5(IconComponent, { size: 16 }),
1045
1085
  option.name
1046
1086
  ]
1047
1087
  },
1048
1088
  option.id
1049
1089
  );
1050
1090
  }) }),
1051
- msg.role === "assistant" && parsed.blocks.length > 0 && !(analyzedData == null ? void 0 : analyzedData.messageId) && (!isStreaming || msg.id !== ((_a2 = messages[messages.length - 1]) == null ? void 0 : _a2.id)) && /* @__PURE__ */ jsxs5("div", { className: "flex gap-3 pt-4 mt-2", children: [
1052
- /* @__PURE__ */ jsxs5(
1091
+ msg.role === "assistant" && parsed.blocks.length > 0 && !(analyzedData == null ? void 0 : analyzedData.messageId) && (!isStreaming || msg.id !== ((_a2 = messages[messages.length - 1]) == null ? void 0 : _a2.id)) && /* @__PURE__ */ jsxs4("div", { className: "cnfy-msg-actions", children: [
1092
+ /* @__PURE__ */ jsxs4(
1053
1093
  "button",
1054
1094
  {
1055
1095
  onClick: () => handleEdit(parsed.blocks, parsed.metaKeywords, msg.id),
1056
- className: "flex items-center gap-2 px-4 py-2 border border-gray-300 rounded-lg text-sm font-medium text-gray-700 hover:bg-gray-50 transition-colors",
1096
+ className: "cnfy-btn-edit",
1057
1097
  children: [
1058
- /* @__PURE__ */ jsx6(Edit3, { size: 16 }),
1098
+ /* @__PURE__ */ jsx5(Edit3, { size: 16 }),
1059
1099
  "Edit"
1060
1100
  ]
1061
1101
  }
1062
1102
  ),
1063
- /* @__PURE__ */ jsxs5(
1103
+ /* @__PURE__ */ jsxs4(
1064
1104
  "button",
1065
1105
  {
1066
1106
  onClick: () => handlePost(msg.content, parsed.metaKeywords),
1067
- className: "flex items-center gap-2 px-4 py-2 rounded-lg text-sm font-medium text-white hover:bg-emerald-700 transition-colors",
1107
+ className: "cnfy-btn-post",
1068
1108
  style: { backgroundColor: primaryColor, color: "#fff" },
1069
1109
  children: [
1070
- /* @__PURE__ */ jsx6(Send, { size: 16 }),
1110
+ /* @__PURE__ */ jsx5(Send, { size: 16 }),
1071
1111
  "Post"
1072
1112
  ]
1073
1113
  }
@@ -1076,34 +1116,34 @@ function ChatWindow({
1076
1116
  ] })
1077
1117
  ] }, msg.id);
1078
1118
  }),
1079
- /* @__PURE__ */ jsx6("div", { ref: bottomRef })
1119
+ /* @__PURE__ */ jsx5("div", { ref: bottomRef })
1080
1120
  ] }) }),
1081
- /* @__PURE__ */ jsx6("div", { className: "shrink-0 bg-white px-4 py-3", children: /* @__PURE__ */ jsxs5("div", { className: "max-w-3xl mx-auto relative flex gap-2 items-end", children: [
1082
- !showNewsPanel && /* @__PURE__ */ jsxs5("div", { ref: dropdownRef, className: "absolute left-3 top-1/2 -translate-y-1/2 z-10", children: [
1083
- /* @__PURE__ */ jsx6(
1121
+ /* @__PURE__ */ jsx5("div", { className: "cnfy-input-area", children: /* @__PURE__ */ jsxs4("div", { className: "cnfy-input-inner", children: [
1122
+ /* @__PURE__ */ jsxs4("div", { ref: dropdownRef, className: "cnfy-news-pulse-wrap", children: [
1123
+ /* @__PURE__ */ jsx5(
1084
1124
  "button",
1085
1125
  {
1086
1126
  onClick: handleOpenNewsDropdown,
1087
- className: "flex h-8 w-8 items-center justify-center rounded-full bg-gradient-to-r from-purple-500 to-pink-500 text-white hover:from-purple-600 hover:to-pink-600 transition-all animate-pulse hover:animate-none",
1127
+ className: "cnfy-news-pulse-btn cnfy-animate-pulse",
1088
1128
  title: "Select from trending news",
1089
- children: /* @__PURE__ */ jsx6(Zap, { size: 16 })
1129
+ children: /* @__PURE__ */ jsx5(Zap, { size: 16 })
1090
1130
  }
1091
1131
  ),
1092
- showNewsDropdown && /* @__PURE__ */ jsxs5("div", { className: "absolute bottom-full left-0 mb-2 w-[600px] bg-white border border-gray-200 rounded-lg shadow-xl max-h-[600px] overflow-hidden", children: [
1093
- /* @__PURE__ */ jsxs5("div", { className: "flex items-center justify-between px-3 py-2 border-b border-gray-100", style: { backgroundColor: primaryColor, color: "#fff" }, children: [
1094
- /* @__PURE__ */ jsx6("span", { className: "text-sm font-medium text-white", children: "Select News" }),
1095
- /* @__PURE__ */ jsx6(
1132
+ showNewsDropdown && /* @__PURE__ */ jsxs4("div", { className: "cnfy-news-dropdown", children: [
1133
+ /* @__PURE__ */ jsxs4("div", { className: "cnfy-news-dropdown-header", style: { backgroundColor: primaryColor, color: "#fff" }, children: [
1134
+ /* @__PURE__ */ jsx5("span", { className: "cnfy-news-dropdown-title", children: "Select News" }),
1135
+ /* @__PURE__ */ jsx5(
1096
1136
  "button",
1097
1137
  {
1098
1138
  onClick: () => setShowNewsDropdown(false),
1099
- className: "p-1 hover:bg-gray-200 rounded transition",
1139
+ className: "cnfy-news-dropdown-close",
1100
1140
  style: { backgroundColor: primaryColor, color: "#fff" },
1101
- children: /* @__PURE__ */ jsx6(X2, { size: 14, className: "text-white" })
1141
+ children: /* @__PURE__ */ jsx5(X2, { size: 14 })
1102
1142
  }
1103
1143
  )
1104
1144
  ] }),
1105
- /* @__PURE__ */ jsxs5("div", { className: "px-3 py-2 border-b border-gray-100 flex items-center gap-2", children: [
1106
- /* @__PURE__ */ jsx6("div", { className: "flex-1 min-w-[180px]", children: /* @__PURE__ */ jsx6(
1145
+ /* @__PURE__ */ jsxs4("div", { className: "cnfy-news-dropdown-source", children: [
1146
+ /* @__PURE__ */ jsx5("div", { className: "cnfy-news-dropdown-select-wrap", children: /* @__PURE__ */ jsx5(
1107
1147
  Select,
1108
1148
  {
1109
1149
  options: [
@@ -1149,36 +1189,36 @@ function ChatWindow({
1149
1189
  }
1150
1190
  }
1151
1191
  ) }),
1152
- selectedSource && /* @__PURE__ */ jsxs5(
1192
+ selectedSource && /* @__PURE__ */ jsxs4(
1153
1193
  "button",
1154
1194
  {
1155
1195
  onClick: handleScrape,
1156
1196
  disabled: scraping,
1157
- className: "flex items-center gap-1.5 px-3 py-2 bg-emerald-600 text-white rounded-lg text-sm font-medium hover:bg-emerald-700 transition disabled:opacity-50",
1197
+ className: "cnfy-scrape-btn",
1158
1198
  title: "Fetch latest news",
1159
1199
  children: [
1160
- /* @__PURE__ */ jsx6(RefreshCcw2, { size: 14, className: scraping ? "animate-spin" : "" }),
1200
+ /* @__PURE__ */ jsx5(RefreshCcw2, { size: 14, className: scraping ? "cnfy-animate-spin" : "" }),
1161
1201
  scraping ? "Scraping..." : "Scrape"
1162
1202
  ]
1163
1203
  }
1164
1204
  ),
1165
- !selectedSource && /* @__PURE__ */ jsxs5(
1205
+ !selectedSource && /* @__PURE__ */ jsxs4(
1166
1206
  "button",
1167
1207
  {
1168
1208
  onClick: () => fetchNews(null),
1169
1209
  disabled: loadingNews,
1170
- className: "flex items-center gap-1 px-3 py-2 text-sm text-gray-600 hover:text-gray-900 border border-gray-200 rounded-lg transition",
1210
+ className: "cnfy-refresh-btn",
1171
1211
  children: [
1172
- /* @__PURE__ */ jsx6(RefreshCcw2, { size: 14, className: loadingNews ? "animate-spin" : "" }),
1212
+ /* @__PURE__ */ jsx5(RefreshCcw2, { size: 14, className: loadingNews ? "cnfy-animate-spin" : "" }),
1173
1213
  "Refresh"
1174
1214
  ]
1175
1215
  }
1176
1216
  )
1177
1217
  ] }),
1178
- /* @__PURE__ */ jsx6("div", { className: "overflow-y-auto max-h-[320px]", children: loadingNews ? /* @__PURE__ */ jsx6("div", { className: "p-4 text-center text-sm text-gray-500", children: "Loading news..." }) : trendingNews.length === 0 ? /* @__PURE__ */ jsxs5("div", { className: "p-4 text-center text-sm text-gray-500", children: [
1179
- /* @__PURE__ */ jsx6("p", { children: "No news found." }),
1180
- selectedSource && /* @__PURE__ */ jsx6("p", { className: "mt-1 text-xs", children: 'Click "Scrape" to fetch latest news.' })
1181
- ] }) : /* @__PURE__ */ jsx6(
1218
+ /* @__PURE__ */ jsx5("div", { className: "cnfy-news-dropdown-list", children: loadingNews ? /* @__PURE__ */ jsx5("div", { className: "cnfy-news-dropdown-msg", children: "Loading news..." }) : trendingNews.length === 0 ? /* @__PURE__ */ jsxs4("div", { className: "cnfy-news-dropdown-msg", children: [
1219
+ /* @__PURE__ */ jsx5("p", { children: "No news found." }),
1220
+ selectedSource && /* @__PURE__ */ jsx5("p", { className: "cnfy-news-dropdown-hint", children: 'Click "Scrape" to fetch latest news.' })
1221
+ ] }) : /* @__PURE__ */ jsx5(
1182
1222
  NewsList,
1183
1223
  {
1184
1224
  news: trendingNews.slice(0, 10),
@@ -1191,7 +1231,7 @@ function ChatWindow({
1191
1231
  ) })
1192
1232
  ] })
1193
1233
  ] }),
1194
- /* @__PURE__ */ jsx6(
1234
+ /* @__PURE__ */ jsx5(
1195
1235
  "textarea",
1196
1236
  {
1197
1237
  ref: textareaRef,
@@ -1205,21 +1245,21 @@ function ChatWindow({
1205
1245
  },
1206
1246
  rows: 1,
1207
1247
  placeholder: "Ask AI something\u2026",
1208
- className: `flex-1 resize-none overflow-hidden border border-gray-300 ${!showNewsPanel ? "!pl-14" : "!pl-5"} !pr-[50px] input_box_textarea`,
1248
+ className: `cnfy-chat-textarea ${!showNewsPanel ? "cnfy-chat-textarea--with-pulse" : ""}`,
1209
1249
  style: { maxHeight: "200px", overflowY: input.split("\n").length > 6 ? "auto" : "hidden" }
1210
1250
  }
1211
1251
  ),
1212
- /* @__PURE__ */ jsx6(
1252
+ /* @__PURE__ */ jsx5(
1213
1253
  "button",
1214
1254
  {
1215
1255
  onClick: handleSend,
1216
- className: "flex h-10 w-10 absolute right-[10px] top-[5px] items-center justify-center rounded-full bg-emerald-600 text-white",
1256
+ className: "cnfy-send-btn",
1217
1257
  style: { backgroundColor: primaryColor, color: "#fff" },
1218
- children: /* @__PURE__ */ jsx6(SendHorizontal, { size: 18 })
1258
+ children: /* @__PURE__ */ jsx5(SendHorizontal, { size: 18 })
1219
1259
  }
1220
1260
  )
1221
1261
  ] }) }),
1222
- /* @__PURE__ */ jsx6(
1262
+ /* @__PURE__ */ jsx5(
1223
1263
  EditModal,
1224
1264
  {
1225
1265
  isOpen: editModal.isOpen,
@@ -1234,340 +1274,611 @@ function ChatWindow({
1234
1274
  }
1235
1275
 
1236
1276
  // components/chatbot/UserMenu.tsx
1237
- import { useEffect as useEffect5, useRef as useRef2, useState as useState5 } from "react";
1238
- import {
1239
- Settings,
1240
- User,
1241
- HelpCircle,
1242
- LogOut,
1243
- Palette
1244
- } from "lucide-react";
1245
- import toast from "react-hot-toast";
1246
-
1247
- // services/auth.service.ts
1248
- var logoutUser = async () => {
1249
- const { data } = await api_default.post("/auth/logout");
1250
- return data;
1251
- };
1252
-
1253
- // components/chatbot/UserMenu.tsx
1254
- import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
1277
+ import { Settings } from "lucide-react";
1278
+ import { jsx as jsx6 } from "react/jsx-runtime";
1255
1279
  function UserMenu({
1256
- onNavigate,
1257
- onLogout
1280
+ onOpenPreferences
1258
1281
  }) {
1259
- const [open, setOpen] = useState5(false);
1260
- const ref = useRef2(null);
1261
- useEffect5(() => {
1262
- const handler = (e) => {
1263
- if (ref.current && !ref.current.contains(e.target)) {
1264
- setOpen(false);
1265
- }
1266
- };
1267
- document.addEventListener("mousedown", handler);
1268
- return () => document.removeEventListener("mousedown", handler);
1269
- }, []);
1270
- function go(path) {
1271
- setOpen(false);
1272
- onNavigate == null ? void 0 : onNavigate(path);
1273
- }
1274
- async function logout() {
1275
- setOpen(false);
1276
- if (onLogout) {
1277
- onLogout();
1278
- return;
1279
- }
1280
- try {
1281
- await logoutUser();
1282
- toast.success("Logged out successfully");
1283
- onNavigate == null ? void 0 : onNavigate("/login");
1284
- } catch (err) {
1285
- toast.error(err || "Logout failed");
1286
- }
1287
- }
1288
- return /* @__PURE__ */ jsxs6("div", { ref, className: "relative", children: [
1289
- /* @__PURE__ */ jsx7(
1290
- "button",
1291
- {
1292
- onClick: () => setOpen((v) => !v),
1293
- className: "p-2 rounded-full hover:bg-gray-100 transition",
1294
- "aria-label": "Settings",
1295
- children: /* @__PURE__ */ jsx7(Settings, { size: 20, className: "text-gray-600" })
1296
- }
1297
- ),
1298
- open && /* @__PURE__ */ jsxs6("div", { className: "absolute right-0 top-full mb-2 w-52 bg-white border border-gray-200 rounded-lg shadow-lg z-50", children: [
1299
- /* @__PURE__ */ jsx7(MenuItem, { icon: User, label: "Account", onClick: () => go("/dashboard/account") }),
1300
- /* @__PURE__ */ jsx7(MenuItem, { icon: Settings, label: "Preferences", onClick: () => go("/dashboard/preferences") }),
1301
- /* @__PURE__ */ jsx7(MenuItem, { icon: Palette, label: "Appearance", onClick: () => go("/dashboard/appearance") }),
1302
- /* @__PURE__ */ jsx7(MenuItem, { icon: HelpCircle, label: "Settings", onClick: () => go("/dashboard/settings") }),
1303
- /* @__PURE__ */ jsx7(MenuItem, { icon: HelpCircle, label: "Help & Support", onClick: () => go("/dashboard/help") }),
1304
- /* @__PURE__ */ jsx7("div", { className: "border-t border-gray-300 my-1" }),
1305
- /* @__PURE__ */ jsx7(
1306
- MenuItem,
1307
- {
1308
- icon: LogOut,
1309
- label: "Logout",
1310
- danger: true,
1311
- onClick: logout
1312
- }
1313
- )
1314
- ] })
1315
- ] });
1316
- }
1317
- function MenuItem({
1318
- icon: Icon,
1319
- label,
1320
- onClick,
1321
- danger = false
1322
- }) {
1323
- return /* @__PURE__ */ jsxs6(
1282
+ return /* @__PURE__ */ jsx6("div", { className: "cnfy-user-menu", children: /* @__PURE__ */ jsx6(
1324
1283
  "button",
1325
1284
  {
1326
- onClick,
1327
- className: `w-full flex items-center gap-2 px-4 py-2 text-sm transition ${danger ? "text-red-600 hover:bg-red-50" : "text-gray-700 hover:bg-gray-100"}`,
1328
- children: [
1329
- /* @__PURE__ */ jsx7(Icon, { size: 16 }),
1330
- label
1331
- ]
1285
+ onClick: () => onOpenPreferences == null ? void 0 : onOpenPreferences(),
1286
+ className: "cnfy-user-menu-trigger",
1287
+ "aria-label": "Settings",
1288
+ children: /* @__PURE__ */ jsx6(Settings, { size: 20, className: "cnfy-user-menu-trigger-icon" })
1332
1289
  }
1333
- );
1290
+ ) });
1334
1291
  }
1335
1292
 
1336
1293
  // components/chatbot/headerBar.tsx
1337
- import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
1294
+ import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
1338
1295
  function HeaderBar({
1339
- onNavigate,
1340
- onLogout
1296
+ onOpenPreferences
1341
1297
  }) {
1342
1298
  const { primaryColor, botName, logoUrl } = useTheme();
1343
- return /* @__PURE__ */ jsx8("header", { className: "sticky top-0 z-40 bg-white border-b border-gray-200", children: /* @__PURE__ */ jsxs7("div", { className: "mx-auto flex h-14 items-center justify-between px-4", children: [
1344
- /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-3 cursor-pointer", onClick: () => onNavigate == null ? void 0 : onNavigate("/"), children: [
1345
- logoUrl ? /* @__PURE__ */ jsx8("img", { src: logoUrl, alt: "Logo", className: "h-8 w-8 rounded-md object-cover" }) : /* @__PURE__ */ jsx8(
1299
+ return /* @__PURE__ */ jsx7("header", { className: "cnfy-header", children: /* @__PURE__ */ jsxs5("div", { className: "cnfy-header-inner", children: [
1300
+ /* @__PURE__ */ jsxs5("div", { className: "cnfy-header-left", children: [
1301
+ logoUrl ? /* @__PURE__ */ jsx7("img", { src: logoUrl, alt: "Logo", className: "cnfy-header-logo-img" }) : /* @__PURE__ */ jsx7(
1346
1302
  "div",
1347
1303
  {
1348
- className: "h-8 w-8 rounded-md text-white flex items-center justify-center font-bold text-sm",
1304
+ className: "cnfy-header-logo-fallback",
1349
1305
  style: { backgroundColor: primaryColor },
1350
1306
  children: botName.charAt(0).toUpperCase()
1351
1307
  }
1352
1308
  ),
1353
- /* @__PURE__ */ jsx8("span", { className: "font-semibold text-gray-900 text-base", children: botName.toUpperCase() })
1309
+ /* @__PURE__ */ jsx7("span", { className: "cnfy-header-brand", children: botName.toUpperCase() })
1354
1310
  ] }),
1355
- /* @__PURE__ */ jsx8("div", { className: "flex items-center gap-3", children: /* @__PURE__ */ jsx8(UserMenu, { onNavigate, onLogout }) })
1311
+ /* @__PURE__ */ jsx7("div", { className: "cnfy-header-right", children: /* @__PURE__ */ jsx7(UserMenu, { onOpenPreferences }) })
1356
1312
  ] }) });
1357
1313
  }
1358
1314
 
1359
- // components/news/TrendingNews.tsx
1360
- import { useEffect as useEffect6, useState as useState6, useCallback } from "react";
1361
- import toast2 from "react-hot-toast";
1362
- import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
1363
- function TrendingNews({
1364
- onRecreate,
1365
- selectedSource,
1366
- refreshKey,
1367
- news: externalNews,
1368
- isLoading: externalLoading
1315
+ // components/ui/Drawer.tsx
1316
+ import { useEffect as useEffect5 } from "react";
1317
+ import { X as X3 } from "lucide-react";
1318
+ import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
1319
+ function Drawer({
1320
+ open,
1321
+ onClose,
1322
+ title,
1323
+ children
1369
1324
  }) {
1370
- const [news, setNews] = useState6([]);
1371
- const [loading, setLoading] = useState6(false);
1372
- const displayNews = externalNews !== void 0 ? externalNews : news;
1373
- const isLoading = externalLoading !== void 0 ? externalLoading : loading;
1374
- const fetchNews = useCallback(async () => {
1375
- if (externalNews !== void 0) {
1376
- return;
1377
- }
1378
- setLoading(true);
1379
- try {
1380
- let data;
1381
- if (selectedSource) {
1382
- data = await getNewsBySource(selectedSource);
1383
- } else {
1384
- data = await getTrendingNews();
1385
- }
1386
- setNews(data || []);
1387
- } catch (e) {
1388
- toast2.error("Failed to load news");
1389
- } finally {
1390
- setLoading(false);
1391
- }
1392
- }, [selectedSource, externalNews]);
1393
- useEffect6(() => {
1394
- fetchNews();
1395
- }, [fetchNews, refreshKey]);
1396
- function handleView(item) {
1397
- window.open(item.sourceUrl || item.link, "_blank");
1398
- }
1399
- if (isLoading) {
1400
- return /* @__PURE__ */ jsx9("div", { className: "p-4 text-sm text-gray-500", children: "Loading news..." });
1401
- }
1402
- if (!displayNews || displayNews.length === 0) {
1403
- return /* @__PURE__ */ jsxs8("div", { className: "p-4 text-sm text-gray-500 text-center", children: [
1404
- /* @__PURE__ */ jsx9("p", { children: "No news found for this source." }),
1405
- /* @__PURE__ */ jsx9("p", { className: "mt-1 text-xs", children: 'Click "Scrape" to fetch latest news.' })
1406
- ] });
1407
- }
1408
- return /* @__PURE__ */ jsx9(
1409
- NewsList,
1410
- {
1411
- news: displayNews,
1412
- onView: handleView,
1413
- onRecreate
1325
+ useEffect5(() => {
1326
+ if (open) {
1327
+ document.body.style.overflow = "hidden";
1328
+ } else {
1329
+ document.body.style.overflow = "";
1414
1330
  }
1415
- );
1331
+ return () => {
1332
+ document.body.style.overflow = "";
1333
+ };
1334
+ }, [open]);
1335
+ if (!open) return null;
1336
+ return /* @__PURE__ */ jsxs6("div", { className: "cnfy-drawer-overlay", children: [
1337
+ /* @__PURE__ */ jsx8("div", { className: "cnfy-drawer-backdrop", onClick: onClose }),
1338
+ /* @__PURE__ */ jsxs6("div", { className: "cnfy-drawer-panel", children: [
1339
+ /* @__PURE__ */ jsxs6("div", { className: "cnfy-drawer-header", children: [
1340
+ title && /* @__PURE__ */ jsx8("h2", { className: "cnfy-drawer-title", children: title }),
1341
+ /* @__PURE__ */ jsx8("button", { onClick: onClose, className: "cnfy-drawer-close-btn", children: /* @__PURE__ */ jsx8(X3, { size: 20 }) })
1342
+ ] }),
1343
+ /* @__PURE__ */ jsx8("div", { className: "cnfy-drawer-body", children })
1344
+ ] })
1345
+ ] });
1416
1346
  }
1417
1347
 
1418
- // components/news/SourceSelector.tsx
1419
- import { useEffect as useEffect7, useState as useState7, useCallback as useCallback2 } from "react";
1420
- import { RefreshCcw as RefreshCcw3 } from "lucide-react";
1421
- import Select2 from "react-select";
1422
- import toast3 from "react-hot-toast";
1423
- import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
1424
- var ALL_SOURCES_VALUE = "__all__";
1425
- function SourceSelector({
1426
- selectedSource,
1427
- onSourceChange,
1428
- onScrapeComplete,
1429
- onNewsLoaded,
1430
- onLoadingChange
1431
- }) {
1432
- const [sources, setSources] = useState7([]);
1433
- const [loading, setLoading] = useState7(true);
1434
- const [scraping, setScraping] = useState7(false);
1435
- const [fetchingNews, setFetchingNews] = useState7(true);
1436
- const { primaryColor } = useTheme();
1437
- useEffect7(() => {
1438
- onLoadingChange == null ? void 0 : onLoadingChange(fetchingNews);
1439
- }, [fetchingNews, onLoadingChange]);
1348
+ // components/preferences/Preferences.tsx
1349
+ import { useState as useState6, useEffect as useEffect7 } from "react";
1350
+ import toast from "react-hot-toast";
1351
+
1352
+ // services/settings.service.ts
1353
+ var triggerScrape = async ({
1354
+ state,
1355
+ cities
1356
+ }) => {
1357
+ const { data } = await api_default.post("/scrape/trigger", {
1358
+ state,
1359
+ cities
1360
+ });
1361
+ return data;
1362
+ };
1363
+ var getScrapeStatus = async () => {
1364
+ const { data } = await api_default.get("/scrape/status");
1365
+ return data.data;
1366
+ };
1367
+
1368
+ // components/ClientSelect.tsx
1369
+ import { useEffect as useEffect6, useState as useState5 } from "react";
1370
+ import { jsx as jsx9 } from "react/jsx-runtime";
1371
+ var ReactSelect = null;
1372
+ var ClientSelect = (props) => {
1373
+ const [mounted, setMounted] = useState5(false);
1374
+ useEffect6(() => {
1375
+ setMounted(true);
1376
+ import("react-select").then((mod) => {
1377
+ ReactSelect = mod.default;
1378
+ });
1379
+ }, []);
1380
+ if (!mounted || !ReactSelect) return null;
1381
+ return /* @__PURE__ */ jsx9(ReactSelect, __spreadValues({}, props));
1382
+ };
1383
+ var ClientSelect_default = ClientSelect;
1384
+
1385
+ // components/preferences/Preferences.tsx
1386
+ import { Fragment, jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
1387
+ var STATE_OPTIONS = [
1388
+ { value: "Uttar Pradesh", label: "Uttar Pradesh" }
1389
+ ];
1390
+ var CITY_OPTIONS = [
1391
+ "Agra",
1392
+ "Aligarh",
1393
+ "Ayodhya",
1394
+ "Bareilly",
1395
+ "Bijnor",
1396
+ "Bulandshahr",
1397
+ "Etawah",
1398
+ "Firozabad",
1399
+ "Ghaziabad",
1400
+ "Gorakhpur",
1401
+ "Jhansi",
1402
+ "Kanpur",
1403
+ "Lucknow",
1404
+ "Mathura",
1405
+ "Meerut",
1406
+ "Moradabad",
1407
+ "Muzaffarnagar",
1408
+ "Noida",
1409
+ "Prayagraj",
1410
+ "Rampur",
1411
+ "Saharanpur",
1412
+ "Sitapur",
1413
+ "Unnao",
1414
+ "Varanasi"
1415
+ ].map((city) => ({ value: city, label: city }));
1416
+ var LANGUAGE_OPTIONS = [
1417
+ { value: "en", label: "English" },
1418
+ { value: "hi", label: "Hindi" }
1419
+ ];
1420
+ var TONE_OPTIONS = [
1421
+ { value: "formal", label: "Formal" },
1422
+ { value: "casual", label: "Casual" },
1423
+ { value: "engaging", label: "Engaging" },
1424
+ { value: "professional", label: "Professional" }
1425
+ ];
1426
+ var STYLE_OPTIONS = [
1427
+ { value: "news", label: "News Article" },
1428
+ { value: "blog", label: "Blog Post" },
1429
+ { value: "editorial", label: "Editorial" },
1430
+ { value: "summary", label: "Summary" }
1431
+ ];
1432
+ var WORD_COUNT_OPTIONS = [
1433
+ { value: "short", label: "Short (~300 words)" },
1434
+ { value: "medium", label: "Medium (~600 words)" },
1435
+ { value: "long", label: "Long (~1000+ words)" }
1436
+ ];
1437
+ function PreferencesPage() {
1438
+ var _a, _b, _c;
1439
+ const { preferences, loading, refreshPreferences, updatePreferences } = usePreferences();
1440
+ const primaryColor = ((_a = preferences == null ? void 0 : preferences.chatbot) == null ? void 0 : _a.primaryColor) || "#10b981";
1441
+ const [botName, setBotName] = useState6("");
1442
+ const [logo, setLogo] = useState6(null);
1443
+ const [logoUrl, setLogoUrl] = useState6(null);
1444
+ const [state, setState] = useState6(null);
1445
+ const [cities, setCities] = useState6([]);
1446
+ const [language, setLanguage] = useState6(null);
1447
+ const [tone, setTone] = useState6(null);
1448
+ const [style, setStyle] = useState6(null);
1449
+ const [wordCount, setWordCount] = useState6(null);
1450
+ const [includeQuotes, setIncludeQuotes] = useState6(true);
1451
+ const [includeFAQ, setIncludeFAQ] = useState6(false);
1452
+ const [targetAudience, setTargetAudience] = useState6("");
1453
+ const [saving, setSaving] = useState6(false);
1454
+ const [success, setSuccess] = useState6(false);
1455
+ const [scraping, setScraping] = useState6(false);
1456
+ const [scrapeStatus, setScrapeStatus] = useState6(null);
1457
+ const [loadingStatus, setLoadingStatus] = useState6(true);
1458
+ const [originalValues, setOriginalValues] = useState6({
1459
+ botName: "",
1460
+ state: void 0,
1461
+ cities: [],
1462
+ language: void 0,
1463
+ tone: void 0,
1464
+ style: void 0,
1465
+ wordCount: void 0,
1466
+ includeQuotes: true,
1467
+ includeFAQ: false,
1468
+ targetAudience: ""
1469
+ });
1440
1470
  useEffect7(() => {
1441
- const fetchSources = async () => {
1471
+ const fetchScrapeStatus = async () => {
1442
1472
  try {
1443
- const data = await getNewsSources();
1444
- setSources(data || []);
1445
- } catch (e) {
1446
- toast3.error("Failed to load news sources");
1473
+ const data = await getScrapeStatus();
1474
+ setScrapeStatus(data);
1475
+ } catch (error) {
1476
+ console.log("Failed to fetch scrape status:", error);
1447
1477
  } finally {
1448
- setLoading(false);
1478
+ setLoadingStatus(false);
1449
1479
  }
1450
1480
  };
1451
- fetchSources();
1481
+ fetchScrapeStatus();
1452
1482
  }, []);
1453
- const fetchNews = useCallback2(async (sourceId) => {
1454
- setFetchingNews(true);
1483
+ const handleScrape = async () => {
1484
+ var _a2, _b2;
1485
+ setScraping(true);
1455
1486
  try {
1456
- let news;
1457
- if (sourceId) {
1458
- news = await getNewsBySource(sourceId);
1459
- } else {
1460
- news = await getTrendingNews();
1461
- }
1462
- onNewsLoaded == null ? void 0 : onNewsLoaded(news || []);
1463
- } catch (err) {
1464
- console.error("Failed to fetch news:", err);
1487
+ await triggerScrape({
1488
+ state: (_a2 = preferences == null ? void 0 : preferences.localization) == null ? void 0 : _a2.state,
1489
+ cities: (_b2 = preferences == null ? void 0 : preferences.localization) == null ? void 0 : _b2.cities
1490
+ });
1491
+ toast.success("News scraping started successfully!");
1492
+ setTimeout(async () => {
1493
+ try {
1494
+ const data = await getScrapeStatus();
1495
+ setScrapeStatus(data);
1496
+ } catch (e) {
1497
+ console.log("Failed to refresh scrape status:", e);
1498
+ }
1499
+ }, 2e3);
1500
+ } catch (error) {
1501
+ console.error(error);
1502
+ toast.error("Failed to trigger news scraping");
1465
1503
  } finally {
1466
- setFetchingNews(false);
1504
+ setScraping(false);
1467
1505
  }
1468
- }, []);
1469
- useEffect7(() => {
1470
- fetchNews(selectedSource);
1471
- }, [selectedSource, fetchNews]);
1472
- const handleSourceSelect = (option) => {
1473
- var _a;
1474
- const value = (option == null ? void 0 : option.value) === ALL_SOURCES_VALUE ? null : (_a = option == null ? void 0 : option.value) != null ? _a : null;
1475
- onSourceChange(value);
1476
1506
  };
1477
- const handleScrape = async () => {
1478
- if (!selectedSource) {
1479
- toast3.error("Please select a source first");
1507
+ useEffect7(() => {
1508
+ var _a2, _b2, _c2, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
1509
+ if (preferences) {
1510
+ const name = ((_a2 = preferences.chatbot) == null ? void 0 : _a2.name) || "";
1511
+ const pState = (_b2 = preferences.localization) == null ? void 0 : _b2.state;
1512
+ const pCities = ((_c2 = preferences.localization) == null ? void 0 : _c2.cities) || [];
1513
+ const pLanguage = (_d = preferences.localization) == null ? void 0 : _d.language;
1514
+ setBotName(name);
1515
+ if ((_e = preferences.chatbot) == null ? void 0 : _e.logoUrl) setLogoUrl(preferences.chatbot.logoUrl);
1516
+ if (pState) {
1517
+ setState({ value: pState, label: pState });
1518
+ }
1519
+ if (Array.isArray(pCities)) {
1520
+ setCities(pCities.map((city) => ({ value: city, label: city })));
1521
+ }
1522
+ if (pLanguage) {
1523
+ const langOption = LANGUAGE_OPTIONS.find((opt) => opt.value === pLanguage);
1524
+ setLanguage(langOption || null);
1525
+ }
1526
+ const pTone = (_f = preferences.content) == null ? void 0 : _f.tone;
1527
+ const pStyle = (_g = preferences.content) == null ? void 0 : _g.style;
1528
+ const pWordCount = (_h = preferences.content) == null ? void 0 : _h.wordCount;
1529
+ const pIncludeQuotes = (_j = (_i = preferences.content) == null ? void 0 : _i.includeQuotes) != null ? _j : true;
1530
+ const pIncludeFAQ = (_l = (_k = preferences.content) == null ? void 0 : _k.includeFAQ) != null ? _l : false;
1531
+ const pTargetAudience = ((_m = preferences.content) == null ? void 0 : _m.targetAudience) || "";
1532
+ if (pTone) {
1533
+ const toneOption = TONE_OPTIONS.find((opt) => opt.value === pTone);
1534
+ setTone(toneOption || null);
1535
+ }
1536
+ if (pStyle) {
1537
+ const styleOption = STYLE_OPTIONS.find((opt) => opt.value === pStyle);
1538
+ setStyle(styleOption || null);
1539
+ }
1540
+ if (pWordCount) {
1541
+ const wordCountOption = WORD_COUNT_OPTIONS.find((opt) => opt.value === pWordCount);
1542
+ setWordCount(wordCountOption || null);
1543
+ }
1544
+ setIncludeQuotes(pIncludeQuotes);
1545
+ setIncludeFAQ(pIncludeFAQ);
1546
+ setTargetAudience(pTargetAudience);
1547
+ setOriginalValues({
1548
+ botName: name,
1549
+ state: pState,
1550
+ cities: pCities,
1551
+ language: pLanguage,
1552
+ tone: pTone,
1553
+ style: pStyle,
1554
+ wordCount: pWordCount,
1555
+ includeQuotes: pIncludeQuotes,
1556
+ includeFAQ: pIncludeFAQ,
1557
+ targetAudience: pTargetAudience
1558
+ });
1559
+ }
1560
+ }, [preferences]);
1561
+ const handleSave = async () => {
1562
+ if (!botName) {
1563
+ toast.error("Chatbot name is required");
1480
1564
  return;
1481
1565
  }
1482
- setScraping(true);
1566
+ setSaving(true);
1567
+ setSuccess(false);
1483
1568
  try {
1484
- await scrapeNewsSource(selectedSource);
1485
- toast3.success("News scraped successfully!");
1486
- onScrapeComplete == null ? void 0 : onScrapeComplete();
1487
- const news = await getNewsBySource(selectedSource);
1488
- onNewsLoaded == null ? void 0 : onNewsLoaded(news || []);
1489
- } catch (err) {
1490
- toast3.error(err || "Failed to scrape news");
1569
+ const payload = {};
1570
+ if (botName !== originalValues.botName) {
1571
+ payload.botName = botName;
1572
+ }
1573
+ if (logo) {
1574
+ payload.logo = logo;
1575
+ }
1576
+ const currentState = state == null ? void 0 : state.value;
1577
+ if (currentState !== originalValues.state) {
1578
+ payload.state = currentState;
1579
+ }
1580
+ const currentCities = cities.map((c) => c.value);
1581
+ const citiesChanged = currentCities.length !== originalValues.cities.length || currentCities.some((city, index) => city !== originalValues.cities[index]);
1582
+ if (citiesChanged) {
1583
+ payload.cities = currentCities;
1584
+ }
1585
+ const currentLanguage = language == null ? void 0 : language.value;
1586
+ if (currentLanguage !== originalValues.language) {
1587
+ payload.language = currentLanguage;
1588
+ }
1589
+ const currentTone = tone == null ? void 0 : tone.value;
1590
+ if (currentTone !== originalValues.tone) {
1591
+ payload.tone = currentTone;
1592
+ }
1593
+ const currentStyle = style == null ? void 0 : style.value;
1594
+ if (currentStyle !== originalValues.style) {
1595
+ payload.style = currentStyle;
1596
+ }
1597
+ const currentWordCount = wordCount == null ? void 0 : wordCount.value;
1598
+ if (currentWordCount !== originalValues.wordCount) {
1599
+ payload.wordCount = currentWordCount;
1600
+ }
1601
+ if (includeQuotes !== originalValues.includeQuotes) {
1602
+ payload.includeQuotes = includeQuotes;
1603
+ }
1604
+ if (includeFAQ !== originalValues.includeFAQ) {
1605
+ payload.includeFAQ = includeFAQ;
1606
+ }
1607
+ if (targetAudience !== originalValues.targetAudience) {
1608
+ payload.targetAudience = targetAudience;
1609
+ }
1610
+ if (Object.keys(payload).length === 0) {
1611
+ toast.error("No changes to save");
1612
+ setSaving(false);
1613
+ return;
1614
+ }
1615
+ const updatedPreferences = await savePreferencesApi(payload);
1616
+ if (updatedPreferences) {
1617
+ updatePreferences(updatedPreferences);
1618
+ } else {
1619
+ await refreshPreferences();
1620
+ }
1621
+ setSuccess(true);
1622
+ setLogo(null);
1623
+ toast.success("Preferences saved successfully!");
1624
+ } catch (error) {
1625
+ console.error(error);
1626
+ toast.error("Failed to save preferences");
1491
1627
  } finally {
1492
- setScraping(false);
1628
+ setSaving(false);
1493
1629
  }
1494
1630
  };
1495
- const options = [
1496
- { value: ALL_SOURCES_VALUE, label: "All Sources (Trending)" },
1497
- ...sources.map((source) => ({
1498
- value: source.id,
1499
- label: source.name
1500
- }))
1501
- ];
1502
- const selectedOption = options.find(
1503
- (opt) => selectedSource === null ? opt.value === ALL_SOURCES_VALUE : opt.value === selectedSource
1504
- ) || options[0];
1505
- return /* @__PURE__ */ jsxs9("div", { className: "px-3 py-2 border-b border-gray-100 flex items-center gap-2", children: [
1506
- /* @__PURE__ */ jsx10("div", { className: "flex-1 min-w-[180px]", children: /* @__PURE__ */ jsx10(
1507
- Select2,
1508
- {
1509
- options,
1510
- value: selectedOption,
1511
- onChange: handleSourceSelect,
1512
- isLoading: loading,
1513
- isDisabled: loading,
1514
- placeholder: "Select source...",
1515
- classNamePrefix: "react-select",
1516
- menuPlacement: "bottom",
1517
- menuPosition: "fixed",
1518
- menuShouldScrollIntoView: false,
1519
- maxMenuHeight: 220,
1520
- menuPortalTarget: typeof window !== "undefined" ? document.body : null,
1521
- styles: {
1522
- container: (base) => __spreadProps(__spreadValues({}, base), {
1523
- width: "100%"
1524
- }),
1525
- control: (base) => __spreadProps(__spreadValues({}, base), {
1526
- minHeight: "38px",
1527
- borderColor: "#e5e7eb",
1528
- boxShadow: "none",
1529
- width: "100%"
1530
- }),
1531
- menu: (base) => __spreadProps(__spreadValues({}, base), {
1532
- width: "100%",
1533
- zIndex: 999999
1534
- }),
1535
- menuPortal: (base) => __spreadProps(__spreadValues({}, base), {
1536
- zIndex: 999999
1537
- }),
1538
- option: (base, state) => __spreadProps(__spreadValues({}, base), {
1539
- backgroundColor: state.isSelected ? primaryColor : state.isFocused ? "#f3f4f6" : "white",
1540
- color: state.isSelected ? "white" : "#374151",
1541
- cursor: "pointer"
1542
- })
1631
+ if (loading) {
1632
+ return /* @__PURE__ */ jsx10("div", { className: "cnfy-dash-page", children: /* @__PURE__ */ jsx10("p", { className: "cnfy-dash-page-subtitle", children: "Loading settings..." }) });
1633
+ }
1634
+ return /* @__PURE__ */ jsxs7("div", { className: "cnfy-dash-page", children: [
1635
+ /* @__PURE__ */ jsxs7("div", { className: "cnfy-dash-card", children: [
1636
+ /* @__PURE__ */ jsx10("h2", { className: "cnfy-dash-card-title", children: "Chatbot Settings" }),
1637
+ /* @__PURE__ */ jsxs7("div", { className: "cnfy-dash-field", children: [
1638
+ /* @__PURE__ */ jsx10("label", { className: "cnfy-dash-label", children: "Chatbot Name" }),
1639
+ /* @__PURE__ */ jsx10(
1640
+ "input",
1641
+ {
1642
+ value: botName,
1643
+ onChange: (e) => setBotName(e.target.value),
1644
+ className: "cnfy-dash-input",
1645
+ placeholder: "Contenify AI"
1646
+ }
1647
+ )
1648
+ ] }),
1649
+ /* @__PURE__ */ jsxs7("div", { className: "cnfy-dash-field", children: [
1650
+ /* @__PURE__ */ jsx10("label", { className: "cnfy-dash-label", children: "Chatbot Logo" }),
1651
+ /* @__PURE__ */ jsxs7("div", { className: "cnfy-logo-upload", children: [
1652
+ /* @__PURE__ */ jsx10("div", { className: "cnfy-logo-preview", children: logo ? /* @__PURE__ */ jsx10(
1653
+ "img",
1654
+ {
1655
+ src: URL.createObjectURL(logo),
1656
+ alt: "Logo preview",
1657
+ className: "cnfy-logo-img"
1658
+ }
1659
+ ) : logoUrl ? /* @__PURE__ */ jsx10(
1660
+ "img",
1661
+ {
1662
+ src: logoUrl,
1663
+ alt: "Current logo",
1664
+ className: "cnfy-logo-img"
1665
+ }
1666
+ ) : /* @__PURE__ */ jsx10("span", { className: "cnfy-logo-placeholder", children: "No logo" }) }),
1667
+ /* @__PURE__ */ jsx10(
1668
+ "input",
1669
+ {
1670
+ type: "file",
1671
+ accept: "image/*",
1672
+ onChange: (e) => {
1673
+ var _a2;
1674
+ return setLogo(((_a2 = e.target.files) == null ? void 0 : _a2[0]) || null);
1675
+ },
1676
+ className: "cnfy-file-input"
1677
+ }
1678
+ )
1679
+ ] })
1680
+ ] })
1681
+ ] }),
1682
+ /* @__PURE__ */ jsxs7("div", { className: "cnfy-dash-card", children: [
1683
+ /* @__PURE__ */ jsx10("h2", { className: "cnfy-dash-card-title", children: "Localization Settings" }),
1684
+ /* @__PURE__ */ jsxs7("div", { className: "cnfy-dash-field", children: [
1685
+ /* @__PURE__ */ jsx10("label", { className: "cnfy-dash-label", children: "State" }),
1686
+ /* @__PURE__ */ jsx10(
1687
+ ClientSelect_default,
1688
+ {
1689
+ options: STATE_OPTIONS,
1690
+ value: state,
1691
+ onChange: (option) => setState(option),
1692
+ placeholder: "Select state"
1693
+ }
1694
+ )
1695
+ ] }),
1696
+ /* @__PURE__ */ jsxs7("div", { className: "cnfy-dash-field", children: [
1697
+ /* @__PURE__ */ jsx10("label", { className: "cnfy-dash-label", children: "Cities" }),
1698
+ /* @__PURE__ */ jsx10(
1699
+ ClientSelect_default,
1700
+ {
1701
+ isMulti: true,
1702
+ options: CITY_OPTIONS,
1703
+ value: cities,
1704
+ onChange: (options) => setCities(options),
1705
+ placeholder: "Select cities",
1706
+ isDisabled: !state
1707
+ }
1708
+ )
1709
+ ] }),
1710
+ /* @__PURE__ */ jsxs7("div", { className: "cnfy-dash-field", children: [
1711
+ /* @__PURE__ */ jsx10("label", { className: "cnfy-dash-label", children: "Language" }),
1712
+ /* @__PURE__ */ jsx10(
1713
+ ClientSelect_default,
1714
+ {
1715
+ options: LANGUAGE_OPTIONS,
1716
+ value: language,
1717
+ onChange: (option) => setLanguage(option),
1718
+ placeholder: "Select language"
1719
+ }
1720
+ )
1721
+ ] })
1722
+ ] }),
1723
+ /* @__PURE__ */ jsxs7("div", { className: "cnfy-dash-card", children: [
1724
+ /* @__PURE__ */ jsx10("h2", { className: "cnfy-dash-card-title", children: "Content Generation Settings" }),
1725
+ /* @__PURE__ */ jsxs7("div", { className: "cnfy-dash-field", children: [
1726
+ /* @__PURE__ */ jsx10("label", { className: "cnfy-dash-label", children: "Tone" }),
1727
+ /* @__PURE__ */ jsx10(
1728
+ ClientSelect_default,
1729
+ {
1730
+ options: TONE_OPTIONS,
1731
+ value: tone,
1732
+ onChange: (option) => setTone(option),
1733
+ placeholder: "Select tone"
1734
+ }
1735
+ ),
1736
+ /* @__PURE__ */ jsx10("p", { className: "cnfy-dash-hint", children: "The writing tone for generated content" })
1737
+ ] }),
1738
+ /* @__PURE__ */ jsxs7("div", { className: "cnfy-dash-field", children: [
1739
+ /* @__PURE__ */ jsx10("label", { className: "cnfy-dash-label", children: "Style" }),
1740
+ /* @__PURE__ */ jsx10(
1741
+ ClientSelect_default,
1742
+ {
1743
+ options: STYLE_OPTIONS,
1744
+ value: style,
1745
+ onChange: (option) => setStyle(option),
1746
+ placeholder: "Select style"
1747
+ }
1748
+ ),
1749
+ /* @__PURE__ */ jsx10("p", { className: "cnfy-dash-hint", children: "The format/style of generated articles" })
1750
+ ] }),
1751
+ /* @__PURE__ */ jsxs7("div", { className: "cnfy-dash-field", children: [
1752
+ /* @__PURE__ */ jsx10("label", { className: "cnfy-dash-label", children: "Word Count" }),
1753
+ /* @__PURE__ */ jsx10(
1754
+ ClientSelect_default,
1755
+ {
1756
+ options: WORD_COUNT_OPTIONS,
1757
+ value: wordCount,
1758
+ onChange: (option) => setWordCount(option),
1759
+ placeholder: "Select word count"
1760
+ }
1761
+ ),
1762
+ /* @__PURE__ */ jsx10("p", { className: "cnfy-dash-hint", children: "Target length for generated content" })
1763
+ ] }),
1764
+ /* @__PURE__ */ jsxs7("div", { className: "cnfy-dash-field", children: [
1765
+ /* @__PURE__ */ jsx10("label", { className: "cnfy-dash-label", children: "Target Audience" }),
1766
+ /* @__PURE__ */ jsx10(
1767
+ "input",
1768
+ {
1769
+ value: targetAudience,
1770
+ onChange: (e) => setTargetAudience(e.target.value),
1771
+ className: "cnfy-dash-input",
1772
+ placeholder: "e.g. tech-savvy millennials, business professionals"
1773
+ }
1774
+ ),
1775
+ /* @__PURE__ */ jsx10("p", { className: "cnfy-dash-hint", children: "Describe your target audience for personalized content" })
1776
+ ] }),
1777
+ /* @__PURE__ */ jsxs7("div", { className: "cnfy-toggle-group", children: [
1778
+ /* @__PURE__ */ jsxs7("div", { className: "cnfy-toggle-row", children: [
1779
+ /* @__PURE__ */ jsxs7("div", { children: [
1780
+ /* @__PURE__ */ jsx10("p", { className: "cnfy-toggle-label", children: "Include Quotes" }),
1781
+ /* @__PURE__ */ jsx10("p", { className: "cnfy-toggle-desc", children: "Add relevant quotes to generated articles" })
1782
+ ] }),
1783
+ /* @__PURE__ */ jsx10(
1784
+ "button",
1785
+ {
1786
+ type: "button",
1787
+ role: "switch",
1788
+ "aria-checked": includeQuotes,
1789
+ onClick: () => setIncludeQuotes(!includeQuotes),
1790
+ className: "cnfy-toggle",
1791
+ style: { backgroundColor: includeQuotes ? primaryColor : "#d1d5db" },
1792
+ children: /* @__PURE__ */ jsx10(
1793
+ "span",
1794
+ {
1795
+ className: `cnfy-toggle-thumb ${includeQuotes ? "cnfy-toggle-thumb--on" : ""}`
1796
+ }
1797
+ )
1798
+ }
1799
+ )
1800
+ ] }),
1801
+ /* @__PURE__ */ jsxs7("div", { className: "cnfy-toggle-row", children: [
1802
+ /* @__PURE__ */ jsxs7("div", { children: [
1803
+ /* @__PURE__ */ jsx10("p", { className: "cnfy-toggle-label", children: "Include FAQ Section" }),
1804
+ /* @__PURE__ */ jsx10("p", { className: "cnfy-toggle-desc", children: "Add FAQ section at the end of articles" })
1805
+ ] }),
1806
+ /* @__PURE__ */ jsx10(
1807
+ "button",
1808
+ {
1809
+ type: "button",
1810
+ role: "switch",
1811
+ "aria-checked": includeFAQ,
1812
+ onClick: () => setIncludeFAQ(!includeFAQ),
1813
+ className: "cnfy-toggle",
1814
+ style: { backgroundColor: includeFAQ ? primaryColor : "#d1d5db" },
1815
+ children: /* @__PURE__ */ jsx10(
1816
+ "span",
1817
+ {
1818
+ className: `cnfy-toggle-thumb ${includeFAQ ? "cnfy-toggle-thumb--on" : ""}`
1819
+ }
1820
+ )
1821
+ }
1822
+ )
1823
+ ] })
1824
+ ] })
1825
+ ] }),
1826
+ /* @__PURE__ */ jsxs7("div", { className: "cnfy-dash-card", children: [
1827
+ /* @__PURE__ */ jsxs7("div", { className: "cnfy-dash-card-header", children: [
1828
+ /* @__PURE__ */ jsx10("h2", { className: "cnfy-dash-card-title-inline", children: "News Scraping" }),
1829
+ /* @__PURE__ */ jsx10("p", { className: "cnfy-dash-card-desc", children: "Scrape latest news from your configured locations" })
1830
+ ] }),
1831
+ !loadingStatus && scrapeStatus && /* @__PURE__ */ jsxs7("div", { className: "cnfy-dash-grid cnfy-dash-grid--sm", children: [
1832
+ /* @__PURE__ */ jsxs7("div", { children: [
1833
+ /* @__PURE__ */ jsx10("span", { className: "cnfy-dash-label-muted", children: "Status:" }),
1834
+ /* @__PURE__ */ jsx10("p", { className: "cnfy-dash-label-bold", children: scrapeStatus.isRunning ? /* @__PURE__ */ jsx10("span", { className: "cnfy-dash-badge cnfy-dash-badge--yellow", children: "Running" }) : /* @__PURE__ */ jsx10("span", { className: "cnfy-dash-badge cnfy-dash-badge--green", children: "Idle" }) })
1835
+ ] }),
1836
+ scrapeStatus.lastRun && /* @__PURE__ */ jsxs7("div", { children: [
1837
+ /* @__PURE__ */ jsx10("span", { className: "cnfy-dash-label-muted", children: "Last Run:" }),
1838
+ /* @__PURE__ */ jsx10("p", { className: "cnfy-dash-label-bold", children: new Date(scrapeStatus.lastRun).toLocaleString() })
1839
+ ] }),
1840
+ scrapeStatus.totalScraped !== void 0 && /* @__PURE__ */ jsxs7("div", { children: [
1841
+ /* @__PURE__ */ jsx10("span", { className: "cnfy-dash-label-muted", children: "Total Scraped:" }),
1842
+ /* @__PURE__ */ jsxs7("p", { className: "cnfy-dash-label-bold", children: [
1843
+ scrapeStatus.totalScraped.toLocaleString(),
1844
+ " articles"
1845
+ ] })
1846
+ ] })
1847
+ ] }),
1848
+ /* @__PURE__ */ jsxs7("div", { children: [
1849
+ /* @__PURE__ */ jsxs7("p", { className: "cnfy-dash-info-text", children: [
1850
+ "Current configuration: ",
1851
+ /* @__PURE__ */ jsx10("strong", { children: (_b = preferences == null ? void 0 : preferences.localization) == null ? void 0 : _b.state }),
1852
+ ((_c = preferences == null ? void 0 : preferences.localization) == null ? void 0 : _c.cities) && preferences.localization.cities.length > 0 && /* @__PURE__ */ jsxs7(Fragment, { children: [
1853
+ " - ",
1854
+ preferences.localization.cities.join(", ")
1855
+ ] })
1856
+ ] }),
1857
+ /* @__PURE__ */ jsx10(
1858
+ "button",
1859
+ {
1860
+ onClick: handleScrape,
1861
+ disabled: scraping || (scrapeStatus == null ? void 0 : scrapeStatus.isRunning),
1862
+ className: "cnfy-dash-btn-save",
1863
+ style: { backgroundColor: primaryColor },
1864
+ children: scraping ? "Starting Scrape..." : (scrapeStatus == null ? void 0 : scrapeStatus.isRunning) ? "Scraping in Progress..." : "Start Scraping"
1865
+ }
1866
+ )
1867
+ ] })
1868
+ ] }),
1869
+ /* @__PURE__ */ jsxs7("div", { className: "cnfy-dash-actions", children: [
1870
+ /* @__PURE__ */ jsx10(
1871
+ "button",
1872
+ {
1873
+ onClick: handleSave,
1874
+ disabled: saving,
1875
+ className: "cnfy-dash-btn-save",
1876
+ style: { backgroundColor: primaryColor },
1877
+ children: saving ? "Saving..." : "Save Preferences"
1543
1878
  }
1544
- }
1545
- ) }),
1546
- selectedSource && /* @__PURE__ */ jsxs9(
1547
- "button",
1548
- {
1549
- onClick: handleScrape,
1550
- disabled: scraping,
1551
- className: "flex items-center gap-1.5 px-3 py-2 bg-emerald-600 text-white rounded-lg text-sm font-medium hover:bg-emerald-700 transition disabled:opacity-50",
1552
- title: "Fetch latest news",
1553
- children: [
1554
- /* @__PURE__ */ jsx10(RefreshCcw3, { size: 14, className: scraping ? "animate-spin" : "" }),
1555
- scraping ? "Scraping..." : "Scrape"
1556
- ]
1557
- }
1558
- ),
1559
- !selectedSource && /* @__PURE__ */ jsxs9(
1560
- "button",
1561
- {
1562
- onClick: () => fetchNews(null),
1563
- disabled: fetchingNews,
1564
- className: "flex items-center gap-1 px-3 py-2 text-sm text-gray-600 hover:text-gray-900 border border-gray-200 rounded-lg transition",
1565
- children: [
1566
- /* @__PURE__ */ jsx10(RefreshCcw3, { size: 14, className: fetchingNews ? "animate-spin" : "" }),
1567
- "Refresh"
1568
- ]
1569
- }
1570
- )
1879
+ ),
1880
+ success && /* @__PURE__ */ jsx10("p", { className: "cnfy-dash-success", style: { color: primaryColor }, children: "Preferences saved successfully \u2705" })
1881
+ ] })
1571
1882
  ] });
1572
1883
  }
1573
1884
 
@@ -1591,7 +1902,7 @@ var createContentStreamApi = async ({
1591
1902
  }) => {
1592
1903
  var _a;
1593
1904
  const API_BASE_URL = getApiBaseUrl();
1594
- const apiKey = process.env.NEXT_PUBLIC_API_KEY;
1905
+ const apiKey = getApiKey();
1595
1906
  const headers = {
1596
1907
  "Content-Type": "application/json"
1597
1908
  };
@@ -1684,7 +1995,7 @@ var rewriteNewsStreamApi = async ({
1684
1995
  if (targetAudience) payload.targetAudience = targetAudience;
1685
1996
  try {
1686
1997
  const API_BASE_URL = getApiBaseUrl();
1687
- const apiKey = process.env.NEXT_PUBLIC_API_KEY;
1998
+ const apiKey = getApiKey();
1688
1999
  console.log("\u{1F680} Starting stream request to:", `${API_BASE_URL}/chat/rewrite/stream`);
1689
2000
  console.log("\u{1F4E6} Payload:", payload);
1690
2001
  const headers = {
@@ -1813,32 +2124,18 @@ var rewriteNewsApi = async ({
1813
2124
  };
1814
2125
 
1815
2126
  // components/chatbot/ChatBot.tsx
1816
- import toast4 from "react-hot-toast";
2127
+ import toast2 from "react-hot-toast";
1817
2128
  import { Loader2 } from "lucide-react";
1818
- import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
1819
- function ChatBot({
1820
- onNavigate,
1821
- onLogout
1822
- } = {}) {
1823
- const { loading, showNewsPanel } = useTheme();
2129
+ import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
2130
+ function ChatBot() {
2131
+ const { loading } = useTheme();
1824
2132
  const { preferences } = usePreferences();
1825
- const [selectedSource, setSelectedSource] = useState8(null);
1826
- const [news, setNews] = useState8([]);
1827
- const [newsLoading, setNewsLoading] = useState8(true);
1828
- const [selectedArticle, setSelectedArticle] = useState8(null);
1829
- const [messages, setMessages] = useState8([]);
1830
- const [showChatMobile, setShowChatMobile] = useState8(false);
1831
- const [isStreaming, setIsStreaming] = useState8(false);
1832
- const [analyzedData, setAnalyzedData] = useState8(null);
1833
- const handleNewsLoaded = useCallback3((loadedNews) => {
1834
- setNews(loadedNews);
1835
- }, []);
1836
- const handleLoadingChange = useCallback3((isLoading) => {
1837
- setNewsLoading(isLoading);
1838
- }, []);
2133
+ const [preferencesOpen, setPreferencesOpen] = useState7(false);
2134
+ const [messages, setMessages] = useState7([]);
2135
+ const [isStreaming, setIsStreaming] = useState7(false);
2136
+ const [analyzedData, setAnalyzedData] = useState7(null);
1839
2137
  const handleRecreate = async ({ title, content, id }) => {
1840
2138
  var _a;
1841
- setShowChatMobile(true);
1842
2139
  const assistantId = crypto.randomUUID();
1843
2140
  setMessages((prev) => [
1844
2141
  ...prev,
@@ -1861,7 +2158,7 @@ ${title}`
1861
2158
  const lang = ((_a = preferences == null ? void 0 : preferences.localization) == null ? void 0 : _a.language) === "hi" ? "Hindi" : "English";
1862
2159
  try {
1863
2160
  await rewriteNewsStreamApi({
1864
- article: content,
2161
+ article: content || "",
1865
2162
  language: lang,
1866
2163
  articleId: id,
1867
2164
  tone: contentPrefs == null ? void 0 : contentPrefs.tone,
@@ -1881,7 +2178,7 @@ ${title}`
1881
2178
  },
1882
2179
  onComplete: () => {
1883
2180
  console.log("Streaming completed successfully");
1884
- toast4.success("Article created successfully!");
2181
+ toast2.success("Article created successfully!");
1885
2182
  },
1886
2183
  onError: async (error) => {
1887
2184
  console.error("Streaming error:", error);
@@ -1889,7 +2186,7 @@ ${title}`
1889
2186
  console.log("Falling back to regular API...");
1890
2187
  throw error;
1891
2188
  } else {
1892
- toast4.error("Failed to complete article generation");
2189
+ toast2.error("Failed to complete article generation");
1893
2190
  setMessages(
1894
2191
  (prev) => prev.map(
1895
2192
  (m) => m.id === assistantId ? __spreadProps(__spreadValues({}, m), { content: accumulatedContent || "\u274C Failed to create article. Please try again." }) : m
@@ -1906,7 +2203,7 @@ ${title}`
1906
2203
  )
1907
2204
  );
1908
2205
  const result = await rewriteNewsApi({
1909
- article: content,
2206
+ article: content || "",
1910
2207
  language: lang,
1911
2208
  articleId: id,
1912
2209
  tone: contentPrefs == null ? void 0 : contentPrefs.tone,
@@ -1921,11 +2218,11 @@ ${title}`
1921
2218
  (m) => m.id === assistantId ? __spreadProps(__spreadValues({}, m), { content: result.article || result }) : m
1922
2219
  )
1923
2220
  );
1924
- toast4.success("Article created successfully!");
2221
+ toast2.success("Article created successfully!");
1925
2222
  }
1926
2223
  } catch (err) {
1927
2224
  console.error("Complete Error:", err);
1928
- toast4.error((err == null ? void 0 : err.message) || "An error occurred while creating the article");
2225
+ toast2.error((err == null ? void 0 : err.message) || "An error occurred while creating the article");
1929
2226
  setMessages(
1930
2227
  (prev) => prev.map(
1931
2228
  (m) => m.id === assistantId ? __spreadProps(__spreadValues({}, m), { content: "\u274C Failed to create article. Please try again." }) : m
@@ -1976,7 +2273,7 @@ ${optionsList}`
1976
2273
  }
1977
2274
  } catch (err) {
1978
2275
  console.error("Analyze input error:", err);
1979
- toast4.error("Failed to analyze the link");
2276
+ toast2.error("Failed to analyze the link");
1980
2277
  setMessages(
1981
2278
  (prev) => prev.map(
1982
2279
  (m) => m.id === assistantId ? __spreadProps(__spreadValues({}, m), { content: "\u274C Failed to analyze the link. Please try again." }) : m
@@ -2012,12 +2309,12 @@ ${optionsList}`
2012
2309
  },
2013
2310
  onComplete: () => {
2014
2311
  setIsStreaming(false);
2015
- toast4.success("Content generated!");
2312
+ toast2.success("Content generated!");
2016
2313
  },
2017
2314
  onError: (error) => {
2018
2315
  console.error("Stream error:", error);
2019
2316
  setIsStreaming(false);
2020
- toast4.error("Failed to generate content");
2317
+ toast2.error("Failed to generate content");
2021
2318
  }
2022
2319
  });
2023
2320
  } catch (err) {
@@ -2065,12 +2362,12 @@ ${optionsList}`
2065
2362
  },
2066
2363
  onComplete: () => {
2067
2364
  setIsStreaming(false);
2068
- toast4.success("Content created!");
2365
+ toast2.success("Content created!");
2069
2366
  },
2070
2367
  onError: (error) => {
2071
2368
  console.error("Stream error:", error);
2072
2369
  setIsStreaming(false);
2073
- toast4.error("Failed to create content");
2370
+ toast2.error("Failed to create content");
2074
2371
  }
2075
2372
  });
2076
2373
  } catch (e) {
@@ -2085,7 +2382,7 @@ ${optionsList}`
2085
2382
  )
2086
2383
  );
2087
2384
  setIsStreaming(false);
2088
- toast4.success("Content created!");
2385
+ toast2.success("Content created!");
2089
2386
  }
2090
2387
  } catch (err) {
2091
2388
  console.error("Create content error:", err);
@@ -2098,93 +2395,54 @@ ${optionsList}`
2098
2395
  }
2099
2396
  };
2100
2397
  if (loading) {
2101
- return /* @__PURE__ */ jsx11("div", { className: "w-full h-screen flex items-center justify-center bg-white", children: /* @__PURE__ */ jsxs10("div", { className: "flex flex-col items-center gap-3", children: [
2102
- /* @__PURE__ */ jsx11(Loader2, { className: "h-8 w-8 animate-spin text-gray-400" }),
2103
- /* @__PURE__ */ jsx11("p", { className: "text-sm text-gray-500", children: "Loading..." })
2398
+ return /* @__PURE__ */ jsx11("div", { className: "cnfy-loading", children: /* @__PURE__ */ jsxs8("div", { className: "cnfy-loading-inner", children: [
2399
+ /* @__PURE__ */ jsx11(Loader2, { className: "cnfy-loading-spinner cnfy-animate-spin" }),
2400
+ /* @__PURE__ */ jsx11("p", { className: "cnfy-loading-text", children: "Loading..." })
2104
2401
  ] }) });
2105
2402
  }
2106
- return (
2107
- // FULL SCREEN
2108
- /* @__PURE__ */ jsxs10("div", { className: "w-full h-screen flex flex-col bg-white", children: [
2109
- /* @__PURE__ */ jsx11(HeaderBar, { onNavigate, onLogout }),
2110
- /* @__PURE__ */ jsxs10("div", { className: `flex-1 min-h-0 md:grid ${showNewsPanel ? "md:grid-cols-12" : ""}`, children: [
2111
- showNewsPanel && /* @__PURE__ */ jsxs10("aside", { className: "relative col-span-4 bg-gray-50/60 border-r border-gray-300 h-[90vh] overflow-y-auto", children: [
2112
- /* @__PURE__ */ jsx11("div", { className: "", children: /* @__PURE__ */ jsx11(
2113
- SourceSelector,
2114
- {
2115
- selectedSource,
2116
- onSourceChange: (value) => {
2117
- console.log("Selected source:", value);
2118
- setSelectedSource(value);
2119
- },
2120
- onNewsLoaded: handleNewsLoaded,
2121
- onLoadingChange: handleLoadingChange
2122
- }
2123
- ) }),
2124
- /* @__PURE__ */ jsx11(
2125
- TrendingNews,
2126
- {
2127
- onRecreate: handleRecreate,
2128
- news,
2129
- isLoading: newsLoading
2130
- }
2131
- )
2132
- ] }),
2133
- /* @__PURE__ */ jsxs10(
2134
- "section",
2135
- {
2136
- className: `
2137
- ${showNewsPanel ? "md:col-span-8" : "w-full"} bg-white flex flex-col h-full relative
2138
- ${showChatMobile ? "block" : "hidden md:block"}
2139
- `,
2140
- children: [
2141
- /* @__PURE__ */ jsx11("div", { className: "md:hidden border-b border-gray-300 p-3", children: /* @__PURE__ */ jsx11(
2142
- "button",
2143
- {
2144
- onClick: () => setShowChatMobile(false),
2145
- className: "text-sm text-gray-600",
2146
- children: "\u2190 Back to news"
2147
- }
2148
- ) }),
2149
- /* @__PURE__ */ jsx11("div", { className: "flex-1 min-h-0", children: /* @__PURE__ */ jsx11(
2150
- ChatWindow,
2151
- {
2152
- messages,
2153
- onSend: handleSendMessage,
2154
- onSelectNews: handleRecreate,
2155
- isStreaming,
2156
- analyzedData,
2157
- onSelectAction: handleSelectAction
2158
- }
2159
- ) }),
2160
- !messages.length && /* @__PURE__ */ jsx11("div", { className: "pointer-events-none absolute inset-0 flex items-center justify-center text-center text-gray-400 text-sm px-4", children: /* @__PURE__ */ jsxs10("div", { children: [
2161
- /* @__PURE__ */ jsx11("p", { className: "font-medium", children: "AI News Assistant" }),
2162
- /* @__PURE__ */ jsx11("p", { className: "mt-1", children: "Select a news article or type a message to begin" })
2163
- ] }) })
2164
- ]
2165
- }
2166
- )
2167
- ] }),
2168
- selectedArticle && /* @__PURE__ */ jsx11(
2169
- ArticleModal,
2403
+ return /* @__PURE__ */ jsxs8("div", { className: "cnfy-root", children: [
2404
+ /* @__PURE__ */ jsx11(HeaderBar, { onOpenPreferences: () => setPreferencesOpen(true) }),
2405
+ /* @__PURE__ */ jsx11("div", { className: "cnfy-main", children: /* @__PURE__ */ jsxs8("section", { className: "cnfy-chat-section cnfy-chat-section--full", children: [
2406
+ /* @__PURE__ */ jsx11("div", { className: "cnfy-chat-inner", children: /* @__PURE__ */ jsx11(
2407
+ ChatWindow,
2170
2408
  {
2171
- article: selectedArticle,
2172
- onClose: () => setSelectedArticle(null),
2173
- onRecreate: handleRecreate
2409
+ messages,
2410
+ onSend: handleSendMessage,
2411
+ onSelectNews: handleRecreate,
2412
+ isStreaming,
2413
+ analyzedData,
2414
+ onSelectAction: handleSelectAction
2174
2415
  }
2175
- )
2176
- ] })
2177
- );
2416
+ ) }),
2417
+ !messages.length && /* @__PURE__ */ jsx11("div", { className: "cnfy-empty-state", children: /* @__PURE__ */ jsxs8("div", { children: [
2418
+ /* @__PURE__ */ jsx11("p", { className: "cnfy-empty-state-title", children: "AI News Assistant" }),
2419
+ /* @__PURE__ */ jsx11("p", { className: "cnfy-empty-state-subtitle", children: "Type a message or paste a link to begin" })
2420
+ ] }) })
2421
+ ] }) }),
2422
+ /* @__PURE__ */ jsx11(
2423
+ Drawer,
2424
+ {
2425
+ open: preferencesOpen,
2426
+ onClose: () => setPreferencesOpen(false),
2427
+ title: "Settings",
2428
+ children: /* @__PURE__ */ jsx11(PreferencesPage, {})
2429
+ }
2430
+ )
2431
+ ] });
2178
2432
  }
2179
2433
 
2180
2434
  // src/index.tsx
2181
2435
  import { jsx as jsx12 } from "react/jsx-runtime";
2182
- function ContenifyChatBot({ onNavigate, onLogout }) {
2183
- return /* @__PURE__ */ jsx12(PreferencesProvider, { children: /* @__PURE__ */ jsx12(ChatBot, { onNavigate, onLogout }) });
2436
+ function ContenifyChatBot({ apiUrl, apiKey, domain }) {
2437
+ useEffect8(() => {
2438
+ setConfig({ apiUrl, apiKey, domain });
2439
+ }, [apiUrl, apiKey, domain]);
2440
+ return /* @__PURE__ */ jsx12(PreferencesProvider, { children: /* @__PURE__ */ jsx12(ChatBot, {}) });
2184
2441
  }
2185
2442
  var index_default = ContenifyChatBot;
2186
2443
  export {
2187
2444
  ContenifyChatBot,
2188
- index_default as default
2445
+ index_default as default,
2446
+ setConfig
2189
2447
  };
2190
2448
  //# sourceMappingURL=index.mjs.map