@contenify/chatbot 0.1.4 → 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.js CHANGED
@@ -49,9 +49,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
49
49
  var index_exports = {};
50
50
  __export(index_exports, {
51
51
  ContenifyChatBot: () => ContenifyChatBot,
52
- default: () => index_default
52
+ default: () => index_default,
53
+ setConfig: () => setConfig
53
54
  });
54
55
  module.exports = __toCommonJS(index_exports);
56
+ var import_react11 = require("react");
55
57
 
56
58
  // contexts/PreferencesContext.tsx
57
59
  var import_react = require("react");
@@ -60,12 +62,22 @@ var import_react = require("react");
60
62
  var import_axios = __toESM(require("axios"));
61
63
 
62
64
  // lib/config.ts
65
+ var _apiUrl = process.env.NEXT_PUBLIC_CONTENIFY_API_URL || "http://localhost:8080/api";
66
+ var _apiKey = process.env.NEXT_PUBLIC_API_KEY || "";
67
+ var _domain = process.env.NEXT_PUBLIC_DOMAIN || "";
68
+ function setConfig(config) {
69
+ if (config.apiUrl) _apiUrl = config.apiUrl;
70
+ if (config.apiKey) _apiKey = config.apiKey;
71
+ if (config.domain) _domain = config.domain;
72
+ }
63
73
  function getApiBaseUrl() {
64
- return process.env.NEXT_PUBLIC_CONTENIFY_API_URL || "http://localhost:8080/api";
74
+ return _apiUrl;
65
75
  }
66
76
  function getServerBaseUrl() {
67
- const apiUrl = getApiBaseUrl();
68
- return apiUrl.replace(/\/api\/?$/, "");
77
+ return _apiUrl.replace(/\/api\/?$/, "");
78
+ }
79
+ function getApiKey() {
80
+ return _apiKey;
69
81
  }
70
82
 
71
83
  // lib/api.ts
@@ -78,7 +90,7 @@ var api = import_axios.default.create({
78
90
  });
79
91
  api.interceptors.request.use(
80
92
  (config) => {
81
- const apiKey = process.env.NEXT_PUBLIC_API_KEY;
93
+ const apiKey = getApiKey();
82
94
  if (apiKey) {
83
95
  config.headers["x-api-key"] = apiKey;
84
96
  }
@@ -101,6 +113,88 @@ var getMyPreferencesApi = async () => {
101
113
  const { data } = await api_default.get("/preferences/me");
102
114
  return data.data;
103
115
  };
116
+ var savePreferencesApi = async ({
117
+ botName,
118
+ logo,
119
+ state,
120
+ cities,
121
+ primaryColor,
122
+ secondaryColor,
123
+ theme,
124
+ language,
125
+ showSidebar,
126
+ showHeader,
127
+ activeThemePreset,
128
+ showNewsPanel,
129
+ tone,
130
+ style,
131
+ wordCount,
132
+ includeQuotes,
133
+ includeFAQ,
134
+ targetAudience
135
+ }) => {
136
+ const formData = new FormData();
137
+ if (botName) {
138
+ formData.append("botName", botName);
139
+ }
140
+ if (logo) {
141
+ formData.append("logo", logo);
142
+ }
143
+ if (state) {
144
+ formData.append("state", state);
145
+ }
146
+ if (cities) {
147
+ formData.append("cities", JSON.stringify(cities));
148
+ }
149
+ if (primaryColor) {
150
+ formData.append("primaryColor", primaryColor);
151
+ }
152
+ if (secondaryColor) {
153
+ formData.append("secondaryColor", secondaryColor);
154
+ }
155
+ if (theme) {
156
+ formData.append("theme", theme);
157
+ }
158
+ if (language) {
159
+ formData.append("language", language);
160
+ }
161
+ if (showSidebar !== void 0) {
162
+ formData.append("showSidebar", String(showSidebar));
163
+ }
164
+ if (showHeader !== void 0) {
165
+ formData.append("showHeader", String(showHeader));
166
+ }
167
+ if (activeThemePreset !== void 0) {
168
+ formData.append("activeThemePreset", activeThemePreset != null ? activeThemePreset : "");
169
+ }
170
+ if (showNewsPanel !== void 0) {
171
+ formData.append("showNewsPanel", String(showNewsPanel));
172
+ }
173
+ if (tone) {
174
+ formData.append("tone", tone);
175
+ }
176
+ if (style) {
177
+ formData.append("style", style);
178
+ }
179
+ if (wordCount) {
180
+ formData.append("wordCount", wordCount);
181
+ }
182
+ if (includeQuotes !== void 0) {
183
+ formData.append("includeQuotes", String(includeQuotes));
184
+ }
185
+ if (includeFAQ !== void 0) {
186
+ formData.append("includeFAQ", String(includeFAQ));
187
+ }
188
+ if (targetAudience !== void 0) {
189
+ formData.append("targetAudience", targetAudience);
190
+ }
191
+ const { data } = await api_default.put("/preferences", formData, {
192
+ headers: {
193
+ "Content-Type": "multipart/form-data"
194
+ }
195
+ });
196
+ return data.data;
197
+ };
104
198
 
105
199
  // contexts/PreferencesContext.tsx
106
200
  var import_jsx_runtime = require("react/jsx-runtime");
@@ -205,58 +299,6 @@ function usePreferences() {
205
299
  // components/chatbot/ChatBot.tsx
206
300
  var import_react10 = require("react");
207
301
 
208
- // components/chatbot/ArticleModal.tsx
209
- var import_jsx_runtime2 = require("react/jsx-runtime");
210
- function ArticleModal({
211
- article,
212
- onClose,
213
- onRecreate
214
- }) {
215
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "cnfy-article-modal-overlay", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "cnfy-article-modal", children: [
216
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "cnfy-article-modal-header", children: [
217
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
218
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "cnfy-article-modal-source", children: "Source Article" }),
219
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { className: "cnfy-article-modal-title", children: article.title })
220
- ] }),
221
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
222
- "button",
223
- {
224
- onClick: onClose,
225
- className: "cnfy-article-modal-close-btn",
226
- "aria-label": "Close modal",
227
- children: "\u2715"
228
- }
229
- )
230
- ] }),
231
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "cnfy-article-modal-body", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "cnfy-article-modal-content", children: article.content }) }),
232
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "cnfy-article-modal-footer", children: [
233
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "cnfy-article-modal-footer-text", children: "This content will be recreated using AI" }),
234
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "cnfy-article-modal-footer-actions", children: [
235
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
236
- "button",
237
- {
238
- onClick: onClose,
239
- className: "cnfy-btn-cancel",
240
- children: "Cancel"
241
- }
242
- ),
243
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
244
- "button",
245
- {
246
- onClick: () => onRecreate({
247
- title: article.title,
248
- content: article.content,
249
- id: article._id
250
- }),
251
- className: "cnfy-btn-recreate",
252
- children: "Recreate Article"
253
- }
254
- )
255
- ] })
256
- ] })
257
- ] }) });
258
- }
259
-
260
302
  // util/util.ts
261
303
  function extractArticleContent(raw) {
262
304
  if (!raw) {
@@ -298,7 +340,7 @@ var import_starter_kit = __toESM(require("@tiptap/starter-kit"));
298
340
  var import_extension_placeholder = __toESM(require("@tiptap/extension-placeholder"));
299
341
  var import_lucide_react = require("lucide-react");
300
342
  var import_react3 = require("react");
301
- var import_jsx_runtime3 = require("react/jsx-runtime");
343
+ var import_jsx_runtime2 = require("react/jsx-runtime");
302
344
  function RichTextEditor({
303
345
  content,
304
346
  onChange,
@@ -333,96 +375,96 @@ function RichTextEditor({
333
375
  }
334
376
  }, [content, editor]);
335
377
  if (!editor) {
336
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "cnfy-editor-loading", children: "Loading editor..." });
378
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "cnfy-editor-loading", children: "Loading editor..." });
337
379
  }
338
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "cnfy-editor", children: [
339
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "cnfy-toolbar", children: [
340
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
380
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "cnfy-editor", children: [
381
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "cnfy-toolbar", children: [
382
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
341
383
  ToolbarButton,
342
384
  {
343
385
  onClick: () => editor.chain().focus().toggleHeading({ level: 1 }).run(),
344
386
  isActive: editor.isActive("heading", { level: 1 }),
345
387
  title: "Heading 1",
346
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react.Heading1, { size: 18 })
388
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.Heading1, { size: 18 })
347
389
  }
348
390
  ),
349
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
391
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
350
392
  ToolbarButton,
351
393
  {
352
394
  onClick: () => editor.chain().focus().toggleHeading({ level: 2 }).run(),
353
395
  isActive: editor.isActive("heading", { level: 2 }),
354
396
  title: "Heading 2",
355
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react.Heading2, { size: 18 })
397
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.Heading2, { size: 18 })
356
398
  }
357
399
  ),
358
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
400
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
359
401
  ToolbarButton,
360
402
  {
361
403
  onClick: () => editor.chain().focus().setParagraph().run(),
362
404
  isActive: editor.isActive("paragraph"),
363
405
  title: "Paragraph",
364
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react.Pilcrow, { size: 18 })
406
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.Pilcrow, { size: 18 })
365
407
  }
366
408
  ),
367
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "cnfy-toolbar-divider" }),
368
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
409
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "cnfy-toolbar-divider" }),
410
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
369
411
  ToolbarButton,
370
412
  {
371
413
  onClick: () => editor.chain().focus().toggleBold().run(),
372
414
  isActive: editor.isActive("bold"),
373
415
  title: "Bold",
374
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react.Bold, { size: 18 })
416
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.Bold, { size: 18 })
375
417
  }
376
418
  ),
377
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
419
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
378
420
  ToolbarButton,
379
421
  {
380
422
  onClick: () => editor.chain().focus().toggleItalic().run(),
381
423
  isActive: editor.isActive("italic"),
382
424
  title: "Italic",
383
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react.Italic, { size: 18 })
425
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.Italic, { size: 18 })
384
426
  }
385
427
  ),
386
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "cnfy-toolbar-divider" }),
387
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
428
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "cnfy-toolbar-divider" }),
429
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
388
430
  ToolbarButton,
389
431
  {
390
432
  onClick: () => editor.chain().focus().toggleBulletList().run(),
391
433
  isActive: editor.isActive("bulletList"),
392
434
  title: "Bullet List",
393
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react.List, { size: 18 })
435
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.List, { size: 18 })
394
436
  }
395
437
  ),
396
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
438
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
397
439
  ToolbarButton,
