@contenify/chatbot 1.0.0 → 3.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/README.md +202 -48
- package/dist/index.js +625 -644
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +631 -650
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +192 -26
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -77,7 +77,7 @@ var api_default = api;
|
|
|
77
77
|
|
|
78
78
|
// services/preferences.service.ts
|
|
79
79
|
var getMyPreferencesApi = async () => {
|
|
80
|
-
const { data } = await api_default.get("/preferences/me");
|
|
80
|
+
const { data } = await api_default.get("/chatboat/preferences/me");
|
|
81
81
|
return data.data;
|
|
82
82
|
};
|
|
83
83
|
var savePreferencesApi = async ({
|
|
@@ -155,7 +155,7 @@ var savePreferencesApi = async ({
|
|
|
155
155
|
if (targetAudience !== void 0) {
|
|
156
156
|
formData.append("targetAudience", targetAudience);
|
|
157
157
|
}
|
|
158
|
-
const { data } = await api_default.put("/preferences", formData, {
|
|
158
|
+
const { data } = await api_default.put("/chatboat/preferences", formData, {
|
|
159
159
|
headers: {
|
|
160
160
|
"Content-Type": "multipart/form-data"
|
|
161
161
|
}
|
|
@@ -167,7 +167,7 @@ var savePreferencesApi = async ({
|
|
|
167
167
|
import { jsx } from "react/jsx-runtime";
|
|
168
168
|
var defaultPreferences = {
|
|
169
169
|
chatbot: {
|
|
170
|
-
name: "
|
|
170
|
+
name: "ContenifyAI Assistant",
|
|
171
171
|
primaryColor: "#10b981",
|
|
172
172
|
secondaryColor: "#064e3b",
|
|
173
173
|
theme: "system"
|
|
@@ -266,35 +266,83 @@ function usePreferences() {
|
|
|
266
266
|
// components/chatbot/ChatBot.tsx
|
|
267
267
|
import { useState as useState7 } from "react";
|
|
268
268
|
|
|
269
|
-
//
|
|
270
|
-
function
|
|
271
|
-
if (!raw)
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
269
|
+
// src/utils/ aiJsonParser.ts
|
|
270
|
+
function extractJSON(raw) {
|
|
271
|
+
if (!raw) return null;
|
|
272
|
+
let cleaned = raw.replace(/```json/gi, "").replace(/```/g, "").trim();
|
|
273
|
+
const first = cleaned.indexOf("{");
|
|
274
|
+
const last = cleaned.lastIndexOf("}");
|
|
275
|
+
if (first === -1 || last === -1 || last <= first) return null;
|
|
276
|
+
const possibleJson = cleaned.substring(first, last + 1);
|
|
277
|
+
try {
|
|
278
|
+
return JSON.parse(possibleJson);
|
|
279
|
+
} catch (err) {
|
|
280
|
+
console.warn("JSON parse failed:", err);
|
|
281
|
+
return null;
|
|
279
282
|
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// src/utils/decodeUnicode.ts
|
|
286
|
+
function decodeUnicode(text) {
|
|
287
|
+
if (!text) return "";
|
|
280
288
|
try {
|
|
281
|
-
|
|
282
|
-
return {
|
|
283
|
-
title: parsed.title || "",
|
|
284
|
-
article: parsed.article || parsed.content || "",
|
|
285
|
-
metaKeywords: Array.isArray(parsed.metaKeywords) ? parsed.metaKeywords : []
|
|
286
|
-
};
|
|
289
|
+
return JSON.parse(`"${text.replace(/"/g, '\\"')}"`);
|
|
287
290
|
} catch (e) {
|
|
288
|
-
|
|
291
|
+
return text;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// src/utils/articleTextToHtml.ts
|
|
296
|
+
function articleTextToHtml(text) {
|
|
297
|
+
if (!text) return "";
|
|
298
|
+
text = text.replace(/\\n/g, "\n");
|
|
299
|
+
const lines = text.split("\n").map((line) => line.trim()).filter(Boolean);
|
|
300
|
+
let html = "";
|
|
301
|
+
for (const line of lines) {
|
|
302
|
+
if (line.length < 80 && !line.endsWith("\u0964") && !line.endsWith(".")) {
|
|
303
|
+
html += `<h2>${line}</h2>`;
|
|
304
|
+
continue;
|
|
305
|
+
}
|
|
306
|
+
html += `<p>${line}</p>`;
|
|
307
|
+
}
|
|
308
|
+
return html;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// src/utils/formatAIContent.ts
|
|
312
|
+
function formatAIContent(raw) {
|
|
313
|
+
const empty = {
|
|
314
|
+
isArticle: false,
|
|
315
|
+
title: "",
|
|
316
|
+
subtitle: "",
|
|
317
|
+
articleHtml: "",
|
|
318
|
+
article: "",
|
|
319
|
+
metaDescription: "",
|
|
320
|
+
metaKeywords: [],
|
|
321
|
+
plainText: ""
|
|
322
|
+
};
|
|
323
|
+
if (!raw) return empty;
|
|
324
|
+
const parsed = extractJSON(raw);
|
|
325
|
+
if (parsed && (parsed.title || parsed.article)) {
|
|
326
|
+
const rawArticle = (parsed.article || "").trim();
|
|
327
|
+
const safeArticle = decodeUnicode(rawArticle);
|
|
328
|
+
const isHtml = /<[a-z][\s\S]*>/i.test(safeArticle);
|
|
329
|
+
const articleHtml = isHtml ? safeArticle : articleTextToHtml(safeArticle);
|
|
289
330
|
return {
|
|
290
|
-
|
|
291
|
-
|
|
331
|
+
isArticle: true,
|
|
332
|
+
title: parsed.title || "",
|
|
333
|
+
subtitle: parsed.subtitle || "",
|
|
334
|
+
articleHtml,
|
|
335
|
+
article: rawArticle,
|
|
336
|
+
metaDescription: parsed.metaDescription || "",
|
|
337
|
+
metaKeywords: Array.isArray(parsed.metaKeywords) ? parsed.metaKeywords : [],
|
|
338
|
+
plainText: raw
|
|
292
339
|
};
|
|
293
340
|
}
|
|
341
|
+
return __spreadProps(__spreadValues({}, empty), { plainText: raw });
|
|
294
342
|
}
|
|
295
343
|
|
|
296
344
|
// components/chatbot/ChatWindow.tsx
|
|
297
|
-
import { Check, Copy, Edit3, Send, SendHorizontal, Zap, X as X2, RefreshCcw as RefreshCcw2, FileText, ListChecks, Share2, BookOpen, Mail, Key } from "lucide-react";
|
|
345
|
+
import { Check, Copy, Edit3, Send, SendHorizontal, Zap, X as X2, RefreshCcw as RefreshCcw2, FileText, ListChecks, Share2, BookOpen, Mail, Key, Loader2 } from "lucide-react";
|
|
298
346
|
import { useLayoutEffect, useRef, useState as useState4, useEffect as useEffect4 } from "react";
|
|
299
347
|
|
|
300
348
|
// components/chatbot/EditModal.tsx
|
|
@@ -483,38 +531,38 @@ function useTheme() {
|
|
|
483
531
|
|
|
484
532
|
// components/chatbot/EditModal.tsx
|
|
485
533
|
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
534
|
+
function toSlug(text) {
|
|
535
|
+
return text.toLowerCase().trim().replace(/[^\w\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-");
|
|
536
|
+
}
|
|
486
537
|
function EditModal({
|
|
487
538
|
isOpen,
|
|
539
|
+
initialTitle = "",
|
|
540
|
+
initialSubtitle = "",
|
|
488
541
|
initialContent,
|
|
542
|
+
initialMetaDescription = "",
|
|
489
543
|
metaKeywords,
|
|
490
544
|
onClose,
|
|
491
545
|
onSaveDraft,
|
|
492
546
|
onPost
|
|
493
547
|
}) {
|
|
494
548
|
const { primaryColor } = useTheme();
|
|
549
|
+
const [title, setTitle] = useState2("");
|
|
550
|
+
const [subtitle, setSubtitle] = useState2("");
|
|
551
|
+
const [slug, setSlug] = useState2("");
|
|
552
|
+
const [slugEdited, setSlugEdited] = useState2(false);
|
|
553
|
+
const [metaDescription, setMetaDescription] = useState2("");
|
|
495
554
|
const [content, setContent] = useState2("");
|
|
496
555
|
const [keywords, setKeywords] = useState2(metaKeywords);
|
|
497
556
|
const [newKeyword, setNewKeyword] = useState2("");
|
|
498
|
-
const markdownToHtml = (text) => {
|
|
499
|
-
const lines = text.split("\n").filter((line) => line.trim());
|
|
500
|
-
let html = "";
|
|
501
|
-
lines.forEach((line) => {
|
|
502
|
-
const trimmed = line.trim();
|
|
503
|
-
if (trimmed.startsWith("# ")) {
|
|
504
|
-
html += `<h1>${trimmed.replace(/^#\s+/, "")}</h1>`;
|
|
505
|
-
} else if (trimmed.startsWith("## ")) {
|
|
506
|
-
html += `<h2>${trimmed.replace(/^##\s+/, "")}</h2>`;
|
|
507
|
-
} else {
|
|
508
|
-
html += `<p>${trimmed}</p>`;
|
|
509
|
-
}
|
|
510
|
-
});
|
|
511
|
-
return html;
|
|
512
|
-
};
|
|
513
557
|
useEffect3(() => {
|
|
514
|
-
|
|
515
|
-
|
|
558
|
+
setTitle(initialTitle);
|
|
559
|
+
setSubtitle(initialSubtitle);
|
|
560
|
+
setMetaDescription(initialMetaDescription);
|
|
561
|
+
setSlug(toSlug(initialTitle));
|
|
562
|
+
setSlugEdited(false);
|
|
563
|
+
setContent(initialContent);
|
|
516
564
|
setKeywords(metaKeywords);
|
|
517
|
-
}, [initialContent, metaKeywords]);
|
|
565
|
+
}, [initialTitle, initialSubtitle, initialContent, initialMetaDescription, metaKeywords]);
|
|
518
566
|
useEffect3(() => {
|
|
519
567
|
if (isOpen) {
|
|
520
568
|
document.body.style.overflow = "hidden";
|
|
@@ -525,6 +573,16 @@ function EditModal({
|
|
|
525
573
|
document.body.style.overflow = "";
|
|
526
574
|
};
|
|
527
575
|
}, [isOpen]);
|
|
576
|
+
const handleTitleChange = (value) => {
|
|
577
|
+
setTitle(value);
|
|
578
|
+
if (!slugEdited) {
|
|
579
|
+
setSlug(toSlug(value));
|
|
580
|
+
}
|
|
581
|
+
};
|
|
582
|
+
const handleSlugChange = (value) => {
|
|
583
|
+
setSlug(toSlug(value));
|
|
584
|
+
setSlugEdited(true);
|
|
585
|
+
};
|
|
528
586
|
const handleAddKeyword = () => {
|
|
529
587
|
if (newKeyword.trim() && !keywords.includes(newKeyword.trim())) {
|
|
530
588
|
setKeywords([...keywords, newKeyword.trim()]);
|
|
@@ -540,28 +598,62 @@ function EditModal({
|
|
|
540
598
|
handleAddKeyword();
|
|
541
599
|
}
|
|
542
600
|
};
|
|
601
|
+
const getEditData = () => ({
|
|
602
|
+
title,
|
|
603
|
+
subtitle,
|
|
604
|
+
article: content,
|
|
605
|
+
metaDescription,
|
|
606
|
+
slug,
|
|
607
|
+
keywords
|
|
608
|
+
});
|
|
543
609
|
if (!isOpen) return null;
|
|
544
610
|
return /* @__PURE__ */ jsxs2("div", { className: "cnfy-edit-modal-overlay", children: [
|
|
545
|
-
/* @__PURE__ */ jsx3(
|
|
546
|
-
"div",
|
|
547
|
-
{
|
|
548
|
-
className: "cnfy-edit-modal-backdrop",
|
|
549
|
-
onClick: onClose
|
|
550
|
-
}
|
|
551
|
-
),
|
|
611
|
+
/* @__PURE__ */ jsx3("div", { className: "cnfy-edit-modal-backdrop", onClick: onClose }),
|
|
552
612
|
/* @__PURE__ */ jsxs2("div", { className: "cnfy-edit-modal", children: [
|
|
553
613
|
/* @__PURE__ */ jsxs2("div", { className: "cnfy-edit-modal-header", children: [
|
|
554
614
|
/* @__PURE__ */ jsx3("h2", { className: "cnfy-edit-modal-title", children: "Edit Article" }),
|
|
555
|
-
/* @__PURE__ */ jsx3(
|
|
556
|
-
"button",
|
|
557
|
-
{
|
|
558
|
-
onClick: onClose,
|
|
559
|
-
className: "cnfy-edit-modal-close-btn",
|
|
560
|
-
children: /* @__PURE__ */ jsx3(X, { size: 20, className: "cnfy-edit-modal-close-icon" })
|
|
561
|
-
}
|
|
562
|
-
)
|
|
615
|
+
/* @__PURE__ */ jsx3("button", { onClick: onClose, className: "cnfy-edit-modal-close-btn", children: /* @__PURE__ */ jsx3(X, { size: 20, className: "cnfy-edit-modal-close-icon" }) })
|
|
563
616
|
] }),
|
|
564
617
|
/* @__PURE__ */ jsxs2("div", { className: "cnfy-edit-modal-body", children: [
|
|
618
|
+
/* @__PURE__ */ jsxs2("div", { children: [
|
|
619
|
+
/* @__PURE__ */ jsx3("label", { className: "cnfy-edit-label", children: "Title" }),
|
|
620
|
+
/* @__PURE__ */ jsx3(
|
|
621
|
+
"input",
|
|
622
|
+
{
|
|
623
|
+
type: "text",
|
|
624
|
+
value: title,
|
|
625
|
+
onChange: (e) => handleTitleChange(e.target.value),
|
|
626
|
+
placeholder: "Article title...",
|
|
627
|
+
className: "cnfy-edit-input"
|
|
628
|
+
}
|
|
629
|
+
)
|
|
630
|
+
] }),
|
|
631
|
+
/* @__PURE__ */ jsxs2("div", { children: [
|
|
632
|
+
/* @__PURE__ */ jsx3("label", { className: "cnfy-edit-label", children: "Subtitle" }),
|
|
633
|
+
/* @__PURE__ */ jsx3(
|
|
634
|
+
"input",
|
|
635
|
+
{
|
|
636
|
+
type: "text",
|
|
637
|
+
value: subtitle,
|
|
638
|
+
onChange: (e) => setSubtitle(e.target.value),
|
|
639
|
+
placeholder: "Article subtitle...",
|
|
640
|
+
className: "cnfy-edit-input"
|
|
641
|
+
}
|
|
642
|
+
)
|
|
643
|
+
] }),
|
|
644
|
+
/* @__PURE__ */ jsxs2("div", { children: [
|
|
645
|
+
/* @__PURE__ */ jsx3("label", { className: "cnfy-edit-label", children: "Slug" }),
|
|
646
|
+
/* @__PURE__ */ jsx3(
|
|
647
|
+
"input",
|
|
648
|
+
{
|
|
649
|
+
type: "text",
|
|
650
|
+
value: slug,
|
|
651
|
+
onChange: (e) => handleSlugChange(e.target.value),
|
|
652
|
+
placeholder: "article-url-slug",
|
|
653
|
+
className: "cnfy-edit-input cnfy-edit-input--mono"
|
|
654
|
+
}
|
|
655
|
+
)
|
|
656
|
+
] }),
|
|
565
657
|
/* @__PURE__ */ jsxs2("div", { children: [
|
|
566
658
|
/* @__PURE__ */ jsx3("label", { className: "cnfy-edit-label", children: "Article Content" }),
|
|
567
659
|
/* @__PURE__ */ jsx3(
|
|
@@ -574,26 +666,32 @@ function EditModal({
|
|
|
574
666
|
)
|
|
575
667
|
] }),
|
|
576
668
|
/* @__PURE__ */ jsxs2("div", { children: [
|
|
577
|
-
/* @__PURE__ */ jsx3("label", { className: "cnfy-edit-label", children: "Meta
|
|
578
|
-
/* @__PURE__ */ jsx3(
|
|
579
|
-
"
|
|
669
|
+
/* @__PURE__ */ jsx3("label", { className: "cnfy-edit-label", children: "Meta Description" }),
|
|
670
|
+
/* @__PURE__ */ jsx3(
|
|
671
|
+
"textarea",
|
|
580
672
|
{
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
673
|
+
value: metaDescription,
|
|
674
|
+
onChange: (e) => setMetaDescription(e.target.value),
|
|
675
|
+
placeholder: "Brief description for search engines...",
|
|
676
|
+
className: "cnfy-edit-textarea",
|
|
677
|
+
rows: 3
|
|
678
|
+
}
|
|
679
|
+
)
|
|
680
|
+
] }),
|
|
681
|
+
/* @__PURE__ */ jsxs2("div", { children: [
|
|
682
|
+
/* @__PURE__ */ jsx3("label", { className: "cnfy-edit-label", children: "Meta Keywords" }),
|
|
683
|
+
/* @__PURE__ */ jsx3("div", { className: "cnfy-keyword-list", children: keywords.map((keyword, index) => /* @__PURE__ */ jsxs2("span", { className: "cnfy-keyword-tag", children: [
|
|
684
|
+
"#",
|
|
685
|
+
keyword,
|
|
686
|
+
/* @__PURE__ */ jsx3(
|
|
687
|
+
"button",
|
|
688
|
+
{
|
|
689
|
+
onClick: () => handleRemoveKeyword(index),
|
|
690
|
+
className: "cnfy-keyword-remove-btn",
|
|
691
|
+
children: /* @__PURE__ */ jsx3(X, { size: 14 })
|
|
692
|
+
}
|
|
693
|
+
)
|
|
694
|
+
] }, index)) }),
|
|
597
695
|
/* @__PURE__ */ jsxs2("div", { className: "cnfy-keyword-input-row", children: [
|
|
598
696
|
/* @__PURE__ */ jsx3(
|
|
599
697
|
"input",
|
|
@@ -606,30 +704,16 @@ function EditModal({
|
|
|
606
704
|
className: "cnfy-keyword-input"
|
|
607
705
|
}
|
|
608
706
|
),
|
|
609
|
-
/* @__PURE__ */ jsx3(
|
|
610
|
-
"button",
|
|
611
|
-
{
|
|
612
|
-
onClick: handleAddKeyword,
|
|
613
|
-
className: "cnfy-btn-add-keyword",
|
|
614
|
-
children: "Add"
|
|
615
|
-
}
|
|
616
|
-
)
|
|
707
|
+
/* @__PURE__ */ jsx3("button", { onClick: handleAddKeyword, className: "cnfy-btn-add-keyword", children: "Add" })
|
|
617
708
|
] })
|
|
618
709
|
] })
|
|
619
710
|
] }),
|
|
620
711
|
/* @__PURE__ */ jsxs2("div", { className: "cnfy-edit-modal-footer", children: [
|
|
712
|
+
/* @__PURE__ */ jsx3("button", { onClick: onClose, className: "cnfy-btn-footer-cancel", children: "Cancel" }),
|
|
621
713
|
/* @__PURE__ */ jsx3(
|
|
622
714
|
"button",
|
|
623
715
|
{
|
|
624
|
-
onClick:
|
|
625
|
-
className: "cnfy-btn-footer-cancel",
|
|
626
|
-
children: "Cancel"
|
|
627
|
-
}
|
|
628
|
-
),
|
|
629
|
-
/* @__PURE__ */ jsx3(
|
|
630
|
-
"button",
|
|
631
|
-
{
|
|
632
|
-
onClick: () => onSaveDraft(content, keywords),
|
|
716
|
+
onClick: () => onSaveDraft(getEditData()),
|
|
633
717
|
className: "cnfy-btn-save-draft",
|
|
634
718
|
children: "Save Draft"
|
|
635
719
|
}
|
|
@@ -637,7 +721,7 @@ function EditModal({
|
|
|
637
721
|
/* @__PURE__ */ jsx3(
|
|
638
722
|
"button",
|
|
639
723
|
{
|
|
640
|
-
onClick: () => onPost(
|
|
724
|
+
onClick: () => onPost(getEditData()),
|
|
641
725
|
className: "cnfy-btn-post-article",
|
|
642
726
|
style: { backgroundColor: primaryColor, color: "#fff" },
|
|
643
727
|
children: "Post"
|
|
@@ -819,25 +903,25 @@ function NewsList({
|
|
|
819
903
|
|
|
820
904
|
// services/news.service.ts
|
|
821
905
|
var getTrendingNews = async () => {
|
|
822
|
-
const { data } = await api_default.get("/
|
|
906
|
+
const { data } = await api_default.get("/chatboat/trending");
|
|
823
907
|
return data.data;
|
|
824
908
|
};
|
|
825
909
|
var getNewsSources = async () => {
|
|
826
|
-
const { data } = await api_default.get("/
|
|
910
|
+
const { data } = await api_default.get("/chatboat/scrape/sources");
|
|
827
911
|
return data.data;
|
|
828
912
|
};
|
|
829
913
|
var scrapeNewsSource = async (sourceId) => {
|
|
830
|
-
const { data } = await api_default.post("/
|
|
914
|
+
const { data } = await api_default.post("/chatboat/scrape/source", { sourceId });
|
|
831
915
|
return data.data;
|
|
832
916
|
};
|
|
833
917
|
var getNewsBySource = async (sourceId) => {
|
|
834
|
-
const { data } = await api_default.get(`/
|
|
918
|
+
const { data } = await api_default.get(`/chatboat/scrape/by-source/${sourceId}`);
|
|
835
919
|
return data.data;
|
|
836
920
|
};
|
|
837
921
|
|
|
838
922
|
// components/chatbot/ChatWindow.tsx
|
|
839
923
|
import Select from "react-select";
|
|
840
|
-
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
924
|
+
import { Fragment, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
841
925
|
var ACTION_ICONS = {
|
|
842
926
|
recreate_article: RefreshCcw2,
|
|
843
927
|
create_summary: ListChecks,
|
|
@@ -851,12 +935,13 @@ function ChatWindow({
|
|
|
851
935
|
onSend,
|
|
852
936
|
onSelectNews,
|
|
853
937
|
isStreaming = false,
|
|
938
|
+
activeField,
|
|
854
939
|
analyzedData,
|
|
855
940
|
onSelectAction,
|
|
856
941
|
onPost: onPostCallback
|
|
857
942
|
}) {
|
|
858
943
|
var _a, _b;
|
|
859
|
-
const {
|
|
944
|
+
const { showNewsPanel } = useTheme();
|
|
860
945
|
const bottomRef = useRef(null);
|
|
861
946
|
const textareaRef = useRef(null);
|
|
862
947
|
const dropdownRef = useRef(null);
|
|
@@ -869,40 +954,48 @@ function ChatWindow({
|
|
|
869
954
|
const [selectedSource, setSelectedSource] = useState4(null);
|
|
870
955
|
const [loadingSources, setLoadingSources] = useState4(false);
|
|
871
956
|
const [scraping, setScraping] = useState4(false);
|
|
872
|
-
const [editModal, setEditModal] = useState4({ isOpen: false, content: "", metaKeywords: [], messageId: "" });
|
|
957
|
+
const [editModal, setEditModal] = useState4({ isOpen: false, title: "", subtitle: "", content: "", metaDescription: "", metaKeywords: [], messageId: "" });
|
|
873
958
|
const { primaryColor } = useTheme();
|
|
874
959
|
const { preferences } = usePreferences();
|
|
875
960
|
const preferredLanguage = (_a = preferences == null ? void 0 : preferences.localization) == null ? void 0 : _a.language;
|
|
876
|
-
const handleCopy = async (
|
|
961
|
+
const handleCopy = async (parsed, messageId) => {
|
|
877
962
|
try {
|
|
878
|
-
const
|
|
879
|
-
|
|
963
|
+
const tempDiv = document.createElement("div");
|
|
964
|
+
let textContent = "";
|
|
965
|
+
if (parsed.title) textContent += parsed.title + "\n\n";
|
|
966
|
+
if (parsed.subtitle) textContent += parsed.subtitle + "\n\n";
|
|
967
|
+
if (parsed.articleHtml) {
|
|
968
|
+
tempDiv.innerHTML = parsed.articleHtml;
|
|
969
|
+
textContent += tempDiv.textContent || tempDiv.innerText || "";
|
|
970
|
+
}
|
|
971
|
+
if (parsed.metaDescription) textContent += "\n\nMeta Description:\n" + parsed.metaDescription;
|
|
972
|
+
await navigator.clipboard.writeText(textContent);
|
|
880
973
|
setCopiedId(messageId);
|
|
881
974
|
setTimeout(() => setCopiedId(null), 2e3);
|
|
882
975
|
} catch (err) {
|
|
883
976
|
console.error("Failed to copy:", err);
|
|
884
977
|
}
|
|
885
978
|
};
|
|
886
|
-
const
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
979
|
+
const handleEdit = (parsed, messageId) => {
|
|
980
|
+
setEditModal({
|
|
981
|
+
isOpen: true,
|
|
982
|
+
title: parsed.title || "",
|
|
983
|
+
subtitle: parsed.subtitle || "",
|
|
984
|
+
content: parsed.articleHtml || "",
|
|
985
|
+
metaDescription: parsed.metaDescription || "",
|
|
986
|
+
metaKeywords: parsed.metaKeywords,
|
|
987
|
+
messageId
|
|
988
|
+
});
|
|
896
989
|
};
|
|
897
990
|
const handleCloseModal = () => {
|
|
898
|
-
setEditModal({ isOpen: false, content: "", metaKeywords: [], messageId: "" });
|
|
991
|
+
setEditModal({ isOpen: false, title: "", subtitle: "", content: "", metaDescription: "", metaKeywords: [], messageId: "" });
|
|
899
992
|
};
|
|
900
|
-
const handleSaveDraft = (
|
|
901
|
-
console.log("Saving draft:",
|
|
993
|
+
const handleSaveDraft = (data) => {
|
|
994
|
+
console.log("Saving draft:", data);
|
|
902
995
|
handleCloseModal();
|
|
903
996
|
};
|
|
904
|
-
const handlePost = (
|
|
905
|
-
onPostCallback == null ? void 0 : onPostCallback(
|
|
997
|
+
const handlePost = (data) => {
|
|
998
|
+
onPostCallback == null ? void 0 : onPostCallback(data.article, data.keywords);
|
|
906
999
|
handleCloseModal();
|
|
907
1000
|
};
|
|
908
1001
|
useLayoutEffect(() => {
|
|
@@ -966,7 +1059,6 @@ function ChatWindow({
|
|
|
966
1059
|
const handleSourceSelect = (option) => {
|
|
967
1060
|
var _a2;
|
|
968
1061
|
const sourceId = (_a2 = option == null ? void 0 : option.value) != null ? _a2 : null;
|
|
969
|
-
console.log("Selected source:", option);
|
|
970
1062
|
setSelectedSource(sourceId);
|
|
971
1063
|
fetchNews(sourceId);
|
|
972
1064
|
};
|
|
@@ -992,130 +1084,103 @@ function ChatWindow({
|
|
|
992
1084
|
document.removeEventListener("mousedown", handleClickOutside);
|
|
993
1085
|
};
|
|
994
1086
|
}, [showNewsDropdown]);
|
|
995
|
-
function formatAIContent(raw) {
|
|
996
|
-
const extracted = extractArticleContent(raw);
|
|
997
|
-
if (!extracted || !extracted.article) {
|
|
998
|
-
return { blocks: [], metaKeywords: [] };
|
|
999
|
-
}
|
|
1000
|
-
const { article, metaKeywords } = extracted;
|
|
1001
|
-
const normalized = article.replace(/^H1:\s*/gm, "").replace(/^H2:\s*/gm, "").replace(/<\/h1>/gi, "\n").replace(/<\/h2>/gi, "\n").replace(/<\/p>/gi, "\n").replace(/<br\s*\/?>/gi, "\n");
|
|
1002
|
-
const lines = normalized.split("\n").map((line) => line.replace(/<[^>]+>/g, "").trim()).filter(Boolean);
|
|
1003
|
-
const blocks = [];
|
|
1004
|
-
lines.forEach((line, index) => {
|
|
1005
|
-
if (index === 0 && line.length < 120) {
|
|
1006
|
-
blocks.push({ type: "h1", text: line });
|
|
1007
|
-
return;
|
|
1008
|
-
}
|
|
1009
|
-
if (line.length < 90 && !line.endsWith("\u0964") && !line.endsWith(".")) {
|
|
1010
|
-
blocks.push({ type: "h2", text: line });
|
|
1011
|
-
return;
|
|
1012
|
-
}
|
|
1013
|
-
blocks.push({ type: "p", text: line });
|
|
1014
|
-
});
|
|
1015
|
-
return { blocks, metaKeywords };
|
|
1016
|
-
}
|
|
1017
1087
|
return /* @__PURE__ */ jsxs4("div", { className: "cnfy-chat", children: [
|
|
1018
1088
|
/* @__PURE__ */ jsx5("div", { className: "cnfy-chat-area", children: /* @__PURE__ */ jsxs4("div", { className: "cnfy-chat-scroll", children: [
|
|
1019
1089
|
messages.map((msg) => {
|
|
1020
|
-
var _a2;
|
|
1090
|
+
var _a2, _b2;
|
|
1021
1091
|
const parsed = formatAIContent(msg.content);
|
|
1022
|
-
return /* @__PURE__ */
|
|
1023
|
-
/* @__PURE__ */ jsx5("div", { className: "cnfy-msg-
|
|
1024
|
-
"
|
|
1092
|
+
return /* @__PURE__ */ jsx5("div", { className: "cnfy-msg", children: /* @__PURE__ */ jsxs4("div", { className: msg.role === "assistant" ? `cnfy-msg-body` : `cnfy-msg-body you`, children: [
|
|
1093
|
+
msg.role === "assistant" && parsed.isArticle && /* @__PURE__ */ jsx5("div", { className: "cnfy-msg-copy-row", children: /* @__PURE__ */ jsx5(
|
|
1094
|
+
"button",
|
|
1025
1095
|
{
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
},
|
|
1030
|
-
children: msg.role === "assistant" ? "AI" : "You"
|
|
1096
|
+
onClick: () => handleCopy(parsed, msg.id),
|
|
1097
|
+
className: "cnfy-copy-btn",
|
|
1098
|
+
title: "Copy to clipboard",
|
|
1099
|
+
children: copiedId === msg.id ? /* @__PURE__ */ jsx5(Check, { size: 16, className: "cnfy-copy-icon--copied" }) : /* @__PURE__ */ jsx5(Copy, { size: 16 })
|
|
1031
1100
|
}
|
|
1032
1101
|
) }),
|
|
1033
|
-
/* @__PURE__ */ jsxs4("div", { className: "cnfy-
|
|
1034
|
-
|
|
1035
|
-
|
|
1102
|
+
msg.role === "assistant" && isStreaming && msg.id === ((_a2 = messages[messages.length - 1]) == null ? void 0 : _a2.id) && !parsed.isArticle && !parsed.plainText && /* @__PURE__ */ jsxs4("div", { className: "cnfy-creating-indicator", children: [
|
|
1103
|
+
/* @__PURE__ */ jsx5(Loader2, { size: 16, className: "cnfy-animate-spin" }),
|
|
1104
|
+
/* @__PURE__ */ jsx5("span", { children: "Creating article..." })
|
|
1105
|
+
] }),
|
|
1106
|
+
parsed.isArticle ? /* @__PURE__ */ jsxs4(Fragment, { children: [
|
|
1107
|
+
parsed.title && /* @__PURE__ */ jsxs4("h1", { className: "cnfy-block-h1", children: [
|
|
1108
|
+
parsed.title,
|
|
1109
|
+
activeField === "title" && /* @__PURE__ */ jsx5("span", { className: "cnfy-cursor-blink", children: "|" })
|
|
1110
|
+
] }),
|
|
1111
|
+
parsed.subtitle && /* @__PURE__ */ jsxs4("h1", { className: "cnfy-block-h2", children: [
|
|
1112
|
+
parsed.subtitle,
|
|
1113
|
+
activeField === "subtitle" && /* @__PURE__ */ jsx5("span", { className: "cnfy-cursor-blink", children: "|" })
|
|
1114
|
+
] }),
|
|
1115
|
+
/* @__PURE__ */ jsx5("hr", { className: "cnfy-divider" }),
|
|
1116
|
+
parsed.articleHtml && /* @__PURE__ */ jsx5(
|
|
1117
|
+
"div",
|
|
1036
1118
|
{
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
title: "Copy to clipboard",
|
|
1040
|
-
children: copiedId === msg.id ? /* @__PURE__ */ jsx5(Check, { size: 16, className: "cnfy-copy-icon--copied" }) : /* @__PURE__ */ jsx5(Copy, { size: 16 })
|
|
1119
|
+
className: "cnfy-article-content",
|
|
1120
|
+
dangerouslySetInnerHTML: { __html: parsed.articleHtml }
|
|
1041
1121
|
}
|
|
1042
|
-
)
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
return /* @__PURE__ */ jsx5(
|
|
1056
|
-
"h2",
|
|
1057
|
-
{
|
|
1058
|
-
className: "cnfy-block-h2",
|
|
1059
|
-
children: block.text
|
|
1060
|
-
},
|
|
1061
|
-
idx
|
|
1062
|
-
);
|
|
1063
|
-
}
|
|
1064
|
-
return /* @__PURE__ */ jsx5("p", { className: "cnfy-block-p", children: block.text }, idx);
|
|
1065
|
-
}),
|
|
1066
|
-
parsed.metaKeywords.length > 0 && /* @__PURE__ */ jsx5("div", { className: "cnfy-msg-keywords", children: /* @__PURE__ */ jsx5("div", { className: "cnfy-msg-keywords-list", children: parsed.metaKeywords.map((tag, i) => /* @__PURE__ */ jsxs4(
|
|
1122
|
+
),
|
|
1123
|
+
activeField === "article" && /* @__PURE__ */ jsx5("span", { className: "cnfy-cursor-blink", children: "|" })
|
|
1124
|
+
] }) : (
|
|
1125
|
+
/* Plain text messages (status, error, options, etc.) */
|
|
1126
|
+
parsed.plainText && /* @__PURE__ */ jsx5("p", { className: "cnfy-block-p", children: parsed.plainText })
|
|
1127
|
+
),
|
|
1128
|
+
parsed.metaDescription && /* @__PURE__ */ jsxs4("div", { className: "cnfy-msg-keywords", children: [
|
|
1129
|
+
/* @__PURE__ */ jsx5("div", { className: "cnfy-msg-keywords-label", children: "Meta Description" }),
|
|
1130
|
+
/* @__PURE__ */ jsx5("div", { className: "cnfy-block-p", children: parsed.metaDescription })
|
|
1131
|
+
] }),
|
|
1132
|
+
parsed.metaKeywords.length > 0 && /* @__PURE__ */ jsxs4("div", { className: "cnfy-msg-keywords", children: [
|
|
1133
|
+
/* @__PURE__ */ jsx5("div", { className: "cnfy-msg-keywords-label", children: "Keywords" }),
|
|
1134
|
+
/* @__PURE__ */ jsx5("div", { className: "cnfy-msg-keywords-list", children: parsed.metaKeywords.map((tag, i) => /* @__PURE__ */ jsx5(
|
|
1067
1135
|
"span",
|
|
1068
1136
|
{
|
|
1069
1137
|
className: "cnfy-msg-keyword-tag",
|
|
1138
|
+
children: tag
|
|
1139
|
+
},
|
|
1140
|
+
i
|
|
1141
|
+
)) })
|
|
1142
|
+
] }),
|
|
1143
|
+
msg.role === "assistant" && (analyzedData == null ? void 0 : analyzedData.messageId) === msg.id && analyzedData.options.length > 0 && /* @__PURE__ */ jsx5("div", { className: "cnfy-action-options", children: analyzedData.options.map((option) => {
|
|
1144
|
+
const IconComponent = ACTION_ICONS[option.id] || FileText;
|
|
1145
|
+
return /* @__PURE__ */ jsxs4(
|
|
1146
|
+
"button",
|
|
1147
|
+
{
|
|
1148
|
+
onClick: () => onSelectAction == null ? void 0 : onSelectAction(option.id, analyzedData.url, analyzedData.content),
|
|
1149
|
+
className: "cnfy-action-btn",
|
|
1070
1150
|
children: [
|
|
1071
|
-
|
|
1072
|
-
|
|
1151
|
+
/* @__PURE__ */ jsx5(IconComponent, { size: 16 }),
|
|
1152
|
+
option.name
|
|
1073
1153
|
]
|
|
1074
1154
|
},
|
|
1075
|
-
|
|
1076
|
-
)
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
"
|
|
1095
|
-
{
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
}
|
|
1103
|
-
),
|
|
1104
|
-
/* @__PURE__ */ jsxs4(
|
|
1105
|
-
"button",
|
|
1106
|
-
{
|
|
1107
|
-
onClick: () => handlePost(msg.content, parsed.metaKeywords),
|
|
1108
|
-
className: "cnfy-btn-post",
|
|
1109
|
-
style: { backgroundColor: primaryColor, color: "#fff" },
|
|
1110
|
-
children: [
|
|
1111
|
-
/* @__PURE__ */ jsx5(Send, { size: 16 }),
|
|
1112
|
-
"Post"
|
|
1113
|
-
]
|
|
1114
|
-
}
|
|
1115
|
-
)
|
|
1116
|
-
] })
|
|
1155
|
+
option.id
|
|
1156
|
+
);
|
|
1157
|
+
}) }),
|
|
1158
|
+
msg.role === "assistant" && parsed.isArticle && !(analyzedData == null ? void 0 : analyzedData.messageId) && (!isStreaming || msg.id !== ((_b2 = messages[messages.length - 1]) == null ? void 0 : _b2.id)) && /* @__PURE__ */ jsxs4("div", { className: "cnfy-msg-actions", children: [
|
|
1159
|
+
/* @__PURE__ */ jsxs4(
|
|
1160
|
+
"button",
|
|
1161
|
+
{
|
|
1162
|
+
onClick: () => handleEdit(parsed, msg.id),
|
|
1163
|
+
className: "cnfy-btn-edit",
|
|
1164
|
+
children: [
|
|
1165
|
+
/* @__PURE__ */ jsx5(Edit3, { size: 16 }),
|
|
1166
|
+
"Edit"
|
|
1167
|
+
]
|
|
1168
|
+
}
|
|
1169
|
+
),
|
|
1170
|
+
/* @__PURE__ */ jsxs4(
|
|
1171
|
+
"button",
|
|
1172
|
+
{
|
|
1173
|
+
onClick: () => handlePost({ article: parsed.articleHtml, keywords: parsed.metaKeywords }),
|
|
1174
|
+
className: "cnfy-btn-post",
|
|
1175
|
+
style: { backgroundColor: primaryColor, color: "#fff" },
|
|
1176
|
+
children: [
|
|
1177
|
+
/* @__PURE__ */ jsx5(Send, { size: 16 }),
|
|
1178
|
+
"Post"
|
|
1179
|
+
]
|
|
1180
|
+
}
|
|
1181
|
+
)
|
|
1117
1182
|
] })
|
|
1118
|
-
] }, msg.id);
|
|
1183
|
+
] }) }, msg.id);
|
|
1119
1184
|
}),
|
|
1120
1185
|
/* @__PURE__ */ jsx5("div", { ref: bottomRef })
|
|
1121
1186
|
] }) }),
|
|
@@ -1247,7 +1312,8 @@ function ChatWindow({
|
|
|
1247
1312
|
rows: 1,
|
|
1248
1313
|
placeholder: "Ask AI something\u2026",
|
|
1249
1314
|
className: `cnfy-chat-textarea ${!showNewsPanel ? "cnfy-chat-textarea--with-pulse" : ""}`,
|
|
1250
|
-
style: { maxHeight: "200px", overflowY: input.split("\n").length > 6 ? "auto" : "hidden" }
|
|
1315
|
+
style: { maxHeight: "200px", overflowY: input.split("\n").length > 6 ? "auto" : "hidden" },
|
|
1316
|
+
disabled: true
|
|
1251
1317
|
}
|
|
1252
1318
|
),
|
|
1253
1319
|
/* @__PURE__ */ jsx5(
|
|
@@ -1264,11 +1330,14 @@ function ChatWindow({
|
|
|
1264
1330
|
EditModal,
|
|
1265
1331
|
{
|
|
1266
1332
|
isOpen: editModal.isOpen,
|
|
1333
|
+
initialTitle: editModal.title,
|
|
1334
|
+
initialSubtitle: editModal.subtitle,
|
|
1267
1335
|
initialContent: editModal.content,
|
|
1336
|
+
initialMetaDescription: editModal.metaDescription,
|
|
1268
1337
|
metaKeywords: editModal.metaKeywords,
|
|
1269
1338
|
onClose: handleCloseModal,
|
|
1270
|
-
onSaveDraft: handleSaveDraft,
|
|
1271
|
-
onPost: handlePost
|
|
1339
|
+
onSaveDraft: (data) => handleSaveDraft({ article: data.article, keywords: data.keywords }),
|
|
1340
|
+
onPost: (data) => handlePost({ article: data.article, keywords: data.keywords })
|
|
1272
1341
|
}
|
|
1273
1342
|
)
|
|
1274
1343
|
] });
|
|
@@ -1355,14 +1424,14 @@ var triggerScrape = async ({
|
|
|
1355
1424
|
state,
|
|
1356
1425
|
cities
|
|
1357
1426
|
}) => {
|
|
1358
|
-
const { data } = await api_default.post("/scrape/trigger", {
|
|
1427
|
+
const { data } = await api_default.post("/chatboat/scrape/trigger", {
|
|
1359
1428
|
state,
|
|
1360
1429
|
cities
|
|
1361
1430
|
});
|
|
1362
1431
|
return data;
|
|
1363
1432
|
};
|
|
1364
1433
|
var getScrapeStatus = async () => {
|
|
1365
|
-
const { data } = await api_default.get("/scrape/status");
|
|
1434
|
+
const { data } = await api_default.get("/chatboat/scrape/status");
|
|
1366
1435
|
return data.data;
|
|
1367
1436
|
};
|
|
1368
1437
|
|
|
@@ -1383,8 +1452,17 @@ var ClientSelect = (props) => {
|
|
|
1383
1452
|
};
|
|
1384
1453
|
var ClientSelect_default = ClientSelect;
|
|
1385
1454
|
|
|
1455
|
+
// src/utils/util.ts
|
|
1456
|
+
var hexToRgba = (hex, opacity) => {
|
|
1457
|
+
const sanitizedHex = hex.replace("#", "");
|
|
1458
|
+
const r = parseInt(sanitizedHex.substring(0, 2), 16);
|
|
1459
|
+
const g = parseInt(sanitizedHex.substring(2, 4), 16);
|
|
1460
|
+
const b = parseInt(sanitizedHex.substring(4, 6), 16);
|
|
1461
|
+
return `rgba(${r}, ${g}, ${b}, ${opacity})`;
|
|
1462
|
+
};
|
|
1463
|
+
|
|
1386
1464
|
// components/preferences/Preferences.tsx
|
|
1387
|
-
import { Fragment, jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1465
|
+
import { Fragment as Fragment2, jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1388
1466
|
var STATE_OPTIONS = [
|
|
1389
1467
|
{ value: "Uttar Pradesh", label: "Uttar Pradesh" }
|
|
1390
1468
|
];
|
|
@@ -1418,23 +1496,6 @@ var LANGUAGE_OPTIONS = [
|
|
|
1418
1496
|
{ value: "en", label: "English" },
|
|
1419
1497
|
{ value: "hi", label: "Hindi" }
|
|
1420
1498
|
];
|
|
1421
|
-
var TONE_OPTIONS = [
|
|
1422
|
-
{ value: "formal", label: "Formal" },
|
|
1423
|
-
{ value: "casual", label: "Casual" },
|
|
1424
|
-
{ value: "engaging", label: "Engaging" },
|
|
1425
|
-
{ value: "professional", label: "Professional" }
|
|
1426
|
-
];
|
|
1427
|
-
var STYLE_OPTIONS = [
|
|
1428
|
-
{ value: "news", label: "News Article" },
|
|
1429
|
-
{ value: "blog", label: "Blog Post" },
|
|
1430
|
-
{ value: "editorial", label: "Editorial" },
|
|
1431
|
-
{ value: "summary", label: "Summary" }
|
|
1432
|
-
];
|
|
1433
|
-
var WORD_COUNT_OPTIONS = [
|
|
1434
|
-
{ value: "short", label: "Short (~300 words)" },
|
|
1435
|
-
{ value: "medium", label: "Medium (~600 words)" },
|
|
1436
|
-
{ value: "long", label: "Long (~1000+ words)" }
|
|
1437
|
-
];
|
|
1438
1499
|
function PreferencesPage() {
|
|
1439
1500
|
var _a, _b, _c;
|
|
1440
1501
|
const { preferences, loading, refreshPreferences, updatePreferences } = usePreferences();
|
|
@@ -1445,12 +1506,6 @@ function PreferencesPage() {
|
|
|
1445
1506
|
const [state, setState] = useState6(null);
|
|
1446
1507
|
const [cities, setCities] = useState6([]);
|
|
1447
1508
|
const [language, setLanguage] = useState6(null);
|
|
1448
|
-
const [tone, setTone] = useState6(null);
|
|
1449
|
-
const [style, setStyle] = useState6(null);
|
|
1450
|
-
const [wordCount, setWordCount] = useState6(null);
|
|
1451
|
-
const [includeQuotes, setIncludeQuotes] = useState6(true);
|
|
1452
|
-
const [includeFAQ, setIncludeFAQ] = useState6(false);
|
|
1453
|
-
const [targetAudience, setTargetAudience] = useState6("");
|
|
1454
1509
|
const [saving, setSaving] = useState6(false);
|
|
1455
1510
|
const [success, setSuccess] = useState6(false);
|
|
1456
1511
|
const [scraping, setScraping] = useState6(false);
|
|
@@ -1460,13 +1515,7 @@ function PreferencesPage() {
|
|
|
1460
1515
|
botName: "",
|
|
1461
1516
|
state: void 0,
|
|
1462
1517
|
cities: [],
|
|
1463
|
-
language: void 0
|
|
1464
|
-
tone: void 0,
|
|
1465
|
-
style: void 0,
|
|
1466
|
-
wordCount: void 0,
|
|
1467
|
-
includeQuotes: true,
|
|
1468
|
-
includeFAQ: false,
|
|
1469
|
-
targetAudience: ""
|
|
1518
|
+
language: void 0
|
|
1470
1519
|
});
|
|
1471
1520
|
useEffect7(() => {
|
|
1472
1521
|
const fetchScrapeStatus = async () => {
|
|
@@ -1506,7 +1555,7 @@ function PreferencesPage() {
|
|
|
1506
1555
|
}
|
|
1507
1556
|
};
|
|
1508
1557
|
useEffect7(() => {
|
|
1509
|
-
var _a2, _b2, _c2, _d, _e
|
|
1558
|
+
var _a2, _b2, _c2, _d, _e;
|
|
1510
1559
|
if (preferences) {
|
|
1511
1560
|
const name = ((_a2 = preferences.chatbot) == null ? void 0 : _a2.name) || "";
|
|
1512
1561
|
const pState = (_b2 = preferences.localization) == null ? void 0 : _b2.state;
|
|
@@ -1524,38 +1573,11 @@ function PreferencesPage() {
|
|
|
1524
1573
|
const langOption = LANGUAGE_OPTIONS.find((opt) => opt.value === pLanguage);
|
|
1525
1574
|
setLanguage(langOption || null);
|
|
1526
1575
|
}
|
|
1527
|
-
const pTone = (_f = preferences.content) == null ? void 0 : _f.tone;
|
|
1528
|
-
const pStyle = (_g = preferences.content) == null ? void 0 : _g.style;
|
|
1529
|
-
const pWordCount = (_h = preferences.content) == null ? void 0 : _h.wordCount;
|
|
1530
|
-
const pIncludeQuotes = (_j = (_i = preferences.content) == null ? void 0 : _i.includeQuotes) != null ? _j : true;
|
|
1531
|
-
const pIncludeFAQ = (_l = (_k = preferences.content) == null ? void 0 : _k.includeFAQ) != null ? _l : false;
|
|
1532
|
-
const pTargetAudience = ((_m = preferences.content) == null ? void 0 : _m.targetAudience) || "";
|
|
1533
|
-
if (pTone) {
|
|
1534
|
-
const toneOption = TONE_OPTIONS.find((opt) => opt.value === pTone);
|
|
1535
|
-
setTone(toneOption || null);
|
|
1536
|
-
}
|
|
1537
|
-
if (pStyle) {
|
|
1538
|
-
const styleOption = STYLE_OPTIONS.find((opt) => opt.value === pStyle);
|
|
1539
|
-
setStyle(styleOption || null);
|
|
1540
|
-
}
|
|
1541
|
-
if (pWordCount) {
|
|
1542
|
-
const wordCountOption = WORD_COUNT_OPTIONS.find((opt) => opt.value === pWordCount);
|
|
1543
|
-
setWordCount(wordCountOption || null);
|
|
1544
|
-
}
|
|
1545
|
-
setIncludeQuotes(pIncludeQuotes);
|
|
1546
|
-
setIncludeFAQ(pIncludeFAQ);
|
|
1547
|
-
setTargetAudience(pTargetAudience);
|
|
1548
1576
|
setOriginalValues({
|
|
1549
1577
|
botName: name,
|
|
1550
1578
|
state: pState,
|
|
1551
1579
|
cities: pCities,
|
|
1552
|
-
language: pLanguage
|
|
1553
|
-
tone: pTone,
|
|
1554
|
-
style: pStyle,
|
|
1555
|
-
wordCount: pWordCount,
|
|
1556
|
-
includeQuotes: pIncludeQuotes,
|
|
1557
|
-
includeFAQ: pIncludeFAQ,
|
|
1558
|
-
targetAudience: pTargetAudience
|
|
1580
|
+
language: pLanguage
|
|
1559
1581
|
});
|
|
1560
1582
|
}
|
|
1561
1583
|
}, [preferences]);
|
|
@@ -1587,27 +1609,6 @@ function PreferencesPage() {
|
|
|
1587
1609
|
if (currentLanguage !== originalValues.language) {
|
|
1588
1610
|
payload.language = currentLanguage;
|
|
1589
1611
|
}
|
|
1590
|
-
const currentTone = tone == null ? void 0 : tone.value;
|
|
1591
|
-
if (currentTone !== originalValues.tone) {
|
|
1592
|
-
payload.tone = currentTone;
|
|
1593
|
-
}
|
|
1594
|
-
const currentStyle = style == null ? void 0 : style.value;
|
|
1595
|
-
if (currentStyle !== originalValues.style) {
|
|
1596
|
-
payload.style = currentStyle;
|
|
1597
|
-
}
|
|
1598
|
-
const currentWordCount = wordCount == null ? void 0 : wordCount.value;
|
|
1599
|
-
if (currentWordCount !== originalValues.wordCount) {
|
|
1600
|
-
payload.wordCount = currentWordCount;
|
|
1601
|
-
}
|
|
1602
|
-
if (includeQuotes !== originalValues.includeQuotes) {
|
|
1603
|
-
payload.includeQuotes = includeQuotes;
|
|
1604
|
-
}
|
|
1605
|
-
if (includeFAQ !== originalValues.includeFAQ) {
|
|
1606
|
-
payload.includeFAQ = includeFAQ;
|
|
1607
|
-
}
|
|
1608
|
-
if (targetAudience !== originalValues.targetAudience) {
|
|
1609
|
-
payload.targetAudience = targetAudience;
|
|
1610
|
-
}
|
|
1611
1612
|
if (Object.keys(payload).length === 0) {
|
|
1612
1613
|
toast.error("No changes to save");
|
|
1613
1614
|
setSaving(false);
|
|
@@ -1680,150 +1681,6 @@ function PreferencesPage() {
|
|
|
1680
1681
|
] })
|
|
1681
1682
|
] })
|
|
1682
1683
|
] }),
|
|
1683
|
-
/* @__PURE__ */ jsxs7("div", { className: "cnfy-dash-card", children: [
|
|
1684
|
-
/* @__PURE__ */ jsx10("h2", { className: "cnfy-dash-card-title", children: "Localization Settings" }),
|
|
1685
|
-
/* @__PURE__ */ jsxs7("div", { className: "cnfy-dash-field", children: [
|
|
1686
|
-
/* @__PURE__ */ jsx10("label", { className: "cnfy-dash-label", children: "State" }),
|
|
1687
|
-
/* @__PURE__ */ jsx10(
|
|
1688
|
-
ClientSelect_default,
|
|
1689
|
-
{
|
|
1690
|
-
options: STATE_OPTIONS,
|
|
1691
|
-
value: state,
|
|
1692
|
-
onChange: (option) => setState(option),
|
|
1693
|
-
placeholder: "Select state"
|
|
1694
|
-
}
|
|
1695
|
-
)
|
|
1696
|
-
] }),
|
|
1697
|
-
/* @__PURE__ */ jsxs7("div", { className: "cnfy-dash-field", children: [
|
|
1698
|
-
/* @__PURE__ */ jsx10("label", { className: "cnfy-dash-label", children: "Cities" }),
|
|
1699
|
-
/* @__PURE__ */ jsx10(
|
|
1700
|
-
ClientSelect_default,
|
|
1701
|
-
{
|
|
1702
|
-
isMulti: true,
|
|
1703
|
-
options: CITY_OPTIONS,
|
|
1704
|
-
value: cities,
|
|
1705
|
-
onChange: (options) => setCities(options),
|
|
1706
|
-
placeholder: "Select cities",
|
|
1707
|
-
isDisabled: !state
|
|
1708
|
-
}
|
|
1709
|
-
)
|
|
1710
|
-
] }),
|
|
1711
|
-
/* @__PURE__ */ jsxs7("div", { className: "cnfy-dash-field", children: [
|
|
1712
|
-
/* @__PURE__ */ jsx10("label", { className: "cnfy-dash-label", children: "Language" }),
|
|
1713
|
-
/* @__PURE__ */ jsx10(
|
|
1714
|
-
ClientSelect_default,
|
|
1715
|
-
{
|
|
1716
|
-
options: LANGUAGE_OPTIONS,
|
|
1717
|
-
value: language,
|
|
1718
|
-
onChange: (option) => setLanguage(option),
|
|
1719
|
-
placeholder: "Select language"
|
|
1720
|
-
}
|
|
1721
|
-
)
|
|
1722
|
-
] })
|
|
1723
|
-
] }),
|
|
1724
|
-
/* @__PURE__ */ jsxs7("div", { className: "cnfy-dash-card", children: [
|
|
1725
|
-
/* @__PURE__ */ jsx10("h2", { className: "cnfy-dash-card-title", children: "Content Generation Settings" }),
|
|
1726
|
-
/* @__PURE__ */ jsxs7("div", { className: "cnfy-dash-field", children: [
|
|
1727
|
-
/* @__PURE__ */ jsx10("label", { className: "cnfy-dash-label", children: "Tone" }),
|
|
1728
|
-
/* @__PURE__ */ jsx10(
|
|
1729
|
-
ClientSelect_default,
|
|
1730
|
-
{
|
|
1731
|
-
options: TONE_OPTIONS,
|
|
1732
|
-
value: tone,
|
|
1733
|
-
onChange: (option) => setTone(option),
|
|
1734
|
-
placeholder: "Select tone"
|
|
1735
|
-
}
|
|
1736
|
-
),
|
|
1737
|
-
/* @__PURE__ */ jsx10("p", { className: "cnfy-dash-hint", children: "The writing tone for generated content" })
|
|
1738
|
-
] }),
|
|
1739
|
-
/* @__PURE__ */ jsxs7("div", { className: "cnfy-dash-field", children: [
|
|
1740
|
-
/* @__PURE__ */ jsx10("label", { className: "cnfy-dash-label", children: "Style" }),
|
|
1741
|
-
/* @__PURE__ */ jsx10(
|
|
1742
|
-
ClientSelect_default,
|
|
1743
|
-
{
|
|
1744
|
-
options: STYLE_OPTIONS,
|
|
1745
|
-
value: style,
|
|
1746
|
-
onChange: (option) => setStyle(option),
|
|
1747
|
-
placeholder: "Select style"
|
|
1748
|
-
}
|
|
1749
|
-
),
|
|
1750
|
-
/* @__PURE__ */ jsx10("p", { className: "cnfy-dash-hint", children: "The format/style of generated articles" })
|
|
1751
|
-
] }),
|
|
1752
|
-
/* @__PURE__ */ jsxs7("div", { className: "cnfy-dash-field", children: [
|
|
1753
|
-
/* @__PURE__ */ jsx10("label", { className: "cnfy-dash-label", children: "Word Count" }),
|
|
1754
|
-
/* @__PURE__ */ jsx10(
|
|
1755
|
-
ClientSelect_default,
|
|
1756
|
-
{
|
|
1757
|
-
options: WORD_COUNT_OPTIONS,
|
|
1758
|
-
value: wordCount,
|
|
1759
|
-
onChange: (option) => setWordCount(option),
|
|
1760
|
-
placeholder: "Select word count"
|
|
1761
|
-
}
|
|
1762
|
-
),
|
|
1763
|
-
/* @__PURE__ */ jsx10("p", { className: "cnfy-dash-hint", children: "Target length for generated content" })
|
|
1764
|
-
] }),
|
|
1765
|
-
/* @__PURE__ */ jsxs7("div", { className: "cnfy-dash-field", children: [
|
|
1766
|
-
/* @__PURE__ */ jsx10("label", { className: "cnfy-dash-label", children: "Target Audience" }),
|
|
1767
|
-
/* @__PURE__ */ jsx10(
|
|
1768
|
-
"input",
|
|
1769
|
-
{
|
|
1770
|
-
value: targetAudience,
|
|
1771
|
-
onChange: (e) => setTargetAudience(e.target.value),
|
|
1772
|
-
className: "cnfy-dash-input",
|
|
1773
|
-
placeholder: "e.g. tech-savvy millennials, business professionals"
|
|
1774
|
-
}
|
|
1775
|
-
),
|
|
1776
|
-
/* @__PURE__ */ jsx10("p", { className: "cnfy-dash-hint", children: "Describe your target audience for personalized content" })
|
|
1777
|
-
] }),
|
|
1778
|
-
/* @__PURE__ */ jsxs7("div", { className: "cnfy-toggle-group", children: [
|
|
1779
|
-
/* @__PURE__ */ jsxs7("div", { className: "cnfy-toggle-row", children: [
|
|
1780
|
-
/* @__PURE__ */ jsxs7("div", { children: [
|
|
1781
|
-
/* @__PURE__ */ jsx10("p", { className: "cnfy-toggle-label", children: "Include Quotes" }),
|
|
1782
|
-
/* @__PURE__ */ jsx10("p", { className: "cnfy-toggle-desc", children: "Add relevant quotes to generated articles" })
|
|
1783
|
-
] }),
|
|
1784
|
-
/* @__PURE__ */ jsx10(
|
|
1785
|
-
"button",
|
|
1786
|
-
{
|
|
1787
|
-
type: "button",
|
|
1788
|
-
role: "switch",
|
|
1789
|
-
"aria-checked": includeQuotes,
|
|
1790
|
-
onClick: () => setIncludeQuotes(!includeQuotes),
|
|
1791
|
-
className: "cnfy-toggle",
|
|
1792
|
-
style: { backgroundColor: includeQuotes ? primaryColor : "#d1d5db" },
|
|
1793
|
-
children: /* @__PURE__ */ jsx10(
|
|
1794
|
-
"span",
|
|
1795
|
-
{
|
|
1796
|
-
className: `cnfy-toggle-thumb ${includeQuotes ? "cnfy-toggle-thumb--on" : ""}`
|
|
1797
|
-
}
|
|
1798
|
-
)
|
|
1799
|
-
}
|
|
1800
|
-
)
|
|
1801
|
-
] }),
|
|
1802
|
-
/* @__PURE__ */ jsxs7("div", { className: "cnfy-toggle-row", children: [
|
|
1803
|
-
/* @__PURE__ */ jsxs7("div", { children: [
|
|
1804
|
-
/* @__PURE__ */ jsx10("p", { className: "cnfy-toggle-label", children: "Include FAQ Section" }),
|
|
1805
|
-
/* @__PURE__ */ jsx10("p", { className: "cnfy-toggle-desc", children: "Add FAQ section at the end of articles" })
|
|
1806
|
-
] }),
|
|
1807
|
-
/* @__PURE__ */ jsx10(
|
|
1808
|
-
"button",
|
|
1809
|
-
{
|
|
1810
|
-
type: "button",
|
|
1811
|
-
role: "switch",
|
|
1812
|
-
"aria-checked": includeFAQ,
|
|
1813
|
-
onClick: () => setIncludeFAQ(!includeFAQ),
|
|
1814
|
-
className: "cnfy-toggle",
|
|
1815
|
-
style: { backgroundColor: includeFAQ ? primaryColor : "#d1d5db" },
|
|
1816
|
-
children: /* @__PURE__ */ jsx10(
|
|
1817
|
-
"span",
|
|
1818
|
-
{
|
|
1819
|
-
className: `cnfy-toggle-thumb ${includeFAQ ? "cnfy-toggle-thumb--on" : ""}`
|
|
1820
|
-
}
|
|
1821
|
-
)
|
|
1822
|
-
}
|
|
1823
|
-
)
|
|
1824
|
-
] })
|
|
1825
|
-
] })
|
|
1826
|
-
] }),
|
|
1827
1684
|
/* @__PURE__ */ jsxs7("div", { className: "cnfy-dash-card", children: [
|
|
1828
1685
|
/* @__PURE__ */ jsxs7("div", { className: "cnfy-dash-card-header", children: [
|
|
1829
1686
|
/* @__PURE__ */ jsx10("h2", { className: "cnfy-dash-card-title-inline", children: "News Scraping" }),
|
|
@@ -1850,7 +1707,7 @@ function PreferencesPage() {
|
|
|
1850
1707
|
/* @__PURE__ */ jsxs7("p", { className: "cnfy-dash-info-text", children: [
|
|
1851
1708
|
"Current configuration: ",
|
|
1852
1709
|
/* @__PURE__ */ jsx10("strong", { children: (_b = preferences == null ? void 0 : preferences.localization) == null ? void 0 : _b.state }),
|
|
1853
|
-
((_c = preferences == null ? void 0 : preferences.localization) == null ? void 0 : _c.cities) && preferences.localization.cities.length > 0 && /* @__PURE__ */ jsxs7(
|
|
1710
|
+
((_c = preferences == null ? void 0 : preferences.localization) == null ? void 0 : _c.cities) && preferences.localization.cities.length > 0 && /* @__PURE__ */ jsxs7(Fragment2, { children: [
|
|
1854
1711
|
" - ",
|
|
1855
1712
|
preferences.localization.cities.join(", ")
|
|
1856
1713
|
] })
|
|
@@ -1861,35 +1718,133 @@ function PreferencesPage() {
|
|
|
1861
1718
|
onClick: handleScrape,
|
|
1862
1719
|
disabled: scraping || (scrapeStatus == null ? void 0 : scrapeStatus.isRunning),
|
|
1863
1720
|
className: "cnfy-dash-btn-save",
|
|
1864
|
-
style: { backgroundColor: primaryColor },
|
|
1721
|
+
style: { backgroundColor: hexToRgba(primaryColor, 0.8) },
|
|
1865
1722
|
children: scraping ? "Starting Scrape..." : (scrapeStatus == null ? void 0 : scrapeStatus.isRunning) ? "Scraping in Progress..." : "Start Scraping"
|
|
1866
1723
|
}
|
|
1867
1724
|
)
|
|
1868
1725
|
] })
|
|
1869
1726
|
] }),
|
|
1870
|
-
/* @__PURE__ */ jsxs7("div", { className: "cnfy-dash-
|
|
1871
|
-
/* @__PURE__ */ jsx10(
|
|
1872
|
-
|
|
1873
|
-
{
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1727
|
+
/* @__PURE__ */ jsxs7("div", { className: "cnfy-dash-card", children: [
|
|
1728
|
+
/* @__PURE__ */ jsx10("h2", { className: "cnfy-dash-card-title", children: "Localization Settings" }),
|
|
1729
|
+
/* @__PURE__ */ jsxs7("div", { className: "cnfy-dash-field", children: [
|
|
1730
|
+
/* @__PURE__ */ jsx10("label", { className: "cnfy-dash-label", children: "State" }),
|
|
1731
|
+
/* @__PURE__ */ jsx10(
|
|
1732
|
+
ClientSelect_default,
|
|
1733
|
+
{
|
|
1734
|
+
options: STATE_OPTIONS,
|
|
1735
|
+
value: state,
|
|
1736
|
+
onChange: (option) => setState(option),
|
|
1737
|
+
placeholder: "Select state"
|
|
1738
|
+
}
|
|
1739
|
+
)
|
|
1740
|
+
] }),
|
|
1741
|
+
/* @__PURE__ */ jsxs7("div", { className: "cnfy-dash-field", children: [
|
|
1742
|
+
/* @__PURE__ */ jsx10("label", { className: "cnfy-dash-label", children: "Cities" }),
|
|
1743
|
+
/* @__PURE__ */ jsx10(
|
|
1744
|
+
ClientSelect_default,
|
|
1745
|
+
{
|
|
1746
|
+
isMulti: true,
|
|
1747
|
+
options: CITY_OPTIONS,
|
|
1748
|
+
value: cities,
|
|
1749
|
+
onChange: (options) => setCities(options),
|
|
1750
|
+
placeholder: "Select cities",
|
|
1751
|
+
isDisabled: !state
|
|
1752
|
+
}
|
|
1753
|
+
)
|
|
1754
|
+
] }),
|
|
1755
|
+
/* @__PURE__ */ jsxs7("div", { className: "cnfy-dash-field", children: [
|
|
1756
|
+
/* @__PURE__ */ jsx10("label", { className: "cnfy-dash-label", children: "Language" }),
|
|
1757
|
+
/* @__PURE__ */ jsx10(
|
|
1758
|
+
ClientSelect_default,
|
|
1759
|
+
{
|
|
1760
|
+
options: LANGUAGE_OPTIONS,
|
|
1761
|
+
value: language,
|
|
1762
|
+
onChange: (option) => setLanguage(option),
|
|
1763
|
+
placeholder: "Select language"
|
|
1764
|
+
}
|
|
1765
|
+
)
|
|
1766
|
+
] })
|
|
1767
|
+
] }),
|
|
1768
|
+
/* @__PURE__ */ jsx10("div", { className: "cnfy-dash-actions", children: /* @__PURE__ */ jsx10(
|
|
1769
|
+
"button",
|
|
1770
|
+
{
|
|
1771
|
+
onClick: handleSave,
|
|
1772
|
+
disabled: saving,
|
|
1773
|
+
className: "cnfy-dash-btn-save",
|
|
1774
|
+
style: { backgroundColor: primaryColor },
|
|
1775
|
+
children: saving ? "Saving..." : "Save Preferences"
|
|
1776
|
+
}
|
|
1777
|
+
) })
|
|
1883
1778
|
] });
|
|
1884
1779
|
}
|
|
1885
1780
|
|
|
1886
1781
|
// services/chat.service.ts
|
|
1782
|
+
function getHeaders() {
|
|
1783
|
+
const apiKey = getApiKey();
|
|
1784
|
+
const headers = {
|
|
1785
|
+
"Content-Type": "application/json"
|
|
1786
|
+
};
|
|
1787
|
+
if (apiKey) {
|
|
1788
|
+
headers["x-api-key"] = apiKey;
|
|
1789
|
+
}
|
|
1790
|
+
return headers;
|
|
1791
|
+
}
|
|
1792
|
+
async function processSSEStream(reader, callbacks) {
|
|
1793
|
+
const decoder = new TextDecoder();
|
|
1794
|
+
let buffer = "";
|
|
1795
|
+
const processLines = (lines) => {
|
|
1796
|
+
var _a, _b, _c, _d, _e;
|
|
1797
|
+
for (const line of lines) {
|
|
1798
|
+
const trimmed = line.trim();
|
|
1799
|
+
if (!trimmed.startsWith("data: ")) continue;
|
|
1800
|
+
const data = trimmed.slice(6).trim();
|
|
1801
|
+
try {
|
|
1802
|
+
const event = JSON.parse(data);
|
|
1803
|
+
switch (event.type) {
|
|
1804
|
+
case "start":
|
|
1805
|
+
break;
|
|
1806
|
+
case "field_start":
|
|
1807
|
+
(_a = callbacks.onFieldStart) == null ? void 0 : _a.call(callbacks, event.field);
|
|
1808
|
+
break;
|
|
1809
|
+
case "content":
|
|
1810
|
+
callbacks.onContent(event.field, event.content);
|
|
1811
|
+
break;
|
|
1812
|
+
case "keywords":
|
|
1813
|
+
(_b = callbacks.onKeywords) == null ? void 0 : _b.call(callbacks, event.content);
|
|
1814
|
+
break;
|
|
1815
|
+
case "field_end":
|
|
1816
|
+
(_c = callbacks.onFieldEnd) == null ? void 0 : _c.call(callbacks, event.field);
|
|
1817
|
+
break;
|
|
1818
|
+
case "done":
|
|
1819
|
+
(_d = callbacks.onComplete) == null ? void 0 : _d.call(callbacks, event.data);
|
|
1820
|
+
return true;
|
|
1821
|
+
case "error":
|
|
1822
|
+
(_e = callbacks.onError) == null ? void 0 : _e.call(callbacks, new Error(event.message));
|
|
1823
|
+
return true;
|
|
1824
|
+
}
|
|
1825
|
+
} catch (e) {
|
|
1826
|
+
}
|
|
1827
|
+
}
|
|
1828
|
+
return false;
|
|
1829
|
+
};
|
|
1830
|
+
while (true) {
|
|
1831
|
+
const { done, value } = await reader.read();
|
|
1832
|
+
if (done) break;
|
|
1833
|
+
buffer += decoder.decode(value, { stream: true });
|
|
1834
|
+
const lines = buffer.split("\n");
|
|
1835
|
+
buffer = lines.pop() || "";
|
|
1836
|
+
if (processLines(lines)) return;
|
|
1837
|
+
}
|
|
1838
|
+
if (buffer.trim()) {
|
|
1839
|
+
processLines([buffer]);
|
|
1840
|
+
}
|
|
1841
|
+
}
|
|
1887
1842
|
var analyzeInputApi = async (input) => {
|
|
1888
|
-
const { data } = await api_default.post("/
|
|
1843
|
+
const { data } = await api_default.post("/chatboat/analyze-input", { input });
|
|
1889
1844
|
return data.data;
|
|
1890
1845
|
};
|
|
1891
1846
|
var createContentApi = async (payload) => {
|
|
1892
|
-
const { data } = await api_default.post("/
|
|
1847
|
+
const { data } = await api_default.post("/chatboat/create-content", payload);
|
|
1893
1848
|
return data.data;
|
|
1894
1849
|
};
|
|
1895
1850
|
var createContentStreamApi = async ({
|
|
@@ -1897,22 +1852,18 @@ var createContentStreamApi = async ({
|
|
|
1897
1852
|
content,
|
|
1898
1853
|
actionId,
|
|
1899
1854
|
settings,
|
|
1900
|
-
|
|
1855
|
+
onFieldStart,
|
|
1856
|
+
onContent,
|
|
1857
|
+
onKeywords,
|
|
1858
|
+
onFieldEnd,
|
|
1901
1859
|
onComplete,
|
|
1902
1860
|
onError
|
|
1903
1861
|
}) => {
|
|
1904
1862
|
var _a;
|
|
1905
1863
|
const API_BASE_URL = getApiBaseUrl();
|
|
1906
|
-
const apiKey = getApiKey();
|
|
1907
|
-
const headers = {
|
|
1908
|
-
"Content-Type": "application/json"
|
|
1909
|
-
};
|
|
1910
|
-
if (apiKey) {
|
|
1911
|
-
headers["x-api-key"] = apiKey;
|
|
1912
|
-
}
|
|
1913
1864
|
const response = await fetch(`${API_BASE_URL}/chat/create-content/stream`, {
|
|
1914
1865
|
method: "POST",
|
|
1915
|
-
headers,
|
|
1866
|
+
headers: getHeaders(),
|
|
1916
1867
|
credentials: "include",
|
|
1917
1868
|
body: JSON.stringify({ url, content, actionId, settings })
|
|
1918
1869
|
});
|
|
@@ -1921,50 +1872,17 @@ var createContentStreamApi = async ({
|
|
|
1921
1872
|
throw new Error(`HTTP error! status: ${response.status} - ${errorText}`);
|
|
1922
1873
|
}
|
|
1923
1874
|
const reader = (_a = response.body) == null ? void 0 : _a.getReader();
|
|
1924
|
-
const decoder = new TextDecoder();
|
|
1925
1875
|
if (!reader) {
|
|
1926
1876
|
throw new Error("No reader available");
|
|
1927
1877
|
}
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
const chunk = decoder.decode(value, { stream: true });
|
|
1937
|
-
buffer += chunk;
|
|
1938
|
-
const lines = buffer.split("\n");
|
|
1939
|
-
buffer = lines.pop() || "";
|
|
1940
|
-
for (const line of lines) {
|
|
1941
|
-
const trimmedLine = line.trim();
|
|
1942
|
-
if (trimmedLine === "") continue;
|
|
1943
|
-
hasReceivedData = true;
|
|
1944
|
-
if (trimmedLine.startsWith("data: ")) {
|
|
1945
|
-
const data = trimmedLine.slice(6).trim();
|
|
1946
|
-
if (data === "[DONE]") {
|
|
1947
|
-
onComplete == null ? void 0 : onComplete();
|
|
1948
|
-
return;
|
|
1949
|
-
}
|
|
1950
|
-
try {
|
|
1951
|
-
const parsed = JSON.parse(data);
|
|
1952
|
-
if (parsed.content) onChunk(parsed.content);
|
|
1953
|
-
else if (parsed.delta) onChunk(parsed.delta);
|
|
1954
|
-
else if (parsed.text) onChunk(parsed.text);
|
|
1955
|
-
else if (parsed.chunk) onChunk(parsed.chunk);
|
|
1956
|
-
else if (typeof parsed === "string") onChunk(parsed);
|
|
1957
|
-
} catch (e) {
|
|
1958
|
-
if (data) onChunk(data);
|
|
1959
|
-
}
|
|
1960
|
-
} else if (trimmedLine) {
|
|
1961
|
-
onChunk(trimmedLine + "\n");
|
|
1962
|
-
}
|
|
1963
|
-
}
|
|
1964
|
-
}
|
|
1965
|
-
if (!hasReceivedData) {
|
|
1966
|
-
throw new Error("No data received from stream");
|
|
1967
|
-
}
|
|
1878
|
+
await processSSEStream(reader, {
|
|
1879
|
+
onFieldStart,
|
|
1880
|
+
onContent,
|
|
1881
|
+
onKeywords,
|
|
1882
|
+
onFieldEnd,
|
|
1883
|
+
onComplete,
|
|
1884
|
+
onError
|
|
1885
|
+
});
|
|
1968
1886
|
};
|
|
1969
1887
|
var rewriteNewsStreamApi = async ({
|
|
1970
1888
|
article,
|
|
@@ -1976,7 +1894,10 @@ var rewriteNewsStreamApi = async ({
|
|
|
1976
1894
|
includeQuotes,
|
|
1977
1895
|
includeFAQ,
|
|
1978
1896
|
targetAudience,
|
|
1979
|
-
|
|
1897
|
+
onFieldStart,
|
|
1898
|
+
onContent,
|
|
1899
|
+
onKeywords,
|
|
1900
|
+
onFieldEnd,
|
|
1980
1901
|
onComplete,
|
|
1981
1902
|
onError
|
|
1982
1903
|
}) => {
|
|
@@ -1985,9 +1906,7 @@ var rewriteNewsStreamApi = async ({
|
|
|
1985
1906
|
article,
|
|
1986
1907
|
language
|
|
1987
1908
|
};
|
|
1988
|
-
if (articleId)
|
|
1989
|
-
payload.articleId = articleId;
|
|
1990
|
-
}
|
|
1909
|
+
if (articleId) payload.articleId = articleId;
|
|
1991
1910
|
if (tone) payload.tone = tone;
|
|
1992
1911
|
if (style) payload.style = style;
|
|
1993
1912
|
if (wordCount) payload.wordCount = wordCount;
|
|
@@ -1996,102 +1915,42 @@ var rewriteNewsStreamApi = async ({
|
|
|
1996
1915
|
if (targetAudience) payload.targetAudience = targetAudience;
|
|
1997
1916
|
try {
|
|
1998
1917
|
const API_BASE_URL = getApiBaseUrl();
|
|
1999
|
-
const
|
|
2000
|
-
console.log("\u{1F680} Starting stream request to:", `${API_BASE_URL}/chat/rewrite/stream`);
|
|
2001
|
-
console.log("\u{1F4E6} Payload:", payload);
|
|
2002
|
-
const headers = {
|
|
2003
|
-
"Content-Type": "application/json"
|
|
2004
|
-
};
|
|
2005
|
-
if (apiKey) {
|
|
2006
|
-
headers["x-api-key"] = apiKey;
|
|
2007
|
-
}
|
|
2008
|
-
const response = await fetch(`${API_BASE_URL}/chat/rewrite/stream`, {
|
|
1918
|
+
const response = await fetch(`${API_BASE_URL}/chatboat/rewrite/stream`, {
|
|
2009
1919
|
method: "POST",
|
|
2010
|
-
headers,
|
|
1920
|
+
headers: getHeaders(),
|
|
2011
1921
|
credentials: "include",
|
|
2012
|
-
// Include cookies for authentication
|
|
2013
1922
|
body: JSON.stringify(payload)
|
|
2014
1923
|
});
|
|
2015
|
-
console.log("\u{1F4E1} Response status:", response.status);
|
|
2016
|
-
console.log("\u{1F4E1} Response headers:", Object.fromEntries(response.headers.entries()));
|
|
2017
1924
|
if (!response.ok) {
|
|
2018
1925
|
const errorText = await response.text();
|
|
2019
|
-
console.error("\u274C API Error:", response.status, errorText);
|
|
2020
1926
|
throw new Error(`HTTP error! status: ${response.status} - ${errorText}`);
|
|
2021
1927
|
}
|
|
1928
|
+
const contentType = response.headers.get("content-type") || "";
|
|
1929
|
+
if (contentType.includes("application/json")) {
|
|
1930
|
+
const json = await response.json();
|
|
1931
|
+
const data = json.data || json;
|
|
1932
|
+
onComplete == null ? void 0 : onComplete({
|
|
1933
|
+
title: data.title || "",
|
|
1934
|
+
subtitle: data.subtitle || "",
|
|
1935
|
+
article: data.article || "",
|
|
1936
|
+
metaDescription: data.metaDescription || "",
|
|
1937
|
+
metaKeywords: Array.isArray(data.metaKeywords) ? data.metaKeywords : []
|
|
1938
|
+
});
|
|
1939
|
+
return;
|
|
1940
|
+
}
|
|
2022
1941
|
const reader = (_a = response.body) == null ? void 0 : _a.getReader();
|
|
2023
|
-
const decoder = new TextDecoder();
|
|
2024
1942
|
if (!reader) {
|
|
2025
1943
|
throw new Error("No reader available");
|
|
2026
1944
|
}
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
}
|
|
2035
|
-
break;
|
|
2036
|
-
}
|
|
2037
|
-
const chunk = decoder.decode(value, { stream: true });
|
|
2038
|
-
buffer += chunk;
|
|
2039
|
-
const lines = buffer.split("\n");
|
|
2040
|
-
buffer = lines.pop() || "";
|
|
2041
|
-
for (const line of lines) {
|
|
2042
|
-
const trimmedLine = line.trim();
|
|
2043
|
-
if (trimmedLine === "") continue;
|
|
2044
|
-
hasReceivedData = true;
|
|
2045
|
-
console.log("\u{1F4E8} Received line:", trimmedLine.substring(0, 100) + (trimmedLine.length > 100 ? "..." : ""));
|
|
2046
|
-
if (trimmedLine.startsWith("data: ")) {
|
|
2047
|
-
const data = trimmedLine.slice(6).trim();
|
|
2048
|
-
if (data === "[DONE]") {
|
|
2049
|
-
console.log("\u2705 Stream completed with [DONE] signal");
|
|
2050
|
-
onComplete == null ? void 0 : onComplete();
|
|
2051
|
-
return;
|
|
2052
|
-
}
|
|
2053
|
-
try {
|
|
2054
|
-
const parsed = JSON.parse(data);
|
|
2055
|
-
console.log("\u{1F4CB} Parsed JSON:", parsed);
|
|
2056
|
-
if (parsed.content) {
|
|
2057
|
-
onChunk(parsed.content);
|
|
2058
|
-
} else if (parsed.delta) {
|
|
2059
|
-
onChunk(parsed.delta);
|
|
2060
|
-
} else if (parsed.text) {
|
|
2061
|
-
onChunk(parsed.text);
|
|
2062
|
-
} else if (parsed.chunk) {
|
|
2063
|
-
onChunk(parsed.chunk);
|
|
2064
|
-
} else if (typeof parsed === "string") {
|
|
2065
|
-
onChunk(parsed);
|
|
2066
|
-
} else {
|
|
2067
|
-
console.warn("\u26A0\uFE0F Unknown JSON format:", parsed);
|
|
2068
|
-
}
|
|
2069
|
-
} catch (e) {
|
|
2070
|
-
console.log("\u{1F4DD} Non-JSON data, treating as plain text");
|
|
2071
|
-
if (data) {
|
|
2072
|
-
onChunk(data);
|
|
2073
|
-
}
|
|
2074
|
-
}
|
|
2075
|
-
} else {
|
|
2076
|
-
console.log("\u{1F4C4} Plain text chunk");
|
|
2077
|
-
if (trimmedLine) {
|
|
2078
|
-
onChunk(trimmedLine + "\n");
|
|
2079
|
-
}
|
|
2080
|
-
}
|
|
2081
|
-
}
|
|
2082
|
-
}
|
|
2083
|
-
if (!hasReceivedData) {
|
|
2084
|
-
console.error("\u274C No data received from stream");
|
|
2085
|
-
throw new Error("No data received from stream");
|
|
2086
|
-
}
|
|
2087
|
-
console.log("\u2705 Stream completed successfully");
|
|
2088
|
-
} catch (error) {
|
|
2089
|
-
console.error("\u274C Streaming error:", error);
|
|
2090
|
-
console.error("Error details:", {
|
|
2091
|
-
message: error.message,
|
|
2092
|
-
name: error.name,
|
|
2093
|
-
stack: error.stack
|
|
1945
|
+
await processSSEStream(reader, {
|
|
1946
|
+
onFieldStart,
|
|
1947
|
+
onContent,
|
|
1948
|
+
onKeywords,
|
|
1949
|
+
onFieldEnd,
|
|
1950
|
+
onComplete,
|
|
1951
|
+
onError
|
|
2094
1952
|
});
|
|
1953
|
+
} catch (error) {
|
|
2095
1954
|
onError == null ? void 0 : onError(error);
|
|
2096
1955
|
throw error;
|
|
2097
1956
|
}
|
|
@@ -2111,29 +1970,31 @@ var rewriteNewsApi = async ({
|
|
|
2111
1970
|
article,
|
|
2112
1971
|
language
|
|
2113
1972
|
};
|
|
2114
|
-
if (articleId)
|
|
2115
|
-
payload.articleId = articleId;
|
|
2116
|
-
}
|
|
1973
|
+
if (articleId) payload.articleId = articleId;
|
|
2117
1974
|
if (tone) payload.tone = tone;
|
|
2118
1975
|
if (style) payload.style = style;
|
|
2119
1976
|
if (wordCount) payload.wordCount = wordCount;
|
|
2120
1977
|
if (includeQuotes !== void 0) payload.includeQuotes = includeQuotes;
|
|
2121
1978
|
if (includeFAQ !== void 0) payload.includeFAQ = includeFAQ;
|
|
2122
1979
|
if (targetAudience) payload.targetAudience = targetAudience;
|
|
2123
|
-
const { data } = await api_default.post("/
|
|
1980
|
+
const { data } = await api_default.post("/chatboat/rewrite", payload);
|
|
2124
1981
|
return data.data;
|
|
2125
1982
|
};
|
|
2126
1983
|
|
|
2127
1984
|
// components/chatbot/ChatBot.tsx
|
|
2128
1985
|
import toast2 from "react-hot-toast";
|
|
2129
|
-
import { Loader2 } from "lucide-react";
|
|
1986
|
+
import { Loader2 as Loader22 } from "lucide-react";
|
|
2130
1987
|
import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1988
|
+
function buildStructuredContent(title, article, metaKeywords, subtitle = "", metaDescription = "") {
|
|
1989
|
+
return JSON.stringify({ title, subtitle, article, metaDescription, metaKeywords });
|
|
1990
|
+
}
|
|
2131
1991
|
function ChatBot({ onPost }) {
|
|
2132
1992
|
const { loading } = useTheme();
|
|
2133
1993
|
const { preferences } = usePreferences();
|
|
2134
1994
|
const [preferencesOpen, setPreferencesOpen] = useState7(false);
|
|
2135
1995
|
const [messages, setMessages] = useState7([]);
|
|
2136
1996
|
const [isStreaming, setIsStreaming] = useState7(false);
|
|
1997
|
+
const [activeField, setActiveField] = useState7(null);
|
|
2137
1998
|
const [analyzedData, setAnalyzedData] = useState7(null);
|
|
2138
1999
|
const handleRecreate = async ({ title, content, id }) => {
|
|
2139
2000
|
var _a;
|
|
@@ -2144,17 +2005,28 @@ function ChatBot({ onPost }) {
|
|
|
2144
2005
|
id: crypto.randomUUID(),
|
|
2145
2006
|
role: "user",
|
|
2146
2007
|
content: `Recreate this news:
|
|
2147
|
-
${title}`
|
|
2008
|
+
${title}`
|
|
2148
2009
|
},
|
|
2149
2010
|
{
|
|
2150
2011
|
id: assistantId,
|
|
2151
2012
|
role: "assistant",
|
|
2152
|
-
content: "
|
|
2013
|
+
content: ""
|
|
2153
2014
|
}
|
|
2154
2015
|
]);
|
|
2016
|
+
setIsStreaming(true);
|
|
2155
2017
|
try {
|
|
2156
|
-
let accumulatedContent = "";
|
|
2157
2018
|
let hasStartedStreaming = false;
|
|
2019
|
+
let titleBuffer = "";
|
|
2020
|
+
let articleBuffer = "";
|
|
2021
|
+
let keywordsBuffer = [];
|
|
2022
|
+
const updateMessage = () => {
|
|
2023
|
+
const structured = buildStructuredContent(titleBuffer, articleBuffer, keywordsBuffer);
|
|
2024
|
+
setMessages(
|
|
2025
|
+
(prev) => prev.map(
|
|
2026
|
+
(m) => m.id === assistantId ? __spreadProps(__spreadValues({}, m), { content: structured }) : m
|
|
2027
|
+
)
|
|
2028
|
+
);
|
|
2029
|
+
};
|
|
2158
2030
|
const contentPrefs = preferences == null ? void 0 : preferences.content;
|
|
2159
2031
|
const lang = ((_a = preferences == null ? void 0 : preferences.localization) == null ? void 0 : _a.language) === "hi" ? "Hindi" : "English";
|
|
2160
2032
|
try {
|
|
@@ -2168,39 +2040,66 @@ ${title}`
|
|
|
2168
2040
|
includeQuotes: contentPrefs == null ? void 0 : contentPrefs.includeQuotes,
|
|
2169
2041
|
includeFAQ: contentPrefs == null ? void 0 : contentPrefs.includeFAQ,
|
|
2170
2042
|
targetAudience: contentPrefs == null ? void 0 : contentPrefs.targetAudience,
|
|
2171
|
-
|
|
2043
|
+
onFieldStart: (field) => {
|
|
2044
|
+
setActiveField(field);
|
|
2045
|
+
},
|
|
2046
|
+
onContent: (field, chunk) => {
|
|
2172
2047
|
hasStartedStreaming = true;
|
|
2173
|
-
|
|
2048
|
+
if (field === "title") titleBuffer += chunk;
|
|
2049
|
+
else articleBuffer += chunk;
|
|
2050
|
+
updateMessage();
|
|
2051
|
+
},
|
|
2052
|
+
onKeywords: (keywords) => {
|
|
2053
|
+
keywordsBuffer = keywords;
|
|
2054
|
+
updateMessage();
|
|
2055
|
+
},
|
|
2056
|
+
onFieldEnd: () => {
|
|
2057
|
+
setActiveField(null);
|
|
2058
|
+
},
|
|
2059
|
+
onComplete: (data) => {
|
|
2060
|
+
const finalContent = data && (data.title || data.article) ? JSON.stringify(data) : buildStructuredContent(titleBuffer, articleBuffer, keywordsBuffer);
|
|
2174
2061
|
setMessages(
|
|
2175
2062
|
(prev) => prev.map(
|
|
2176
|
-
(m) => m.id === assistantId ? __spreadProps(__spreadValues({}, m), { content:
|
|
2063
|
+
(m) => m.id === assistantId ? __spreadProps(__spreadValues({}, m), { content: finalContent }) : m
|
|
2177
2064
|
)
|
|
2178
2065
|
);
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
console.log("Streaming completed successfully");
|
|
2066
|
+
setIsStreaming(false);
|
|
2067
|
+
setActiveField(null);
|
|
2182
2068
|
toast2.success("Article created successfully!");
|
|
2183
2069
|
},
|
|
2184
2070
|
onError: async (error) => {
|
|
2185
2071
|
console.error("Streaming error:", error);
|
|
2186
2072
|
if (!hasStartedStreaming) {
|
|
2187
|
-
console.log("Falling back to regular API...");
|
|
2188
2073
|
throw error;
|
|
2189
2074
|
} else {
|
|
2075
|
+
setIsStreaming(false);
|
|
2076
|
+
setActiveField(null);
|
|
2190
2077
|
toast2.error("Failed to complete article generation");
|
|
2191
2078
|
setMessages(
|
|
2192
2079
|
(prev) => prev.map(
|
|
2193
|
-
(m) => m.id === assistantId ? __spreadProps(__spreadValues({}, m), { content:
|
|
2080
|
+
(m) => m.id === assistantId ? __spreadProps(__spreadValues({}, m), { content: titleBuffer || articleBuffer ? buildStructuredContent(titleBuffer, articleBuffer, keywordsBuffer) : "Failed to create article. Please try again." }) : m
|
|
2194
2081
|
)
|
|
2195
2082
|
);
|
|
2196
2083
|
}
|
|
2197
2084
|
}
|
|
2198
2085
|
});
|
|
2086
|
+
if (isStreaming) {
|
|
2087
|
+
if (titleBuffer || articleBuffer) {
|
|
2088
|
+
const structured = buildStructuredContent(titleBuffer, articleBuffer, keywordsBuffer);
|
|
2089
|
+
setMessages(
|
|
2090
|
+
(prev) => prev.map(
|
|
2091
|
+
(m) => m.id === assistantId ? __spreadProps(__spreadValues({}, m), { content: structured }) : m
|
|
2092
|
+
)
|
|
2093
|
+
);
|
|
2094
|
+
}
|
|
2095
|
+
setIsStreaming(false);
|
|
2096
|
+
setActiveField(null);
|
|
2097
|
+
}
|
|
2199
2098
|
} catch (streamError) {
|
|
2200
2099
|
console.log("Streaming failed, using regular API...", streamError);
|
|
2201
2100
|
setMessages(
|
|
2202
2101
|
(prev) => prev.map(
|
|
2203
|
-
(m) => m.id === assistantId ? __spreadProps(__spreadValues({}, m), { content: "
|
|
2102
|
+
(m) => m.id === assistantId ? __spreadProps(__spreadValues({}, m), { content: "" }) : m
|
|
2204
2103
|
)
|
|
2205
2104
|
);
|
|
2206
2105
|
const result = await rewriteNewsApi({
|
|
@@ -2216,17 +2115,20 @@ ${title}`
|
|
|
2216
2115
|
});
|
|
2217
2116
|
setMessages(
|
|
2218
2117
|
(prev) => prev.map(
|
|
2219
|
-
(m) => m.id === assistantId ? __spreadProps(__spreadValues({}, m), { content: result
|
|
2118
|
+
(m) => m.id === assistantId ? __spreadProps(__spreadValues({}, m), { content: typeof result === "string" ? result : JSON.stringify(result) }) : m
|
|
2220
2119
|
)
|
|
2221
2120
|
);
|
|
2121
|
+
setIsStreaming(false);
|
|
2222
2122
|
toast2.success("Article created successfully!");
|
|
2223
2123
|
}
|
|
2224
2124
|
} catch (err) {
|
|
2225
2125
|
console.error("Complete Error:", err);
|
|
2126
|
+
setIsStreaming(false);
|
|
2127
|
+
setActiveField(null);
|
|
2226
2128
|
toast2.error((err == null ? void 0 : err.message) || "An error occurred while creating the article");
|
|
2227
2129
|
setMessages(
|
|
2228
2130
|
(prev) => prev.map(
|
|
2229
|
-
(m) => m.id === assistantId ? __spreadProps(__spreadValues({}, m), { content: "
|
|
2131
|
+
(m) => m.id === assistantId ? __spreadProps(__spreadValues({}, m), { content: "Failed to create article. Please try again." }) : m
|
|
2230
2132
|
)
|
|
2231
2133
|
);
|
|
2232
2134
|
}
|
|
@@ -2244,9 +2146,10 @@ ${title}`
|
|
|
2244
2146
|
if (hasUrl) {
|
|
2245
2147
|
setMessages((prev) => [
|
|
2246
2148
|
...prev,
|
|
2247
|
-
{ id: assistantId, role: "assistant", content: "
|
|
2149
|
+
{ id: assistantId, role: "assistant", content: "Analyzing your link..." }
|
|
2248
2150
|
]);
|
|
2249
2151
|
try {
|
|
2152
|
+
return;
|
|
2250
2153
|
const result = await analyzeInputApi(text);
|
|
2251
2154
|
if (result.hasUrl && ((_a = result.options) == null ? void 0 : _a.length) > 0) {
|
|
2252
2155
|
setAnalyzedData({
|
|
@@ -2277,20 +2180,30 @@ ${optionsList}`
|
|
|
2277
2180
|
toast2.error("Failed to analyze the link");
|
|
2278
2181
|
setMessages(
|
|
2279
2182
|
(prev) => prev.map(
|
|
2280
|
-
(m) => m.id === assistantId ? __spreadProps(__spreadValues({}, m), { content: "
|
|
2183
|
+
(m) => m.id === assistantId ? __spreadProps(__spreadValues({}, m), { content: "Failed to analyze the link. Please try again." }) : m
|
|
2281
2184
|
)
|
|
2282
2185
|
);
|
|
2283
2186
|
}
|
|
2284
2187
|
} else {
|
|
2285
2188
|
setMessages((prev) => [
|
|
2286
2189
|
...prev,
|
|
2287
|
-
{ id: assistantId, role: "assistant", content: "
|
|
2190
|
+
{ id: assistantId, role: "assistant", content: "" }
|
|
2288
2191
|
]);
|
|
2289
2192
|
setIsStreaming(true);
|
|
2290
2193
|
try {
|
|
2291
2194
|
const contentPrefs = preferences == null ? void 0 : preferences.content;
|
|
2292
2195
|
const lang = ((_b = preferences == null ? void 0 : preferences.localization) == null ? void 0 : _b.language) === "hi" ? "Hindi" : "English";
|
|
2293
|
-
let
|
|
2196
|
+
let titleBuffer = "";
|
|
2197
|
+
let articleBuffer = "";
|
|
2198
|
+
let keywordsBuffer = [];
|
|
2199
|
+
const updateMessage = () => {
|
|
2200
|
+
const structured = buildStructuredContent(titleBuffer, articleBuffer, keywordsBuffer);
|
|
2201
|
+
setMessages(
|
|
2202
|
+
(prev) => prev.map(
|
|
2203
|
+
(m) => m.id === assistantId ? __spreadProps(__spreadValues({}, m), { content: structured }) : m
|
|
2204
|
+
)
|
|
2205
|
+
);
|
|
2206
|
+
};
|
|
2294
2207
|
await rewriteNewsStreamApi({
|
|
2295
2208
|
article: text,
|
|
2296
2209
|
language: lang,
|
|
@@ -2300,30 +2213,58 @@ ${optionsList}`
|
|
|
2300
2213
|
includeQuotes: contentPrefs == null ? void 0 : contentPrefs.includeQuotes,
|
|
2301
2214
|
includeFAQ: contentPrefs == null ? void 0 : contentPrefs.includeFAQ,
|
|
2302
2215
|
targetAudience: contentPrefs == null ? void 0 : contentPrefs.targetAudience,
|
|
2303
|
-
|
|
2304
|
-
|
|
2216
|
+
onFieldStart: (field) => {
|
|
2217
|
+
setActiveField(field);
|
|
2218
|
+
},
|
|
2219
|
+
onContent: (field, chunk) => {
|
|
2220
|
+
if (field === "title") titleBuffer += chunk;
|
|
2221
|
+
else articleBuffer += chunk;
|
|
2222
|
+
updateMessage();
|
|
2223
|
+
},
|
|
2224
|
+
onKeywords: (keywords) => {
|
|
2225
|
+
keywordsBuffer = keywords;
|
|
2226
|
+
updateMessage();
|
|
2227
|
+
},
|
|
2228
|
+
onFieldEnd: () => {
|
|
2229
|
+
setActiveField(null);
|
|
2230
|
+
},
|
|
2231
|
+
onComplete: (data) => {
|
|
2232
|
+
const finalContent = data && (data.title || data.article) ? JSON.stringify(data) : buildStructuredContent(titleBuffer, articleBuffer, keywordsBuffer);
|
|
2305
2233
|
setMessages(
|
|
2306
2234
|
(prev) => prev.map(
|
|
2307
|
-
(m) => m.id === assistantId ? __spreadProps(__spreadValues({}, m), { content:
|
|
2235
|
+
(m) => m.id === assistantId ? __spreadProps(__spreadValues({}, m), { content: finalContent }) : m
|
|
2308
2236
|
)
|
|
2309
2237
|
);
|
|
2310
|
-
},
|
|
2311
|
-
onComplete: () => {
|
|
2312
2238
|
setIsStreaming(false);
|
|
2239
|
+
setActiveField(null);
|
|
2313
2240
|
toast2.success("Content generated!");
|
|
2314
2241
|
},
|
|
2315
2242
|
onError: (error) => {
|
|
2316
2243
|
console.error("Stream error:", error);
|
|
2317
2244
|
setIsStreaming(false);
|
|
2245
|
+
setActiveField(null);
|
|
2318
2246
|
toast2.error("Failed to generate content");
|
|
2319
2247
|
}
|
|
2320
2248
|
});
|
|
2249
|
+
if (isStreaming) {
|
|
2250
|
+
if (titleBuffer || articleBuffer) {
|
|
2251
|
+
const structured = buildStructuredContent(titleBuffer, articleBuffer, keywordsBuffer);
|
|
2252
|
+
setMessages(
|
|
2253
|
+
(prev) => prev.map(
|
|
2254
|
+
(m) => m.id === assistantId ? __spreadProps(__spreadValues({}, m), { content: structured }) : m
|
|
2255
|
+
)
|
|
2256
|
+
);
|
|
2257
|
+
}
|
|
2258
|
+
setIsStreaming(false);
|
|
2259
|
+
setActiveField(null);
|
|
2260
|
+
}
|
|
2321
2261
|
} catch (err) {
|
|
2322
2262
|
console.error("Send message error:", err);
|
|
2323
2263
|
setIsStreaming(false);
|
|
2264
|
+
setActiveField(null);
|
|
2324
2265
|
setMessages(
|
|
2325
2266
|
(prev) => prev.map(
|
|
2326
|
-
(m) => m.id === assistantId ? __spreadProps(__spreadValues({}, m), { content: "
|
|
2267
|
+
(m) => m.id === assistantId ? __spreadProps(__spreadValues({}, m), { content: "Failed to generate content. Please try again." }) : m
|
|
2327
2268
|
)
|
|
2328
2269
|
);
|
|
2329
2270
|
}
|
|
@@ -2337,12 +2278,22 @@ ${optionsList}`
|
|
|
2337
2278
|
setMessages((prev) => [
|
|
2338
2279
|
...prev,
|
|
2339
2280
|
{ id: crypto.randomUUID(), role: "user", content: `Action: ${actionName}` },
|
|
2340
|
-
{ id: assistantId, role: "assistant", content: "
|
|
2281
|
+
{ id: assistantId, role: "assistant", content: "" }
|
|
2341
2282
|
]);
|
|
2342
2283
|
setIsStreaming(true);
|
|
2343
2284
|
try {
|
|
2344
2285
|
const contentPrefs = preferences == null ? void 0 : preferences.content;
|
|
2345
|
-
let
|
|
2286
|
+
let titleBuffer = "";
|
|
2287
|
+
let articleBuffer = "";
|
|
2288
|
+
let keywordsBuffer = [];
|
|
2289
|
+
const updateMessage = () => {
|
|
2290
|
+
const structured = buildStructuredContent(titleBuffer, articleBuffer, keywordsBuffer);
|
|
2291
|
+
setMessages(
|
|
2292
|
+
(prev) => prev.map(
|
|
2293
|
+
(m) => m.id === assistantId ? __spreadProps(__spreadValues({}, m), { content: structured }) : m
|
|
2294
|
+
)
|
|
2295
|
+
);
|
|
2296
|
+
};
|
|
2346
2297
|
try {
|
|
2347
2298
|
await createContentStreamApi({
|
|
2348
2299
|
url,
|
|
@@ -2353,24 +2304,51 @@ ${optionsList}`
|
|
|
2353
2304
|
style: contentPrefs == null ? void 0 : contentPrefs.style,
|
|
2354
2305
|
wordCount: contentPrefs == null ? void 0 : contentPrefs.wordCount
|
|
2355
2306
|
},
|
|
2356
|
-
|
|
2357
|
-
|
|
2307
|
+
onFieldStart: (field) => {
|
|
2308
|
+
setActiveField(field);
|
|
2309
|
+
},
|
|
2310
|
+
onContent: (field, chunk) => {
|
|
2311
|
+
if (field === "title") titleBuffer += chunk;
|
|
2312
|
+
else articleBuffer += chunk;
|
|
2313
|
+
updateMessage();
|
|
2314
|
+
},
|
|
2315
|
+
onKeywords: (keywords) => {
|
|
2316
|
+
keywordsBuffer = keywords;
|
|
2317
|
+
updateMessage();
|
|
2318
|
+
},
|
|
2319
|
+
onFieldEnd: () => {
|
|
2320
|
+
setActiveField(null);
|
|
2321
|
+
},
|
|
2322
|
+
onComplete: (data) => {
|
|
2323
|
+
const finalContent = data && (data.title || data.article) ? JSON.stringify(data) : buildStructuredContent(titleBuffer, articleBuffer, keywordsBuffer);
|
|
2358
2324
|
setMessages(
|
|
2359
2325
|
(prev) => prev.map(
|
|
2360
|
-
(m) => m.id === assistantId ? __spreadProps(__spreadValues({}, m), { content:
|
|
2326
|
+
(m) => m.id === assistantId ? __spreadProps(__spreadValues({}, m), { content: finalContent }) : m
|
|
2361
2327
|
)
|
|
2362
2328
|
);
|
|
2363
|
-
},
|
|
2364
|
-
onComplete: () => {
|
|
2365
2329
|
setIsStreaming(false);
|
|
2330
|
+
setActiveField(null);
|
|
2366
2331
|
toast2.success("Content created!");
|
|
2367
2332
|
},
|
|
2368
2333
|
onError: (error) => {
|
|
2369
2334
|
console.error("Stream error:", error);
|
|
2370
2335
|
setIsStreaming(false);
|
|
2336
|
+
setActiveField(null);
|
|
2371
2337
|
toast2.error("Failed to create content");
|
|
2372
2338
|
}
|
|
2373
2339
|
});
|
|
2340
|
+
if (isStreaming) {
|
|
2341
|
+
if (titleBuffer || articleBuffer) {
|
|
2342
|
+
const structured = buildStructuredContent(titleBuffer, articleBuffer, keywordsBuffer);
|
|
2343
|
+
setMessages(
|
|
2344
|
+
(prev) => prev.map(
|
|
2345
|
+
(m) => m.id === assistantId ? __spreadProps(__spreadValues({}, m), { content: structured }) : m
|
|
2346
|
+
)
|
|
2347
|
+
);
|
|
2348
|
+
}
|
|
2349
|
+
setIsStreaming(false);
|
|
2350
|
+
setActiveField(null);
|
|
2351
|
+
}
|
|
2374
2352
|
} catch (e) {
|
|
2375
2353
|
const result = await createContentApi({ url, content, actionId, settings: {
|
|
2376
2354
|
tone: contentPrefs == null ? void 0 : contentPrefs.tone,
|
|
@@ -2379,25 +2357,27 @@ ${optionsList}`
|
|
|
2379
2357
|
} });
|
|
2380
2358
|
setMessages(
|
|
2381
2359
|
(prev) => prev.map(
|
|
2382
|
-
(m) => m.id === assistantId ? __spreadProps(__spreadValues({}, m), { content: result
|
|
2360
|
+
(m) => m.id === assistantId ? __spreadProps(__spreadValues({}, m), { content: typeof result === "string" ? result : JSON.stringify(result) }) : m
|
|
2383
2361
|
)
|
|
2384
2362
|
);
|
|
2385
2363
|
setIsStreaming(false);
|
|
2364
|
+
setActiveField(null);
|
|
2386
2365
|
toast2.success("Content created!");
|
|
2387
2366
|
}
|
|
2388
2367
|
} catch (err) {
|
|
2389
2368
|
console.error("Create content error:", err);
|
|
2390
2369
|
setIsStreaming(false);
|
|
2370
|
+
setActiveField(null);
|
|
2391
2371
|
setMessages(
|
|
2392
2372
|
(prev) => prev.map(
|
|
2393
|
-
(m) => m.id === assistantId ? __spreadProps(__spreadValues({}, m), { content: "
|
|
2373
|
+
(m) => m.id === assistantId ? __spreadProps(__spreadValues({}, m), { content: "Failed to create content. Please try again." }) : m
|
|
2394
2374
|
)
|
|
2395
2375
|
);
|
|
2396
2376
|
}
|
|
2397
2377
|
};
|
|
2398
2378
|
if (loading) {
|
|
2399
2379
|
return /* @__PURE__ */ jsx11("div", { className: "cnfy-loading", children: /* @__PURE__ */ jsxs8("div", { className: "cnfy-loading-inner", children: [
|
|
2400
|
-
/* @__PURE__ */ jsx11(
|
|
2380
|
+
/* @__PURE__ */ jsx11(Loader22, { className: "cnfy-loading-spinner cnfy-animate-spin" }),
|
|
2401
2381
|
/* @__PURE__ */ jsx11("p", { className: "cnfy-loading-text", children: "Loading..." })
|
|
2402
2382
|
] }) });
|
|
2403
2383
|
}
|
|
@@ -2411,6 +2391,7 @@ ${optionsList}`
|
|
|
2411
2391
|
onSend: handleSendMessage,
|
|
2412
2392
|
onSelectNews: handleRecreate,
|
|
2413
2393
|
isStreaming,
|
|
2394
|
+
activeField,
|
|
2414
2395
|
analyzedData,
|
|
2415
2396
|
onSelectAction: handleSelectAction,
|
|
2416
2397
|
onPost
|