pager-widget 1.0.11-alpha.9 → 1.0.13

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.
Files changed (79) hide show
  1. package/dist/index.css +1 -1
  2. package/dist/index.html +40 -0
  3. package/dist/index.js +8 -8
  4. package/dist/react-parcel.9f367d21.css +2970 -0
  5. package/dist/react-parcel.9f367d21.css.map +1 -0
  6. package/dist/react-parcel.js +231527 -0
  7. package/dist/react-parcel.js.map +1 -0
  8. package/dist/server.html +33 -39
  9. package/out/AgentFeedbackButtonWrapper.js +15 -0
  10. package/out/App.js +28 -0
  11. package/out/BotMain.js +91 -0
  12. package/out/ButtonsWrapper.js +29 -0
  13. package/out/ChatPage.js +9 -0
  14. package/out/ChatPageContent.js +131 -0
  15. package/out/ChatPageHeader.js +267 -0
  16. package/out/ChatPageInput.js +29 -0
  17. package/out/ChatWidget.js +17 -0
  18. package/out/Consent.js +66 -0
  19. package/out/CountryDropdown.js +31 -0
  20. package/out/Form.js +238 -0
  21. package/out/HomePage.js +11 -0
  22. package/out/HomePageContent.js +32 -0
  23. package/out/HomePageFooter.js +87 -0
  24. package/out/HomePageHeader.js +66 -0
  25. package/out/InputField.js +80 -0
  26. package/out/Markdown.js +126 -0
  27. package/out/Message.js +197 -0
  28. package/out/MessagesT.js +2 -0
  29. package/out/NewRecentMessagePage.js +525 -0
  30. package/out/NewRecentMessageTab.js +23 -0
  31. package/out/ReceivedMessage.js +211 -0
  32. package/out/RecentMessageDetail.js +178 -0
  33. package/out/RecentMessageList.js +112 -0
  34. package/out/RecentMessageListCard.js +20 -0
  35. package/out/RecentMessageListHeader.js +156 -0
  36. package/out/RecentMessagePage.js +183 -0
  37. package/out/RecentMessageTab.js +35 -0
  38. package/out/WidgetMessage.js +14 -0
  39. package/out/WidgetToggleButton.js +191 -0
  40. package/out/WidgetType.js +2 -0
  41. package/out/assets/icons/pikaicons-react.js +17475 -0
  42. package/out/components/ConsentForm.js +7 -0
  43. package/out/components/CustomTooltip.js +34 -0
  44. package/out/hooks/useChatHistoryExists.js +32 -0
  45. package/out/hooks/useChatHistoryListExist.js +81 -0
  46. package/out/hooks/useChatScroll.js +14 -0
  47. package/out/hooks/useCurrentConversationExists.js +88 -0
  48. package/out/hooks/useInitialMessage.js +33 -0
  49. package/out/hooks/useMessage.js +230 -0
  50. package/out/hooks/useMessageReceiver.js +183 -0
  51. package/out/hooks/usePopupAnimation.js +20 -0
  52. package/out/hooks/useSocket.js +19 -0
  53. package/out/hooks/useSocketContext.js +81 -0
  54. package/out/hooks/useWidgetDimension.js +41 -0
  55. package/out/hooks/useWidgetToggle.js +22 -0
  56. package/out/index.js +31 -0
  57. package/out/markdown/CodeCopy.js +22 -0
  58. package/out/markdown/CodeHighlight.js +58 -0
  59. package/out/markdown/PagerMarkdown.js +36 -0
  60. package/out/markdown/pager_md.js +152 -0
  61. package/out/onscreenNotificationPopup.js +23 -0
  62. package/out/socket.js +11 -0
  63. package/out/utils/checkConversationExit.js +24 -0
  64. package/out/utils/convertTime.js +43 -0
  65. package/out/utils/sendInitialMessage.js +82 -0
  66. package/out/widget.js +21 -0
  67. package/out/widgetConfigStore.js +205 -0
  68. package/out/widgetConfigStore2.js +569 -0
  69. package/out/widgetControlstore.js +23 -0
  70. package/out/widgetStateHandler.js +106 -0
  71. package/out/widgetStore.js +171 -0
  72. package/out/widgetUserStore.js +47 -0
  73. package/package.json +3 -3
  74. package/server.html +33 -39
  75. package/.husky/pre-commit +0 -4
  76. package/docs/issues/001-use-widget-resize-hook.md +0 -51
  77. package/docs/issues/002-embed-snippet-container-resize.md +0 -81
  78. package/docs/prd/0001-iframe-resize-scroll-through.md +0 -333
  79. package/test-iframe-resize.html +0 -74