398
440
  {
399
441
  onClick: () => editor.chain().focus().toggleOrderedList().run(),
400
442
  isActive: editor.isActive("orderedList"),
401
443
  title: "Numbered List",
402
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react.ListOrdered, { size: 18 })
444
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.ListOrdered, { size: 18 })
403
445
  }
404
446
  ),
405
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "cnfy-toolbar-divider" }),
406
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
447
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "cnfy-toolbar-divider" }),
448
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
407
449
  ToolbarButton,
408
450
  {
409
451
  onClick: () => editor.chain().focus().undo().run(),
410
452
  disabled: !editor.can().undo(),
411
453
  title: "Undo",
412
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react.Undo, { size: 18 })
454
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.Undo, { size: 18 })
413
455
  }
414
456
  ),
415
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
457
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
416
458
  ToolbarButton,
417
459
  {
418
460
  onClick: () => editor.chain().focus().redo().run(),
419
461
  disabled: !editor.can().redo(),
420
462
  title: "Redo",
421
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react.Redo, { size: 18 })
463
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.Redo, { size: 18 })
422
464
  }
423
465
  )
424
466
  ] }),
425
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react2.EditorContent, { editor, className: "cnfy-editor-content" })
467
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react2.EditorContent, { editor, className: "cnfy-editor-content" })
426
468
  ] });
427
469
  }
428
470
  function ToolbarButton({
@@ -432,7 +474,7 @@ function ToolbarButton({
432
474
  title,
433
475
  children
434
476
  }) {
435
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
477
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
436
478
  "button",
437
479
  {
438
480
  onClick,
@@ -463,7 +505,7 @@ function useTheme() {
463
505
  }
464
506
 
465
507
  // components/chatbot/EditModal.tsx
466
- var import_jsx_runtime4 = require("react/jsx-runtime");
508
+ var import_jsx_runtime3 = require("react/jsx-runtime");
467
509
  function EditModal({
468
510
  isOpen,
469
511
  initialContent,
@@ -522,30 +564,30 @@ function EditModal({
522
564
  }
523
565
  };
524
566
  if (!isOpen) return null;
525
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "cnfy-edit-modal-overlay", children: [
526
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
567
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "cnfy-edit-modal-overlay", children: [
568
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
527
569
  "div",
528
570
  {
529
571
  className: "cnfy-edit-modal-backdrop",
530
572
  onClick: onClose
531
573
  }
532
574
  ),
533
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "cnfy-edit-modal", children: [
534
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "cnfy-edit-modal-header", children: [
535
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h2", { className: "cnfy-edit-modal-title", children: "Edit Article" }),
536
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
575
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "cnfy-edit-modal", children: [
576
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "cnfy-edit-modal-header", children: [
577
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { className: "cnfy-edit-modal-title", children: "Edit Article" }),
578
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
537
579
  "button",
538
580
  {
539
581
  onClick: onClose,
540
582
  className: "cnfy-edit-modal-close-btn",
541
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react2.X, { size: 20, className: "cnfy-edit-modal-close-icon" })
583
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.X, { size: 20, className: "cnfy-edit-modal-close-icon" })
542
584
  }
543
585
  )
544
586
  ] }),
545
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "cnfy-edit-modal-body", children: [
546
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
547
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("label", { className: "cnfy-edit-label", children: "Article Content" }),
548
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
587
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "cnfy-edit-modal-body", children: [
588
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { children: [
589
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("label", { className: "cnfy-edit-label", children: "Article Content" }),
590
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
549
591
  RichTextEditor,
550
592
  {
551
593
  content,
@@ -554,29 +596,29 @@ function EditModal({
554
596
  }
555
597
  )
556
598
  ] }),
557
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
558
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("label", { className: "cnfy-edit-label", children: "Meta Keywords" }),
559
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "cnfy-keyword-list", children: keywords.map((keyword, index) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
599
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { children: [
600
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("label", { className: "cnfy-edit-label", children: "Meta Keywords" }),
601
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "cnfy-keyword-list", children: keywords.map((keyword, index) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
560
602
  "span",
561
603
  {
562
604
  className: "cnfy-keyword-tag",
563
605
  children: [
564
606
  "#",
565
607
  keyword,
566
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
608
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
567
609
  "button",
568
610
  {
569
611
  onClick: () => handleRemoveKeyword(index),
570
612
  className: "cnfy-keyword-remove-btn",
571
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react2.X, { size: 14 })
613
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.X, { size: 14 })
572
614
  }
573
615
  )
574
616
  ]
575
617
  },
576
618
  index
577
619
  )) }),
578
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "cnfy-keyword-input-row", children: [
579
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
620
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "cnfy-keyword-input-row", children: [
621
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
580
622
  "input",
581
623
  {
582
624
  type: "text",
@@ -587,7 +629,7 @@ function EditModal({
587
629
  className: "cnfy-keyword-input"
588
630
  }
589
631
  ),
590
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
632
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
591
633
  "button",
592
634
  {
593
635
  onClick: handleAddKeyword,
@@ -598,8 +640,8 @@ function EditModal({
598
640
  ] })
599
641
  ] })
600
642
  ] }),
601
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "cnfy-edit-modal-footer", children: [
602
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
643
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "cnfy-edit-modal-footer", children: [
644
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
603
645
  "button",
604
646
  {
605
647
  onClick: onClose,
@@ -607,7 +649,7 @@ function EditModal({
607
649
  children: "Cancel"
608
650
  }
609
651
  ),
610
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
652
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
611
653
  "button",
612
654
  {
613
655
  onClick: () => onSaveDraft(content, keywords),
@@ -615,7 +657,7 @@ function EditModal({
615
657
  children: "Save Draft"
616
658
  }
617
659
  ),
618
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
660
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
619
661
  "button",
620
662
  {
621
663
  onClick: () => onPost(content, keywords),
@@ -632,7 +674,7 @@ function EditModal({
632
674
  // components/news/NewsList.tsx
633
675
  var import_react5 = require("react");
634
676
  var import_lucide_react3 = require("lucide-react");
635
- var import_jsx_runtime5 = require("react/jsx-runtime");
677
+ var import_jsx_runtime4 = require("react/jsx-runtime");
636
678
  var dateFormatter = new Intl.DateTimeFormat("en-GB", {
637
679
  day: "2-digit",
638
680
  month: "short",
@@ -674,19 +716,19 @@ function NewsList({
674
716
  b = Math.round(b + (255 - b) * (percent / 100));
675
717
  return `rgb(${r}, ${g}, ${b})`;
676
718
  };
677
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "cnfy-news-list", children: news.flatMap((item) => {
719
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "cnfy-news-list", children: news.flatMap((item) => {
678
720
  const publishedDate = new Date(item.publishedAt);
679
721
  const links = extractLinksFromContent(item.content);
680
722
  if (links.length > 0) {
681
- return links.map((link, idx) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
723
+ return links.map((link, idx) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
682
724
  "div",
683
725
  {
684
726
  className: "cnfy-news-card",
685
727
  children: [
686
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "cnfy-news-card-content", children: [
687
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "cnfy-news-card-title", children: link.title }),
688
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "cnfy-news-card-meta", children: [
689
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
728
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "cnfy-news-card-content", children: [
729
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "cnfy-news-card-title", children: link.title }),
730
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "cnfy-news-card-meta", children: [
731
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
690
732
  "span",
691
733
  {
692
734
  className: "cnfy-news-badge",
@@ -698,27 +740,27 @@ function NewsList({
698
740
  children: link.source || item.sourceName
699
741
  }
700
742
  ),
701
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "\u2022" }),
702
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "cnfy-news-card-category", children: item.category }),
703
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "\u2022" }),
704
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { children: [
743
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "\u2022" }),
744
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "cnfy-news-card-category", children: item.category }),
745
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "\u2022" }),
746
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { children: [
705
747
  dateFormatter.format(publishedDate),
706
748
  " ",
707
749
  timeFormatter.format(publishedDate)
708
750
  ] })
709
751
  ] })
710
752
  ] }),
711
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "cnfy-news-card-actions", children: [
712
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
753
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "cnfy-news-card-actions", children: [
754
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
713
755
  "button",
714
756
  {
715
757
  onClick: () => window.open(link.url, "_blank"),
716
758
  className: "cnfy-news-action-btn",
717
759
  title: "View",
718
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react3.Eye, { size: 16 })
760
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react3.Eye, { size: 16 })
719
761
  }
720
762
  ),
721
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
763
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
722
764
  "button",
723
765
  {
724
766
  onClick: () => onRecreate({
@@ -728,7 +770,7 @@ function NewsList({
728
770
  }),
729
771
  className: "cnfy-news-action-btn",
730
772
  title: "Recreate",
731
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react3.RefreshCcw, { size: 16 })
773
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react3.RefreshCcw, { size: 16 })
732
774
  }
733
775
  )
734
776
  ] })
@@ -737,15 +779,15 @@ function NewsList({
737
779
  `${item._id}-link-${idx}`
738
780
  ));
739
781
  }
740
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
782
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
741
783
  "div",
742
784
  {
743
785
  className: "cnfy-news-card",
744
786
  children: [
745
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "cnfy-news-card-content", children: [
746
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "cnfy-news-card-title", children: item.title }),
747
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "cnfy-news-card-meta", children: [
748
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
787
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "cnfy-news-card-content", children: [
788
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "cnfy-news-card-title", children: item.title }),
789
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "cnfy-news-card-meta", children: [
790
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
749
791
  "span",
750
792
  {
751
793
  className: "cnfy-news-badge",
@@ -757,27 +799,27 @@ function NewsList({
757
799
  children: item.sourceName
758
800
  }
759
801
  ),
760
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "\u2022" }),
761
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "cnfy-news-card-category", children: item.category }),
762
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "\u2022" }),
763
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { children: [
802
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "\u2022" }),
803
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "cnfy-news-card-category", children: item.category }),
804
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "\u2022" }),
805
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { children: [
764
806
  dateFormatter.format(publishedDate),
765
807
  " ",
766
808
  timeFormatter.format(publishedDate)
767
809
  ] })
768
810
  ] })
769
811
  ] }),
770
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "cnfy-news-card-actions", children: [
771
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
812
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "cnfy-news-card-actions", children: [
813
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
772
814
  "button",
773
815
  {
774
816
  onClick: () => onView(item),
775
817
  className: "cnfy-news-action-btn",
776
818
  title: "View",
777
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react3.Eye, { size: 16 })
819
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react3.Eye, { size: 16 })
778
820
  }
779
821
  ),
780
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
822
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
781
823
  "button",
