@contenify/chatbot 0.1.4 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,
@@ -833,7 +875,8 @@ function ChatWindow({
833
875
  onSelectNews,
834
876
  isStreaming = false,
835
877
  analyzedData,
836
- onSelectAction
878
+ onSelectAction,
879
+ onPost: onPostCallback
837
880
  }) {
838
881
  var _a, _b;
839
882
  const { loading, showNewsPanel } = useTheme();
@@ -882,7 +925,7 @@ function ChatWindow({
882
925
  handleCloseModal();
883
926
  };
884
927
  const handlePost = (content, keywords) => {
885
- console.log("Posting:", { content, keywords });
928
+ onPostCallback == null ? void 0 : onPostCallback(content, keywords);
886
929
  handleCloseModal();
887
930
  };
888
931
  (0, import_react6.useLayoutEffect)(() => {
@@ -994,13 +1037,13 @@ function ChatWindow({
994
1037
  });
995
1038
  return { blocks, metaKeywords };
996
1039
  }
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: [
1040
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "cnfy-chat", children: [
1041
+ /* @__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
1042
  messages.map((msg) => {
1000
1043
  var _a2;
1001
1044
  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)(
1045
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "cnfy-msg", children: [
1046
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "cnfy-msg-avatar-wrap", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1004
1047
  "div",
1005
1048
  {
1006
1049
  className: "cnfy-msg-avatar",
@@ -1010,19 +1053,19 @@ function ChatWindow({
1010
1053
  children: msg.role === "assistant" ? "AI" : "You"
1011
1054
  }
1012
1055
  ) }),
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)(
1056
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "cnfy-msg-body", children: [
1057
+ 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
1058
  "button",
1016
1059
  {
1017
1060
  onClick: () => handleCopy(parsed.blocks, msg.id),
1018
1061
  className: "cnfy-copy-btn",
1019
1062
  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 })
1063
+ 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
1064
  }
1022
1065
  ) }),
1023
1066
  parsed.blocks.map((block, idx) => {
1024
1067
  if (block.type === "h1") {
1025
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1068
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1026
1069
  "h1",
1027
1070
  {
1028
1071
  className: "cnfy-block-h1",
@@ -1032,7 +1075,7 @@ function ChatWindow({
1032
1075
  );
1033
1076
  }
1034
1077
  if (block.type === "h2") {
1035
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1078
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1036
1079
  "h2",
1037
1080
  {
1038
1081
  className: "cnfy-block-h2",
@@ -1041,9 +1084,9 @@ function ChatWindow({
1041
1084
  idx
1042
1085
  );
1043
1086
  }
1044
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "cnfy-block-p", children: block.text }, idx);
1087
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "cnfy-block-p", children: block.text }, idx);
1045
1088
  }),
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)(
1089
+ 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
1090
  "span",
1048
1091
  {
1049
1092
  className: "cnfy-msg-keyword-tag",
@@ -1054,41 +1097,41 @@ function ChatWindow({
1054
1097
  },
1055
1098
  i
1056
1099
  )) }) }),
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) => {
1100
+ 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
1101
  const IconComponent = ACTION_ICONS[option.id] || import_lucide_react4.FileText;
1059
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1102
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1060
1103
  "button",
1061
1104
  {
1062
1105
  onClick: () => onSelectAction == null ? void 0 : onSelectAction(option.id, analyzedData.url, analyzedData.content),
1063
1106
  className: "cnfy-action-btn",
1064
1107
  children: [
1065
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(IconComponent, { size: 16 }),
1108
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(IconComponent, { size: 16 }),
1066
1109
  option.name
1067
1110
  ]
1068
1111
  },
1069
1112
  option.id
1070
1113
  );
1071
1114
  }) }),
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)(
1115
+ 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: [
1116
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1074
1117
  "button",
1075
1118
  {
1076
1119
  onClick: () => handleEdit(parsed.blocks, parsed.metaKeywords, msg.id),
1077
1120
  className: "cnfy-btn-edit",
1078
1121
  children: [
1079
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react4.Edit3, { size: 16 }),
1122
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react4.Edit3, { size: 16 }),
1080
1123
  "Edit"
1081
1124
  ]
1082
1125
  }
1083
1126
  ),
1084
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1127
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1085
1128
  "button",
1086
1129
  {
1087
1130
  onClick: () => handlePost(msg.content, parsed.metaKeywords),
1088
1131
  className: "cnfy-btn-post",
1089
1132
  style: { backgroundColor: primaryColor, color: "#fff" },
1090
1133
  children: [
1091
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react4.Send, { size: 16 }),
1134
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react4.Send, { size: 16 }),
1092
1135
  "Post"
1093
1136
  ]
1094
1137
  }
@@ -1097,34 +1140,34 @@ function ChatWindow({
1097
1140
  ] })
1098
1141
  ] }, msg.id);
1099
1142
  }),
1100
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { ref: bottomRef })
1143
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { ref: bottomRef })
1101
1144
  ] }) }),
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)(
1145
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "cnfy-input-area", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "cnfy-input-inner", children: [
1146
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { ref: dropdownRef, className: "cnfy-news-pulse-wrap", children: [
1147
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1105
1148
  "button",
1106
1149
  {
1107
1150
  onClick: handleOpenNewsDropdown,
1108
1151
  className: "cnfy-news-pulse-btn cnfy-animate-pulse",
1109
1152
  title: "Select from trending news",
1110
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react4.Zap, { size: 16 })
1153
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react4.Zap, { size: 16 })
1111
1154
  }
1112
1155
  ),
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)(
1156
+ showNewsDropdown && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "cnfy-news-dropdown", children: [
1157
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "cnfy-news-dropdown-header", style: { backgroundColor: primaryColor, color: "#fff" }, children: [
1158
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "cnfy-news-dropdown-title", children: "Select News" }),
1159
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1117
1160
  "button",
1118
1161
  {
1119
1162
  onClick: () => setShowNewsDropdown(false),
1120
1163
  className: "cnfy-news-dropdown-close",
1121
1164
  style: { backgroundColor: primaryColor, color: "#fff" },
1122
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react4.X, { size: 14 })
1165
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react4.X, { size: 14 })
1123
1166
  }
1124
1167
  )
1125
1168
  ] }),
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)(
1169
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "cnfy-news-dropdown-source", children: [
1170
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "cnfy-news-dropdown-select-wrap", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1128
1171
  import_react_select.default,
1129
1172
  {
1130
1173
  options: [
@@ -1170,7 +1213,7 @@ function ChatWindow({
1170
1213
  }
1171
1214
  }
1172
1215
  ) }),
1173
- selectedSource && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1216
+ selectedSource && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1174
1217
  "button",
1175
1218
  {
1176
1219
  onClick: handleScrape,
@@ -1178,28 +1221,28 @@ function ChatWindow({
1178
1221
  className: "cnfy-scrape-btn",
1179
1222
  title: "Fetch latest news",
1180
1223
  children: [
1181
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react4.RefreshCcw, { size: 14, className: scraping ? "cnfy-animate-spin" : "" }),
1224
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react4.RefreshCcw, { size: 14, className: scraping ? "cnfy-animate-spin" : "" }),
1182
1225
  scraping ? "Scraping..." : "Scrape"
1183
1226
  ]
1184
1227
  }
1185
1228
  ),
1186
- !selectedSource && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1229
+ !selectedSource && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1187
1230
  "button",
1188
1231
  {
1189
1232
  onClick: () => fetchNews(null),
1190
1233
  disabled: loadingNews,
1191
1234
  className: "cnfy-refresh-btn",
1192
1235
  children: [
1193
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react4.RefreshCcw, { size: 14, className: loadingNews ? "cnfy-animate-spin" : "" }),
1236
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react4.RefreshCcw, { size: 14, className: loadingNews ? "cnfy-animate-spin" : "" }),
1194
1237
  "Refresh"
1195
1238
  ]
1196
1239
  }
1197
1240
  )
1198
1241
  ] }),
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)(
1242
+ /* @__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: [
1243
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { children: "No news found." }),
1244
+ selectedSource && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "cnfy-news-dropdown-hint", children: 'Click "Scrape" to fetch latest news.' })
1245
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1203
1246
  NewsList,
1204
1247
  {
1205
1248
  news: trendingNews.slice(0, 10),
@@ -1212,7 +1255,7 @@ function ChatWindow({
1212
1255
  ) })
1213
1256
  ] })
1214
1257
  ] }),
1215
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1258
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1216
1259
  "textarea",
1217
1260
  {
1218
1261
  ref: textareaRef,
@@ -1230,17 +1273,17 @@ function ChatWindow({
1230
1273
  style: { maxHeight: "200px", overflowY: input.split("\n").length > 6 ? "auto" : "hidden" }
1231
1274
  }
1232
1275
  ),
1233
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1276
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1234
1277
  "button",
1235
1278
  {
1236
1279
  onClick: handleSend,
1237
1280
  className: "cnfy-send-btn",
1238
1281
  style: { backgroundColor: primaryColor, color: "#fff" },
1239
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react4.SendHorizontal, { size: 18 })
1282
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react4.SendHorizontal, { size: 18 })
1240
1283
  }
1241
1284
  )
1242
1285
  ] }) }),
1243
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1286
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1244
1287
  EditModal,
1245
1288
  {
1246
1289
  isOpen: editModal.isOpen,
@@ -1255,109 +1298,31 @@ function ChatWindow({
1255
1298
  }
1256
1299
 
1257
1300
  // components/chatbot/UserMenu.tsx
1258
- var import_react7 = require("react");
1259
1301
  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");
1302
+ var import_jsx_runtime6 = require("react/jsx-runtime");
1270
1303
  function UserMenu({
1271
- onNavigate,
1272
- onLogout
1304
+ onOpenPreferences
1273
1305
  }) {
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)(
1306
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "cnfy-user-menu", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1339
1307
  "button",
1340
1308
  {
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
- ]
1309
+ onClick: () => onOpenPreferences == null ? void 0 : onOpenPreferences(),
1310
+ className: "cnfy-user-menu-trigger",
1311
+ "aria-label": "Settings",
1312
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.Settings, { size: 20, className: "cnfy-user-menu-trigger-icon" })
1347
1313
  }
1348
- );
1314
+ ) });
1349
1315
  }
1350
1316
 
1351
1317
  // components/chatbot/headerBar.tsx
1352
- var import_jsx_runtime8 = require("react/jsx-runtime");
1318
+ var import_jsx_runtime7 = require("react/jsx-runtime");
1353
1319
  function HeaderBar({
1354
- onNavigate,
1355
- onLogout
1320
+ onOpenPreferences
1356
1321
  }) {
1357
1322
  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)(
1323
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("header", { className: "cnfy-header", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "cnfy-header-inner", children: [
1324
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "cnfy-header-left", children: [
1325
+ logoUrl ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("img", { src: logoUrl, alt: "Logo", className: "cnfy-header-logo-img" }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1361
1326
  "div",
1362
1327
  {
1363
1328
  className: "cnfy-header-logo-fallback",
@@ -1365,224 +1330,579 @@ function HeaderBar({
1365
1330
  children: botName.charAt(0).toUpperCase()
1366
1331
  }
1367
1332
  ),
1368
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "cnfy-header-brand", children: botName.toUpperCase() })
1333
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "cnfy-header-brand", children: botName.toUpperCase() })
1369
1334
  ] }),
1370
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "cnfy-header-right", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(UserMenu, { onNavigate, onLogout }) })
1335
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "cnfy-header-right", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(UserMenu, { onOpenPreferences }) })
1371
1336
  ] }) });
1372
1337
  }
1373
1338
 
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
1339
+ // components/ui/Drawer.tsx
1340
+ var import_react7 = require("react");
1341
+ var import_lucide_react6 = require("lucide-react");
1342
+ var import_jsx_runtime8 = require("react/jsx-runtime");
1343
+ function Drawer({
1344
+ open,
1345
+ onClose,
1346
+ title,
1347
+ children
1384
1348
  }) {
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
1349
+ (0, import_react7.useEffect)(() => {
1350
+ if (open) {
1351
+ document.body.style.overflow = "hidden";
1352
+ } else {
1353
+ document.body.style.overflow = "";
1429
1354
  }
1430
- );
1355
+ return () => {
1356
+ document.body.style.overflow = "";
1357
+ };
1358
+ }, [open]);
1359
+ if (!open) return null;
1360
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "cnfy-drawer-overlay", children: [
1361
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "cnfy-drawer-backdrop", onClick: onClose }),
1362
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "cnfy-drawer-panel", children: [
1363
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "cnfy-drawer-header", children: [
1364
+ title && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h2", { className: "cnfy-drawer-title", children: title }),
1365
+ /* @__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 }) })
1366
+ ] }),
1367
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "cnfy-drawer-body", children })
1368
+ ] })
1369
+ ] });
1431
1370
  }
1432
1371
 
1433
- // components/news/SourceSelector.tsx
1372
+ // components/preferences/Preferences.tsx
1434
1373
  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"));
1374
+ var import_react_hot_toast = __toESM(require("react-hot-toast"));
1375
+
1376
+ // services/settings.service.ts
1377
+ var triggerScrape = async ({
1378
+ state,
1379
+ cities
1380
+ }) => {
1381
+ const { data } = await api_default.post("/scrape/trigger", {
1382
+ state,
1383
+ cities
1384
+ });
1385
+ return data;
1386
+ };
1387
+ var getScrapeStatus = async () => {
1388
+ const { data } = await api_default.get("/scrape/status");
1389
+ return data.data;
1390
+ };
1391
+
1392
+ // components/ClientSelect.tsx
1393
+ var import_react8 = require("react");
1394
+ var import_jsx_runtime9 = require("react/jsx-runtime");
1395
+ var ReactSelect = null;
1396
+ var ClientSelect = (props) => {
1397
+ const [mounted, setMounted] = (0, import_react8.useState)(false);
1398
+ (0, import_react8.useEffect)(() => {
1399
+ setMounted(true);
1400
+ import("react-select").then((mod) => {
1401
+ ReactSelect = mod.default;
1402
+ });
1403
+ }, []);
1404
+ if (!mounted || !ReactSelect) return null;
1405
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ReactSelect, __spreadValues({}, props));
1406
+ };
1407
+ var ClientSelect_default = ClientSelect;
1408
+
1409
+ // components/preferences/Preferences.tsx
1438
1410
  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);
1411
+ var STATE_OPTIONS = [
1412
+ { value: "Uttar Pradesh", label: "Uttar Pradesh" }
1413
+ ];
1414
+ var CITY_OPTIONS = [
1415
+ "Agra",
1416
+ "Aligarh",
1417
+ "Ayodhya",
1418
+ "Bareilly",
1419
+ "Bijnor",
1420
+ "Bulandshahr",
1421
+ "Etawah",
1422
+ "Firozabad",
1423
+ "Ghaziabad",
1424
+ "Gorakhpur",
1425
+ "Jhansi",
1426
+ "Kanpur",
1427
+ "Lucknow",
1428
+ "Mathura",
1429
+ "Meerut",
1430
+ "Moradabad",
1431
+ "Muzaffarnagar",
1432
+ "Noida",
1433
+ "Prayagraj",
1434
+ "Rampur",
1435
+ "Saharanpur",
1436
+ "Sitapur",
1437
+ "Unnao",
1438
+ "Varanasi"
1439
+ ].map((city) => ({ value: city, label: city }));
1440
+ var LANGUAGE_OPTIONS = [
1441
+ { value: "en", label: "English" },
1442
+ { value: "hi", label: "Hindi" }
1443
+ ];
1444
+ var TONE_OPTIONS = [
1445
+ { value: "formal", label: "Formal" },
1446
+ { value: "casual", label: "Casual" },
1447
+ { value: "engaging", label: "Engaging" },
1448
+ { value: "professional", label: "Professional" }
1449
+ ];
1450
+ var STYLE_OPTIONS = [
1451
+ { value: "news", label: "News Article" },
1452
+ { value: "blog", label: "Blog Post" },
1453
+ { value: "editorial", label: "Editorial" },
1454
+ { value: "summary", label: "Summary" }
1455
+ ];
1456
+ var WORD_COUNT_OPTIONS = [
1457
+ { value: "short", label: "Short (~300 words)" },
1458
+ { value: "medium", label: "Medium (~600 words)" },
1459
+ { value: "long", label: "Long (~1000+ words)" }
1460
+ ];
1461
+ function PreferencesPage() {
1462
+ var _a, _b, _c;
1463
+ const { preferences, loading, refreshPreferences, updatePreferences } = usePreferences();
1464
+ const primaryColor = ((_a = preferences == null ? void 0 : preferences.chatbot) == null ? void 0 : _a.primaryColor) || "#10b981";
1465
+ const [botName, setBotName] = (0, import_react9.useState)("");
1466
+ const [logo, setLogo] = (0, import_react9.useState)(null);
1467
+ const [logoUrl, setLogoUrl] = (0, import_react9.useState)(null);
1468
+ const [state, setState] = (0, import_react9.useState)(null);
1469
+ const [cities, setCities] = (0, import_react9.useState)([]);
1470
+ const [language, setLanguage] = (0, import_react9.useState)(null);
1471
+ const [tone, setTone] = (0, import_react9.useState)(null);
1472
+ const [style, setStyle] = (0, import_react9.useState)(null);
1473
+ const [wordCount, setWordCount] = (0, import_react9.useState)(null);
1474
+ const [includeQuotes, setIncludeQuotes] = (0, import_react9.useState)(true);
1475
+ const [includeFAQ, setIncludeFAQ] = (0, import_react9.useState)(false);
1476
+ const [targetAudience, setTargetAudience] = (0, import_react9.useState)("");
1477
+ const [saving, setSaving] = (0, import_react9.useState)(false);
1478
+ const [success, setSuccess] = (0, import_react9.useState)(false);
1449
1479
  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]);
1480
+ const [scrapeStatus, setScrapeStatus] = (0, import_react9.useState)(null);
1481
+ const [loadingStatus, setLoadingStatus] = (0, import_react9.useState)(true);
1482
+ const [originalValues, setOriginalValues] = (0, import_react9.useState)({
1483
+ botName: "",
1484
+ state: void 0,
1485
+ cities: [],
1486
+ language: void 0,
1487
+ tone: void 0,
1488
+ style: void 0,
1489
+ wordCount: void 0,
1490
+ includeQuotes: true,
1491
+ includeFAQ: false,
1492
+ targetAudience: ""
1493
+ });
1455
1494
  (0, import_react9.useEffect)(() => {
1456
- const fetchSources = async () => {
1495
+ const fetchScrapeStatus = async () => {
1457
1496
  try {
1458
- const data = await getNewsSources();
1459
- setSources(data || []);
1460
- } catch (e) {
1461
- import_react_hot_toast3.default.error("Failed to load news sources");
1497
+ const data = await getScrapeStatus();
1498
+ setScrapeStatus(data);
1499
+ } catch (error) {
1500
+ console.log("Failed to fetch scrape status:", error);
1462
1501
  } finally {
1463
- setLoading(false);
1502
+ setLoadingStatus(false);
1464
1503
  }
1465
1504
  };
1466
- fetchSources();
1505
+ fetchScrapeStatus();
1467
1506
  }, []);
1468
- const fetchNews = (0, import_react9.useCallback)(async (sourceId) => {
1469
- setFetchingNews(true);
1507
+ const handleScrape = async () => {
1508
+ var _a2, _b2;
1509
+ setScraping(true);
1470
1510
  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);
1511
+ await triggerScrape({
1512
+ state: (_a2 = preferences == null ? void 0 : preferences.localization) == null ? void 0 : _a2.state,
1513
+ cities: (_b2 = preferences == null ? void 0 : preferences.localization) == null ? void 0 : _b2.cities
1514
+ });
1515
+ import_react_hot_toast.default.success("News scraping started successfully!");
1516
+ setTimeout(async () => {
1517
+ try {
1518
+ const data = await getScrapeStatus();
1519
+ setScrapeStatus(data);
1520
+ } catch (e) {
1521
+ console.log("Failed to refresh scrape status:", e);
1522
+ }
1523
+ }, 2e3);
1524
+ } catch (error) {
1525
+ console.error(error);
1526
+ import_react_hot_toast.default.error("Failed to trigger news scraping");
1480
1527
  } finally {
1481
- setFetchingNews(false);
1528
+ setScraping(false);
1482
1529
  }
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
1530
  };
1492
- const handleScrape = async () => {
1493
- if (!selectedSource) {
1494
- import_react_hot_toast3.default.error("Please select a source first");
1531
+ (0, import_react9.useEffect)(() => {
1532
+ var _a2, _b2, _c2, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
1533
+ if (preferences) {
1534
+ const name = ((_a2 = preferences.chatbot) == null ? void 0 : _a2.name) || "";
1535
+ const pState = (_b2 = preferences.localization) == null ? void 0 : _b2.state;
1536
+ const pCities = ((_c2 = preferences.localization) == null ? void 0 : _c2.cities) || [];
1537
+ const pLanguage = (_d = preferences.localization) == null ? void 0 : _d.language;
1538
+ setBotName(name);
1539
+ if ((_e = preferences.chatbot) == null ? void 0 : _e.logoUrl) setLogoUrl(preferences.chatbot.logoUrl);
1540
+ if (pState) {
1541
+ setState({ value: pState, label: pState });
1542
+ }
1543
+ if (Array.isArray(pCities)) {
1544
+ setCities(pCities.map((city) => ({ value: city, label: city })));
1545
+ }
1546
+ if (pLanguage) {
1547
+ const langOption = LANGUAGE_OPTIONS.find((opt) => opt.value === pLanguage);
1548
+ setLanguage(langOption || null);
1549
+ }
1550
+ const pTone = (_f = preferences.content) == null ? void 0 : _f.tone;
1551
+ const pStyle = (_g = preferences.content) == null ? void 0 : _g.style;
1552
+ const pWordCount = (_h = preferences.content) == null ? void 0 : _h.wordCount;
1553
+ const pIncludeQuotes = (_j = (_i = preferences.content) == null ? void 0 : _i.includeQuotes) != null ? _j : true;
1554
+ const pIncludeFAQ = (_l = (_k = preferences.content) == null ? void 0 : _k.includeFAQ) != null ? _l : false;
1555
+ const pTargetAudience = ((_m = preferences.content) == null ? void 0 : _m.targetAudience) || "";
1556
+ if (pTone) {
1557
+ const toneOption = TONE_OPTIONS.find((opt) => opt.value === pTone);
1558
+ setTone(toneOption || null);
1559
+ }
1560
+ if (pStyle) {
1561
+ const styleOption = STYLE_OPTIONS.find((opt) => opt.value === pStyle);
1562
+ setStyle(styleOption || null);
1563
+ }
1564
+ if (pWordCount) {
1565
+ const wordCountOption = WORD_COUNT_OPTIONS.find((opt) => opt.value === pWordCount);
1566
+ setWordCount(wordCountOption || null);
1567
+ }
1568
+ setIncludeQuotes(pIncludeQuotes);
1569
+ setIncludeFAQ(pIncludeFAQ);
1570
+ setTargetAudience(pTargetAudience);
1571
+ setOriginalValues({
1572
+ botName: name,
1573
+ state: pState,
1574
+ cities: pCities,
1575
+ language: pLanguage,
1576
+ tone: pTone,
1577
+ style: pStyle,
1578
+ wordCount: pWordCount,
1579
+ includeQuotes: pIncludeQuotes,
1580
+ includeFAQ: pIncludeFAQ,
1581
+ targetAudience: pTargetAudience
1582
+ });
1583
+ }
1584
+ }, [preferences]);
1585
+ const handleSave = async () => {
1586
+ if (!botName) {
1587
+ import_react_hot_toast.default.error("Chatbot name is required");
1495
1588
  return;
1496
1589
  }
1497
- setScraping(true);
1590
+ setSaving(true);
1591
+ setSuccess(false);
1498
1592
  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");
1593
+ const payload = {};
1594
+ if (botName !== originalValues.botName) {
1595
+ payload.botName = botName;
1596
+ }
1597
+ if (logo) {
1598
+ payload.logo = logo;
1599
+ }
1600
+ const currentState = state == null ? void 0 : state.value;
1601
+ if (currentState !== originalValues.state) {
1602
+ payload.state = currentState;
1603
+ }
1604
+ const currentCities = cities.map((c) => c.value);
1605
+ const citiesChanged = currentCities.length !== originalValues.cities.length || currentCities.some((city, index) => city !== originalValues.cities[index]);
1606
+ if (citiesChanged) {
1607
+ payload.cities = currentCities;
1608
+ }
1609
+ const currentLanguage = language == null ? void 0 : language.value;
1610
+ if (currentLanguage !== originalValues.language) {
1611
+ payload.language = currentLanguage;
1612
+ }
1613
+ const currentTone = tone == null ? void 0 : tone.value;
1614
+ if (currentTone !== originalValues.tone) {
1615
+ payload.tone = currentTone;
1616
+ }
1617
+ const currentStyle = style == null ? void 0 : style.value;
1618
+ if (currentStyle !== originalValues.style) {
1619
+ payload.style = currentStyle;
1620
+ }
1621
+ const currentWordCount = wordCount == null ? void 0 : wordCount.value;
1622
+ if (currentWordCount !== originalValues.wordCount) {
1623
+ payload.wordCount = currentWordCount;
1624
+ }
1625
+ if (includeQuotes !== originalValues.includeQuotes) {
1626
+ payload.includeQuotes = includeQuotes;
1627
+ }
1628
+ if (includeFAQ !== originalValues.includeFAQ) {
1629
+ payload.includeFAQ = includeFAQ;
1630
+ }
1631
+ if (targetAudience !== originalValues.targetAudience) {
1632
+ payload.targetAudience = targetAudience;
1633
+ }
1634
+ if (Object.keys(payload).length === 0) {
1635
+ import_react_hot_toast.default.error("No changes to save");
1636
+ setSaving(false);
1637
+ return;
1638
+ }
1639
+ const updatedPreferences = await savePreferencesApi(payload);
1640
+ if (updatedPreferences) {
1641
+ updatePreferences(updatedPreferences);
1642
+ } else {
1643
+ await refreshPreferences();
1644
+ }
1645
+ setSuccess(true);
1646
+ setLogo(null);
1647
+ import_react_hot_toast.default.success("Preferences saved successfully!");
1648
+ } catch (error) {
1649
+ console.error(error);
1650
+ import_react_hot_toast.default.error("Failed to save preferences");
1506
1651
  } finally {
1507
- setScraping(false);
1652
+ setSaving(false);
1508
1653
  }
1509
1654
  };
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
- })
1655
+ if (loading) {
1656
+ 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..." }) });
1657
+ }
1658
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-dash-page", children: [
1659
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-dash-card", children: [
1660
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h2", { className: "cnfy-dash-card-title", children: "Chatbot Settings" }),
1661
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-dash-field", children: [
1662
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { className: "cnfy-dash-label", children: "Chatbot Name" }),
1663
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1664
+ "input",
1665
+ {
1666
+ value: botName,
1667
+ onChange: (e) => setBotName(e.target.value),
1668
+ className: "cnfy-dash-input",
1669
+ placeholder: "Contenify AI"
1670
+ }
1671
+ )
1672
+ ] }),
1673
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-dash-field", children: [
1674
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { className: "cnfy-dash-label", children: "Chatbot Logo" }),
1675
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-logo-upload", children: [
1676
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "cnfy-logo-preview", children: logo ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1677
+ "img",
1678
+ {
1679
+ src: URL.createObjectURL(logo),
1680
+ alt: "Logo preview",
1681
+ className: "cnfy-logo-img"
1682
+ }
1683
+ ) : logoUrl ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1684
+ "img",
1685
+ {
1686
+ src: logoUrl,
1687
+ alt: "Current logo",
1688
+ className: "cnfy-logo-img"
1689
+ }
1690
+ ) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "cnfy-logo-placeholder", children: "No logo" }) }),
1691
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1692
+ "input",
1693
+ {
1694
+ type: "file",
1695
+ accept: "image/*",
1696
+ onChange: (e) => {
1697
+ var _a2;
1698
+ return setLogo(((_a2 = e.target.files) == null ? void 0 : _a2[0]) || null);
1699
+ },
1700
+ className: "cnfy-file-input"
1701
+ }
1702
+ )
1703
+ ] })
1704
+ ] })
1705
+ ] }),
1706
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-dash-card", children: [
1707
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h2", { className: "cnfy-dash-card-title", children: "Localization Settings" }),
1708
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-dash-field", children: [
1709
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { className: "cnfy-dash-label", children: "State" }),
1710
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1711
+ ClientSelect_default,
1712
+ {
1713
+ options: STATE_OPTIONS,
1714
+ value: state,
1715
+ onChange: (option) => setState(option),
1716
+ placeholder: "Select state"
1717
+ }
1718
+ )
1719
+ ] }),
1720
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-dash-field", children: [
1721
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { className: "cnfy-dash-label", children: "Cities" }),
1722
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1723
+ ClientSelect_default,
1724
+ {
1725
+ isMulti: true,
1726
+ options: CITY_OPTIONS,
1727
+ value: cities,
1728
+ onChange: (options) => setCities(options),
1729
+ placeholder: "Select cities",
1730
+ isDisabled: !state
1731
+ }
1732
+ )
1733
+ ] }),
1734
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-dash-field", children: [
1735
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { className: "cnfy-dash-label", children: "Language" }),
1736
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1737
+ ClientSelect_default,
1738
+ {
1739
+ options: LANGUAGE_OPTIONS,
1740
+ value: language,
1741
+ onChange: (option) => setLanguage(option),
1742
+ placeholder: "Select language"
1743
+ }
1744
+ )
1745
+ ] })
1746
+ ] }),
1747
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-dash-card", children: [
1748
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h2", { className: "cnfy-dash-card-title", children: "Content Generation Settings" }),
1749
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-dash-field", children: [
1750
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { className: "cnfy-dash-label", children: "Tone" }),
1751
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1752
+ ClientSelect_default,
1753
+ {
1754
+ options: TONE_OPTIONS,
1755
+ value: tone,
1756
+ onChange: (option) => setTone(option),
1757
+ placeholder: "Select tone"
1758
+ }
1759
+ ),
1760
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "cnfy-dash-hint", children: "The writing tone for generated content" })
1761
+ ] }),
1762
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-dash-field", children: [
1763
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { className: "cnfy-dash-label", children: "Style" }),
1764
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1765
+ ClientSelect_default,
1766
+ {
1767
+ options: STYLE_OPTIONS,
1768
+ value: style,
1769
+ onChange: (option) => setStyle(option),
1770
+ placeholder: "Select style"
1771
+ }
1772
+ ),
1773
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "cnfy-dash-hint", children: "The format/style of generated articles" })
1774
+ ] }),
1775
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-dash-field", children: [
1776
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { className: "cnfy-dash-label", children: "Word Count" }),
1777
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1778
+ ClientSelect_default,
1779
+ {
1780
+ options: WORD_COUNT_OPTIONS,
1781
+ value: wordCount,
1782
+ onChange: (option) => setWordCount(option),
1783
+ placeholder: "Select word count"
1784
+ }
1785
+ ),
1786
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "cnfy-dash-hint", children: "Target length for generated content" })
1787
+ ] }),
1788
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-dash-field", children: [
1789
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { className: "cnfy-dash-label", children: "Target Audience" }),
1790
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1791
+ "input",
1792
+ {
1793
+ value: targetAudience,
1794
+ onChange: (e) => setTargetAudience(e.target.value),
1795
+ className: "cnfy-dash-input",
1796
+ placeholder: "e.g. tech-savvy millennials, business professionals"
1797
+ }
1798
+ ),
1799
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "cnfy-dash-hint", children: "Describe your target audience for personalized content" })
1800
+ ] }),
1801
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-toggle-group", children: [
1802
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-toggle-row", children: [
1803
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { children: [
1804
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "cnfy-toggle-label", children: "Include Quotes" }),
1805
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "cnfy-toggle-desc", children: "Add relevant quotes to generated articles" })
1806
+ ] }),
1807
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1808
+ "button",
1809
+ {
1810
+ type: "button",
1811
+ role: "switch",
1812
+ "aria-checked": includeQuotes,
1813
+ onClick: () => setIncludeQuotes(!includeQuotes),
1814
+ className: "cnfy-toggle",
1815
+ style: { backgroundColor: includeQuotes ? primaryColor : "#d1d5db" },
1816
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1817
+ "span",
1818
+ {
1819
+ className: `cnfy-toggle-thumb ${includeQuotes ? "cnfy-toggle-thumb--on" : ""}`
1820
+ }
1821
+ )
1822
+ }
1823
+ )
1824
+ ] }),
1825
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-toggle-row", children: [
1826
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { children: [
1827
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "cnfy-toggle-label", children: "Include FAQ Section" }),
1828
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "cnfy-toggle-desc", children: "Add FAQ section at the end of articles" })
1829
+ ] }),
1830
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1831
+ "button",
1832
+ {
1833
+ type: "button",
1834
+ role: "switch",
1835
+ "aria-checked": includeFAQ,
1836
+ onClick: () => setIncludeFAQ(!includeFAQ),
1837
+ className: "cnfy-toggle",
1838
+ style: { backgroundColor: includeFAQ ? primaryColor : "#d1d5db" },
1839
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1840
+ "span",
1841
+ {
1842
+ className: `cnfy-toggle-thumb ${includeFAQ ? "cnfy-toggle-thumb--on" : ""}`
1843
+ }
1844
+ )
1845
+ }
1846
+ )
1847
+ ] })
1848
+ ] })
1849
+ ] }),
1850
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-dash-card", children: [
1851
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-dash-card-header", children: [
1852
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h2", { className: "cnfy-dash-card-title-inline", children: "News Scraping" }),
1853
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "cnfy-dash-card-desc", children: "Scrape latest news from your configured locations" })
1854
+ ] }),
1855
+ !loadingStatus && scrapeStatus && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-dash-grid cnfy-dash-grid--sm", children: [
1856
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { children: [
1857
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "cnfy-dash-label-muted", children: "Status:" }),
1858
+ /* @__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" }) })
1859
+ ] }),
1860
+ scrapeStatus.lastRun && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { children: [
1861
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "cnfy-dash-label-muted", children: "Last Run:" }),
1862
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "cnfy-dash-label-bold", children: new Date(scrapeStatus.lastRun).toLocaleString() })
1863
+ ] }),
1864
+ scrapeStatus.totalScraped !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { children: [
1865
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "cnfy-dash-label-muted", children: "Total Scraped:" }),
1866
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("p", { className: "cnfy-dash-label-bold", children: [
1867
+ scrapeStatus.totalScraped.toLocaleString(),
1868
+ " articles"
1869
+ ] })
1870
+ ] })
1871
+ ] }),
1872
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { children: [
1873
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("p", { className: "cnfy-dash-info-text", children: [
1874
+ "Current configuration: ",
1875
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("strong", { children: (_b = preferences == null ? void 0 : preferences.localization) == null ? void 0 : _b.state }),
1876
+ ((_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: [
1877
+ " - ",
1878
+ preferences.localization.cities.join(", ")
1879
+ ] })
1880
+ ] }),
1881
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1882
+ "button",
1883
+ {
1884
+ onClick: handleScrape,
1885
+ disabled: scraping || (scrapeStatus == null ? void 0 : scrapeStatus.isRunning),
1886
+ className: "cnfy-dash-btn-save",
1887
+ style: { backgroundColor: primaryColor },
1888
+ children: scraping ? "Starting Scrape..." : (scrapeStatus == null ? void 0 : scrapeStatus.isRunning) ? "Scraping in Progress..." : "Start Scraping"
1889
+ }
1890
+ )
1891
+ ] })
1892
+ ] }),
1893
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "cnfy-dash-actions", children: [
1894
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1895
+ "button",
1896
+ {
1897
+ onClick: handleSave,
1898
+ disabled: saving,
1899
+ className: "cnfy-dash-btn-save",
1900
+ style: { backgroundColor: primaryColor },
1901
+ children: saving ? "Saving..." : "Save Preferences"
1558
1902
  }
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
- )
1903
+ ),
1904
+ success && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "cnfy-dash-success", style: { color: primaryColor }, children: "Preferences saved successfully \u2705" })
1905
+ ] })
1586
1906
  ] });
1587
1907
  }
1588
1908
 
@@ -1606,7 +1926,7 @@ var createContentStreamApi = async ({
1606
1926
  }) => {
1607
1927
  var _a;
1608
1928
  const API_BASE_URL = getApiBaseUrl();
1609
- const apiKey = process.env.NEXT_PUBLIC_API_KEY;
1929
+ const apiKey = getApiKey();
1610
1930
  const headers = {
1611
1931
  "Content-Type": "application/json"
1612
1932
  };
@@ -1699,7 +2019,7 @@ var rewriteNewsStreamApi = async ({
1699
2019
  if (targetAudience) payload.targetAudience = targetAudience;
1700
2020
  try {
1701
2021
  const API_BASE_URL = getApiBaseUrl();
1702
- const apiKey = process.env.NEXT_PUBLIC_API_KEY;
2022
+ const apiKey = getApiKey();
1703
2023
  console.log("\u{1F680} Starting stream request to:", `${API_BASE_URL}/chat/rewrite/stream`);
1704
2024
  console.log("\u{1F4E6} Payload:", payload);
1705
2025
  const headers = {
@@ -1828,32 +2148,18 @@ var rewriteNewsApi = async ({
1828
2148
  };
1829
2149
 
1830
2150
  // components/chatbot/ChatBot.tsx
1831
- var import_react_hot_toast4 = __toESM(require("react-hot-toast"));
2151
+ var import_react_hot_toast2 = __toESM(require("react-hot-toast"));
1832
2152
  var import_lucide_react7 = require("lucide-react");
1833
2153
  var import_jsx_runtime11 = require("react/jsx-runtime");
1834
- function ChatBot({
1835
- onNavigate,
1836
- onLogout
1837
- } = {}) {
1838
- const { loading, showNewsPanel } = useTheme();
2154
+ function ChatBot({ onPost }) {
2155
+ const { loading } = useTheme();
1839
2156
  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);
2157
+ const [preferencesOpen, setPreferencesOpen] = (0, import_react10.useState)(false);
1844
2158
  const [messages, setMessages] = (0, import_react10.useState)([]);
1845
- const [showChatMobile, setShowChatMobile] = (0, import_react10.useState)(false);
1846
2159
  const [isStreaming, setIsStreaming] = (0, import_react10.useState)(false);
1847
2160
  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
2161
  const handleRecreate = async ({ title, content, id }) => {
1855
2162
  var _a;
1856
- setShowChatMobile(true);
1857
2163
  const assistantId = crypto.randomUUID();
1858
2164
  setMessages((prev) => [
1859
2165
  ...prev,
@@ -1896,7 +2202,7 @@ ${title}`
1896
2202
  },
1897
2203
  onComplete: () => {
1898
2204
  console.log("Streaming completed successfully");
1899
- import_react_hot_toast4.default.success("Article created successfully!");
2205
+ import_react_hot_toast2.default.success("Article created successfully!");
1900
2206
  },
1901
2207
  onError: async (error) => {
1902
2208
  console.error("Streaming error:", error);
@@ -1904,7 +2210,7 @@ ${title}`
1904
2210
  console.log("Falling back to regular API...");
1905
2211
  throw error;
1906
2212
  } else {
1907
- import_react_hot_toast4.default.error("Failed to complete article generation");
2213
+ import_react_hot_toast2.default.error("Failed to complete article generation");
1908
2214
  setMessages(
1909
2215
  (prev) => prev.map(
1910
2216
  (m) => m.id === assistantId ? __spreadProps(__spreadValues({}, m), { content: accumulatedContent || "\u274C Failed to create article. Please try again." }) : m
@@ -1936,11 +2242,11 @@ ${title}`
1936
2242
  (m) => m.id === assistantId ? __spreadProps(__spreadValues({}, m), { content: result.article || result }) : m
1937
2243
  )
1938
2244
  );
1939
- import_react_hot_toast4.default.success("Article created successfully!");
2245
+ import_react_hot_toast2.default.success("Article created successfully!");
1940
2246
  }
1941
2247
  } catch (err) {
1942
2248
  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");
2249
+ import_react_hot_toast2.default.error((err == null ? void 0 : err.message) || "An error occurred while creating the article");
1944
2250
  setMessages(
1945
2251
  (prev) => prev.map(
1946
2252
  (m) => m.id === assistantId ? __spreadProps(__spreadValues({}, m), { content: "\u274C Failed to create article. Please try again." }) : m
@@ -1991,7 +2297,7 @@ ${optionsList}`
1991
2297
  }
1992
2298
  } catch (err) {
1993
2299
  console.error("Analyze input error:", err);
1994
- import_react_hot_toast4.default.error("Failed to analyze the link");
2300
+ import_react_hot_toast2.default.error("Failed to analyze the link");
1995
2301
  setMessages(
1996
2302
  (prev) => prev.map(
1997
2303
  (m) => m.id === assistantId ? __spreadProps(__spreadValues({}, m), { content: "\u274C Failed to analyze the link. Please try again." }) : m
@@ -2027,12 +2333,12 @@ ${optionsList}`
2027
2333
  },
2028
2334
  onComplete: () => {
2029
2335
  setIsStreaming(false);
2030
- import_react_hot_toast4.default.success("Content generated!");
2336
+ import_react_hot_toast2.default.success("Content generated!");
2031
2337
  },
2032
2338
  onError: (error) => {
2033
2339
  console.error("Stream error:", error);
2034
2340
  setIsStreaming(false);
2035
- import_react_hot_toast4.default.error("Failed to generate content");
2341
+ import_react_hot_toast2.default.error("Failed to generate content");
2036
2342
  }
2037
2343
  });
2038
2344
  } catch (err) {
@@ -2080,12 +2386,12 @@ ${optionsList}`
2080
2386
  },
2081
2387
  onComplete: () => {
2082
2388
  setIsStreaming(false);
2083
- import_react_hot_toast4.default.success("Content created!");
2389
+ import_react_hot_toast2.default.success("Content created!");
2084
2390
  },
2085
2391
  onError: (error) => {
2086
2392
  console.error("Stream error:", error);
2087
2393
  setIsStreaming(false);
2088
- import_react_hot_toast4.default.error("Failed to create content");
2394
+ import_react_hot_toast2.default.error("Failed to create content");
2089
2395
  }
2090
2396
  });
2091
2397
  } catch (e) {
@@ -2100,7 +2406,7 @@ ${optionsList}`
2100
2406
  )
2101
2407
  );
2102
2408
  setIsStreaming(false);
2103
- import_react_hot_toast4.default.success("Content created!");
2409
+ import_react_hot_toast2.default.success("Content created!");
2104
2410
  }
2105
2411
  } catch (err) {
2106
2412
  console.error("Create content error:", err);
@@ -2119,68 +2425,32 @@ ${optionsList}`
2119
2425
  ] }) });
2120
2426
  }
2121
2427
  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",
2428
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(HeaderBar, { onOpenPreferences: () => setPreferencesOpen(true) }),
2429
+ /* @__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: [
2430
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "cnfy-chat-inner", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2431
+ ChatWindow,
2148
2432
  {
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
- ]
2433
+ messages,
2434
+ onSend: handleSendMessage,
2435
+ onSelectNews: handleRecreate,
2436
+ isStreaming,
2437
+ analyzedData,
2438
+ onSelectAction: handleSelectAction,
2439
+ onPost
2175
2440
  }
2176
- )
2177
- ] }),
2178
- selectedArticle && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2179
- ArticleModal,
2441
+ ) }),
2442
+ !messages.length && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "cnfy-empty-state", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { children: [
2443
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "cnfy-empty-state-title", children: "AI News Assistant" }),
2444
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "cnfy-empty-state-subtitle", children: "Type a message or paste a link to begin" })
2445
+ ] }) })
2446
+ ] }) }),
2447
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2448
+ Drawer,
2180
2449
  {
2181
- article: selectedArticle,
2182
- onClose: () => setSelectedArticle(null),
2183
- onRecreate: handleRecreate
2450
+ open: preferencesOpen,
2451
+ onClose: () => setPreferencesOpen(false),
2452
+ title: "Settings",
2453
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PreferencesPage, {})
2184
2454
  }
2185
2455
  )
2186
2456
  ] });
@@ -2188,12 +2458,16 @@ ${optionsList}`
2188
2458
 
2189
2459
  // src/index.tsx
2190
2460
  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 }) });
2461
+ function ContenifyChatBot({ apiUrl, apiKey, domain, onPost }) {
2462
+ (0, import_react11.useEffect)(() => {
2463
+ setConfig({ apiUrl, apiKey, domain });
2464
+ }, [apiUrl, apiKey, domain]);
2465
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(PreferencesProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ChatBot, { onPost }) });
2193
2466
  }
2194
2467
  var index_default = ContenifyChatBot;
2195
2468
  // Annotate the CommonJS export names for ESM import in node:
2196
2469
  0 && (module.exports = {
2197
- ContenifyChatBot
2470
+ ContenifyChatBot,
2471
+ setConfig
2198
2472
  });
2199
2473
  //# sourceMappingURL=index.js.map