package/out/Form.js ADDED
@@ -0,0 +1,238 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Form = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const widgetConfigStore2_1 = require("./widgetConfigStore2");
7
+ const uuid_1 = require("uuid");
8
+ const InputField_1 = require("./InputField");
9
+ const pikaicons_react_1 = require("./assets/icons/pikaicons-react");
10
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
11
+ const Form = ({ conversationId }) => {
12
+ const widget = (0, widgetConfigStore2_1.useWidgetData)();
13
+ const widgetData = (0, widgetConfigStore2_1.widgetHasData)(widget) ? widget.data : null;
14
+ const [formValues, setFormValues] = (0, react_1.useState)({});
15
+ const [formErrors, setFormErrors] = (0, react_1.useState)({});
16
+ const [isSubmittedFormOpen, setIsSubmittedFormOpen] = (0, react_1.useState)(false);
17
+ const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
18
+ const isUuid = typeof widgetData?.source_id === 'string' &&
19
+ uuidRegex.test(widgetData.source_id);
20
+ console.log('widget status from form', widget);
21
+ (0, react_1.useEffect)(() => {
22
+ if (widget.status === 'FORM_INPUT_NEEDED' && isUuid) {
23
+ console.log('Trigger here');
24
+ widgetConfigStore2_1.widgetFetchStore2.trigger.processMessage();
25
+ }
26
+ if (widget.status === 'FORM_INPUT_NEEDED' && widget.form_data) {
27
+ const localKey = `CONVERSATION::${widget.data.id}`;
28
+ try {
29
+ const existingRaw = localStorage.getItem(localKey);
30
+ const existingData = existingRaw
31
+ ? JSON.parse(existingRaw)
32
+ : {
33
+ widget_id: widget.data.id,
34
+ conversation_id: null,
35
+ user_state: 'FORM_INPUT_NEEDED',
36
+ events: [],
37
+ };
38
+ // ✅ Check if already added to prevent duplicates
39
+ const alreadyExists = existingData.events.some((e) => e.type === 'FORM_INPUT_NEEDED' &&
40
+ e.form_data?.form_id === widget.form_data.form_id);
41
+ if (!alreadyExists) {
42
+ const newEvent = {
43
+ type: 'FORM_INPUT_NEEDED',
44
+ form_data: widget.form_data,
45
+ };
46
+ existingData.events.push(newEvent);
47
+ localStorage.setItem(localKey, JSON.stringify(existingData));
48
+ console.log('✅ FORM_INPUT_NEEDED appended successfully');
49
+ }
50
+ else {
51
+ console.log('ℹ️ FORM_INPUT_NEEDED already present, skipping append.');
52
+ }
53
+ }
54
+ catch (error) {
55
+ console.error('❌ Failed to append FORM_INPUT_NEEDED event:', error);
56
+ }
57
+ }
58
+ }, [widget.status, widget?.form_data, widget.data.id]);
59
+ (0, react_1.useEffect)(() => {
60
+ switch (widget.status) {
61
+ case 'WIDGET_LOADING':
62
+ widgetConfigStore2_1.widgetFetchStore2.trigger.setFetchConfig(widget.config);
63
+ break;
64
+ case 'CONSENT_GIVEN':
65
+ widgetConfigStore2_1.widgetFetchStore2.trigger.shouldShowForm({
66
+ browser_data: widget.browser_data ?? null,
67
+ });
68
+ break;
69
+ case 'WIDGET_LOADED':
70
+ widgetConfigStore2_1.widgetFetchStore2.trigger.shouldShowForm({ browser_data: null });
71
+ break;
72
+ case 'FORM_SUBMITTED':
73
+ widgetConfigStore2_1.widgetFetchStore2.trigger.processMessage();
74
+ break;
75
+ }
76
+ }, [widget.status]);
77
+ if (widget.status !== 'ALLOW_MESSAGE' &&
78
+ widget.status !== 'FORM_INPUT_NEEDED' &&
79
+ widget.status !== 'WIDGET_LOADED' &&
80
+ widget.status !== 'CONSENT_NEEDED' &&
81
+ widget.status !== 'CONSENT_GIVEN' &&
82
+ widget.status !== 'FORM_SUBMITTED') {
83
+ return null;
84
+ }
85
+ // const getFormTemplateFromLocalStorage = () => {
86
+ // const raw = localStorage.getItem(`CONVERSATION_LIST::${widget.data.id}`);
87
+ // if (!raw) {
88
+ // console.warn('No data found in localStorage');
89
+ // return null;
90
+ // }
91
+ // try {
92
+ // const parsed: any = JSON.parse(raw);
93
+ // console.log("parsed event", parsed);
94
+ // const eventsArray = Array.isArray(parsed)
95
+ // ? parsed.reduce<any[]>((acc, item) => {
96
+ // if (item.events && Array.isArray(item.events)) acc.push(...item.events);
97
+ // return acc;
98
+ // }, [])
99
+ // : parsed.events || [];
100
+ // const formInputNeededEvent = eventsArray.find(
101
+ // (e: any) => e.type === "FORM_INPUT_NEEDED"
102
+ // );
103
+ // console.log("form input needed event", formInputNeededEvent);
104
+ // return formInputNeededEvent?.form_data || null;
105
+ // } catch (error) {
106
+ // console.error("Failed to parse localStorage data:", error);
107
+ // return null;
108
+ // }
109
+ // };
110
+ const getFormTemplateFromLocalStorage = () => {
111
+ const raw = localStorage.getItem(`CONVERSATION::${widget.data.id}`);
112
+ if (!raw) {
113
+ console.warn('No data found in localStorage under key "DUMMY"');
114
+ return null;
115
+ }
116
+ try {
117
+ const parsed = JSON.parse(raw);
118
+ console.log('parsed event', parsed);
119
+ const formInputNeededEvent = parsed.events.find((e) => e.type === 'FORM_INPUT_NEEDED');
120
+ console.log('form input needed event', formInputNeededEvent);
121
+ return formInputNeededEvent?.form_data || null;
122
+ }
123
+ catch (error) {
124
+ console.error('Failed to parse localStorage DUMMY data:', error);
125
+ return null;
126
+ }
127
+ };
128
+ const formData = getFormTemplateFromLocalStorage();
129
+ const formTemplate = formData?.form_template ?? []; // ✅ Safely fallback to empty array
130
+ console.log('form template', formTemplate);
131
+ const submittedValueMap = (() => {
132
+ try {
133
+ const raw = localStorage.getItem(`CONVERSATION::${widget.data.id}`);
134
+ if (!raw)
135
+ return {};
136
+ const parsed = JSON.parse(raw);
137
+ const formSubmittedEvent = parsed.events.find((e) => e.type === 'FORM_SUBMITTED');
138
+ const submittedArray = formSubmittedEvent?.submissionPayload?.lead_data?.fields ?? [];
139
+ return submittedArray.reduce((acc, { field_id, value }) => {
140
+ acc[field_id] = value;
141
+ return acc;
142
+ }, {});
143
+ }
144
+ catch (error) {
145
+ console.error('Error parsing submitted data:', error);
146
+ return {};
147
+ }
148
+ })();
149
+ const isFormSubmitted = (() => {
150
+ try {
151
+ const raw = localStorage.getItem(`CONVERSATION::${widget.data.id}`);
152
+ if (!raw)
153
+ return false;
154
+ const parsed = JSON.parse(raw);
155
+ return parsed.events.some((e) => e.type === 'FORM_SUBMITTED');
156
+ }
157
+ catch (error) {
158
+ console.error('Error checking form submission:', error);
159
+ return false;
160
+ }
161
+ })();
162
+ const handleChange = (e) => {
163
+ const { name, value } = e.target;
164
+ setFormValues((prev) => ({ ...prev, [name]: value }));
165
+ setFormErrors((prev) => ({ ...prev, [name]: '' }));
166
+ };
167
+ const validateForm = () => {
168
+ const errors = {};
169
+ formTemplate.forEach((field) => {
170
+ const value = formValues[field.field_id]?.trim() || '';
171
+ if (field.is_mandatory && !value) {
172
+ errors[field.field_id] =
173
+ `${field.dispaly_name || field.name} is required`;
174
+ }
175
+ if (field.field_type === 'email' &&
176
+ value &&
177
+ !emailRegex.test(value)) {
178
+ errors[field.field_id] = 'Please enter a valid email address';
179
+ }
180
+ });
181
+ setFormErrors(errors);
182
+ return Object.keys(errors).length === 0;
183
+ };
184
+ const handleFormSubmission = (e) => {
185
+ e.preventDefault();
186
+ if (!validateForm())
187
+ return;
188
+ const fieldsArray = Object.entries(formValues).map(([field_id, value]) => ({ field_id, value }));
189
+ const submissionPayload = {
190
+ form_id: formData?.form_id ?? '',
191
+ conversation_id: conversationId ?? (0, uuid_1.v4)(),
192
+ lead_data: {
193
+ name: formData?.name ?? '',
194
+ fields: fieldsArray,
195
+ ws: formData?.ws ?? '',
196
+ user_consent: widget.data.user_consent,
197
+ },
198
+ type: 'lead',
199
+ };
200
+ widgetConfigStore2_1.widgetFetchStore2.trigger.processFormSubmission({ submissionPayload });
201
+ const localKey = `form::${widget?.data?.id}::${conversationId}`;
202
+ let existingData = {};
203
+ try {
204
+ const stored = localStorage.getItem(localKey);
205
+ existingData = stored ? JSON.parse(stored) : {};
206
+ }
207
+ catch (err) {
208
+ console.error(`Failed to parse localStorage for ${localKey}`, err);
209
+ }
210
+ existingData[formData?.form_id] = fieldsArray;
211
+ try {
212
+ localStorage.setItem(localKey, JSON.stringify(existingData));
213
+ localStorage.setItem('current_conversation', conversationId);
214
+ }
215
+ catch (err) {
216
+ console.error(`Failed to save form data to ${localKey}`, err);
217
+ }
218
+ };
219
+ const shouldShowForm = (widget.status === 'FORM_INPUT_NEEDED' && !isUuid) ||
220
+ widget.status === 'WIDGET_LOADED' ||
221
+ (widget.status === 'ALLOW_MESSAGE' &&
222
+ conversationId === localStorage.getItem('current_conversation'));
223
+ if (!shouldShowForm)
224
+ return null;
225
+ console.log('should show form ', shouldShowForm, formTemplate, conversationId);
226
+ return ((0, jsx_runtime_1.jsx)("div", { className: "flex flex-col items-start gap-1.5 w-full px-5 animate-slide-in-left", children: (0, jsx_runtime_1.jsx)("div", { className: "flex items-start w-full", children: (0, jsx_runtime_1.jsxs)("div", { className: "flex gap-1.5 items-start w-full rounded-lg overflow-hidden", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex items-center gap-2", children: (0, jsx_runtime_1.jsx)("div", { className: "flex items-start gap-[5px]", children: (0, jsx_runtime_1.jsx)("div", { className: "flex w-[24px] h-[24px] items-center justify-center rounded-full", children: (0, jsx_runtime_1.jsx)("img", { src: widget?.data?.logo_url, className: "w-6 h-6 text-white" }) }) }) }), (0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col items-start gap-2 w-[90%]", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex gap-2 items-baseline pt-0.5", children: (0, jsx_runtime_1.jsx)("div", { className: "font-inter text-sm font-medium text-[#020618]", children: widget?.data?.name }) }), (0, jsx_runtime_1.jsx)("div", { className: "relative mt-[-1.00px] text-sm text-[#020618] w-full", children: isFormSubmitted ? ((0, jsx_runtime_1.jsxs)("div", { className: "py-2.5 px-3.5 flex w-full flex-col items-start gap-4 rounded-lg border border-zinc-200", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 rounded-sm w-full justify-between", children: [(0, jsx_runtime_1.jsxs)("span", { className: "flex gap-1 items-center text-slate-950 text-sm font-regular leading-5", children: ["Form submitted", ' ', (0, jsx_runtime_1.jsx)(pikaicons_react_1.PiCheckTickCircleSolid, { className: "h-[18px] w-[18px] text-green-500" })] }), (0, jsx_runtime_1.jsx)("span", { onClick: () => setIsSubmittedFormOpen(!isSubmittedFormOpen), className: "cursor-pointer text-slate-500 hover:text-slate-700 transition-colors hover:bg-slate-100 rounded-full", children: !isSubmittedFormOpen ? ((0, jsx_runtime_1.jsx)(pikaicons_react_1.PiChevronDownStroke, {})) : ((0, jsx_runtime_1.jsx)(pikaicons_react_1.PiChevronUpStroke, {})) })] }), isSubmittedFormOpen && ((0, jsx_runtime_1.jsx)("div", { className: "flex flex-col items-start gap-4", children: formTemplate.map((input, index) => ((0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col items-start gap-1.5", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-slate-700 text-sm font-medium leading-5", children: input.dispaly_name ||
227
+ input.name }), (0, jsx_runtime_1.jsx)("span", { className: "text-slate-950 text-sm font-regular leading-5", children: formValues[input.field_id] ??
228
+ submittedValueMap[input
229
+ .field_id] ??
230
+ '' })] }, index))) }))] })) : ((0, jsx_runtime_1.jsx)("div", { className: "flex flex-col bg-white w-full gap-2.5 px-3.5 py-2.5 rounded-lg border border-zinc-200", children: (0, jsx_runtime_1.jsxs)("form", { onSubmit: handleFormSubmission, className: "space-y-4 w-full", children: [formTemplate.map((input) => ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsx)(InputField_1.InputField, { input: input, handleChange: handleChange, value: formValues[input.field_id] ??
231
+ submittedValueMap[input.field_id] ??
232
+ '', error: formErrors[input.field_id], disabled: isFormSubmitted }, input.field_id) }))), (0, jsx_runtime_1.jsx)("button", { type: "submit", className: `${!isFormSubmitted
233
+ ? 'hover:bg-[#4b2fff]/90'
234
+ : 'opacity-50'} w-full text-sm bg-[#4b2fff] text-white cursor-pointer font-medium py-2 px-4 rounded-lg transition-colors`, disabled: isFormSubmitted, children: isFormSubmitted
235
+ ? 'Submitted'
236
+ : 'Submit' })] }) })) })] })] }) }) }));
237
+ };
238
+ exports.Form = Form;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HomePage = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const HomePageContent_1 = require("./HomePageContent");
6
+ const HomePageFooter_1 = require("./HomePageFooter");
7
+ const HomePageHeader_1 = require("./HomePageHeader");
8
+ const HomePage = ({ toggleWidget, switchTab, isExpanded, }) => {
9
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(HomePageHeader_1.HomePageHeader, { toggleWidget: toggleWidget }), (0, jsx_runtime_1.jsxs)("div", { className: "flex flex-1 flex-col justify-between", children: [(0, jsx_runtime_1.jsx)(HomePageContent_1.HomePageContent, {}), (0, jsx_runtime_1.jsx)(HomePageFooter_1.HomePageFooter, { switchTab: switchTab, isExpanded: isExpanded })] })] }));
10
+ };
11
+ exports.HomePage = HomePage;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HomePageContent = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const widgetConfigStore2_1 = require("./widgetConfigStore2");
7
+ const RecentMessageTab_1 = require("./RecentMessageTab");
8
+ const BotMain_1 = require("./BotMain");
9
+ const widgetStore_1 = require("./widgetStore");
10
+ // import { NewRecentMessageTab } from './NewRecentMessageTab'
11
+ // import { setWidgetLocalState } from './widgetStateHandler'
12
+ const HomePageContent = () => {
13
+ const widget = (0, widgetConfigStore2_1.useWidgetData)();
14
+ const [isHovered, setIsHovered] = (0, react_1.useState)(false);
15
+ return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsxs)("div", { className: "p-5 ", children: [(0, jsx_runtime_1.jsx)(RecentMessageTab_1.RecentMessageTab, {}), (0, jsx_runtime_1.jsx)("div", { className: "flex flex-col gap-2 mt-2", children: (0, jsx_runtime_1.jsxs)("button", { className: `flex w-full items-center justify-between rounded-xl pl-5 pr-4 py-[13px] text-sm font-medium text-slate-950 cursor-pointer`, onClick: () => {
16
+ localStorage.setItem('Tab', 'Chat');
17
+ widgetStore_1.widgetStore.trigger.selectTab({ tab: BotMain_1.TabType.CHAT });
18
+ widgetStore_1.widgetStore.send({
19
+ type: 'handleExitChatState',
20
+ value: false,
21
+ });
22
+ }, onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false), style: {
23
+ border: `1px solid ${isHovered
24
+ ? widget?.data?.brand_color
25
+ : '#e4e4e7'}`,
26
+ }, children: [(0, jsx_runtime_1.jsx)("span", { className: "self-stretch mt-[-1.00px] text-sm text-[#020618]", children: widget?.data?.send_message_description }), (0, jsx_runtime_1.jsx)("svg", { style: {
27
+ color: isHovered
28
+ ? widget?.data?.brand_color
29
+ : '#b8b8b8',
30
+ }, width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: (0, jsx_runtime_1.jsx)("path", { d: "M9 18l6-6-6-6" }) })] }) })] }) }));
31
+ };
32
+ exports.HomePageContent = HomePageContent;
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.HomePageFooter = void 0;
7
+ const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const react_1 = __importDefault(require("react"));
9
+ const pikaicons_react_1 = require("./assets/icons/pikaicons-react");
10
+ const BotMain_1 = require("./BotMain");
11
+ const widgetStore_1 = require("./widgetStore");
12
+ const widgetConfigStore2_1 = require("./widgetConfigStore2");
13
+ const CustomTooltip_1 = require("./components/CustomTooltip");
14
+ const HomePageFooter = ({ switchTab, isExpanded, }) => {
15
+ const widget = (0, widgetConfigStore2_1.useWidgetData)();
16
+ const [isHomeHovered, setIsHomeHovered] = react_1.default.useState(false);
17
+ const [isRecentHovered, setIsRecentHovered] = react_1.default.useState(false);
18
+ // if (
19
+ // !(
20
+ // status !== 'NOT_STARTED' &&
21
+ // status !== 'WIDGET_LOADING' &&
22
+ // status !== 'INVALID_STATE' &&
23
+ // status !== 'ALLOW_MESSAGE'
24
+ // )
25
+ // ) {
26
+ // return null
27
+ // }
28
+ function hexToRGB(hex) {
29
+ hex = hex.replace(/^#/, '');
30
+ if (hex.length === 3) {
31
+ hex = hex
32
+ .split('')
33
+ .map((c) => c + c)
34
+ .join('');
35
+ }
36
+ const bigint = parseInt(hex, 16);
37
+ const r = (bigint >> 16) & 255;
38
+ const g = (bigint >> 8) & 255;
39
+ const b = bigint & 255;
40
+ return `rgb(${r}, ${g}, ${b}, 0.1)`;
41
+ }
42
+ const handleHomeButtonClick = () => {
43
+ if (isExpanded !== widgetStore_1.WidgetExpandType.DEFAULT) {
44
+ widgetStore_1.widgetStore.trigger.expandWidget({
45
+ expanded_size: widgetStore_1.WidgetExpandType.DEFAULT,
46
+ });
47
+ setTimeout(() => {
48
+ widgetStore_1.widgetStore.trigger.selectTab({ tab: BotMain_1.TabType.HOME });
49
+ }, 300);
50
+ }
51
+ else {
52
+ widgetStore_1.widgetStore.trigger.selectTab({ tab: BotMain_1.TabType.HOME });
53
+ }
54
+ };
55
+ const widgetData = (0, widgetConfigStore2_1.widgetHasData)(widget) ? widget.data : null;
56
+ return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-center gap-10 border-t border-zinc-200 bg-white px-8 py-3 z-50", children: [(0, jsx_runtime_1.jsx)(CustomTooltip_1.CustomTooltip, { content: "Home", children: (0, jsx_runtime_1.jsx)("button", { className: "rounded-lg cursor-pointer p-1.5", onMouseEnter: () => setIsHomeHovered(true), onMouseLeave: () => setIsHomeHovered(false), onClick: () => handleHomeButtonClick(), style: {
57
+ background: switchTab == 'home'
58
+ ? widgetData?.brand_color
59
+ ? hexToRGB(widgetData?.brand_color)
60
+ : '#EBEFFF'
61
+ : '',
62
+ color: switchTab == 'home' || isHomeHovered
63
+ ? widgetData?.brand_color
64
+ ? widgetData?.brand_color
65
+ : '#45556c'
66
+ : '#62748e',
67
+ }, children: switchTab == 'home' ? ((0, jsx_runtime_1.jsx)(pikaicons_react_1.PiHomeAltSolid, { style: {
68
+ color: widgetData?.brand_color ?? '#564CFF',
69
+ } })) : ((0, jsx_runtime_1.jsx)(pikaicons_react_1.PiHomeAltStroke, {})) }) }), (0, jsx_runtime_1.jsx)(CustomTooltip_1.CustomTooltip, { content: "Recent chats", children: (0, jsx_runtime_1.jsx)("button", { className: "rounded-lg cursor-pointer p-1.5", onMouseEnter: () => setIsRecentHovered(true), onMouseLeave: () => setIsRecentHovered(false), onClick: () => widgetStore_1.widgetStore.trigger.selectTab({
70
+ tab: BotMain_1.TabType.RECENT_MESSAGE_LIST,
71
+ }), style: {
72
+ background: switchTab == 'recentMessageList'
73
+ ? widgetData?.brand_color
74
+ ? hexToRGB(widgetData?.brand_color)
75
+ : '#EBEFFF'
76
+ : '',
77
+ color: switchTab == 'recentMessageList' ||
78
+ isRecentHovered
79
+ ? widgetData?.brand_color
80
+ ? widgetData?.brand_color
81
+ : '#45556c'
82
+ : '#62748e',
83
+ }, children: switchTab == 'recentMessageList' ? ((0, jsx_runtime_1.jsx)(pikaicons_react_1.PiChatDefaultSolid, { style: {
84
+ color: widgetData?.brand_color ?? '#564CFF',
85
+ } })) : ((0, jsx_runtime_1.jsx)(pikaicons_react_1.PiChatDefaultStroke, {})) }) })] }) }));
86
+ };
87
+ exports.HomePageFooter = HomePageFooter;
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HomePageHeader = exports.isDarkColor = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const widgetConfigStore2_1 = require("./widgetConfigStore2");
6
+ /**
7
+ * Determines if a color is "dark" or "light" based on its perceived brightness.
8
+ * @param color The color string in hex (e.g., #RRGGBB, #RGB) or RGB (e.g., rgb(r, g, b)) format.
9
+ * @returns 'dark' or 'light'. Returns 'light' for null or unsupported formats.
10
+ */
11
+ // TODO : Needs to be Verified
12
+ const isDarkColor = (color) => {
13
+ let r;
14
+ let g;
15
+ let b;
16
+ if (color?.startsWith('#')) {
17
+ let hex = color.slice(1);
18
+ if (hex.length === 3) {
19
+ hex = hex
20
+ .split('')
21
+ .map((c) => c + c)
22
+ .join('');
23
+ }
24
+ if (hex.length === 6) {
25
+ const bigint = parseInt(hex, 16);
26
+ r = (bigint >> 16) & 255;
27
+ g = (bigint >> 8) & 255;
28
+ b = bigint & 255;
29
+ }
30
+ }
31
+ else if (color?.startsWith('rgb')) {
32
+ const rgbValues = color.match(/\d+/g);
33
+ if (rgbValues && rgbValues.length >= 3) {
34
+ ;
35
+ [r, g, b] = rgbValues.map(Number);
36
+ }
37
+ }
38
+ if (r === undefined || g === undefined || b === undefined) {
39
+ return 'light';
40
+ }
41
+ // --- Improved brightness formula (HSP model) ---
42
+ const brightness = Math.sqrt(0.299 * (r * r) + 0.587 * (g * g) + 0.114 * (b * b));
43
+ // --- Increased threshold for detecting “light” colors ---
44
+ return brightness < 170 ? 'dark' : 'light';
45
+ };
46
+ exports.isDarkColor = isDarkColor;
47
+ const HomePageHeader = ({ toggleWidget, }) => {
48
+ const widget = (0, widgetConfigStore2_1.useWidgetData)();
49
+ const { status } = widget;
50
+ if (!(status !== 'NOT_STARTED' &&
51
+ status !== 'WIDGET_LOADING' &&
52
+ status !== 'INVALID_STATE')) {
53
+ return null;
54
+ }
55
+ return ((0, jsx_runtime_1.jsxs)("div", { className: `relative h-[40%] w-full rounded-[22px] ${widget?.data?.welcome_text_color && (0, exports.isDarkColor)(widget?.data?.welcome_text_color) == 'light' ? 'bg-widget-home-light-top' : 'bg-widget-home-dark-top'}`, children: [(0, jsx_runtime_1.jsx)("div", { className: "absolute top-0 left-0 w-full h-full rounded-[22px]", style: { backgroundColor: widget.data?.home_background_color }, children: (0, jsx_runtime_1.jsx)("div", { className: "absolute top-0 left-0 w-full h-full z-[0] rounded-[22px] opacity-90", style: {
56
+ backgroundImage: `url(${widget.data?.home_cover_image})`,
57
+ backgroundSize: 'cover',
58
+ backgroundPosition: 'center',
59
+ backgroundRepeat: 'no-repeat',
60
+ }, children: (0, jsx_runtime_1.jsx)("button", { className: "absolute top-6 right-6 hover:bg-white/10 rounded-lg p-1.5 cursor-pointer flex items-start h-max", style: { mixBlendMode: 'difference' }, onClick: toggleWidget, children: (0, jsx_runtime_1.jsx)("svg", { style: {
61
+ mixBlendMode: 'difference',
62
+ }, width: "20", height: "20", viewBox: "0 0 24 24", stroke: "white", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: (0, jsx_runtime_1.jsx)("path", { d: "M18 6L6 18M6 6l12 12" }) }) }) }) }), (0, jsx_runtime_1.jsx)("div", { className: "flex justify-start p-6 z-10 absolute w-2/3", children: (0, jsx_runtime_1.jsx)("img", { className: "h-[32] w-auto cursor-pointer", src: widget?.data?.home_header_logo }) }), (0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col absolute bottom-[1.2rem] left-[1.5rem]", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-2xl font-semibold leading-8 ", style: { color: widget?.data?.welcome_text_color }, children: widget?.data?.home_header_title }), (0, jsx_runtime_1.jsx)("span", { className: "text-base font-medium leading-6", style: {
63
+ color: widget?.data?.welcome_text_color,
64
+ }, children: widget?.data?.home_header_description })] })] }));
65
+ };
66
+ exports.HomePageHeader = HomePageHeader;
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InputField = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const country_codes_flags_phone_codes_1 = require("country-codes-flags-phone-codes");
6
+ const CountryDropdown_1 = require("./CountryDropdown");
7
+ const InputField = ({ input, handleChange, value, error, disabled, }) => {
8
+ // const [selectedCountry, setSelectedCountry] = useState(value||"");
9
+ if (input.field_type === 'short_text' || input.field_type === 'email') {
10
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "w-full", children: [(0, jsx_runtime_1.jsx)("label", { htmlFor: input.name, className: "block text-sm font-medium text-gray-700 mb-1", children: input.dispaly_name ? input.dispaly_name : input.name }), (0, jsx_runtime_1.jsx)("input", { type: input.field_type === 'short_text' ||
11
+ input.field_type === 'email'
12
+ ? 'text'
13
+ : input.field_type, id: input._id, name: input.field_id, value: value, onChange: handleChange, formNoValidate: true, placeholder: input.placeholder, disabled: disabled, className: `w-full px-4 py-2 h-9 text-sm rounded-lg border ${disabled ? 'text-slate-400 border-zinc-200 bg-zinc-50' : 'bg-white'} ${error
14
+ ? 'border-red-500 focus:ring-red-500'
15
+ : 'border-gray-300 focus:ring-blue-500'} focus:outline-none focus:ring-2 focus:border-transparent` }), error && (0, jsx_runtime_1.jsx)("p", { className: "text-red-500 text-xs mt-1", children: error })] }));
16
+ }
17
+ else if (input.field_type === 'country') {
18
+ return ((0, jsx_runtime_1.jsx)(CountryDropdown_1.CountryDropdown, { disabled: disabled, countries: country_codes_flags_phone_codes_1.countries, value: value, onChange: (selectedValue) => {
19
+ const syntheticEvent = {
20
+ target: {
21
+ name: input.field_id,
22
+ value: selectedValue,
23
+ },
24
+ };
25
+ handleChange(syntheticEvent);
26
+ } })
27
+ // <CountryDropdown countries={countries}
28
+ // value={selectedCountry}
29
+ // />
30
+ // <div className="w-full">
31
+ // <label
32
+ // htmlFor={input.field_id}
33
+ // className="block text-sm font-medium text-gray-700 mb-1"
34
+ // >
35
+ // {input.display_name || 'Country'}
36
+ // </label>
37
+ // <select
38
+ // id={input._id}
39
+ // name={input.field_id}
40
+ // value={value}
41
+ // onChange={(e) =>
42
+ // handleChange(
43
+ // e as unknown as React.ChangeEvent<HTMLInputElement>
44
+ // )
45
+ // }
46
+ // className={`w-full px-2 py-2 h-9 text-sm rounded-lg border ${
47
+ // error
48
+ // ? 'border-red-500 focus:ring-red-500'
49
+ // : 'border-gray-300 focus:ring-blue-500'
50
+ // } focus:outline-none focus:ring-2 focus:border-transparent bg-white`}
51
+ // >
52
+ // <option
53
+ // value=""
54
+ // disabled
55
+ // className="bg-[red] mt-10 text-[#fff]"
56
+ // >
57
+ // {input.placeholder || 'Select a country'}
58
+ // </option>
59
+ // {countries.map((c) => (
60
+ // <option key={c.code} value={c.name}>
61
+ // {c.name}
62
+ // </option>
63
+ // ))}
64
+ // </select>
65
+ // {error && <p className="text-red-500 text-xs mt-1">{error}</p>}
66
+ // </div>
67
+ );
68
+ }
69
+ else if (input.field_type === 'long_text') {
70
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("label", { htmlFor: input.name, className: "block text-sm font-medium text-gray-700 mb-1", children: input.dispaly_name ? input.dispaly_name : input.name }), (0, jsx_runtime_1.jsx)("textarea", { name: input.field_id, value: value, className: `w-full px-4 py-2 h-32 text-sm rounded-lg border ${disabled ? 'text-slate-400 border-zinc-200 bg-zinc-50' : 'bg-white'} ${error
71
+ ? 'border-red-500 focus:ring-red-500'
72
+ : 'border-gray-300 focus:ring-blue-500'} focus:outline-none focus:ring-2 focus:border-transparent`, onChange: handleChange }), error && (0, jsx_runtime_1.jsx)("p", { className: "text-red-500 text-xs mt-1", children: error })] }));
73
+ }
74
+ else if (input.field_type === 'phone_number') {
75
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "w-full", children: [(0, jsx_runtime_1.jsx)("label", { htmlFor: input.name, className: "block text-sm font-medium text-gray-700 mb-1", children: input.dispaly_name ? input.dispaly_name : input.name }), (0, jsx_runtime_1.jsx)("input", { id: input._id, name: input.field_id, value: value, onChange: handleChange, formNoValidate: true, placeholder: input.placeholder, disabled: disabled, maxLength: 15, className: `w-full px-4 py-2 h-9 text-sm rounded-lg border ${disabled ? 'text-slate-400 border-zinc-200 bg-zinc-50' : 'bg-white'} ${error
76
+ ? 'border-red-500 focus:ring-red-500'
77
+ : 'border-gray-300 focus:ring-blue-500'} focus:outline-none focus:ring-2 focus:border-transparent` }), error && (0, jsx_runtime_1.jsx)("p", { className: "text-red-500 text-xs mt-1", children: error })] }));
78
+ }
79
+ };
80
+ exports.InputField = InputField;