782
824
  {
783
825
  onClick: () => onRecreate({
@@ -787,7 +829,7 @@ function NewsList({
787
829
  }),
788
830
  className: "cnfy-news-action-btn",
789
831
  title: "Recreate",
790
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react3.RefreshCcw, { size: 16 })
832
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react3.RefreshCcw, { size: 16 })
791
833
  }
792
834
  )
793
835
  ] })
@@ -818,7 +860,7 @@ var getNewsBySource = async (sourceId) => {
818
860
 
819
861
  // components/chatbot/ChatWindow.tsx
820
862
  var import_react_select = __toESM(require("react-select"));
821
- var import_jsx_runtime6 = require("react/jsx-runtime");
863
+ var import_jsx_runtime5 = require("react/jsx-runtime");
822
864
  var ACTION_ICONS = {
823
865
  recreate_article: import_lucide_react4.RefreshCcw,
824
866
  create_summary: import_lucide_react4.ListChecks,
@@ -994,13 +1036,13 @@ function ChatWindow({
994
1036
  });
995
1037
  return { blocks, metaKeywords };
996
1038
  }
997
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "cnfy-chat", children: [
998
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "cnfy-chat-area", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "cnfy-chat-scroll", children: [
1039
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "cnfy-chat", children: [
1040
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "cnfy-chat-area", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "cnfy-chat-scroll", children: [
999
1041
  messages.map((msg) => {
1000
1042
  var _a2;
1001
1043
  const parsed = formatAIContent(msg.content);
1002
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "cnfy-msg", children: [
1003
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "cnfy-msg-avatar-wrap", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1044
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "cnfy-msg", children: [
1045
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "cnfy-msg-avatar-wrap", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1004
1046
  "div",
1005
1047
  {
1006
1048
  className: "cnfy-msg-avatar",
@@ -1010,19 +1052,19 @@ function ChatWindow({
1010
1052
  children: msg.role === "assistant" ? "AI" : "You"
1011
1053
  }
1012
1054
  ) }),
1013
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "cnfy-msg-body", children: [
1014
- msg.role === "assistant" && parsed.blocks.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "cnfy-msg-copy-row", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1055
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "cnfy-msg-body", children: [
1056
+ msg.role === "assistant" && parsed.blocks.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "cnfy-msg-copy-row", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1015
1057
  "button",
1016
1058
  {
1017
1059
  onClick: () => handleCopy(parsed.blocks, msg.id),
1018
1060
  className: "cnfy-copy-btn",
1019
1061
  title: "Copy to clipboard",
1020
- children: copiedId === msg.id ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react4.Check, { size: 16, className: "cnfy-copy-icon--copied" }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react4.Copy, { size: 16 })
1062
+ children: copiedId === msg.id ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react4.Check, { size: 16, className: "cnfy-copy-icon--copied" }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react4.Copy, { size: 16 })
1021
1063
  }
1022
1064
  ) }),
1023
1065
  parsed.blocks.map((block, idx) => {
1024
1066
  if (block.type === "h1") {
1025
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1067
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1026
1068
  "h1",
1027
1069
  {
1028
1070
  className: "cnfy-block-h1",
@@ -1032,7 +1074,7 @@ function ChatWindow({
1032
1074
  );
1033
1075
  }
1034
1076
  if (block.type === "h2") {
1035
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1077
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1036
1078
  "h2",
1037
1079
  {
1038
1080
  className: "cnfy-block-h2",
@@ -1041,9 +1083,9 @@ function ChatWindow({
1041
1083
  idx
1042
1084
  );
1043
1085
  }
1044
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "cnfy-block-p", children: block.text }, idx);
1086
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "cnfy-block-p", children: block.text }, idx);
1045
1087
  }),
1046
- parsed.metaKeywords.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "cnfy-msg-keywords", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "cnfy-msg-keywords-list", children: parsed.metaKeywords.map((tag, i) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1088
+ parsed.metaKeywords.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "cnfy-msg-keywords", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "cnfy-msg-keywords-list", children: parsed.metaKeywords.map((tag, i) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1047
1089
  "span",
1048
1090
  {
1049
1091
  className: "cnfy-msg-keyword-tag",
@@ -1054,41 +1096,41 @@ function ChatWindow({
1054
1096
  },
1055
1097
  i
1056
1098
  )) }) }),
1057
- msg.role === "assistant" && (analyzedData == null ? void 0 : analyzedData.messageId) === msg.id && analyzedData.options.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "cnfy-action-options", children: analyzedData.options.map((option) => {
1099
+ msg.role === "assistant" && (analyzedData == null ? void 0 : analyzedData.messageId) === msg.id && analyzedData.options.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "cnfy-action-options", children: analyzedData.options.map((option) => {
1058
1100
  const IconComponent = ACTION_ICONS[option.id] || import_lucide_react4.FileText;
1059
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1101
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1060
1102
  "button",
1061
1103
  {
1062
1104
  onClick: () => onSelectAction == null ? void 0 : onSelectAction(option.id, analyzedData.url, analyzedData.content),
1063
1105
  className: "cnfy-action-btn",
1064
1106
  children: [
1065
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(IconComponent, { size: 16 }),
1107
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(IconComponent, { size: 16 }),
1066
1108
  option.name
1067
1109
  ]
1068
1110
  },
1069
1111
  option.id
1070
1112
  );
1071
1113
  }) }),
1072
- 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__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "cnfy-msg-actions", children: [
1073
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1114
+ 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__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "cnfy-msg-actions", children: [
1115
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1074
1116
  "button",
1075
1117
  {
1076
1118
  onClick: () => handleEdit(parsed.blocks, parsed.metaKeywords, msg.id),
1077
1119
  className: "cnfy-btn-edit",
1078
1120
  children: [
1079
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react4.Edit3, { size: 16 }),
1121
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react4.Edit3, { size: 16 }),
1080
1122
  "Edit"
1081
1123
  ]
1082
1124
  }
1083
1125
  ),
1084
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1126
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1085
1127
  "button",
1086
1128
  {
1087
1129
  onClick: () => handlePost(msg.content, parsed.metaKeywords),
1088
1130
  className: "cnfy-btn-post",
1089
1131
  style: { backgroundColor: primaryColor, color: "#fff" },
1090
1132
  children: [
1091
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react4.Send, { size: 16 }),
1133
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react4.Send, { size: 16 }),
1092
1134
  "Post"
1093
1135
  ]
1094
1136
  }
@@ -1097,34 +1139,34 @@ function ChatWindow({
1097
1139
  ] })
1098
1140
  ] }, msg.id);
1099
1141
  }),
1100
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { ref: bottomRef })
1142
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { ref: bottomRef })
1101
1143
  ] }) }),
1102
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "cnfy-input-area", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "cnfy-input-inner", children: [
1103
- !showNewsPanel && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { ref: dropdownRef, className: "cnfy-news-pulse-wrap", children: [
1104
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1144
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "cnfy-input-area", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "cnfy-input-inner", children: [
1145
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { ref: dropdownRef, className: "cnfy-news-pulse-wrap", children: [
1146
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1105
1147
  "button",
1106
1148
  {
1107
1149
  onClick: handleOpenNewsDropdown,
1108
1150
  className: "cnfy-news-pulse-btn cnfy-animate-pulse",
1109
1151
  title: "Select from trending news",
1110
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react4.Zap, { size: 16 })
1152
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react4.Zap, { size: 16 })
1111
1153
  }
1112
1154
  ),
1113
- showNewsDropdown && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "cnfy-news-dropdown", children: [
1114
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "cnfy-news-dropdown-header", style: { backgroundColor: primaryColor, color: "#fff" }, children: [
1115
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "cnfy-news-dropdown-title", children: "Select News" }),
1116
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1155
+ showNewsDropdown && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "cnfy-news-dropdown", children: [
1156
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "cnfy-news-dropdown-header", style: { backgroundColor: primaryColor, color: "#fff" }, children: [
1157
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "cnfy-news-dropdown-title", children: "Select News" }),
1158
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1117
1159
  "button",
1118
1160
  {
1119
1161
  onClick: () => setShowNewsDropdown(false),
1120
1162
  className: "cnfy-news-dropdown-close",
1121
1163
  style: { backgroundColor: primaryColor, color: "#fff" },
1122
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react4.X, { size: 14 })
1164
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react4.X, { size: 14 })
1123
1165
  }
1124
1166
  )
1125
1167
  ] }),
1126
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "cnfy-news-dropdown-source", children: [
1127
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "cnfy-news-dropdown-select-wrap", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1168
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "cnfy-news-dropdown-source", children: [
1169
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "cnfy-news-dropdown-select-wrap", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1128
1170
  import_react_select.default,
1129
1171
  {
1130
1172
  options: [
@@ -1170,7 +1212,7 @@ function ChatWindow({
1170
1212
  }
1171
1213
  }
1172
1214
  ) }),
1173
- selectedSource && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1215
+ selectedSource && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1174
1216
  "button",
1175
1217
  {
1176
1218
  onClick: handleScrape,
@@ -1178,28 +1220,28 @@ function ChatWindow({
1178
1220
  className: "cnfy-scrape-btn",
1179
1221
  title: "Fetch latest news",
1180
1222
  children: [
1181
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react4.RefreshCcw, { size: 14, className: scraping ? "cnfy-animate-spin" : "" }),
1223
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react4.RefreshCcw, { size: 14, className: scraping ? "cnfy-animate-spin" : "" }),
1182
1224
  scraping ? "Scraping..." : "Scrape"
1183
1225
  ]
1184
1226
  }
1185
1227
  ),
1186
- !selectedSource && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1228
+ !selectedSource && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1187
1229
  "button",
1188
1230
  {
1189
1231
  onClick: () => fetchNews(null),
1190
1232
  disabled: loadingNews,
1191
1233
  className: "cnfy-refresh-btn",
1192
1234
  children: [
1193
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react4.RefreshCcw, { size: 14, className: loadingNews ? "cnfy-animate-spin" : "" }),
1235
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react4.RefreshCcw, { size: 14, className: loadingNews ? "cnfy-animate-spin" : "" }),
1194
1236
  "Refresh"
1195
1237
  ]
1196
1238
  }
1197
1239
  )
1198
1240
  ] }),
1199
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "cnfy-news-dropdown-list", children: loadingNews ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "cnfy-news-dropdown-msg", children: "Loading news..." }) : trendingNews.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "cnfy-news-dropdown-msg", children: [
1200
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { children: "No news found." }),
1201
- selectedSource && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "cnfy-news-dropdown-hint", children: 'Click "Scrape" to fetch latest news.' })
1202
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1241
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "cnfy-news-dropdown-list", children: loadingNews ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "cnfy-news-dropdown-msg", children: "Loading news..." }) : trendingNews.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "cnfy-news-dropdown-msg", children: [
1242
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { children: "No news found." }),
1243
+ selectedSource && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "cnfy-news-dropdown-hint", children: 'Click "Scrape" to fetch latest news.' })
1244
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1203
1245
  NewsList,
