@synchat/webchat 0.0.19 → 0.0.21

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.mjs CHANGED
@@ -1,11 +1,11 @@
1
- import { styled, Button, IconButton, Box, Typography, CircularProgress, TextField } from '@mui/material';
1
+ import { styled, Button, Box, IconButton, Typography, CircularProgress, TextField } from '@mui/material';
2
2
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
- import { useState, useCallback, useEffect } from 'react';
4
- import CloseIcon from '@mui/icons-material/Close';
5
3
  import ChatIcon from '@mui/icons-material/Chat';
4
+ import CloseIcon from '@mui/icons-material/Close';
6
5
  import ScheduleIcon from '@mui/icons-material/Schedule';
6
+ import { useState, useCallback, useEffect } from 'react';
7
7
 
8
- // src/lib/components/button/styles.tsx
8
+ // src/lib/components/atoms/button/styles.tsx
9
9
  var AtomButton = styled(Button, {
10
10
  shouldForwardProp: (prop) => prop !== "buttonType"
11
11
  })(({ buttonType = "default" }) => {
@@ -33,6 +33,251 @@ var ChatButton = ({ children = "Chat", onClick, className, disabled }) => {
33
33
  }
34
34
  );
35
35
  };
36
+ var FabIconButton = ({
37
+ bgColor,
38
+ hoverColor,
39
+ children,
40
+ sx,
41
+ ...rest
42
+ }) => /* @__PURE__ */ jsx(
43
+ IconButton,
44
+ {
45
+ size: "large",
46
+ sx: {
47
+ width: 56,
48
+ height: 56,
49
+ bgcolor: bgColor,
50
+ color: "white",
51
+ "&:hover": { bgcolor: hoverColor },
52
+ boxShadow: 2,
53
+ ...sx
54
+ },
55
+ ...rest,
56
+ children
57
+ }
58
+ );
59
+ var Spinner = ({ size = 32 }) => /* @__PURE__ */ jsx(Box, { display: "flex", justifyContent: "center", py: 3, children: /* @__PURE__ */ jsx(CircularProgress, { size }) });
60
+ var FabTrigger = ({
61
+ onClick,
62
+ bgColor,
63
+ hoverColor
64
+ }) => /* @__PURE__ */ jsx(
65
+ FabIconButton,
66
+ {
67
+ onClick,
68
+ bgColor,
69
+ hoverColor,
70
+ sx: { position: "fixed", bottom: 20, right: 20 },
71
+ children: /* @__PURE__ */ jsx(ChatIcon, {})
72
+ }
73
+ );
74
+ var PanelHeader = ({ title, onClose }) => /* @__PURE__ */ jsxs(
75
+ Box,
76
+ {
77
+ sx: {
78
+ display: "flex",
79
+ alignItems: "center",
80
+ justifyContent: "space-between",
81
+ p: 1.5,
82
+ borderBottom: 1,
83
+ borderColor: "divider"
84
+ },
85
+ children: [
86
+ /* @__PURE__ */ jsx(Typography, { variant: "subtitle1", fontWeight: 600, children: title }),
87
+ /* @__PURE__ */ jsx(IconButton, { size: "small", onClick: onClose, "aria-label": "Fechar", children: /* @__PURE__ */ jsx(CloseIcon, {}) })
88
+ ]
89
+ }
90
+ );
91
+ var OutOfHoursCard = ({
92
+ message,
93
+ bgColor
94
+ }) => /* @__PURE__ */ jsxs(
95
+ Box,
96
+ {
97
+ sx: {
98
+ textAlign: "center",
99
+ py: 2,
100
+ px: 1,
101
+ bgcolor: bgColor,
102
+ borderRadius: 1,
103
+ color: "white"
104
+ },
105
+ children: [
106
+ /* @__PURE__ */ jsx(ScheduleIcon, { sx: { fontSize: 48, opacity: 0.9, mb: 1 } }),
107
+ /* @__PURE__ */ jsx(Typography, { variant: "body1", sx: { fontWeight: 500, mb: 1 }, children: "Fora do hor\xE1rio de atendimento" }),
108
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", sx: { opacity: 0.95 }, children: message })
109
+ ]
110
+ }
111
+ );
112
+ var ChatForm = ({
113
+ value,
114
+ onChange,
115
+ onSubmit,
116
+ submitting,
117
+ submitLabel = "Iniciar chat"
118
+ }) => /* @__PURE__ */ jsx("form", { onSubmit, children: /* @__PURE__ */ jsxs(Box, { display: "flex", flexDirection: "column", gap: 2, children: [
119
+ /* @__PURE__ */ jsx(
120
+ TextField,
121
+ {
122
+ label: "Nome",
123
+ value: value.name,
124
+ onChange: (e) => onChange({ ...value, name: e.target.value }),
125
+ required: true,
126
+ fullWidth: true,
127
+ size: "small"
128
+ }
129
+ ),
130
+ /* @__PURE__ */ jsx(
131
+ TextField,
132
+ {
133
+ label: "E-mail",
134
+ type: "email",
135
+ value: value.email,
136
+ onChange: (e) => onChange({ ...value, email: e.target.value }),
137
+ fullWidth: true,
138
+ size: "small"
139
+ }
140
+ ),
141
+ /* @__PURE__ */ jsx(
142
+ TextField,
143
+ {
144
+ label: "Telefone",
145
+ value: value.phone,
146
+ onChange: (e) => onChange({ ...value, phone: e.target.value }),
147
+ fullWidth: true,
148
+ size: "small"
149
+ }
150
+ ),
151
+ /* @__PURE__ */ jsx(
152
+ TextField,
153
+ {
154
+ label: "Mensagem",
155
+ value: value.message,
156
+ onChange: (e) => onChange({ ...value, message: e.target.value }),
157
+ multiline: true,
158
+ rows: 3,
159
+ fullWidth: true,
160
+ size: "small"
161
+ }
162
+ ),
163
+ /* @__PURE__ */ jsx(
164
+ Button,
165
+ {
166
+ type: "submit",
167
+ variant: "contained",
168
+ disabled: submitting || !value.name.trim(),
169
+ fullWidth: true,
170
+ children: submitting ? "Enviando\u2026" : submitLabel
171
+ }
172
+ )
173
+ ] }) });
174
+
175
+ // src/lib/components/organisms/webchat/constants.ts
176
+ var DEFAULT_PRIMARY_COLOR = "#0D9488";
177
+ var DEFAULT_PRIMARY_COLOR_HOVER = "#0F766E";
178
+ var DEFAULT_API_BASE_URL = "https://api.synchat.com.br";
179
+ var ChatPanelContent = ({
180
+ state,
181
+ errorMessage,
182
+ outOfHoursMessage,
183
+ outOfHoursBgColor,
184
+ formValue,
185
+ onFormChange,
186
+ onFormSubmit,
187
+ submitting
188
+ }) => /* @__PURE__ */ jsxs(Box, { sx: { p: 2, flex: 1 }, children: [
189
+ state === "loading" && /* @__PURE__ */ jsx(Spinner, {}),
190
+ state === "error" && errorMessage && /* @__PURE__ */ jsx(Typography, { color: "error", variant: "body2", children: errorMessage }),
191
+ state === "inactive" && /* @__PURE__ */ jsx(Typography, { color: "text.secondary", variant: "body2", children: "Este canal n\xE3o est\xE1 dispon\xEDvel no momento." }),
192
+ state === "outOfHours" && /* @__PURE__ */ jsx(OutOfHoursCard, { message: outOfHoursMessage, bgColor: outOfHoursBgColor }),
193
+ state === "form" && /* @__PURE__ */ jsx(
194
+ ChatForm,
195
+ {
196
+ value: formValue,
197
+ onChange: onFormChange,
198
+ onSubmit: onFormSubmit,
199
+ submitting
200
+ }
201
+ ),
202
+ state === "submitted" && /* @__PURE__ */ jsx(Typography, { color: "text.secondary", variant: "body2", sx: { py: 2 }, children: "Sua mensagem foi enviada. Em breve um atendente responder\xE1." })
203
+ ] });
204
+ var ChatPanel = ({
205
+ open,
206
+ title,
207
+ onClose,
208
+ contentState,
209
+ errorMessage,
210
+ outOfHoursMessage,
211
+ primaryColor,
212
+ formValue,
213
+ onFormChange,
214
+ onFormSubmit,
215
+ submitting
216
+ }) => {
217
+ if (!open) return null;
218
+ return /* @__PURE__ */ jsxs(
219
+ Box,
220
+ {
221
+ sx: {
222
+ position: "fixed",
223
+ bottom: 90,
224
+ right: 20,
225
+ width: 380,
226
+ maxWidth: "calc(100vw - 40px)",
227
+ maxHeight: "calc(100vh - 120px)",
228
+ overflow: "auto",
229
+ bgcolor: "background.paper",
230
+ borderRadius: 2,
231
+ boxShadow: 6,
232
+ zIndex: 1300,
233
+ display: "flex",
234
+ flexDirection: "column"
235
+ },
236
+ children: [
237
+ /* @__PURE__ */ jsx(PanelHeader, { title, onClose }),
238
+ /* @__PURE__ */ jsx(
239
+ ChatPanelContent,
240
+ {
241
+ state: contentState,
242
+ errorMessage,
243
+ outOfHoursMessage,
244
+ outOfHoursBgColor: primaryColor,
245
+ formValue,
246
+ onFormChange,
247
+ onFormSubmit,
248
+ submitting
249
+ }
250
+ )
251
+ ]
252
+ }
253
+ );
254
+ };
255
+ var WebChatLayout = (props) => /* @__PURE__ */ jsxs(Fragment, { children: [
256
+ /* @__PURE__ */ jsx(
257
+ FabTrigger,
258
+ {
259
+ onClick: props.onToggleOpen,
260
+ bgColor: props.primaryColor,
261
+ hoverColor: props.hoverColor
262
+ }
263
+ ),
264
+ /* @__PURE__ */ jsx(
265
+ ChatPanel,
266
+ {
267
+ open: props.open,
268
+ title: props.panelTitle,
269
+ onClose: props.onToggleOpen,
270
+ contentState: props.contentState,
271
+ errorMessage: props.errorMessage,
272
+ outOfHoursMessage: props.outOfHoursMessage,
273
+ primaryColor: props.primaryColor,
274
+ formValue: props.formValue,
275
+ onFormChange: props.onFormChange,
276
+ onFormSubmit: props.onFormSubmit,
277
+ submitting: props.submitting
278
+ }
279
+ )
280
+ ] });
36
281
  var DAY_MAP = {
37
282
  0: "SUNDAY",
38
283
  1: "MONDAY",
@@ -74,12 +319,30 @@ function formatScheduleMessage(config) {
74
319
  const weEnd = config.schedule.weekendEnd ?? "13:00";
75
320
  return `Nosso hor\xE1rio de atendimento \xE9 de segunda \xE0 sexta-feira das ${wdStart}h \xE0s ${wdEnd}h. S\xE1bados, domingos e feriados das ${weStart}h \xE0s ${weEnd}h.`;
76
321
  }
77
- var WebChat = ({
78
- secret,
322
+ function parseColor(color) {
323
+ if (!color || !color.trim()) {
324
+ return { main: DEFAULT_PRIMARY_COLOR, hover: DEFAULT_PRIMARY_COLOR_HOVER };
325
+ }
326
+ const c = color.trim();
327
+ if (c.startsWith("#") && c.length === 7) {
328
+ const hex = c.slice(1);
329
+ const r = Math.max(0, parseInt(hex.slice(0, 2), 16) - 18);
330
+ const g = Math.max(0, parseInt(hex.slice(2, 4), 16) - 18);
331
+ const b = Math.max(0, parseInt(hex.slice(4, 6), 16) - 18);
332
+ const hover = `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`;
333
+ return { main: c, hover };
334
+ }
335
+ return { main: c, hover: c };
336
+ }
337
+ var WebChatPage = ({
338
+ token,
79
339
  apiBaseUrl,
340
+ primaryColor,
80
341
  onStartChat,
81
342
  outOfHoursMessage
82
343
  }) => {
344
+ const baseUrl = apiBaseUrl?.trim() || DEFAULT_API_BASE_URL;
345
+ const colors = parseColor(primaryColor);
83
346
  const [config, setConfig] = useState(null);
84
347
  const [loading, setLoading] = useState(true);
85
348
  const [error, setError] = useState(null);
@@ -93,12 +356,12 @@ var WebChat = ({
93
356
  message: ""
94
357
  });
95
358
  const fetchConfig = useCallback(async () => {
96
- if (!secret || !apiBaseUrl) return;
359
+ if (!token) return;
97
360
  setLoading(true);
98
361
  setError(null);
99
362
  try {
100
- const base = apiBaseUrl.replace(/\/$/, "");
101
- const res = await fetch(`${base}/channel/webchat/${encodeURIComponent(secret)}`);
363
+ const base = baseUrl.replace(/\/$/, "");
364
+ const res = await fetch(`${base}/channel/webchat/${encodeURIComponent(token)}`);
102
365
  if (!res.ok) {
103
366
  setError("Canal n\xE3o encontrado.");
104
367
  setConfig(null);
@@ -112,7 +375,7 @@ var WebChat = ({
112
375
  } finally {
113
376
  setLoading(false);
114
377
  }
115
- }, [secret, apiBaseUrl]);
378
+ }, [token, baseUrl]);
116
379
  useEffect(() => {
117
380
  fetchConfig();
118
381
  }, [fetchConfig]);
@@ -120,11 +383,14 @@ var WebChat = ({
120
383
  const outsideHours = config && config.restrictBySchedule && !isWithinSchedule(config);
121
384
  const showOutOfHours = isActive && outsideHours;
122
385
  const showForm = isActive && !outsideHours;
386
+ const contentState = loading ? "loading" : error ? "error" : config && !isActive ? "inactive" : showOutOfHours ? "outOfHours" : showForm && !submitted ? "form" : "submitted";
123
387
  const handleSubmit = async (e) => {
124
388
  e.preventDefault();
125
389
  if (submitting || !form.name.trim()) return;
126
390
  if (!onStartChat) {
127
- setError("In\xEDcio de conversa ser\xE1 via WebSocket. Configure onStartChat no componente.");
391
+ setError(
392
+ "In\xEDcio de conversa ser\xE1 via WebSocket. Configure onStartChat no componente."
393
+ );
128
394
  return;
129
395
  }
130
396
  setSubmitting(true);
@@ -133,7 +399,8 @@ var WebChat = ({
133
399
  name: form.name.trim(),
134
400
  email: form.email.trim(),
135
401
  phone: form.phone.trim(),
136
- message: form.message.trim()
402
+ message: form.message.trim(),
403
+ ...config?.businessId && { businessId: config.businessId }
137
404
  });
138
405
  setSubmitted(true);
139
406
  } catch (err) {
@@ -142,149 +409,26 @@ var WebChat = ({
142
409
  setSubmitting(false);
143
410
  }
144
411
  };
145
- if (!secret) return null;
146
- return /* @__PURE__ */ jsxs(Fragment, { children: [
147
- /* @__PURE__ */ jsx(
148
- IconButton,
149
- {
150
- onClick: () => setOpen((o) => !o),
151
- sx: {
152
- position: "fixed",
153
- bottom: 20,
154
- right: 20,
155
- width: 56,
156
- height: 56,
157
- bgcolor: "#007bff",
158
- color: "white",
159
- "&:hover": { bgcolor: "#0056b3" },
160
- boxShadow: 2
161
- },
162
- size: "large",
163
- children: /* @__PURE__ */ jsx(ChatIcon, {})
164
- }
165
- ),
166
- open && /* @__PURE__ */ jsxs(
167
- Box,
168
- {
169
- sx: {
170
- position: "fixed",
171
- bottom: 90,
172
- right: 20,
173
- width: 380,
174
- maxWidth: "calc(100vw - 40px)",
175
- maxHeight: "calc(100vh - 120px)",
176
- overflow: "auto",
177
- bgcolor: "background.paper",
178
- borderRadius: 2,
179
- boxShadow: 6,
180
- zIndex: 1300,
181
- display: "flex",
182
- flexDirection: "column"
183
- },
184
- children: [
185
- /* @__PURE__ */ jsxs(
186
- Box,
187
- {
188
- sx: {
189
- display: "flex",
190
- alignItems: "center",
191
- justifyContent: "space-between",
192
- p: 1.5,
193
- borderBottom: 1,
194
- borderColor: "divider"
195
- },
196
- children: [
197
- /* @__PURE__ */ jsx(Typography, { variant: "subtitle1", fontWeight: 600, children: config?.name ?? "Chat" }),
198
- /* @__PURE__ */ jsx(IconButton, { size: "small", onClick: () => setOpen(false), children: /* @__PURE__ */ jsx(CloseIcon, {}) })
199
- ]
200
- }
201
- ),
202
- /* @__PURE__ */ jsxs(Box, { sx: { p: 2, flex: 1 }, children: [
203
- loading && /* @__PURE__ */ jsx(Box, { display: "flex", justifyContent: "center", py: 3, children: /* @__PURE__ */ jsx(CircularProgress, { size: 32 }) }),
204
- error && !loading && /* @__PURE__ */ jsx(Typography, { color: "error", variant: "body2", children: error }),
205
- !loading && config && !isActive && /* @__PURE__ */ jsx(Typography, { color: "text.secondary", variant: "body2", children: "Este canal n\xE3o est\xE1 dispon\xEDvel no momento." }),
206
- showOutOfHours && /* @__PURE__ */ jsxs(
207
- Box,
208
- {
209
- sx: {
210
- textAlign: "center",
211
- py: 2,
212
- px: 1,
213
- bgcolor: "#1976d2",
214
- borderRadius: 1,
215
- color: "white"
216
- },
217
- children: [
218
- /* @__PURE__ */ jsx(ScheduleIcon, { sx: { fontSize: 48, opacity: 0.9, mb: 1 } }),
219
- /* @__PURE__ */ jsx(Typography, { variant: "body1", sx: { fontWeight: 500, mb: 1 }, children: "Fora do hor\xE1rio de atendimento" }),
220
- /* @__PURE__ */ jsx(Typography, { variant: "body2", sx: { opacity: 0.95 }, children: outOfHoursMessage ?? formatScheduleMessage(config) })
221
- ]
222
- }
223
- ),
224
- showForm && !submitted && /* @__PURE__ */ jsx("form", { onSubmit: handleSubmit, children: /* @__PURE__ */ jsxs(Box, { display: "flex", flexDirection: "column", gap: 2, children: [
225
- /* @__PURE__ */ jsx(
226
- TextField,
227
- {
228
- label: "Nome",
229
- value: form.name,
230
- onChange: (e) => setForm((f) => ({ ...f, name: e.target.value })),
231
- required: true,
232
- fullWidth: true,
233
- size: "small"
234
- }
235
- ),
236
- /* @__PURE__ */ jsx(
237
- TextField,
238
- {
239
- label: "E-mail",
240
- type: "email",
241
- value: form.email,
242
- onChange: (e) => setForm((f) => ({ ...f, email: e.target.value })),
243
- fullWidth: true,
244
- size: "small"
245
- }
246
- ),
247
- /* @__PURE__ */ jsx(
248
- TextField,
249
- {
250
- label: "Telefone",
251
- value: form.phone,
252
- onChange: (e) => setForm((f) => ({ ...f, phone: e.target.value })),
253
- fullWidth: true,
254
- size: "small"
255
- }
256
- ),
257
- /* @__PURE__ */ jsx(
258
- TextField,
259
- {
260
- label: "Mensagem",
261
- value: form.message,
262
- onChange: (e) => setForm((f) => ({ ...f, message: e.target.value })),
263
- multiline: true,
264
- rows: 3,
265
- fullWidth: true,
266
- size: "small"
267
- }
268
- ),
269
- /* @__PURE__ */ jsx(
270
- Button,
271
- {
272
- type: "submit",
273
- variant: "contained",
274
- disabled: submitting || !form.name.trim(),
275
- fullWidth: true,
276
- children: submitting ? "Enviando\u2026" : "Iniciar chat"
277
- }
278
- )
279
- ] }) }),
280
- showForm && submitted && /* @__PURE__ */ jsx(Typography, { color: "text.secondary", variant: "body2", sx: { py: 2 }, children: "Sua mensagem foi enviada. Em breve um atendente responder\xE1." })
281
- ] })
282
- ]
283
- }
284
- )
285
- ] });
412
+ if (!token) return null;
413
+ return /* @__PURE__ */ jsx(
414
+ WebChatLayout,
415
+ {
416
+ open,
417
+ onToggleOpen: () => setOpen((o) => !o),
418
+ primaryColor: colors.main,
419
+ hoverColor: colors.hover,
420
+ panelTitle: config?.name ?? "Chat",
421
+ contentState,
422
+ errorMessage: error,
423
+ outOfHoursMessage: outOfHoursMessage ?? (config ? formatScheduleMessage(config) : ""),
424
+ formValue: form,
425
+ onFormChange: setForm,
426
+ onFormSubmit: handleSubmit,
427
+ submitting
428
+ }
429
+ );
286
430
  };
287
431
 
288
- export { ChatButton, WebChat };
432
+ export { ChatButton, WebChatPage as WebChat };
289
433
  //# sourceMappingURL=index.mjs.map
290
434
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/lib/components/button/styles.tsx","../src/lib/components/button/index.tsx","../src/lib/components/webchat/index.tsx"],"names":["start","end","jsx","Button"],"mappings":"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","file":"index.mjs","sourcesContent":["import { Button, ButtonProps, styled } from \"@mui/material\";\nimport { ButtonHTMLAttributes } from \"react\";\n\nconst disabledStyles = {\n backgroundColor: \"#E0E0E0\",\n color: \"#9E9E9E\",\n borderColor: \"#BDBDBD\",\n};\n\nconst buttonVariants = {\n primary: {\n background: \"#00BB7E\",\n color: \"#FFF\",\n border: \"none\",\n },\n secondary: {\n background: \"transparent\",\n color: \"#00BB7E\",\n border: \"#00BB7E\",\n },\n error: {\n background: \"transparent\",\n color: \"#D32F2F\",\n border: \"#D32F2F\",\n },\n danger: {\n background: \"#E61E2E\",\n color: \"#fff\",\n border: \"none\",\n },\n outlinedBlue: {\n background: \"transparent\",\n color: \"#2196F3\",\n border: \"#2196F3\",\n },\n outlinedGreen: {\n background: \"transparent\",\n color: \"#00BB7E\",\n border: \"#00BB7E\",\n },\n outlinedBlack: {\n background: \"transparent\",\n color: \"#000000DE\",\n border: \"#000000DE\",\n },\n outlinedGrey: {\n background: \"transparent\",\n color: \"#59676D\",\n border: \"#0B0D0E52\",\n },\n textPrimary: {\n background: \"transparent\",\n color: \"#00BB7E\",\n border: \"transparent\",\n },\n textSecondary: {\n background: \"transparent\",\n color: \"#000000DE\",\n border: \"transparent\",\n },\n textBlue: {\n background: \"transparent\",\n color: \"#2196F3\",\n border: \"transparent\",\n },\n default: {\n background: \"#00BB7E\",\n color: \"#FFF\",\n border: \"#00BB7E\",\n },\n};\n\ninterface AtomButtonProps\n extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"color\">,\n ButtonProps {\n buttonType?: keyof typeof buttonVariants;\n}\n\nexport const AtomButton = styled(Button, {\n shouldForwardProp: (prop) => prop !== \"buttonType\",\n})<AtomButtonProps>(({ buttonType = \"default\" }) => {\n\n return {\n }\n\n});","import * as React from 'react'\nimport { ChatButtonProps } from \"./types\";\nimport IComponent from \"../../../types/component\";\nimport { AtomButton } from \"./styles\";\n\nexport const ChatButton: IComponent<ChatButtonProps> = ({ children = 'Chat', onClick, className, disabled }) => {\n return (\n <AtomButton\n onClick={onClick}\n disabled={disabled}\n className={className}\n style={{\n position: \"fixed\",\n bottom: \"20px\",\n right: \"20px\",\n backgroundColor: \"#007bff\",\n color: \"#fff\",\n display: \"flex\",\n borderRadius: \"50%\",\n width: \"60px\",\n height: \"60px\"\n }}\n >\n {children}\n </AtomButton>\n )\n}\n","import React, { useCallback, useEffect, useState } from \"react\";\nimport {\n Box,\n Button,\n CircularProgress,\n IconButton,\n TextField,\n Typography,\n} from \"@mui/material\";\nimport CloseIcon from \"@mui/icons-material/Close\";\nimport ChatIcon from \"@mui/icons-material/Chat\";\nimport ScheduleIcon from \"@mui/icons-material/Schedule\";\nimport { WebChatConfig, WebChatProps } from \"./types\";\n\nconst DAY_MAP: Record<number, string> = {\n 0: \"SUNDAY\",\n 1: \"MONDAY\",\n 2: \"TUESDAY\",\n 3: \"WEDNESDAY\",\n 4: \"THURSDAY\",\n 5: \"FRIDAY\",\n 6: \"SATURDAY\",\n};\n\nfunction isWithinSchedule(config: WebChatConfig): boolean {\n if (!config.restrictBySchedule || !config.schedule) return true;\n\n const now = new Date();\n const day = DAY_MAP[now.getDay()];\n const time =\n String(now.getHours()).padStart(2, \"0\") +\n \":\" +\n String(now.getMinutes()).padStart(2, \"0\");\n const weekDays = config.schedule.weekDays ?? [\n \"MONDAY\",\n \"TUESDAY\",\n \"WEDNESDAY\",\n \"THURSDAY\",\n \"FRIDAY\",\n ];\n const isWeekday = weekDays.includes(day);\n\n if (isWeekday) {\n const start = config.schedule.weekdaysStart ?? \"07:00\";\n const end = config.schedule.weekdaysEnd ?? \"18:00\";\n return time >= start && time <= end;\n }\n\n const start = config.schedule.weekendStart ?? \"07:00\";\n const end = config.schedule.weekendEnd ?? \"13:00\";\n return time >= start && time <= end;\n}\n\nfunction formatScheduleMessage(config: WebChatConfig): string {\n if (!config.schedule) {\n return \"Nosso horário de atendimento é de segunda à sexta-feira das 07:00h às 18:00h. Sábados, domingos e feriados das 07:00h às 13:00h.\";\n }\n const wdStart = config.schedule.weekdaysStart ?? \"07:00\";\n const wdEnd = config.schedule.weekdaysEnd ?? \"18:00\";\n const weStart = config.schedule.weekendStart ?? \"07:00\";\n const weEnd = config.schedule.weekendEnd ?? \"13:00\";\n return `Nosso horário de atendimento é de segunda à sexta-feira das ${wdStart}h às ${wdEnd}h. Sábados, domingos e feriados das ${weStart}h às ${weEnd}h.`;\n}\n\nexport const WebChat: React.FC<WebChatProps> = ({\n secret,\n apiBaseUrl,\n onStartChat,\n outOfHoursMessage,\n}) => {\n const [config, setConfig] = useState<WebChatConfig | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [open, setOpen] = useState(false);\n const [submitting, setSubmitting] = useState(false);\n const [submitted, setSubmitted] = useState(false);\n\n const [form, setForm] = useState({\n name: \"\",\n email: \"\",\n phone: \"\",\n message: \"\",\n });\n\n const fetchConfig = useCallback(async () => {\n if (!secret || !apiBaseUrl) return;\n setLoading(true);\n setError(null);\n try {\n const base = apiBaseUrl.replace(/\\/$/, \"\");\n const res = await fetch(`${base}/channel/webchat/${encodeURIComponent(secret)}`);\n if (!res.ok) {\n setError(\"Canal não encontrado.\");\n setConfig(null);\n return;\n }\n const data: WebChatConfig = await res.json();\n setConfig(data);\n } catch {\n setError(\"Não foi possível carregar o canal.\");\n setConfig(null);\n } finally {\n setLoading(false);\n }\n }, [secret, apiBaseUrl]);\n\n useEffect(() => {\n fetchConfig();\n }, [fetchConfig]);\n\n const isActive =\n config &&\n (config.status === \"live\" || config.status === \"enable\");\n const outsideHours =\n config && config.restrictBySchedule && !isWithinSchedule(config);\n const showOutOfHours = isActive && outsideHours;\n const showForm = isActive && !outsideHours;\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n if (submitting || !form.name.trim()) return;\n if (!onStartChat) {\n setError(\"Início de conversa será via WebSocket. Configure onStartChat no componente.\");\n return;\n }\n\n setSubmitting(true);\n try {\n await onStartChat({\n name: form.name.trim(),\n email: form.email.trim(),\n phone: form.phone.trim(),\n message: form.message.trim(),\n });\n setSubmitted(true);\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Erro ao enviar.\");\n } finally {\n setSubmitting(false);\n }\n };\n\n if (!secret) return null;\n\n return (\n <>\n <IconButton\n onClick={() => setOpen((o) => !o)}\n sx={{\n position: \"fixed\",\n bottom: 20,\n right: 20,\n width: 56,\n height: 56,\n bgcolor: \"#007bff\",\n color: \"white\",\n \"&:hover\": { bgcolor: \"#0056b3\" },\n boxShadow: 2,\n }}\n size=\"large\"\n >\n <ChatIcon />\n </IconButton>\n\n {open && (\n <Box\n sx={{\n position: \"fixed\",\n bottom: 90,\n right: 20,\n width: 380,\n maxWidth: \"calc(100vw - 40px)\",\n maxHeight: \"calc(100vh - 120px)\",\n overflow: \"auto\",\n bgcolor: \"background.paper\",\n borderRadius: 2,\n boxShadow: 6,\n zIndex: 1300,\n display: \"flex\",\n flexDirection: \"column\",\n }}\n >\n <Box\n sx={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n p: 1.5,\n borderBottom: 1,\n borderColor: \"divider\",\n }}\n >\n <Typography variant=\"subtitle1\" fontWeight={600}>\n {config?.name ?? \"Chat\"}\n </Typography>\n <IconButton size=\"small\" onClick={() => setOpen(false)}>\n <CloseIcon />\n </IconButton>\n </Box>\n\n <Box sx={{ p: 2, flex: 1 }}>\n {loading && (\n <Box display=\"flex\" justifyContent=\"center\" py={3}>\n <CircularProgress size={32} />\n </Box>\n )}\n\n {error && !loading && (\n <Typography color=\"error\" variant=\"body2\">\n {error}\n </Typography>\n )}\n\n {!loading && config && !isActive && (\n <Typography color=\"text.secondary\" variant=\"body2\">\n Este canal não está disponível no momento.\n </Typography>\n )}\n\n {showOutOfHours && (\n <Box\n sx={{\n textAlign: \"center\",\n py: 2,\n px: 1,\n bgcolor: \"#1976d2\",\n borderRadius: 1,\n color: \"white\",\n }}\n >\n <ScheduleIcon sx={{ fontSize: 48, opacity: 0.9, mb: 1 }} />\n <Typography variant=\"body1\" sx={{ fontWeight: 500, mb: 1 }}>\n Fora do horário de atendimento\n </Typography>\n <Typography variant=\"body2\" sx={{ opacity: 0.95 }}>\n {outOfHoursMessage ?? formatScheduleMessage(config)}\n </Typography>\n </Box>\n )}\n\n {showForm && !submitted && (\n <form onSubmit={handleSubmit}>\n <Box display=\"flex\" flexDirection=\"column\" gap={2}>\n <TextField\n label=\"Nome\"\n value={form.name}\n onChange={(e) => setForm((f) => ({ ...f, name: e.target.value }))}\n required\n fullWidth\n size=\"small\"\n />\n <TextField\n label=\"E-mail\"\n type=\"email\"\n value={form.email}\n onChange={(e) => setForm((f) => ({ ...f, email: e.target.value }))}\n fullWidth\n size=\"small\"\n />\n <TextField\n label=\"Telefone\"\n value={form.phone}\n onChange={(e) => setForm((f) => ({ ...f, phone: e.target.value }))}\n fullWidth\n size=\"small\"\n />\n <TextField\n label=\"Mensagem\"\n value={form.message}\n onChange={(e) => setForm((f) => ({ ...f, message: e.target.value }))}\n multiline\n rows={3}\n fullWidth\n size=\"small\"\n />\n <Button\n type=\"submit\"\n variant=\"contained\"\n disabled={submitting || !form.name.trim()}\n fullWidth\n >\n {submitting ? \"Enviando…\" : \"Iniciar chat\"}\n </Button>\n </Box>\n </form>\n )}\n\n {showForm && submitted && (\n <Typography color=\"text.secondary\" variant=\"body2\" sx={{ py: 2 }}>\n Sua mensagem foi enviada. Em breve um atendente responderá.\n </Typography>\n )}\n </Box>\n </Box>\n )}\n </>\n );\n};\n"]}
1
+ {"version":3,"sources":["../src/lib/components/atoms/button/styles.tsx","../src/lib/components/atoms/button/index.tsx","../src/lib/components/atoms/floating-button/FabIconButton.tsx","../src/lib/components/atoms/spinner/Spinner.tsx","../src/lib/components/molecules/floating-button-trigger/FabTrigger.tsx","../src/lib/components/molecules/out-of-hours-card/PanelHeader.tsx","../src/lib/components/molecules/out-of-hours-card/OutOfHoursCard.tsx","../src/lib/components/molecules/chat-form/ChatForm.tsx","../src/lib/components/organisms/webchat/constants.ts","../src/lib/components/organisms/chat-panel-content/ChatPanelContent.tsx","../src/lib/components/organisms/chat-panel/ChatPanel.tsx","../src/lib/components/organisms/layout/WebChatLayout.tsx","../src/lib/components/organisms/webchat/WebChatPage.tsx"],"names":["jsx","Box","IconButton","jsxs","Typography","Button","start","end"],"mappings":"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","file":"index.mjs","sourcesContent":["import { Button, ButtonProps, styled } from \"@mui/material\";\nimport { ButtonHTMLAttributes } from \"react\";\n\nconst disabledStyles = {\n backgroundColor: \"#E0E0E0\",\n color: \"#9E9E9E\",\n borderColor: \"#BDBDBD\",\n};\n\nconst buttonVariants = {\n primary: {\n background: \"#00BB7E\",\n color: \"#FFF\",\n border: \"none\",\n },\n secondary: {\n background: \"transparent\",\n color: \"#00BB7E\",\n border: \"#00BB7E\",\n },\n error: {\n background: \"transparent\",\n color: \"#D32F2F\",\n border: \"#D32F2F\",\n },\n danger: {\n background: \"#E61E2E\",\n color: \"#fff\",\n border: \"none\",\n },\n outlinedBlue: {\n background: \"transparent\",\n color: \"#2196F3\",\n border: \"#2196F3\",\n },\n outlinedGreen: {\n background: \"transparent\",\n color: \"#00BB7E\",\n border: \"#00BB7E\",\n },\n outlinedBlack: {\n background: \"transparent\",\n color: \"#000000DE\",\n border: \"#000000DE\",\n },\n outlinedGrey: {\n background: \"transparent\",\n color: \"#59676D\",\n border: \"#0B0D0E52\",\n },\n textPrimary: {\n background: \"transparent\",\n color: \"#00BB7E\",\n border: \"transparent\",\n },\n textSecondary: {\n background: \"transparent\",\n color: \"#000000DE\",\n border: \"transparent\",\n },\n textBlue: {\n background: \"transparent\",\n color: \"#2196F3\",\n border: \"transparent\",\n },\n default: {\n background: \"#00BB7E\",\n color: \"#FFF\",\n border: \"#00BB7E\",\n },\n};\n\ninterface AtomButtonProps\n extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"color\">,\n ButtonProps {\n buttonType?: keyof typeof buttonVariants;\n}\n\nexport const AtomButton = styled(Button, {\n shouldForwardProp: (prop) => prop !== \"buttonType\",\n})<AtomButtonProps>(({ buttonType = \"default\" }) => {\n\n return {\n }\n\n});","import * as React from 'react'\nimport { ChatButtonProps } from \"./types\";\nimport IComponent from \"../../../../types/component\";\nimport { AtomButton } from \"./styles\";\n\nexport const ChatButton: IComponent<ChatButtonProps> = ({ children = 'Chat', onClick, className, disabled }) => {\n return (\n <AtomButton\n onClick={onClick}\n disabled={disabled}\n className={className}\n style={{\n position: \"fixed\",\n bottom: \"20px\",\n right: \"20px\",\n backgroundColor: \"#007bff\",\n color: \"#fff\",\n display: \"flex\",\n borderRadius: \"50%\",\n width: \"60px\",\n height: \"60px\"\n }}\n >\n {children}\n </AtomButton>\n )\n}\n","import React from \"react\";\nimport { IconButton, IconButtonProps } from \"@mui/material\";\n\nexport interface FabIconButtonProps extends Omit<IconButtonProps, \"size\"> {\n bgColor: string;\n hoverColor: string;\n children: React.ReactNode;\n}\n\nexport const FabIconButton: React.FC<FabIconButtonProps> = ({\n bgColor,\n hoverColor,\n children,\n sx,\n ...rest\n}) => (\n <IconButton\n size=\"large\"\n sx={{\n width: 56,\n height: 56,\n bgcolor: bgColor,\n color: \"white\",\n \"&:hover\": { bgcolor: hoverColor },\n boxShadow: 2,\n ...sx,\n }}\n {...rest}\n >\n {children}\n </IconButton>\n);\n","import React from \"react\";\nimport { Box, CircularProgress } from \"@mui/material\";\n\nexport interface SpinnerProps {\n size?: number;\n}\n\nexport const Spinner: React.FC<SpinnerProps> = ({ size = 32 }) => (\n <Box display=\"flex\" justifyContent=\"center\" py={3}>\n <CircularProgress size={size} />\n </Box>\n);\n","import React from \"react\";\nimport ChatIcon from \"@mui/icons-material/Chat\";\nimport { FabIconButton } from \"../../atoms\";\n\nexport interface FabTriggerProps {\n onClick: () => void;\n bgColor: string;\n hoverColor: string;\n}\n\nexport const FabTrigger: React.FC<FabTriggerProps> = ({\n onClick,\n bgColor,\n hoverColor,\n}) => (\n <FabIconButton\n onClick={onClick}\n bgColor={bgColor}\n hoverColor={hoverColor}\n sx={{ position: \"fixed\", bottom: 20, right: 20 }}\n >\n <ChatIcon />\n </FabIconButton>\n);\n","import React from \"react\";\nimport { Box, IconButton, Typography } from \"@mui/material\";\nimport CloseIcon from \"@mui/icons-material/Close\";\n\nexport interface PanelHeaderProps {\n title: string;\n onClose: () => void;\n}\n\n/**\n * Molécula: cabeçalho do painel com título e botão fechar.\n */\nexport const PanelHeader: React.FC<PanelHeaderProps> = ({ title, onClose }) => (\n <Box\n sx={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n p: 1.5,\n borderBottom: 1,\n borderColor: \"divider\",\n }}\n >\n <Typography variant=\"subtitle1\" fontWeight={600}>\n {title}\n </Typography>\n <IconButton size=\"small\" onClick={onClose} aria-label=\"Fechar\">\n <CloseIcon />\n </IconButton>\n </Box>\n);\n","import React from \"react\";\nimport { Box, Typography } from \"@mui/material\";\nimport ScheduleIcon from \"@mui/icons-material/Schedule\";\n\nexport interface OutOfHoursCardProps {\n message: string;\n bgColor: string;\n}\n\n/**\n * Molécula: card \"Fora do horário de atendimento\" com ícone e mensagem.\n */\nexport const OutOfHoursCard: React.FC<OutOfHoursCardProps> = ({\n message,\n bgColor,\n}) => (\n <Box\n sx={{\n textAlign: \"center\",\n py: 2,\n px: 1,\n bgcolor: bgColor,\n borderRadius: 1,\n color: \"white\",\n }}\n >\n <ScheduleIcon sx={{ fontSize: 48, opacity: 0.9, mb: 1 }} />\n <Typography variant=\"body1\" sx={{ fontWeight: 500, mb: 1 }}>\n Fora do horário de atendimento\n </Typography>\n <Typography variant=\"body2\" sx={{ opacity: 0.95 }}>\n {message}\n </Typography>\n </Box>\n);\n","import React from \"react\";\nimport { Box, Button, TextField } from \"@mui/material\";\n\nexport interface ChatFormData {\n name: string;\n email: string;\n phone: string;\n message: string;\n}\n\nexport interface ChatFormProps {\n value: ChatFormData;\n onChange: (data: ChatFormData) => void;\n onSubmit: (e: React.FormEvent) => void;\n submitting: boolean;\n submitLabel?: string;\n}\n\n/**\n * Molécula: formulário de início de chat (nome, e-mail, telefone, mensagem + enviar).\n */\nexport const ChatForm: React.FC<ChatFormProps> = ({\n value,\n onChange,\n onSubmit,\n submitting,\n submitLabel = \"Iniciar chat\",\n}) => (\n <form onSubmit={onSubmit}>\n <Box display=\"flex\" flexDirection=\"column\" gap={2}>\n <TextField\n label=\"Nome\"\n value={value.name}\n onChange={(e) => onChange({ ...value, name: e.target.value })}\n required\n fullWidth\n size=\"small\"\n />\n <TextField\n label=\"E-mail\"\n type=\"email\"\n value={value.email}\n onChange={(e) => onChange({ ...value, email: e.target.value })}\n fullWidth\n size=\"small\"\n />\n <TextField\n label=\"Telefone\"\n value={value.phone}\n onChange={(e) => onChange({ ...value, phone: e.target.value })}\n fullWidth\n size=\"small\"\n />\n <TextField\n label=\"Mensagem\"\n value={value.message}\n onChange={(e) => onChange({ ...value, message: e.target.value })}\n multiline\n rows={3}\n fullWidth\n size=\"small\"\n />\n <Button\n type=\"submit\"\n variant=\"contained\"\n disabled={submitting || !value.name.trim()}\n fullWidth\n >\n {submitting ? \"Enviando…\" : submitLabel}\n </Button>\n </Box>\n </form>\n);\n","/**\n * Cor padrão do botão/floating action do WebChat (identidade Synchat).\n * Pode ser sobrescrita pela prop primaryColor.\n */\nexport const DEFAULT_PRIMARY_COLOR = \"#0D9488\";\nexport const DEFAULT_PRIMARY_COLOR_HOVER = \"#0F766E\";\n\n/**\n * URL base da API usada quando apiBaseUrl não é passada.\n * No build: para embutir outra URL no pacote, use\n * SYNCHAT_API_URL=https://sua-api.com npm run build\n */\ndeclare const __SYNCHAT_API_URL__: string;\nexport const DEFAULT_API_BASE_URL = __SYNCHAT_API_URL__;\n","import React from \"react\";\nimport { Box, Typography } from \"@mui/material\";\nimport { Spinner } from \"../../atoms\";\nimport { OutOfHoursCard, ChatForm } from \"../../molecules\";\nimport type { ChatFormData } from \"../../molecules\";\n\nexport type PanelContentState =\n | \"loading\"\n | \"error\"\n | \"inactive\"\n | \"outOfHours\"\n | \"form\"\n | \"submitted\";\n\nexport interface ChatPanelContentProps {\n state: PanelContentState;\n errorMessage: string | null;\n outOfHoursMessage: string;\n outOfHoursBgColor: string;\n formValue: ChatFormData;\n onFormChange: (data: ChatFormData) => void;\n onFormSubmit: (e: React.FormEvent) => void;\n submitting: boolean;\n}\n\n/**\n * Organismo: conteúdo do painel (loading, erro, inativo, fora do horário, formulário ou sucesso).\n */\nexport const ChatPanelContent: React.FC<ChatPanelContentProps> = ({\n state,\n errorMessage,\n outOfHoursMessage,\n outOfHoursBgColor,\n formValue,\n onFormChange,\n onFormSubmit,\n submitting,\n}) => (\n <Box sx={{ p: 2, flex: 1 }}>\n {state === \"loading\" && <Spinner />}\n\n {state === \"error\" && errorMessage && (\n <Typography color=\"error\" variant=\"body2\">\n {errorMessage}\n </Typography>\n )}\n\n {state === \"inactive\" && (\n <Typography color=\"text.secondary\" variant=\"body2\">\n Este canal não está disponível no momento.\n </Typography>\n )}\n\n {state === \"outOfHours\" && (\n <OutOfHoursCard message={outOfHoursMessage} bgColor={outOfHoursBgColor} />\n )}\n\n {state === \"form\" && (\n <ChatForm\n value={formValue}\n onChange={onFormChange}\n onSubmit={onFormSubmit}\n submitting={submitting}\n />\n )}\n\n {state === \"submitted\" && (\n <Typography color=\"text.secondary\" variant=\"body2\" sx={{ py: 2 }}>\n Sua mensagem foi enviada. Em breve um atendente responderá.\n </Typography>\n )}\n </Box>\n);\n","import React from \"react\";\nimport { Box } from \"@mui/material\";\nimport { PanelHeader } from \"../../molecules\";\nimport { ChatPanelContent } from \"../chat-panel-content/ChatPanelContent\";\nimport type { PanelContentState } from \"../chat-panel-content/ChatPanelContent\";\nimport type { ChatFormData } from \"../../molecules\";\n\nexport interface ChatPanelProps {\n open: boolean;\n title: string;\n onClose: () => void;\n contentState: PanelContentState;\n errorMessage: string | null;\n outOfHoursMessage: string;\n primaryColor: string;\n formValue: ChatFormData;\n onFormChange: (data: ChatFormData) => void;\n onFormSubmit: (e: React.FormEvent) => void;\n submitting: boolean;\n}\n\n/**\n * Organismo: painel do chat (cabeçalho + conteúdo).\n */\nexport const ChatPanel: React.FC<ChatPanelProps> = ({\n open,\n title,\n onClose,\n contentState,\n errorMessage,\n outOfHoursMessage,\n primaryColor,\n formValue,\n onFormChange,\n onFormSubmit,\n submitting,\n}) => {\n if (!open) return null;\n\n return (\n <Box\n sx={{\n position: \"fixed\",\n bottom: 90,\n right: 20,\n width: 380,\n maxWidth: \"calc(100vw - 40px)\",\n maxHeight: \"calc(100vh - 120px)\",\n overflow: \"auto\",\n bgcolor: \"background.paper\",\n borderRadius: 2,\n boxShadow: 6,\n zIndex: 1300,\n display: \"flex\",\n flexDirection: \"column\",\n }}\n >\n <PanelHeader title={title} onClose={onClose} />\n <ChatPanelContent\n state={contentState}\n errorMessage={errorMessage}\n outOfHoursMessage={outOfHoursMessage}\n outOfHoursBgColor={primaryColor}\n formValue={formValue}\n onFormChange={onFormChange}\n onFormSubmit={onFormSubmit}\n submitting={submitting}\n />\n </Box>\n );\n};\n","import React from \"react\";\nimport { FabTrigger } from \"../../molecules\";\nimport { ChatPanel } from \"../chat-panel/ChatPanel\";\nimport type { PanelContentState } from \"../chat-panel-content/ChatPanelContent\";\nimport type { ChatFormData } from \"../../molecules\";\n\nexport interface WebChatLayoutProps {\n open: boolean;\n onToggleOpen: () => void;\n primaryColor: string;\n hoverColor: string;\n panelTitle: string;\n contentState: PanelContentState;\n errorMessage: string | null;\n outOfHoursMessage: string;\n formValue: ChatFormData;\n onFormChange: (data: ChatFormData) => void;\n onFormSubmit: (e: React.FormEvent) => void;\n submitting: boolean;\n}\n\n/**\n * Template: layout do widget (FAB + painel condicional).\n */\nexport const WebChatLayout: React.FC<WebChatLayoutProps> = (props) => (\n <>\n <FabTrigger\n onClick={props.onToggleOpen}\n bgColor={props.primaryColor}\n hoverColor={props.hoverColor}\n />\n <ChatPanel\n open={props.open}\n title={props.panelTitle}\n onClose={props.onToggleOpen}\n contentState={props.contentState}\n errorMessage={props.errorMessage}\n outOfHoursMessage={props.outOfHoursMessage}\n primaryColor={props.primaryColor}\n formValue={props.formValue}\n onFormChange={props.onFormChange}\n onFormSubmit={props.onFormSubmit}\n submitting={props.submitting}\n />\n </>\n);\n","import React, { useCallback, useEffect, useState } from \"react\";\nimport {\n DEFAULT_API_BASE_URL,\n DEFAULT_PRIMARY_COLOR,\n DEFAULT_PRIMARY_COLOR_HOVER,\n} from \"./constants\";\nimport { WebChatLayout } from \"../layout/WebChatLayout\";\nimport type { PanelContentState } from \"../chat-panel-content/ChatPanelContent\";\nimport type { ChatFormData } from \"../../molecules\";\nimport { WebChatConfig, WebChatProps } from \"./types\";\n\nconst DAY_MAP: Record<number, string> = {\n 0: \"SUNDAY\",\n 1: \"MONDAY\",\n 2: \"TUESDAY\",\n 3: \"WEDNESDAY\",\n 4: \"THURSDAY\",\n 5: \"FRIDAY\",\n 6: \"SATURDAY\",\n};\n\nfunction isWithinSchedule(config: WebChatConfig): boolean {\n if (!config.restrictBySchedule || !config.schedule) return true;\n const now = new Date();\n const day = DAY_MAP[now.getDay()];\n const time =\n String(now.getHours()).padStart(2, \"0\") +\n \":\" +\n String(now.getMinutes()).padStart(2, \"0\");\n const weekDays = config.schedule.weekDays ?? [\n \"MONDAY\",\n \"TUESDAY\",\n \"WEDNESDAY\",\n \"THURSDAY\",\n \"FRIDAY\",\n ];\n const isWeekday = weekDays.includes(day);\n if (isWeekday) {\n const start = config.schedule.weekdaysStart ?? \"07:00\";\n const end = config.schedule.weekdaysEnd ?? \"18:00\";\n return time >= start && time <= end;\n }\n const start = config.schedule.weekendStart ?? \"07:00\";\n const end = config.schedule.weekendEnd ?? \"13:00\";\n return time >= start && time <= end;\n}\n\nfunction formatScheduleMessage(config: WebChatConfig): string {\n if (!config.schedule) {\n return \"Nosso horário de atendimento é de segunda à sexta-feira das 07:00h às 18:00h. Sábados, domingos e feriados das 07:00h às 13:00h.\";\n }\n const wdStart = config.schedule.weekdaysStart ?? \"07:00\";\n const wdEnd = config.schedule.weekdaysEnd ?? \"18:00\";\n const weStart = config.schedule.weekendStart ?? \"07:00\";\n const weEnd = config.schedule.weekendEnd ?? \"13:00\";\n return `Nosso horário de atendimento é de segunda à sexta-feira das ${wdStart}h às ${wdEnd}h. Sábados, domingos e feriados das ${weStart}h às ${weEnd}h.`;\n}\n\nfunction parseColor(color: string | undefined): { main: string; hover: string } {\n if (!color || !color.trim()) {\n return { main: DEFAULT_PRIMARY_COLOR, hover: DEFAULT_PRIMARY_COLOR_HOVER };\n }\n const c = color.trim();\n if (c.startsWith(\"#\") && c.length === 7) {\n const hex = c.slice(1);\n const r = Math.max(0, parseInt(hex.slice(0, 2), 16) - 18);\n const g = Math.max(0, parseInt(hex.slice(2, 4), 16) - 18);\n const b = Math.max(0, parseInt(hex.slice(4, 6), 16) - 18);\n const hover = `#${r.toString(16).padStart(2, \"0\")}${g.toString(16).padStart(2, \"0\")}${b.toString(16).padStart(2, \"0\")}`;\n return { main: c, hover };\n }\n return { main: c, hover: c };\n}\n\nexport const WebChatPage: React.FC<WebChatProps> = ({\n token,\n apiBaseUrl,\n primaryColor,\n onStartChat,\n outOfHoursMessage,\n}) => {\n const baseUrl = apiBaseUrl?.trim() || DEFAULT_API_BASE_URL;\n const colors = parseColor(primaryColor);\n const [config, setConfig] = useState<WebChatConfig | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [open, setOpen] = useState(false);\n const [submitting, setSubmitting] = useState(false);\n const [submitted, setSubmitted] = useState(false);\n const [form, setForm] = useState<ChatFormData>({\n name: \"\",\n email: \"\",\n phone: \"\",\n message: \"\",\n });\n\n const fetchConfig = useCallback(async () => {\n if (!token) return;\n setLoading(true);\n setError(null);\n try {\n const base = baseUrl.replace(/\\/$/, \"\");\n const res = await fetch(`${base}/channel/webchat/${encodeURIComponent(token)}`);\n if (!res.ok) {\n setError(\"Canal não encontrado.\");\n setConfig(null);\n return;\n }\n const data: WebChatConfig = await res.json();\n setConfig(data);\n } catch {\n setError(\"Não foi possível carregar o canal.\");\n setConfig(null);\n } finally {\n setLoading(false);\n }\n }, [token, baseUrl]);\n\n useEffect(() => {\n fetchConfig();\n }, [fetchConfig]);\n\n const isActive =\n config && (config.status === \"live\" || config.status === \"enable\");\n const outsideHours =\n config && config.restrictBySchedule && !isWithinSchedule(config);\n const showOutOfHours = isActive && outsideHours;\n const showForm = isActive && !outsideHours;\n\n const contentState: PanelContentState = loading\n ? \"loading\"\n : error\n ? \"error\"\n : config && !isActive\n ? \"inactive\"\n : showOutOfHours\n ? \"outOfHours\"\n : showForm && !submitted\n ? \"form\"\n : \"submitted\";\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n if (submitting || !form.name.trim()) return;\n if (!onStartChat) {\n setError(\n \"Início de conversa será via WebSocket. Configure onStartChat no componente.\"\n );\n return;\n }\n setSubmitting(true);\n try {\n await onStartChat({\n name: form.name.trim(),\n email: form.email.trim(),\n phone: form.phone.trim(),\n message: form.message.trim(),\n ...(config?.businessId && { businessId: config.businessId }),\n });\n setSubmitted(true);\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Erro ao enviar.\");\n } finally {\n setSubmitting(false);\n }\n };\n\n if (!token) return null;\n\n return (\n <WebChatLayout\n open={open}\n onToggleOpen={() => setOpen((o) => !o)}\n primaryColor={colors.main}\n hoverColor={colors.hover}\n panelTitle={config?.name ?? \"Chat\"}\n contentState={contentState}\n errorMessage={error}\n outOfHoursMessage={\n outOfHoursMessage ?? (config ? formatScheduleMessage(config) : \"\")\n }\n formValue={form}\n onFormChange={setForm}\n onFormSubmit={handleSubmit}\n submitting={submitting}\n />\n );\n};\n"]}