wealth-alpha-chat-widget 1.0.3 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +49 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +83 -37
- package/dist/index.css.map +1 -1
- package/dist/index.mjs +49 -28
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -2
package/dist/index.mjs
CHANGED
|
@@ -677,6 +677,9 @@ function useSession(opts = {}) {
|
|
|
677
677
|
// src/styles/chat.module.css
|
|
678
678
|
var chat_default = {
|
|
679
679
|
root: "chat_root",
|
|
680
|
+
headerTitle: "chat_headerTitle",
|
|
681
|
+
menuItemTitle: "chat_menuItemTitle",
|
|
682
|
+
markdown: "chat_markdown",
|
|
680
683
|
floatingButton: "chat_floatingButton",
|
|
681
684
|
positionRight: "chat_positionRight",
|
|
682
685
|
positionLeft: "chat_positionLeft",
|
|
@@ -684,15 +687,14 @@ var chat_default = {
|
|
|
684
687
|
popupBubbleLeft: "chat_popupBubbleLeft",
|
|
685
688
|
popupBubbleRight: "chat_popupBubbleRight",
|
|
686
689
|
header: "chat_header",
|
|
687
|
-
headerTitle: "chat_headerTitle",
|
|
688
690
|
headerMeta: "chat_headerMeta",
|
|
689
691
|
headerActions: "chat_headerActions",
|
|
690
692
|
iconButton: "chat_iconButton",
|
|
691
693
|
body: "chat_body",
|
|
692
694
|
bubble: "chat_bubble",
|
|
693
|
-
markdown: "chat_markdown",
|
|
694
695
|
bubbleBot: "chat_bubbleBot",
|
|
695
696
|
bubbleUser: "chat_bubbleUser",
|
|
697
|
+
bubbleCard: "chat_bubbleCard",
|
|
696
698
|
bubbleMeta: "chat_bubbleMeta",
|
|
697
699
|
chipRow: "chat_chipRow",
|
|
698
700
|
chip: "chat_chip",
|
|
@@ -720,7 +722,7 @@ var chat_default = {
|
|
|
720
722
|
menuGrid: "chat_menuGrid",
|
|
721
723
|
menuItem: "chat_menuItem",
|
|
722
724
|
menuItemIcon: "chat_menuItemIcon",
|
|
723
|
-
|
|
725
|
+
menuItemSvg: "chat_menuItemSvg",
|
|
724
726
|
menuItemSub: "chat_menuItemSub",
|
|
725
727
|
menuIconGreen: "chat_menuIconGreen",
|
|
726
728
|
menuIconBlue: "chat_menuIconBlue",
|
|
@@ -729,7 +731,8 @@ var chat_default = {
|
|
|
729
731
|
menuIconOrange: "chat_menuIconOrange",
|
|
730
732
|
menuIconGold: "chat_menuIconGold",
|
|
731
733
|
menuIconTeal: "chat_menuIconTeal",
|
|
732
|
-
menuIconPurple: "chat_menuIconPurple"
|
|
734
|
+
menuIconPurple: "chat_menuIconPurple",
|
|
735
|
+
chat_bubbleBot: "chat_chat_bubbleBot"
|
|
733
736
|
};
|
|
734
737
|
function AuthGate({ brandName, loginUrl, onLoginClick }) {
|
|
735
738
|
const handleClick = () => {
|
|
@@ -815,15 +818,21 @@ var SANITIZE_CFG = {
|
|
|
815
818
|
function inlineMarkdownToHtml(text) {
|
|
816
819
|
return text.replace(/^[ \t]*#{1,6}[ \t]+(.+?)[ \t]*$/gm, "<b>$1</b>").replace(/\*\*([^\n<>]+?)\*\*/g, "<b>$1</b>").replace(/__([^\n<>]+?)__/g, "<b>$1</b>").replace(/(?<!\*)\*([^\n*<>]+?)\*(?!\*)/g, "<b>$1</b>").replace(/(?<![_a-zA-Z0-9])_([^\n_<>]+?)_(?![_a-zA-Z0-9])/g, "<i>$1</i>");
|
|
817
820
|
}
|
|
821
|
+
function stripCardDateTime(html) {
|
|
822
|
+
return html.replace(
|
|
823
|
+
/(<span class="wa-card-date">)([^<]*)(<\/span>)/g,
|
|
824
|
+
(_m, open, content, close) => open + content.replace(/,\s*\d{1,2}:\d{2}.*$/, "").trim() + close
|
|
825
|
+
);
|
|
826
|
+
}
|
|
818
827
|
function renderMarkdown(text) {
|
|
819
828
|
if (!text) return "";
|
|
820
829
|
const inlined = inlineMarkdownToHtml(text);
|
|
821
830
|
if (/<div[\s>]/i.test(inlined)) {
|
|
822
|
-
return DOMPurify.sanitize(inlined, SANITIZE_CFG);
|
|
831
|
+
return DOMPurify.sanitize(stripCardDateTime(inlined), SANITIZE_CFG);
|
|
823
832
|
}
|
|
824
833
|
const paragraphs = inlined.split(/\n{2,}/).map((para) => para.replace(/\n/g, "<br>")).filter((p) => p.length > 0);
|
|
825
834
|
const html = paragraphs.length > 1 ? paragraphs.map((p) => `<p>${p}</p>`).join("") : paragraphs[0] ?? "";
|
|
826
|
-
return DOMPurify.sanitize(html, SANITIZE_CFG);
|
|
835
|
+
return DOMPurify.sanitize(stripCardDateTime(html), SANITIZE_CFG);
|
|
827
836
|
}
|
|
828
837
|
var ROOT_MENU_CHIP_IDS = /* @__PURE__ */ new Set([
|
|
829
838
|
"stock_analysis",
|
|
@@ -855,12 +864,23 @@ var MENU_ICON_KEY = {
|
|
|
855
864
|
tradable_picks: "menuIconTeal",
|
|
856
865
|
peer_compare: "menuIconPurple"
|
|
857
866
|
};
|
|
867
|
+
var MENU_ICON_SVG = {
|
|
868
|
+
stock_analysis: ' <path d="M4 16L9 11L13 15L20 8" /> <path d="M20 8V13" /> <path d="M20 8H15" />',
|
|
869
|
+
stock_discovery: '<circle cx="11" cy="11" r="7"/><path d="m21 21-4.3-4.3"/>',
|
|
870
|
+
new_listings: '<rect x="5" y="5" width="14" height="14" rx="3"/><path d="M12 8v8"/> <path d="M8 12h8"/>',
|
|
871
|
+
portfolio_risk: '<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10Z"/>',
|
|
872
|
+
market_forecast: '<path d="M13 2 4 14h7l-1 8 9-12h-7l1-8Z"/>',
|
|
873
|
+
crypto: '<path d="M4 20V10M10 20V4M16 20v-7M22 20v-4"/>',
|
|
874
|
+
tradable_picks: '<circle cx="12" cy="12" r="9"/><circle cx="12" cy="12" r="5"/><circle cx="12" cy="12" r="1.5"/>',
|
|
875
|
+
peer_compare: '<path d="M12 3v18"/><path d="M5 8l-3 6h6z"/><path d="M19 8l-3 6h6z"/>'
|
|
876
|
+
};
|
|
858
877
|
function isRootMenuChips(chips) {
|
|
859
|
-
return chips.
|
|
878
|
+
return chips.length > 0 && chips.every((c) => ROOT_MENU_CHIP_IDS.has(c.id));
|
|
860
879
|
}
|
|
861
880
|
function MessageBubble({ message, onChipClick }) {
|
|
862
881
|
const isBot = message.role === "bot";
|
|
863
|
-
const
|
|
882
|
+
const isCard = isBot && message.content.includes("<div");
|
|
883
|
+
const bubbleClass = isBot ? `${chat_default.bubble} ${isCard ? chat_default.bubbleCard : chat_default.bubbleBot}` : `${chat_default.bubble} ${chat_default.bubbleUser}`;
|
|
864
884
|
const handleMarkdownClick = (e) => {
|
|
865
885
|
const anchor = e.target.closest("a");
|
|
866
886
|
if (!anchor?.href) return;
|
|
@@ -881,6 +901,7 @@ function MessageBubble({ message, onChipClick }) {
|
|
|
881
901
|
showMenuGrid ? /* @__PURE__ */ jsx("div", { className: chat_default.menuGrid, children: chips.map((chip) => {
|
|
882
902
|
const iconKey = MENU_ICON_KEY[chip.id];
|
|
883
903
|
const iconClass = iconKey && chat_default[iconKey] || "";
|
|
904
|
+
const svgIcon = MENU_ICON_SVG[chip.id];
|
|
884
905
|
return /* @__PURE__ */ jsxs(
|
|
885
906
|
"button",
|
|
886
907
|
{
|
|
@@ -888,7 +909,15 @@ function MessageBubble({ message, onChipClick }) {
|
|
|
888
909
|
className: chat_default.menuItem,
|
|
889
910
|
onClick: () => onChipClick(chip),
|
|
890
911
|
children: [
|
|
891
|
-
/* @__PURE__ */ jsx("div", { className: `${chat_default.menuItemIcon} ${iconClass}`, children:
|
|
912
|
+
/* @__PURE__ */ jsx("div", { className: `${chat_default.menuItemIcon} ${iconClass}`, children: svgIcon ? /* @__PURE__ */ jsx(
|
|
913
|
+
"svg",
|
|
914
|
+
{
|
|
915
|
+
className: chat_default.menuItemSvg,
|
|
916
|
+
viewBox: "0 0 24 24",
|
|
917
|
+
"aria-hidden": "true",
|
|
918
|
+
dangerouslySetInnerHTML: { __html: svgIcon }
|
|
919
|
+
}
|
|
920
|
+
) : /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: chip.icon }) }),
|
|
892
921
|
/* @__PURE__ */ jsx("div", { className: chat_default.menuItemTitle, children: chip.label }),
|
|
893
922
|
/* @__PURE__ */ jsx("div", { className: chat_default.menuItemSub, children: MENU_SUBTITLES[chip.id] ?? "" })
|
|
894
923
|
]
|
|
@@ -947,18 +976,6 @@ function ChatBody({
|
|
|
947
976
|
/* @__PURE__ */ jsx("div", { ref: endRef })
|
|
948
977
|
] });
|
|
949
978
|
}
|
|
950
|
-
|
|
951
|
-
// src/utils/time.ts
|
|
952
|
-
function formatCountdown(remainingMs) {
|
|
953
|
-
if (remainingMs <= 0) return "expired";
|
|
954
|
-
const totalSeconds = Math.floor(remainingMs / 1e3);
|
|
955
|
-
const hours = Math.floor(totalSeconds / 3600);
|
|
956
|
-
const minutes = Math.floor(totalSeconds % 3600 / 60);
|
|
957
|
-
const seconds = totalSeconds % 60;
|
|
958
|
-
if (hours > 0) return `${hours}h ${minutes}m left`;
|
|
959
|
-
if (minutes > 0) return `${minutes}m ${seconds}s left`;
|
|
960
|
-
return `${seconds}s left`;
|
|
961
|
-
}
|
|
962
979
|
function ChatHeader({
|
|
963
980
|
brandName,
|
|
964
981
|
remainingMs,
|
|
@@ -967,13 +984,7 @@ function ChatHeader({
|
|
|
967
984
|
onClear
|
|
968
985
|
}) {
|
|
969
986
|
return /* @__PURE__ */ jsxs("div", { className: chat_default.header, children: [
|
|
970
|
-
/* @__PURE__ */
|
|
971
|
-
/* @__PURE__ */ jsx("div", { className: chat_default.headerTitle, children: brandName }),
|
|
972
|
-
showCountdown && remainingMs > 0 ? /* @__PURE__ */ jsxs("div", { className: chat_default.headerMeta, children: [
|
|
973
|
-
"Session: ",
|
|
974
|
-
formatCountdown(remainingMs)
|
|
975
|
-
] }) : null
|
|
976
|
-
] }),
|
|
987
|
+
/* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx("div", { className: chat_default.headerTitle, children: brandName }) }),
|
|
977
988
|
/* @__PURE__ */ jsxs("div", { className: chat_default.headerActions, children: [
|
|
978
989
|
onClear ? /* @__PURE__ */ jsx(
|
|
979
990
|
"button",
|
|
@@ -1130,6 +1141,16 @@ function WealthChat(props) {
|
|
|
1130
1141
|
useEffect(() => {
|
|
1131
1142
|
setMounted(true);
|
|
1132
1143
|
}, []);
|
|
1144
|
+
useEffect(() => {
|
|
1145
|
+
if (typeof document === "undefined") return;
|
|
1146
|
+
const id = "wac-google-fonts";
|
|
1147
|
+
if (document.getElementById(id)) return;
|
|
1148
|
+
const link = document.createElement("link");
|
|
1149
|
+
link.id = id;
|
|
1150
|
+
link.rel = "stylesheet";
|
|
1151
|
+
link.href = "https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700;800&family=Sora:wght@600;700;800&display=swap";
|
|
1152
|
+
document.head.appendChild(link);
|
|
1153
|
+
}, []);
|
|
1133
1154
|
useEffect(() => {
|
|
1134
1155
|
if (!mounted || open || popupShownRef.current) return;
|
|
1135
1156
|
const timer = setTimeout(() => {
|