1204
1246
  {
1205
1247
  news: trendingNews.slice(0, 10),
@@ -1212,7 +1254,7 @@ function ChatWindow({
1212
1254
  ) })
1213
1255
  ] })
1214
1256
  ] }),
1215
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1257
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1216
1258
  "textarea",
1217
1259
  {
1218
1260
  ref: textareaRef,
@@ -1230,17 +1272,17 @@ function ChatWindow({
1230
1272
  style: { maxHeight: "200px", overflowY: input.split("\n").length > 6 ? "auto" : "hidden" }
1231
1273
  }
1232
1274
  ),
1233
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1275
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1234
1276
  "button",
1235
1277
  {
1236
1278
  onClick: handleSend,
1237
1279
  className: "cnfy-send-btn",
1238
1280
  style: { backgroundColor: primaryColor, color: "#fff" },
1239
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react4.SendHorizontal, { size: 18 })
1281
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react4.SendHorizontal, { size: 18 })
1240
1282
  }
1241
1283
  )
1242
1284
  ] }) }),
1243
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1285
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1244
1286
  EditModal,
1245
1287
  {
1246
1288
  isOpen: editModal.isOpen,
@@ -1255,109 +1297,31 @@ function ChatWindow({
1255
1297
  }
1256
1298
 
1257
1299
  // components/chatbot/UserMenu.tsx
1258
- var import_react7 = require("react");
1259
1300
  var import_lucide_react5 = require("lucide-react");
1260
- var import_react_hot_toast = __toESM(require("react-hot-toast"));
1261
-
1262
- // services/auth.service.ts
1263
- var logoutUser = async () => {
1264
- const { data } = await api_default.post("/auth/logout");
1265
- return data;
1266
- };
1267
-
1268
- // components/chatbot/UserMenu.tsx
1269
- var import_jsx_runtime7 = require("react/jsx-runtime");
1301
+ var import_jsx_runtime6 = require("react/jsx-runtime");
1270
1302
  function UserMenu({
1271
- onNavigate,
1272
- onLogout
1303
+ onOpenPreferences
1273
1304
  }) {
1274
- const [open, setOpen] = (0, import_react7.useState)(false);
1275
- const ref = (0, import_react7.useRef)(null);
1276
- (0, import_react7.useEffect)(() => {
1277
- const handler = (e) => {
1278
- if (ref.current && !ref.current.contains(e.target)) {
1279
- setOpen(false);
1280
- }
1281
- };
1282
- document.addEventListener("mousedown", handler);
1283
- return () => document.removeEventListener("mousedown", handler);
1284
- }, []);
1285
- function go(path) {
1286
- setOpen(false);
1287
- onNavigate == null ? void 0 : onNavigate(path);
1288
- }
1289
- async function logout() {
1290
- setOpen(false);
1291
- if (onLogout) {
1292
- onLogout();
1293
- return;
1294
- }
1295
- try {
1296
- await logoutUser();
1297
- import_react_hot_toast.default.success("Logged out successfully");
1298
- onNavigate == null ? void 0 : onNavigate("/login");
1299
- } catch (err) {
1300
- import_react_hot_toast.default.error(err || "Logout failed");
1301
- }
1302
- }
1303
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { ref, className: "cnfy-user-menu", children: [
1304
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1305
- "button",
1306
- {
1307
- onClick: () => setOpen((v) => !v),
1308
- className: "cnfy-user-menu-trigger",
1309
- "aria-label": "Settings",
1310
- children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react5.Settings, { size: 20, className: "cnfy-user-menu-trigger-icon" })
1311
- }
1312
- ),
1313
- open && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "cnfy-dropdown", children: [
1314
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(MenuItem, { icon: import_lucide_react5.User, label: "Account", onClick: () => go("/dashboard/account") }),
1315
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(MenuItem, { icon: import_lucide_react5.Settings, label: "Preferences", onClick: () => go("/dashboard/preferences") }),
1316
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(MenuItem, { icon: import_lucide_react5.Palette, label: "Appearance", onClick: () => go("/dashboard/appearance") }),
1317
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(MenuItem, { icon: import_lucide_react5.HelpCircle, label: "Settings", onClick: () => go("/dashboard/settings") }),
1318
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(MenuItem, { icon: import_lucide_react5.HelpCircle, label: "Help & Support", onClick: () => go("/dashboard/help") }),
1319
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "cnfy-dropdown-divider" }),
1320
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1321
- MenuItem,
1322
- {
1323
- icon: import_lucide_react5.LogOut,
1324
- label: "Logout",
1325
- danger: true,
1326
- onClick: logout
1327
- }
1328
- )
1329
- ] })
1330
- ] });
1331
- }
1332
- function MenuItem({
1333
- icon: Icon,
1334
- label,
1335
- onClick,
1336
- danger = false
1337
- }) {
1338
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1305
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "cnfy-user-menu", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1339
1306
  "button",
1340
1307
  {
1341
- onClick,
1342
- className: `cnfy-menu-item ${danger ? "cnfy-menu-item--danger" : ""}`,
1343
- children: [
1344
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Icon, { size: 16 }),
1345
- label
1346
- ]
1308
+ onClick: () => onOpenPreferences == null ? void 0 : onOpenPreferences(),
1309
+ className: "cnfy-user-menu-trigger",
1310
+ "aria-label": "Settings",
1311
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.Settings, { size: 20, className: "cnfy-user-menu-trigger-icon" })
1347
1312
  }
1348
- );
1313
+ ) });
1349
1314
  }
1350
1315
 
1351
1316
  // components/chatbot/headerBar.tsx
1352
- var import_jsx_runtime8 = require("react/jsx-runtime");
1317
+ var import_jsx_runtime7 = require("react/jsx-runtime");
1353
1318
  function HeaderBar({
1354
- onNavigate,
1355
- onLogout
1319
+ onOpenPreferences
1356
1320
  }) {
1357
1321
  const { primaryColor, botName, logoUrl } = useTheme();
1358
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("header", { className: "cnfy-header", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "cnfy-header-inner", children: [
1359
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "cnfy-header-left", onClick: () => onNavigate == null ? void 0 : onNavigate("/"), children: [
1360
- logoUrl ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("img", { src: logoUrl, alt: "Logo", className: "cnfy-header-logo-img" }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1322
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("header", { className: "cnfy-header", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "cnfy-header-inner", children: [
1323
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "cnfy-header-left", children: [
1324
+ logoUrl ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("img", { src: logoUrl, alt: "Logo", className: "cnfy-header-logo-img" }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1361
1325
  "div",
1362
1326
  {
1363
1327
  className: "cnfy-header-logo-fallback",
@@ -1365,224 +1329,579 @@ function HeaderBar({
1365
1329
  children: botName.charAt(0).toUpperCase()
1366
1330
  }
1367
1331
  ),
1368
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "cnfy-header-brand", children: botName.toUpperCase() })
1332
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "cnfy-header-brand", children: botName.toUpperCase() })
1369
1333
  ] }),
1370
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "cnfy-header-right", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(UserMenu, { onNavigate, onLogout }) })
1334
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "cnfy-header-right", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(UserMenu, { onOpenPreferences }) })
1371
1335
  ] }) });
1372
1336
  }
1373
1337
 
1374
- // components/news/TrendingNews.tsx
1375
- var import_react8 = require("react");
1376
- var import_react_hot_toast2 = __toESM(require("react-hot-toast"));
1377
- var import_jsx_runtime9 = require("react/jsx-runtime");
1378
- function TrendingNews({
1379
- onRecreate,
1380
- selectedSource,
1381
- refreshKey,
1382
- news: externalNews,
1383
- isLoading: externalLoading
1338
+ // components/ui/Drawer.tsx
1339
+ var import_react7 = require("react");
1340
+ var import_lucide_react6 = require("lucide-react");
1341
+ var import_jsx_runtime8 = require("react/jsx-runtime");
1342
+ function Drawer({
1343
+ open,
1344
+ onClose,
1345
+ title,
1346
+ children
1384
1347
  }) {
1385
- const [news, setNews] = (0, import_react8.useState)([]);
1386
- const [loading, setLoading] = (0, import_react8.useState)(false);
1387
- const displayNews = externalNews !== void 0 ? externalNews : news;
1388
- const isLoading = externalLoading !== void 0 ? externalLoading : loading;
1389
- const fetchNews = (0, import_react8.useCallback)(async () => {
1390
- if (externalNews !== void 0) {
1391
- return;
1392
- }
1393
- setLoading(true);
1394
- try {
1395
- let data;
1396
- if (selectedSource) {
1397
- data = await getNewsBySource(selectedSource);
1398
- } else {
1399
- data = await getTrendingNews();
1400
- }
1401
- setNews(data || []);
1402
- } catch (e) {
1403
- import_react_hot_toast2.default.error("Failed to load news");
1404
- } finally {
1405
- setLoading(false);
1406
- }
1407
- }, [selectedSource, externalNews]);
1408
- (0, import_react8.useEffect)(() => {
1409
- fetchNews();
1410
- }, [fetchNews, refreshKey]);
1411
- function handleView(item) {
1412
- window.open(item.sourceUrl || item.link, "_blank");
1413
- }
1414
- if (isLoading) {
1415
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "cnfy-trending-msg", children: "Loading news..." });
1416
- }
1417
- if (!displayNews || displayNews.length === 0) {
1418
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "cnfy-trending-msg cnfy-trending-msg--center", children: [
1419
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { children: "No news found for this source." }),
1420
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "cnfy-trending-hint", children: 'Click "Scrape" to fetch latest news.' })
1421
- ] });
1422
- }
1423
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1424
- NewsList,
1425
- {
1426
- news: displayNews,
1427
- onView: handleView,
1428
- onRecreate
1348
+ (0, import_react7.useEffect)(() => {
1349
+ if (open) {
1350
+ document.body.style.overflow = "hidden";
1351
+ } else {
1352
+ document.body.style.overflow = "";
1429
1353
  }
1430
- );
1354
+ return () => {
1355
+ document.body.style.overflow = "";
1356
+ };
1357
+ }, [open]);
1358
+ if (!open) return null;
1359
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "cnfy-drawer-overlay", children: [
1360
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "cnfy-drawer-backdrop", onClick: onClose }),
1361
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "cnfy-drawer-panel", children: [
1362
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "cnfy-drawer-header", children: [
1363
+ title && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h2", { className: "cnfy-drawer-title", children: title }),
1364
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { onClick: onClose, className: "cnfy-drawer-close-btn", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react6.X, { size: 20 }) })
1365
+ ] }),
1366
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "cnfy-drawer-body", children })
1367
+ ] })
1368
+ ] });
1431
1369
  }
1432
1370
 
1433
- // components/news/SourceSelector.tsx
1371
+ // components/preferences/Preferences.tsx
1434
1372
  var import_react9 = require("react");
1435
- var import_lucide_react6 = require("lucide-react");
1436
- var import_react_select2 = __toESM(require("react-select"));
1437
- var import_react_hot_toast3 = __toESM(require("react-hot-toast"));
1373
+ var import_react_hot_toast = __toESM(require("react-hot-toast"));
1374
+
1375
+ // services/settings.service.ts
1376
+ var triggerScrape = async ({
1377
+ state,
1378
+ cities
1379
+ }) => {
1380
+ const { data } = await api_default.post("/scrape/trigger", {
1381
+ state,
1382
+ cities
1383
+ });
1384
+ return data;
1385
+ };
1386
+ var getScrapeStatus = async () => {
1387
+ const { data } = await api_default.get("/scrape/status");
1388
+ return data.data;
1389
+ };
1390
+
1391
+ // components/ClientSelect.tsx
1392
+ var import_react8 = require("react");
1393
+ var import_jsx_runtime9 = require("react/jsx-runtime");
1394
+ var ReactSelect = null;
1395
+ var ClientSelect = (props) => {
1396
+ const [mounted, setMounted] = (0, import_react8.useState)(false);
1397
+ (0, import_react8.useEffect)(() => {
1398
+ setMounted(true);
1399
+ import("react-select").then((mod) => {
1400
+ ReactSelect = mod.default;
1401
+ });
1402
+ }, []);
1403
+ if (!mounted || !ReactSelect) return null;
1404
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ReactSelect, __spreadValues({}, props));
1405
+ };
1406
+ var ClientSelect_default = ClientSelect;
1407
+
1408
+ // components/preferences/Preferences.tsx
1438
1409
  var import_jsx_runtime10 = require("react/jsx-runtime");
1439
- var ALL_SOURCES_VALUE = "__all__";
1440
- function SourceSelector({
1441
- selectedSource,
1442
- onSourceChange,
1443
- onScrapeComplete,
1444
- onNewsLoaded,
1445
- onLoadingChange
1446
- }) {
1447
- const [sources, setSources] = (0, import_react9.useState)([]);
1448
- const [loading, setLoading] = (0, import_react9.useState)(true);
1410
+ var STATE_OPTIONS = [
1411
+ { value: "Uttar Pradesh", label: "Uttar Pradesh" }
1412
+ ];
1413
+ var CITY_OPTIONS = [
1414
+ "Agra",
1415
+ "Aligarh",
1416
+ "Ayodhya",
1417
+ "Bareilly",
1418
+ "Bijnor",
1419
+ "Bulandshahr",
1420
+ "Etawah",
1421
+ "Firozabad",
1422
+ "Ghaziabad",
1423
+ "Gorakhpur",
1424
+ "Jhansi",
1425
+ "Kanpur",
1426
+ "Lucknow",
1427
+ "Mathura",
1428
+ "Meerut",
1429
+ "Moradabad",
1430
+ "Muzaffarnagar",
1431
+ "Noida",
1432
+ "Prayagraj",
1433
+ "Rampur",
1434
+ "Saharanpur",
1435
+ "Sitapur",
1436
+ "Unnao",
1437
+ "Varanasi"
1438
+ ].map((city) => ({ value: city, label: city }));
1439
+ var LANGUAGE_OPTIONS = [
1440
+ { value: "en", label: "English" },
1441
+ { value: "hi", label: "Hindi" }
1442
+ ];
1443
+ var TONE_OPTIONS = [
1444
+ { value: "formal", label: "Formal" },
1445
+ { value: "casual", label: "Casual" },
1446
+ { value: "engaging", label: "Engaging" },
1447
+ { value: "professional", label: "Professional" }
1448
+ ];
1449
+ var STYLE_OPTIONS = [
1450
+ { value: "news", label: "News Article" },
1451
+ { value: "blog", label: "Blog Post" },
1452
+ { value: "editorial", label: "Editorial" },
1453
+ { value: "summary", label: "Summary" }
1454
+ ];
1455
+ var WORD_COUNT_OPTIONS = [
1456
+ { value: "short", label: "Short (~300 words)" },
1457
+ { value: "medium", label: "Medium (~600 words)" },
1458
+ { value: "long", label: "Long (~1000+ words)" }
1459
+ ];
1460
+ function PreferencesPage() {
1461
+ var _a, _b, _c;
1462
+ const { preferences, loading, refreshPreferences, updatePreferences } = usePreferences();
1463
+ const primaryColor = ((_a = preferences == null ? void 0 : preferences.chatbot) == null ? void 0 : _a.primaryColor) || "#10b981";
1464
+ const [botName, setBotName] = (0, import_react9.useState)("");
1465
+ const [logo, setLogo] = (0, import_react9.useState)(null);
1466
+ const [logoUrl, setLogoUrl] = (0, import_react9.useState)(null);
1467
+ const [state, setState] = (0, import_react9.useState)(null);
1468
+ const [cities, setCities] = (0, import_react9.useState)([]);
1469
+ const [language, setLanguage] = (0, import_react9.useState)(null);
1470
+ const [tone, setTone] = (0, import_react9.useState)(null);
1471
+ const [style, setStyle] = (0, import_react9.useState)(null);
1472
+ const [wordCount, setWordCount] = (0, import_react9.useState)(null);
1473
+ const [includeQuotes, setIncludeQuotes] = (0, import_react9.useState)(true);
1474
+ const [includeFAQ, setIncludeFAQ] = (0, import_react9.useState)(false);
1475
+ const [targetAudience, setTargetAudience] = (0, import_react9.useState)("");
1476
+ const [saving, setSaving] = (0, import_react9.useState)(false);
1477
+ const [success, setSuccess] = (0, import_react9.useState)(false);
1449
1478
  const [scraping, setScraping] = (0, import_react9.useState)(false);
1450
- const [fetchingNews, setFetchingNews] = (0, import_react9.useState)(true);
1451
- const { primaryColor } = useTheme();
1452
- (0, import_react9.useEffect)(() => {
1453
- onLoadingChange == null ? void 0 : onLoadingChange(fetchingNews);
1454
- }, [fetchingNews, onLoadingChange]);
1479
+ const [scrapeStatus, setScrapeStatus] = (0, import_react9.useState)(null);
1480
+ const [loadingStatus, setLoadingStatus] = (0, import_react9.useState)(true);
1481
+ const [originalValues, setOriginalValues] = (0, import_react9.useState)({
1482
+ botName: "",
1483
+ state: void 0,
1484
+ cities: [],
1485
+ language: void 0,
1486
+ tone: void 0,
1487
+ style: void 0,
1488
+ wordCount: void 0,
1489
+ includeQuotes: true,
1490
+ includeFAQ: false,
1491
+ targetAudience: ""
1492
+ });
1455
1493
  (0, import_react9.useEffect)(() => {
1456
- const fetchSources = async () => {
1494
+ const fetchScrapeStatus = async () => {
1457
1495
  try {
1458
- const data = await getNewsSources();
1459
- setSources(data || []);
1460
- } catch (e) {
1461
- import_react_hot_toast3.default.error("Failed to load news sources");
1496
+ const data = await getScrapeStatus();
1497
+ setScrapeStatus(data);
1498
+ } catch (error) {
1499
+ console.log("Failed to fetch scrape status:", error);
1462
1500
  } finally {
1463
- setLoading(false);
1501
+ setLoadingStatus(false);
1464
1502
  }
1465
1503
  };
1466
- fetchSources();
1504
+ fetchScrapeStatus();
1467
1505
  }, []);
1468
- const fetchNews = (0, import_react9.useCallback)(async (sourceId) => {
1469
- setFetchingNews(true);
1506
+ const handleScrape = async () => {
1507
+ var _a2, _b2;
1508
+ setScraping(true);
1470
1509
  try {
1471
- let news;
1472
- if (sourceId) {
1473
- news = await getNewsBySource(sourceId);
1474
- } else {
1475
- news = await getTrendingNews();
1476
- }
1477
- onNewsLoaded == null ? void 0 : onNewsLoaded(news || []);
1478
- } catch (err) {
1479
- console.error("Failed to fetch news:", err);
1510
+ await triggerScrape({
1511
+ state: (_a2 = preferences == null ? void 0 : preferences.localization) == null ? void 0 : _a2.state,
1512
+ cities: (_b2 = preferences == null ? void 0 : preferences.localization) == null ? void 0 : _b2.cities
1513
+ });
1514
+ import_react_hot_toast.default.success("News scraping started successfully!");
1515
+ setTimeout(async () => {
1516
+ try {
1517
+ const data = await getScrapeStatus();
1518
+ setScrapeStatus(data);
1519
+ } catch (e) {
1520
+ console.log("Failed to refresh scrape status:", e);
1521
+ }
1522
+ }, 2e3);
1523
+ } catch (error) {
1524
+ console.error(error);
1525
+ import_react_hot_toast.default.error("Failed to trigger news scraping");
1480
1526
  } finally {
1481
- setFetchingNews(false);
1527
+ setScraping(false);
1482
1528
  }
1483
- }, []);
1484
- (0, import_react9.useEffect)(() => {
1485
- fetchNews(selectedSource);
1486
- }, [selectedSource, fetchNews]);
1487
- const handleSourceSelect = (option) => {
1488
- var _a;
1489
- const value = (option == null ? void 0 : option.value) === ALL_SOURCES_VALUE ? null : (_a = option == null ? void 0 : option.value) != null ? _a : null;
1490
- onSourceChange(value);
1491
1529
  };
1492
- const handleScrape = async () => {
1493
- if (!selectedSource) {
1494
- import_react_hot_toast3.default.error("Please select a source first");
1530
+ (0, import_react9.useEffect)(() => {
1531
+ var _a2, _b2, _c2, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
1532
+ if (preferences) {
1533
+ const name = ((_a2 = preferences.chatbot) == null ? void 0 : _a2.name) || "";
1534
+ const pState = (_b2 = preferences.localization) == null ? void 0 : _b2.state;
1535
+ const pCities = ((_c2 = preferences.localization) == null ? void 0 : _c2.cities) || [];
1536
+ const pLanguage = (_d = preferences.localization) == null ? void 0 : _d.language;
1537
+ setBotName(name);
1538
+ if ((_e = preferences.chatbot) == null ? void 0 : _e.logoUrl) setLogoUrl(preferences.chatbot.logoUrl);
1539
+ if (pState) {
1540
+ setState({ value: pState, label: pState });
1541
+ }
1542
+ if (Array.isArray(pCities)) {
1543
+ setCities(pCities.map((city) => ({ value: city, label: city })));
1544
+ }
1545
+ if (pLanguage) {
1546
+ const langOption = LANGUAGE_OPTIONS.find((opt) => opt.value === pLanguage);
1547
+ setLanguage(langOption || null);
1548
+ }
1549
+ const pTone = (_f = preferences.content) == null ? void 0 : _f.tone;
1550
+ const pStyle = (_g = preferences.content) == null ? void 0 : _g.style;
1551
+ const pWordCount = (_h = preferences.content) == null ? void 0 : _h.wordCount;
1552
+ const pIncludeQuotes = (_j = (_i = preferences.content) == null ? void 0 : _i.includeQuotes) != null ? _j : true;
1553
+ const pIncludeFAQ = (_l = (_k = preferences.content) == null ? void 0 : _k.includeFAQ) != null ? _l : false;
1554
+ const pTargetAudience = ((_m = preferences.content) == null ? void 0 : _m.targetAudience) || "";
1555
+ if (pTone) {
1556
+ const toneOption = TONE_OPTIONS.find((opt) => opt.value === pTone);
1557
+ setTone(toneOption || null);
1558
+ }
1559
+ if (pStyle) {
1560
+ const styleOption = STYLE_OPTIONS.find((opt) => opt.value === pStyle);
1561
+ setStyle(styleOption || null);
1562
+ }
1563
+ if (pWordCount) {
1564
+ const wordCountOption = WORD_COUNT_OPTIONS.find((opt) => opt.value === pWordCount);
1565
+ setWordCount(wordCountOption || null);
1566
+ }
1567
+ setIncludeQuotes(pIncludeQuotes);
1568
+ setIncludeFAQ(pIncludeFAQ);
1569
+ setTargetAudience(pTargetAudience);
1570
+ setOriginalValues({
1571
+ botName: name,
1572
+ state: pState,
1573
+ cities: pCities,
1574
+ language: pLanguage,
1575
+ tone: pTone,
1576
+ style: pStyle,
1577
+ wordCount: pWordCount,
1578
+ includeQuotes: pIncludeQuotes,
1579
+ includeFAQ: pIncludeFAQ,
1580
+ targetAudience: pTargetAudience
1581
+ });
1582
+ }
1583
+ }, [preferences]);
1584
+ const handleSave = async () => {
1585
+ if (!botName) {
1586
+ import_react_hot_toast.default.error("Chatbot name is required");
1495
1587
  return;
1496
1588
  }
1497
- setScraping(true);
1589
+ setSaving(true);
1590
+ setSuccess(false);
1498
1591
  try {
1499
- await scrapeNewsSource(selectedSource);
1500
- import_react_hot_toast3.default.success("News scraped successfully!");
1501
- onScrapeComplete == null ? void 0 : onScrapeComplete();
1502
- const news = await getNewsBySource(selectedSource);
1503
- onNewsLoaded == null ? void 0 : onNewsLoaded(news || []);
1504
- } catch (err) {
1505
- import_react_hot_toast3.default.error(err || "Failed to scrape news");
1592
+ const payload = {};
1593
+ if (botName !== originalValues.botName) {
1594
+ payload.botName = botName;
1595
+ }
1596
+ if (logo) {
1597
+ payload.logo = logo;
1598
+ }
1599
+ const currentState = state == null ? void 0 : state.value;
1600
+ if (currentState !== originalValues.state) {
1601
+ payload.state = currentState;
1602
+ }
1603
+ const currentCities = cities.map((c) => c.value);
1604
+ const citiesChanged = currentCities.length !== originalValues.cities.length || currentCities.some((city, index) => city !== originalValues.cities[index]);
1605
+ if (citiesChanged) {
1606
+ payload.cities = currentCities;
1607
+ }
1608
+ const currentLanguage = language == null ? void 0 : language.value;
1609
+ if (currentLanguage !== originalValues.language) {
1610
+ payload.language = currentLanguage;
1611
+ }
1612
+ const currentTone = tone == null ? void 0 : tone.value;
1613
+ if (currentTone !== originalValues.tone) {
1614
+ payload.tone = currentTone;
1615
+ }
1616
+ const currentStyle = style == null ? void 0 : style.value;
1617
+ if (currentStyle !== originalValues.style) {
1618
+ payload.style = currentStyle;
1619
+ }
1620
+ const currentWordCount = wordCount == null ? void 0 : wordCount.value;
1621
+ if (currentWordCount !== originalValues.wordCount) {
1622
+ payload.wordCount = currentWordCount;
1623
+ }
1624
+ if (includeQuotes !== originalValues.includeQuotes) {
1625
+ payload.includeQuotes = includeQuotes;
1626
+ }
1627
+ if (includeFAQ !== originalValues.includeFAQ) {
1628
+ payload.includeFAQ = includeFAQ;
1629
+ }
1630
+ if (targetAudience !== originalValues.targetAudience) {
1631
+ payload.targetAudience = targetAudience;
1632
+ }
1633
+ if (Object.keys(payload).length === 0) {
1634
+ import_react_hot_toast.default.error("No changes to save");
1635
+ setSaving(false);
1636
+ return;
1637
+ }
1638
+ const updatedPreferences = await savePreferencesApi(payload);
1639
+ if (updatedPreferences) {
1640
+ updatePreferences(updatedPreferences);
1641
+ } else {
1642
+ await refreshPreferences();
1643
+ }
1644
+ setSuccess(true);
1645
+ setLogo(null);
1646
+ import_react_hot_toast.default.success("Preferences saved successfully!");
1647
+ } catch (error) {
1648
+ console.error(error);
1649
+ import_react_hot_toast.default.error("Failed to save preferences");
1506
1650
  } finally {
1507
- setScraping(false);
1651
+ setSaving(false);
1508
1652
  }
1509
1653
  };
1510
- const options = [
1511
- { value: ALL_SOURCES_VALUE, label: "All Sources (Trending)" },
1512
- ...sources.map((source) => ({
1513
- value: source.id,
1514
- label: source.name
1515
- }))
1516
- ];
1517
- const selectedOption = options.find(
1518
- (opt) => selectedSource === null ? opt.value === ALL_SOURCES_VALUE : opt.value === selectedSource
1519
- ) || options[0];
1520
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-source-selector", children: [
1521
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "cnfy-source-selector-select-wrap", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1522
- import_react_select2.default,
1523
- {
1524
- options,
1525
- value: selectedOption,
1526
- onChange: handleSourceSelect,
1527
- isLoading: loading,
1528
- isDisabled: loading,
1529
- placeholder: "Select source...",
1530
- classNamePrefix: "react-select",
1531
- menuPlacement: "bottom",
1532
- menuPosition: "fixed",
1533
- menuShouldScrollIntoView: false,
1534
- maxMenuHeight: 220,
1535
- menuPortalTarget: typeof window !== "undefined" ? document.body : null,
1536
- styles: {
1537
- container: (base) => __spreadProps(__spreadValues({}, base), {
1538
- width: "100%"
1539
- }),
1540
- control: (base) => __spreadProps(__spreadValues({}, base), {
1541
- minHeight: "38px",
1542
- borderColor: "#e5e7eb",
1543
- boxShadow: "none",
1544
- width: "100%"
1545
- }),
1546
- menu: (base) => __spreadProps(__spreadValues({}, base), {
1547
- width: "100%",
1548
- zIndex: 999999
1549
- }),
1550
- menuPortal: (base) => __spreadProps(__spreadValues({}, base), {
1551
- zIndex: 999999
1552
- }),
1553
- option: (base, state) => __spreadProps(__spreadValues({}, base), {
1554
- backgroundColor: state.isSelected ? primaryColor : state.isFocused ? "#f3f4f6" : "white",
1555
- color: state.isSelected ? "white" : "#374151",
1556
- cursor: "pointer"
1557
- })
1654
+ if (loading) {
1655
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "cnfy-dash-page", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "cnfy-dash-page-subtitle", children: "Loading settings..." }) });
1656
+ }
1657
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-dash-page", children: [
1658
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-dash-card", children: [
1659
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h2", { className: "cnfy-dash-card-title", children: "Chatbot Settings" }),
1660
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-dash-field", children: [
1661
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { className: "cnfy-dash-label", children: "Chatbot Name" }),
1662
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1663
+ "input",
1664
+ {
1665
+ value: botName,
1666
+ onChange: (e) => setBotName(e.target.value),
1667
+ className: "cnfy-dash-input",
1668
+ placeholder: "Contenify AI"
1669
+ }
1670
+ )
1671
+ ] }),
1672
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-dash-field", children: [
1673
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { className: "cnfy-dash-label", children: "Chatbot Logo" }),
1674
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-logo-upload", children: [
1675
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "cnfy-logo-preview", children: logo ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1676
+ "img",
1677
+ {
1678
+ src: URL.createObjectURL(logo),
1679
+ alt: "Logo preview",
1680
+ className: "cnfy-logo-img"
1681
+ }
1682
+ ) : logoUrl ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1683
+ "img",
1684
+ {
1685
+ src: logoUrl,
1686
+ alt: "Current logo",
1687
+ className: "cnfy-logo-img"
1688
+ }
1689
+ ) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "cnfy-logo-placeholder", children: "No logo" }) }),
1690
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1691
+ "input",
1692
+ {
1693
+ type: "file",
1694
+ accept: "image/*",
1695
+ onChange: (e) => {
1696
+ var _a2;
1697
+ return setLogo(((_a2 = e.target.files) == null ? void 0 : _a2[0]) || null);
1698
+ },
1699
+ className: "cnfy-file-input"
1700
+ }
1701
+ )
1702
+ ] })
1703
+ ] })
1704
+ ] }),
1705
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-dash-card", children: [
1706
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h2", { className: "cnfy-dash-card-title", children: "Localization Settings" }),
1707
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-dash-field", children: [
1708
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { className: "cnfy-dash-label", children: "State" }),
1709
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1710
+ ClientSelect_default,
1711
+ {
1712
+ options: STATE_OPTIONS,
1713
+ value: state,
1714
+ onChange: (option) => setState(option),
1715
+ placeholder: "Select state"
1716
+ }
1717
+ )
1718
+ ] }),
1719
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-dash-field", children: [
1720
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { className: "cnfy-dash-label", children: "Cities" }),
1721
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1722
+ ClientSelect_default,
1723
+ {
1724
+ isMulti: true,
1725
+ options: CITY_OPTIONS,
1726
+ value: cities,
1727
+ onChange: (options) => setCities(options),
1728
+ placeholder: "Select cities",
1729
+ isDisabled: !state
1730
+ }
1731
+ )
1732
+ ] }),
1733
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-dash-field", children: [
1734
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { className: "cnfy-dash-label", children: "Language" }),
1735
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1736
+ ClientSelect_default,
1737
+ {
1738
+ options: LANGUAGE_OPTIONS,
1739
+ value: language,
1740
+ onChange: (option) => setLanguage(option),
1741
+ placeholder: "Select language"
1742
+ }
1743
+ )
1744
+ ] })
1745
+ ] }),
1746
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-dash-card", children: [
1747
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h2", { className: "cnfy-dash-card-title", children: "Content Generation Settings" }),
1748
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-dash-field", children: [
1749
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { className: "cnfy-dash-label", children: "Tone" }),
1750
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1751
+ ClientSelect_default,
1752
+ {
1753
+ options: TONE_OPTIONS,
1754
+ value: tone,
1755
+ onChange: (option) => setTone(option),
1756
+ placeholder: "Select tone"
1757
+ }
1758
+ ),
1759
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "cnfy-dash-hint", children: "The writing tone for generated content" })
1760
+ ] }),
1761
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-dash-field", children: [
1762
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { className: "cnfy-dash-label", children: "Style" }),
1763
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1764
+ ClientSelect_default,
1765
+ {
1766
+ options: STYLE_OPTIONS,
1767
+ value: style,
1768
+ onChange: (option) => setStyle(option),
1769
+ placeholder: "Select style"
1770
+ }
1771
+ ),
1772
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "cnfy-dash-hint", children: "The format/style of generated articles" })
1773
+ ] }),
1774
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-dash-field", children: [
1775
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { className: "cnfy-dash-label", children: "Word Count" }),
1776
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1777
+ ClientSelect_default,
1778
+ {
1779
+ options: WORD_COUNT_OPTIONS,
1780
+ value: wordCount,
1781
+ onChange: (option) => setWordCount(option),
1782
+ placeholder: "Select word count"
1783
+ }
1784
+ ),
1785
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "cnfy-dash-hint", children: "Target length for generated content" })
1786
+ ] }),
1787
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-dash-field", children: [
1788
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { className: "cnfy-dash-label", children: "Target Audience" }),
1789
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1790
+ "input",
1791
+ {
1792
+ value: targetAudience,
1793
+ onChange: (e) => setTargetAudience(e.target.value),
1794
+ className: "cnfy-dash-input",
1795
+ placeholder: "e.g. tech-savvy millennials, business professionals"
1796
+ }
1797
+ ),
1798
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "cnfy-dash-hint", children: "Describe your target audience for personalized content" })
1799
+ ] }),
1800
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-toggle-group", children: [
1801
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-toggle-row", children: [
1802
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { children: [
1803
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "cnfy-toggle-label", children: "Include Quotes" }),
1804
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "cnfy-toggle-desc", children: "Add relevant quotes to generated articles" })
1805
+ ] }),
1806
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1807
+ "button",
1808
+ {
1809
+ type: "button",
1810
+ role: "switch",
1811
+ "aria-checked": includeQuotes,
1812
+ onClick: () => setIncludeQuotes(!includeQuotes),
1813
+ className: "cnfy-toggle",
1814
+ style: { backgroundColor: includeQuotes ? primaryColor : "#d1d5db" },
1815
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1816
+ "span",
1817
+ {
1818
+ className: `cnfy-toggle-thumb ${includeQuotes ? "cnfy-toggle-thumb--on" : ""}`
1819
+ }
1820
+ )
1821
+ }
1822
+ )
1823
+ ] }),
1824
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-toggle-row", children: [
1825
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { children: [
1826
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "cnfy-toggle-label", children: "Include FAQ Section" }),
1827
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "cnfy-toggle-desc", children: "Add FAQ section at the end of articles" })
1828
+ ] }),
1829
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1830
+ "button",
1831
+ {
1832
+ type: "button",
1833
+ role: "switch",
1834
+ "aria-checked": includeFAQ,
1835
+ onClick: () => setIncludeFAQ(!includeFAQ),
1836
+ className: "cnfy-toggle",
1837
+ style: { backgroundColor: includeFAQ ? primaryColor : "#d1d5db" },
1838
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1839
+ "span",
1840
+ {
1841
+ className: `cnfy-toggle-thumb ${includeFAQ ? "cnfy-toggle-thumb--on" : ""}`
1842
+ }
1843
+ )
1844
+ }
1845
+ )
1846
+ ] })
1847
+ ] })
1848
+ ] }),
1849
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-dash-card", children: [
1850
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-dash-card-header", children: [
1851
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h2", { className: "cnfy-dash-card-title-inline", children: "News Scraping" }),
1852
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "cnfy-dash-card-desc", children: "Scrape latest news from your configured locations" })
1853
+ ] }),
1854
+ !loadingStatus && scrapeStatus && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-dash-grid cnfy-dash-grid--sm", children: [
1855
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { children: [
1856
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "cnfy-dash-label-muted", children: "Status:" }),
1857
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "cnfy-dash-label-bold", children: scrapeStatus.isRunning ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "cnfy-dash-badge cnfy-dash-badge--yellow", children: "Running" }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "cnfy-dash-badge cnfy-dash-badge--green", children: "Idle" }) })
1858
+ ] }),
1859
+ scrapeStatus.lastRun && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { children: [
1860
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "cnfy-dash-label-muted", children: "Last Run:" }),
1861
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "cnfy-dash-label-bold", children: new Date(scrapeStatus.lastRun).toLocaleString() })
1862
+ ] }),
1863
+ scrapeStatus.totalScraped !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { children: [
1864
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "cnfy-dash-label-muted", children: "Total Scraped:" }),
1865
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("p", { className: "cnfy-dash-label-bold", children: [
1866
+ scrapeStatus.totalScraped.toLocaleString(),
1867
+ " articles"
1868
+ ] })
1869
+ ] })
1870
+ ] }),
1871
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { children: [
1872
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("p", { className: "cnfy-dash-info-text", children: [
1873
+ "Current configuration: ",
1874
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("strong", { children: (_b = preferences == null ? void 0 : preferences.localization) == null ? void 0 : _b.state }),
1875
+ ((_c = preferences == null ? void 0 : preferences.localization) == null ? void 0 : _c.cities) && preferences.localization.cities.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1876
+ " - ",
1877
+ preferences.localization.cities.join(", ")
1878
+ ] })
1879
+ ] }),
1880
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1881
+ "button",
1882
+ {
1883
+ onClick: handleScrape,
1884
+ disabled: scraping || (scrapeStatus == null ? void 0 : scrapeStatus.isRunning),
1885
+ className: "cnfy-dash-btn-save",
1886
+ style: { backgroundColor: primaryColor },
1887
+ children: scraping ? "Starting Scrape..." : (scrapeStatus == null ? void 0 : scrapeStatus.isRunning) ? "Scraping in Progress..." : "Start Scraping"
1888
+ }
1889
+ )
1890
+ ] })
1891
+ ] }),
1892
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-dash-actions", children: [
1893
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1894
+ "button",
1895
+ {
1896
+ onClick: handleSave,
1897
+ disabled: saving,
1898
+ className: "cnfy-dash-btn-save",
1899
+ style: { backgroundColor: primaryColor },
1900
+ children: saving ? "Saving..." : "Save Preferences"
1558
1901
  }
1559
- }
1560
- ) }),
1561
- selectedSource && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
1562
- "button",
1563
- {
1564
- onClick: handleScrape,
1565
- disabled: scraping,
1566
- className: "cnfy-scrape-btn",
1567
- title: "Fetch latest news",
1568
- children: [
1569
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react6.RefreshCcw, { size: 14, className: scraping ? "cnfy-animate-spin" : "" }),
1570
- scraping ? "Scraping..." : "Scrape"
1571
- ]
1572
- }
1573
- ),
1574
- !selectedSource && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
1575
- "button",
1576
- {
1577
- onClick: () => fetchNews(null),
1578
- disabled: fetchingNews,
1579
- className: "cnfy-refresh-btn",
1580
- children: [
1581
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react6.RefreshCcw, { size: 14, className: fetchingNews ? "cnfy-animate-spin" : "" }),
1582
- "Refresh"
1583
- ]
1584
- }
1585
- )
1902
+ ),
1903
+ success && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "cnfy-dash-success", style: { color: primaryColor }, children: "Preferences saved successfully \u2705" })
1904
+ ] })
1586
1905
  ] });
1587
1906
  }
1588
1907
 
@@ -1606,7 +1925,7 @@ var createContentStreamApi = async ({
1606
1925
  }) => {
1607
1926
  var _a;
1608
1927
  const API_BASE_URL = getApiBaseUrl();
1609
- const apiKey = process.env.NEXT_PUBLIC_API_KEY;
1928
+ const apiKey = getApiKey();
1610
1929
  const headers = {
1611
1930
  "Content-Type": "application/json"
1612
1931
  };
@@ -1699,7 +2018,7 @@ var rewriteNewsStreamApi = async ({
1699
2018
  if (targetAudience) payload.targetAudience = targetAudience;
1700
2019
  try {
1701
2020
  const API_BASE_URL = getApiBaseUrl();
1702
- const apiKey = process.env.NEXT_PUBLIC_API_KEY;
2021
+ const apiKey = getApiKey();
1703
2022
  console.log("\u{1F680} Starting stream request to:", `${API_BASE_URL}/chat/rewrite/stream`);
1704
2023
  console.log("\u{1F4E6} Payload:", payload);
1705
2024
  const headers = {
@@ -1828,32 +2147,18 @@ var rewriteNewsApi = async ({
1828
2147
  };
1829
2148
 
1830
2149
  // components/chatbot/ChatBot.tsx
1831
- var import_react_hot_toast4 = __toESM(require("react-hot-toast"));
2150
+ var import_react_hot_toast2 = __toESM(require("react-hot-toast"));
1832
2151
  var import_lucide_react7 = require("lucide-react");
1833
2152
  var import_jsx_runtime11 = require("react/jsx-runtime");
1834
- function ChatBot({
1835
- onNavigate,
1836
- onLogout
1837
- } = {}) {
1838
- const { loading, showNewsPanel } = useTheme();
2153
+ function ChatBot() {
2154
+ const { loading } = useTheme();
1839
2155
  const { preferences } = usePreferences();
1840
- const [selectedSource, setSelectedSource] = (0, import_react10.useState)(null);
1841
- const [news, setNews] = (0, import_react10.useState)([]);
1842
- const [newsLoading, setNewsLoading] = (0, import_react10.useState)(true);
1843
- const [selectedArticle, setSelectedArticle] = (0, import_react10.useState)(null);
2156
+ const [preferencesOpen, setPreferencesOpen] = (0, import_react10.useState)(false);
1844
2157
  const [messages, setMessages] = (0, import_react10.useState)([]);
1845
- const [showChatMobile, setShowChatMobile] = (0, import_react10.useState)(false);
1846
2158
  const [isStreaming, setIsStreaming] = (0, import_react10.useState)(false);
1847
2159
  const [analyzedData, setAnalyzedData] = (0, import_react10.useState)(null);
1848
- const handleNewsLoaded = (0, import_react10.useCallback)((loadedNews) => {
1849
- setNews(loadedNews);
1850
- }, []);
1851
- const handleLoadingChange = (0, import_react10.useCallback)((isLoading) => {
1852
- setNewsLoading(isLoading);
1853
- }, []);
1854
2160
  const handleRecreate = async ({ title, content, id }) => {
1855
2161
  var _a;
1856
- setShowChatMobile(true);
1857
2162
  const assistantId = crypto.randomUUID();
1858
2163
  setMessages((prev) => [
1859
2164
  ...prev,
@@ -1896,7 +2201,7 @@ ${title}`
1896
2201
  },
1897
2202
  onComplete: () => {
1898
2203
  console.log("Streaming completed successfully");
1899
- import_react_hot_toast4.default.success("Article created successfully!");
2204
+ import_react_hot_toast2.default.success("Article created successfully!");
1900
2205
  },
1901
2206
  onError: async (error) => {
1902
2207
  console.error("Streaming error:", error);
@@ -1904,7 +2209,7 @@ ${title}`
1904
2209
  console.log("Falling back to regular API...");
1905
2210
  throw error;
1906
2211
  } else {
1907
- import_react_hot_toast4.default.error("Failed to complete article generation");
2212
+ import_react_hot_toast2.default.error("Failed to complete article generation");
1908
2213
  setMessages(
1909
2214
  (prev) => prev.map(
1910
2215
  (m) => m.id === assistantId ? __spreadProps(__spreadValues({}, m), { content: accumulatedContent || "\u274C Failed to create article. Please try again." }) : m
@@ -1936,11 +2241,11 @@ ${title}`
1936
2241
  (m) => m.id === assistantId ? __spreadProps(__spreadValues({}, m), { content: result.article || result }) : m
1937
2242
  )
1938
2243
  );
1939
- import_react_hot_toast4.default.success("Article created successfully!");
2244
+ import_react_hot_toast2.default.success("Article created successfully!");
1940
2245
  }
1941
2246
  } catch (err) {
1942
2247
  console.error("Complete Error:", err);
1943
- import_react_hot_toast4.default.error((err == null ? void 0 : err.message) || "An error occurred while creating the article");
2248
+ import_react_hot_toast2.default.error((err == null ? void 0 : err.message) || "An error occurred while creating the article");
1944
2249
  setMessages(
1945
2250
  (prev) => prev.map(
1946
2251
  (m) => m.id === assistantId ? __spreadProps(__spreadValues({}, m), { content: "\u274C Failed to create article. Please try again." }) : m
@@ -1991,7 +2296,7 @@ ${optionsList}`
1991
2296
  }
1992
2297
  } catch (err) {
1993
2298
  console.error("Analyze input error:", err);
1994
- import_react_hot_toast4.default.error("Failed to analyze the link");
2299
+ import_react_hot_toast2.default.error("Failed to analyze the link");
1995
2300
  setMessages(
1996
2301
  (prev) => prev.map(
1997
2302
  (m) => m.id === assistantId ? __spreadProps(__spreadValues({}, m), { content: "\u274C Failed to analyze the link. Please try again." }) : m
@@ -2027,12 +2332,12 @@ ${optionsList}`
2027
2332
  },
2028
2333
  onComplete: () => {
2029
2334
  setIsStreaming(false);
2030
- import_react_hot_toast4.default.success("Content generated!");
2335
+ import_react_hot_toast2.default.success("Content generated!");
2031
2336
  },
2032
2337
  onError: (error) => {
2033
2338
  console.error("Stream error:", error);
2034
2339
  setIsStreaming(false);
2035
- import_react_hot_toast4.default.error("Failed to generate content");
2340
+ import_react_hot_toast2.default.error("Failed to generate content");
2036
2341
  }
2037
2342
  });
2038
2343
  } catch (err) {
@@ -2080,12 +2385,12 @@ ${optionsList}`
2080
2385
  },
2081
2386
  onComplete: () => {
2082
2387
  setIsStreaming(false);
2083
- import_react_hot_toast4.default.success("Content created!");
2388
+ import_react_hot_toast2.default.success("Content created!");
2084
2389
  },
2085
2390
  onError: (error) => {
2086
2391
  console.error("Stream error:", error);
2087
2392
  setIsStreaming(false);
2088
- import_react_hot_toast4.default.error("Failed to create content");
2393
+ import_react_hot_toast2.default.error("Failed to create content");
2089
2394
  }
2090
2395
  });
2091
2396
  } catch (e) {
@@ -2100,7 +2405,7 @@ ${optionsList}`
2100
2405
  )
2101
2406
  );
2102
2407
  setIsStreaming(false);
2103
- import_react_hot_toast4.default.success("Content created!");
2408
+ import_react_hot_toast2.default.success("Content created!");
2104
2409
  }
2105
2410
  } catch (err) {
2106
2411
  console.error("Create content error:", err);
@@ -2119,68 +2424,31 @@ ${optionsList}`
2119
2424
  ] }) });
2120
2425
  }
2121
2426
  return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "cnfy-root", children: [
2122
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(HeaderBar, { onNavigate, onLogout }),
2123
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: `cnfy-main ${showNewsPanel ? "cnfy-main--with-news" : ""}`, children: [
2124
- showNewsPanel && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("aside", { className: "cnfy-sidebar", children: [
2125
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2126
- SourceSelector,
2127
- {
2128
- selectedSource,
2129
- onSourceChange: (value) => {
2130
- console.log("Selected source:", value);
2131
- setSelectedSource(value);
2132
- },
2133
- onNewsLoaded: handleNewsLoaded,
2134
- onLoadingChange: handleLoadingChange
2135
- }
2136
- ) }),
2137
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2138
- TrendingNews,
2139
- {
2140
- onRecreate: handleRecreate,
2141
- news,
2142
- isLoading: newsLoading
2143
- }
2144
- )
2145
- ] }),
2146
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
2147
- "section",
2427
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(HeaderBar, { onOpenPreferences: () => setPreferencesOpen(true) }),
2428
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "cnfy-main", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("section", { className: "cnfy-chat-section cnfy-chat-section--full", children: [
2429
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "cnfy-chat-inner", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2430
+ ChatWindow,
2148
2431
  {
2149
- className: `cnfy-chat-section ${showNewsPanel ? "cnfy-chat-section--with-news" : "cnfy-chat-section--full"} ${showChatMobile ? "cnfy-chat-section--visible" : "cnfy-chat-section--hidden-mobile"}`,
2150
- children: [
2151
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "cnfy-mobile-back", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2152
- "button",
2153
- {
2154
- onClick: () => setShowChatMobile(false),
2155
- className: "cnfy-mobile-back-btn",
2156
- children: "\u2190 Back to news"
2157
- }
2158
- ) }),
2159
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "cnfy-chat-inner", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2160
- ChatWindow,
2161
- {
2162
- messages,
2163
- onSend: handleSendMessage,
2164
- onSelectNews: handleRecreate,
2165
- isStreaming,
2166
- analyzedData,
2167
- onSelectAction: handleSelectAction
2168
- }
2169
- ) }),
2170
- !messages.length && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "cnfy-empty-state", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { children: [
2171
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "cnfy-empty-state-title", children: "AI News Assistant" }),
2172
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "cnfy-empty-state-subtitle", children: "Select a news article or type a message to begin" })
2173
- ] }) })
2174
- ]
2432
+ messages,
2433
+ onSend: handleSendMessage,
2434
+ onSelectNews: handleRecreate,
2435
+ isStreaming,
2436
+ analyzedData,
2437
+ onSelectAction: handleSelectAction
2175
2438
  }
2176
- )
2177
- ] }),
2178
- selectedArticle && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2179
- ArticleModal,
2439
+ ) }),
2440
+ !messages.length && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "cnfy-empty-state", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { children: [
2441
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "cnfy-empty-state-title", children: "AI News Assistant" }),
2442
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "cnfy-empty-state-subtitle", children: "Type a message or paste a link to begin" })
2443
+ ] }) })
2444
+ ] }) }),
2445
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2446
+ Drawer,
2180
2447
  {
2181
- article: selectedArticle,
2182
- onClose: () => setSelectedArticle(null),
2183
- onRecreate: handleRecreate
2448
+ open: preferencesOpen,
2449
+ onClose: () => setPreferencesOpen(false),
2450
+ title: "Settings",
2451
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PreferencesPage, {})
2184
2452
  }
2185
2453
  )
2186
2454
  ] });
@@ -2188,12 +2456,16 @@ ${optionsList}`
2188
2456
 
2189
2457
  // src/index.tsx
2190
2458
  var import_jsx_runtime12 = require("react/jsx-runtime");
2191
- function ContenifyChatBot({ onNavigate, onLogout }) {
2192
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(PreferencesProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ChatBot, { onNavigate, onLogout }) });
2459
+ function ContenifyChatBot({ apiUrl, apiKey, domain }) {
2460
+ (0, import_react11.useEffect)(() => {
2461
+ setConfig({ apiUrl, apiKey, domain });
2462
+ }, [apiUrl, apiKey, domain]);
2463
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(PreferencesProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ChatBot, {}) });
2193
2464
  }
2194
2465
  var index_default = ContenifyChatBot;
2195
2466
  // Annotate the CommonJS export names for ESM import in node:
2196
2467
  0 && (module.exports = {
2197
- ContenifyChatBot
2468
+ ContenifyChatBot,
2469
+ setConfig
2198
2470
  });
2199
2471
  //# sourceMappingURL=index.js.map