strapi-plugin-magic-mail 2.2.6 → 2.3.1

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.
@@ -1,11 +1,11 @@
1
1
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
- import React, { useRef, useEffect, useState } from "react";
2
+ import React, { useRef, useEffect, useState, useCallback } from "react";
3
3
  import { useNavigate, useLocation } from "react-router-dom";
4
4
  import { Modal, Typography, Flex, Box, Field, TextInput, Alert, Textarea, NumberInput, Divider, Toggle, Badge, Button, Loader, SingleSelect, SingleSelectOption, Thead, Tr, Th, Tbody, Td, Table, Tabs } from "@strapi/design-system";
5
- import { EnvelopeIcon, ServerIcon, SparklesIcon, PlusIcon, PencilIcon, PlayIcon, TrashIcon, MagnifyingGlassIcon, FunnelIcon, CheckIcon, Cog6ToothIcon, DocumentTextIcon, ChartBarIcon, BoltIcon, CheckCircleIcon, ArrowUpTrayIcon, ArrowDownTrayIcon, DocumentArrowDownIcon, CodeBracketIcon, DocumentDuplicateIcon, PaperAirplaneIcon, ClipboardDocumentIcon, ArrowLeftIcon, ClockIcon, XMarkIcon, ArrowUturnLeftIcon, EnvelopeOpenIcon, CursorArrowRaysIcon, ExclamationTriangleIcon, XCircleIcon, KeyIcon } from "@heroicons/react/24/outline";
5
+ import { EnvelopeIcon, ServerIcon, SparklesIcon, PlusIcon, PencilIcon, PlayIcon, TrashIcon, MagnifyingGlassIcon, FunnelIcon, CheckIcon, Cog6ToothIcon, DocumentTextIcon, ChartBarIcon, BoltIcon, CheckCircleIcon, ArrowUpTrayIcon, ArrowDownTrayIcon, DocumentArrowDownIcon, CodeBracketIcon, DocumentDuplicateIcon, PaperAirplaneIcon, ClipboardDocumentIcon, ArrowLeftIcon, ClockIcon, XMarkIcon, ArrowUturnLeftIcon, EnvelopeOpenIcon, CursorArrowRaysIcon, ExclamationTriangleIcon, XCircleIcon, KeyIcon, ChatBubbleLeftIcon } from "@heroicons/react/24/outline";
6
6
  import { useFetchClient, useNotification } from "@strapi/strapi/admin";
7
7
  import styled, { css, keyframes } from "styled-components";
8
- import { Star, Mail, Server, Lock, Cog, Check, Cloud, Key, ArrowLeft, ArrowRight } from "@strapi/icons";
8
+ import { Star, Mail, Server, Lock, Cog, Check, Cloud, Key, ArrowLeft, ArrowRight, ArrowClockwise, Play, Cross } from "@strapi/icons";
9
9
  import * as ReactEmailEditor from "react-email-editor";
10
10
  const useAuthRefresh = () => {
11
11
  const { get } = useFetchClient();
@@ -85,7 +85,7 @@ const theme$3 = {
85
85
  xl: "16px"
86
86
  }
87
87
  };
88
- const fadeIn$5 = keyframes`
88
+ const fadeIn$6 = keyframes`
89
89
  from {
90
90
  opacity: 0;
91
91
  transform: translateY(10px);
@@ -95,7 +95,7 @@ const fadeIn$5 = keyframes`
95
95
  transform: translateY(0);
96
96
  }
97
97
  `;
98
- const pulse$2 = keyframes`
98
+ const pulse$3 = keyframes`
99
99
  0%, 100% {
100
100
  transform: scale(1);
101
101
  }
@@ -113,7 +113,7 @@ const slideIn = keyframes`
113
113
  opacity: 1;
114
114
  }
115
115
  `;
116
- const colors = {
116
+ const colors$1 = {
117
117
  primary: "#4945ff",
118
118
  // Strapi Primary Blue
119
119
  primaryLight: "#f0f0ff",
@@ -133,7 +133,7 @@ const StepHeader = styled(Box)`
133
133
  padding-bottom: 24px;
134
134
  margin-bottom: 32px;
135
135
  position: relative;
136
- animation: ${fadeIn$5} 0.4s ease;
136
+ animation: ${fadeIn$6} 0.4s ease;
137
137
 
138
138
  &::after {
139
139
  content: '';
@@ -142,11 +142,11 @@ const StepHeader = styled(Box)`
142
142
  left: -24px;
143
143
  right: -24px;
144
144
  height: 1px;
145
- background: linear-gradient(90deg, transparent, ${colors.border}, transparent);
145
+ background: linear-gradient(90deg, transparent, ${colors$1.border}, transparent);
146
146
  }
147
147
  `;
148
148
  const StepTitle = styled(Typography)`
149
- color: ${colors.text};
149
+ color: ${colors$1.text};
150
150
  font-size: 24px;
151
151
  font-weight: 600;
152
152
  margin-bottom: 8px;
@@ -155,11 +155,11 @@ const StepTitle = styled(Typography)`
155
155
  gap: 12px;
156
156
  `;
157
157
  const StepSubtitle = styled(Typography)`
158
- color: ${colors.textLight};
158
+ color: ${colors$1.textLight};
159
159
  font-size: 14px;
160
160
  line-height: 1.5;
161
161
  `;
162
- const StepperContainer = styled(Box)`
162
+ const StepperContainer$1 = styled(Box)`
163
163
  display: flex;
164
164
  align-items: flex-start;
165
165
  justify-content: center;
@@ -169,7 +169,7 @@ const StepperContainer = styled(Box)`
169
169
  position: relative;
170
170
  padding: 0 40px;
171
171
  `;
172
- const StepWrapper = styled.div`
172
+ const StepWrapper$1 = styled.div`
173
173
  flex: 1;
174
174
  display: flex;
175
175
  flex-direction: column;
@@ -183,18 +183,18 @@ const StepWrapper = styled.div`
183
183
  left: 50%;
184
184
  width: 100%;
185
185
  height: 3px;
186
- background: ${(props) => props.$completed ? colors.success : colors.neutralLight};
186
+ background: ${(props) => props.$completed ? colors$1.success : colors$1.neutralLight};
187
187
  transition: all 0.4s ease;
188
188
  z-index: 0;
189
189
  }
190
190
  `;
191
- const StepDot = styled.div`
191
+ const StepDot$1 = styled.div`
192
192
  width: 56px;
193
193
  height: 56px;
194
194
  border-radius: 50%;
195
- background: ${(props) => props.$active ? colors.primary : props.$completed ? colors.success : colors.white};
196
- color: ${(props) => props.$active || props.$completed ? colors.white : colors.textLight};
197
- border: 4px solid ${(props) => props.$active ? colors.primary : props.$completed ? colors.success : colors.border};
195
+ background: ${(props) => props.$active ? colors$1.primary : props.$completed ? colors$1.success : colors$1.white};
196
+ color: ${(props) => props.$active || props.$completed ? colors$1.white : colors$1.textLight};
197
+ border: 4px solid ${(props) => props.$active ? colors$1.primary : props.$completed ? colors$1.success : colors$1.border};
198
198
  display: flex;
199
199
  align-items: center;
200
200
  justify-content: center;
@@ -204,20 +204,20 @@ const StepDot = styled.div`
204
204
  position: relative;
205
205
  z-index: 1;
206
206
  cursor: ${(props) => props.$completed ? "pointer" : "default"};
207
- box-shadow: ${(props) => props.$active ? `0 4px 16px ${colors.primary}40, 0 0 0 8px ${colors.primaryLight}` : props.$completed ? `0 4px 12px ${colors.success}30` : "0 2px 8px rgba(0,0,0,0.08)"};
207
+ box-shadow: ${(props) => props.$active ? `0 4px 16px ${colors$1.primary}40, 0 0 0 8px ${colors$1.primaryLight}` : props.$completed ? `0 4px 12px ${colors$1.success}30` : "0 2px 8px rgba(0,0,0,0.08)"};
208
208
 
209
209
  ${(props) => props.$active && css`
210
- animation: ${pulse$2} 2s infinite;
210
+ animation: ${pulse$3} 2s infinite;
211
211
  `}
212
212
 
213
213
  &:hover {
214
214
  transform: ${(props) => props.$completed ? "scale(1.1)" : props.$active ? "scale(1.05)" : "scale(1)"};
215
215
  }
216
216
  `;
217
- const StepLabel = styled(Typography)`
217
+ const StepLabel$1 = styled(Typography)`
218
218
  margin-top: 12px;
219
219
  font-size: 13px;
220
- color: ${(props) => props.$active ? colors.primary : props.$completed ? colors.success : colors.textLight};
220
+ color: ${(props) => props.$active ? colors$1.primary : props.$completed ? colors$1.success : colors$1.textLight};
221
221
  white-space: nowrap;
222
222
  font-weight: ${(props) => props.$active ? 600 : 500};
223
223
  text-align: center;
@@ -234,8 +234,8 @@ const ProvidersGrid = styled(Box)`
234
234
  margin-right: auto;
235
235
  `;
236
236
  const ProviderCard = styled(Box)`
237
- background: ${(props) => props.$selected ? colors.successLight : colors.white};
238
- border: 2px solid ${(props) => props.$selected ? colors.success : colors.border};
237
+ background: ${(props) => props.$selected ? colors$1.successLight : colors$1.white};
238
+ border: 2px solid ${(props) => props.$selected ? colors$1.success : colors$1.border};
239
239
  border-radius: 12px;
240
240
  padding: 24px;
241
241
  cursor: pointer;
@@ -266,7 +266,7 @@ const ProviderCard = styled(Box)`
266
266
  &:hover {
267
267
  transform: translateY(-4px);
268
268
  box-shadow: 0 8px 24px rgba(73, 69, 255, 0.12);
269
- border-color: ${(props) => props.$selected ? colors.success : colors.primary};
269
+ border-color: ${(props) => props.$selected ? colors$1.success : colors$1.primary};
270
270
 
271
271
  &::before {
272
272
  opacity: 1;
@@ -281,7 +281,7 @@ const ProviderCard = styled(Box)`
281
281
  right: 8px;
282
282
  width: 24px;
283
283
  height: 24px;
284
- background: ${colors.success};
284
+ background: ${colors$1.success};
285
285
  color: white;
286
286
  border-radius: 50%;
287
287
  display: flex;
@@ -296,33 +296,33 @@ const ProviderIcon = styled.div`
296
296
  width: 56px;
297
297
  height: 56px;
298
298
  border-radius: ${(props) => props.$round ? "50%" : "12px"};
299
- background: ${(props) => props.$bgColor || colors.primaryLight};
299
+ background: ${(props) => props.$bgColor || colors$1.primaryLight};
300
300
  display: flex;
301
301
  align-items: center;
302
302
  justify-content: center;
303
303
  font-size: ${(props) => props.$fontSize || "24px"};
304
304
  font-weight: bold;
305
- color: ${(props) => props.$color || colors.primary};
305
+ color: ${(props) => props.$color || colors$1.primary};
306
306
  box-shadow: 0 4px 12px ${(props) => props.$shadowColor || "rgba(73, 69, 255, 0.15)"};
307
307
  `;
308
308
  const ProviderName = styled(Typography)`
309
309
  font-weight: 600;
310
310
  font-size: 15px;
311
- color: ${colors.text};
311
+ color: ${colors$1.text};
312
312
  margin: 0;
313
313
  `;
314
314
  styled(Typography)`
315
315
  font-size: 12px;
316
- color: ${colors.textLight};
316
+ color: ${colors$1.textLight};
317
317
  margin: 0;
318
318
  `;
319
319
  const InfoAlert = styled(Alert)`
320
- background: ${colors.primaryLight};
321
- border: 1px solid ${colors.primary}33;
322
- animation: ${fadeIn$5} 0.4s ease;
320
+ background: ${colors$1.primaryLight};
321
+ border: 1px solid ${colors$1.primary}33;
322
+ animation: ${fadeIn$6} 0.4s ease;
323
323
 
324
324
  svg {
325
- color: ${colors.primary};
325
+ color: ${colors$1.primary};
326
326
  }
327
327
  `;
328
328
  const FormSection = styled(Box)`
@@ -342,7 +342,7 @@ const FullWidthField = styled(Box)`
342
342
  }
343
343
  `;
344
344
  const SectionTitle = styled(Typography)`
345
- color: ${colors.text};
345
+ color: ${colors$1.text};
346
346
  font-weight: 600;
347
347
  font-size: 16px;
348
348
  margin-bottom: 16px;
@@ -351,14 +351,14 @@ const SectionTitle = styled(Typography)`
351
351
  gap: 8px;
352
352
  `;
353
353
  styled(Box)`
354
- background: linear-gradient(135deg, ${colors.primaryLight}, ${colors.successLight});
355
- border: 2px solid ${colors.primary}33;
354
+ background: linear-gradient(135deg, ${colors$1.primaryLight}, ${colors$1.successLight});
355
+ border: 2px solid ${colors$1.primary}33;
356
356
  border-radius: 12px;
357
357
  padding: 20px;
358
358
  transition: all 0.3s;
359
359
 
360
360
  &:hover {
361
- border-color: ${colors.primary}66;
361
+ border-color: ${colors$1.primary}66;
362
362
  box-shadow: 0 4px 12px rgba(73, 69, 255, 0.1);
363
363
  }
364
364
  `;
@@ -858,13 +858,13 @@ const AddAccountModal = ({ isOpen, onClose, onAccountAdded, editAccount = null }
858
858
  currentStep === 4 && "Set rate limits and priority for this account"
859
859
  ] })
860
860
  ] }),
861
- /* @__PURE__ */ jsx(StepperContainer, { children: [1, 2, 3, 4].map((step) => /* @__PURE__ */ jsxs(
862
- StepWrapper,
861
+ /* @__PURE__ */ jsx(StepperContainer$1, { children: [1, 2, 3, 4].map((step) => /* @__PURE__ */ jsxs(
862
+ StepWrapper$1,
863
863
  {
864
864
  $completed: currentStep > step,
865
865
  children: [
866
866
  /* @__PURE__ */ jsx(
867
- StepDot,
867
+ StepDot$1,
868
868
  {
869
869
  $active: currentStep === step,
870
870
  $completed: currentStep > step,
@@ -873,7 +873,7 @@ const AddAccountModal = ({ isOpen, onClose, onAccountAdded, editAccount = null }
873
873
  }
874
874
  ),
875
875
  /* @__PURE__ */ jsx(
876
- StepLabel,
876
+ StepLabel$1,
877
877
  {
878
878
  $active: currentStep === step,
879
879
  $completed: currentStep > step,
@@ -1205,7 +1205,7 @@ const AddAccountModal = ({ isOpen, onClose, onAccountAdded, editAccount = null }
1205
1205
  background: "neutral100",
1206
1206
  hasRadius: true,
1207
1207
  style: {
1208
- border: `1px solid ${colors.border}`,
1208
+ border: `1px solid ${colors$1.border}`,
1209
1209
  borderRadius: "8px"
1210
1210
  },
1211
1211
  children: [
@@ -1222,7 +1222,7 @@ const AddAccountModal = ({ isOpen, onClose, onAccountAdded, editAccount = null }
1222
1222
  /* @__PURE__ */ jsxs(Box, { children: [
1223
1223
  /* @__PURE__ */ jsx("strong", { children: "1." }),
1224
1224
  " Go to ",
1225
- /* @__PURE__ */ jsx("a", { href: "https://console.cloud.google.com", target: "_blank", rel: "noopener noreferrer", style: { color: colors.primary, textDecoration: "underline" }, children: "console.cloud.google.com" })
1225
+ /* @__PURE__ */ jsx("a", { href: "https://console.cloud.google.com", target: "_blank", rel: "noopener noreferrer", style: { color: colors$1.primary, textDecoration: "underline" }, children: "console.cloud.google.com" })
1226
1226
  ] }),
1227
1227
  /* @__PURE__ */ jsxs(Box, { children: [
1228
1228
  /* @__PURE__ */ jsx("strong", { children: "2." }),
@@ -1248,7 +1248,7 @@ const AddAccountModal = ({ isOpen, onClose, onAccountAdded, editAccount = null }
1248
1248
  fontFamily: "monospace",
1249
1249
  fontSize: "13px",
1250
1250
  wordBreak: "break-all",
1251
- border: `1px solid ${colors.border}`
1251
+ border: `1px solid ${colors$1.border}`
1252
1252
  },
1253
1253
  children: [
1254
1254
  window.location.origin,
@@ -1349,7 +1349,7 @@ const AddAccountModal = ({ isOpen, onClose, onAccountAdded, editAccount = null }
1349
1349
  background: "neutral100",
1350
1350
  hasRadius: true,
1351
1351
  style: {
1352
- border: `1px solid ${colors.border}`,
1352
+ border: `1px solid ${colors$1.border}`,
1353
1353
  borderRadius: "8px"
1354
1354
  },
1355
1355
  children: [
@@ -1366,7 +1366,7 @@ const AddAccountModal = ({ isOpen, onClose, onAccountAdded, editAccount = null }
1366
1366
  /* @__PURE__ */ jsxs(Box, { children: [
1367
1367
  /* @__PURE__ */ jsx("strong", { children: "1." }),
1368
1368
  " Go to ",
1369
- /* @__PURE__ */ jsx("a", { href: "https://portal.azure.com", target: "_blank", rel: "noopener noreferrer", style: { color: colors.primary, textDecoration: "underline" }, children: "portal.azure.com" })
1369
+ /* @__PURE__ */ jsx("a", { href: "https://portal.azure.com", target: "_blank", rel: "noopener noreferrer", style: { color: colors$1.primary, textDecoration: "underline" }, children: "portal.azure.com" })
1370
1370
  ] }),
1371
1371
  /* @__PURE__ */ jsxs(Box, { children: [
1372
1372
  /* @__PURE__ */ jsx("strong", { children: "2." }),
@@ -1400,8 +1400,8 @@ const AddAccountModal = ({ isOpen, onClose, onAccountAdded, editAccount = null }
1400
1400
  fontFamily: "monospace",
1401
1401
  fontSize: "13px",
1402
1402
  wordBreak: "break-all",
1403
- color: colors.textSecondary,
1404
- border: `1px solid ${colors.border}`
1403
+ color: colors$1.textSecondary,
1404
+ border: `1px solid ${colors$1.border}`
1405
1405
  },
1406
1406
  children: `${window.location.origin}/magic-mail/oauth/microsoft/callback`
1407
1407
  }
@@ -1526,7 +1526,7 @@ const AddAccountModal = ({ isOpen, onClose, onAccountAdded, editAccount = null }
1526
1526
  background: "neutral100",
1527
1527
  hasRadius: true,
1528
1528
  style: {
1529
- border: `1px solid ${colors.border}`,
1529
+ border: `1px solid ${colors$1.border}`,
1530
1530
  borderRadius: "8px"
1531
1531
  },
1532
1532
  children: [
@@ -1543,7 +1543,7 @@ const AddAccountModal = ({ isOpen, onClose, onAccountAdded, editAccount = null }
1543
1543
  /* @__PURE__ */ jsxs(Box, { children: [
1544
1544
  /* @__PURE__ */ jsx("strong", { children: "1." }),
1545
1545
  " Go to ",
1546
- /* @__PURE__ */ jsx("a", { href: "https://developer.yahoo.com/apps/", target: "_blank", rel: "noopener noreferrer", style: { color: colors.primary, textDecoration: "underline" }, children: "developer.yahoo.com/apps" })
1546
+ /* @__PURE__ */ jsx("a", { href: "https://developer.yahoo.com/apps/", target: "_blank", rel: "noopener noreferrer", style: { color: colors$1.primary, textDecoration: "underline" }, children: "developer.yahoo.com/apps" })
1547
1547
  ] }),
1548
1548
  /* @__PURE__ */ jsxs(Box, { children: [
1549
1549
  /* @__PURE__ */ jsx("strong", { children: "2." }),
@@ -1569,8 +1569,8 @@ const AddAccountModal = ({ isOpen, onClose, onAccountAdded, editAccount = null }
1569
1569
  fontFamily: "monospace",
1570
1570
  fontSize: "13px",
1571
1571
  wordBreak: "break-all",
1572
- color: colors.textSecondary,
1573
- border: `1px solid ${colors.border}`
1572
+ color: colors$1.textSecondary,
1573
+ border: `1px solid ${colors$1.border}`
1574
1574
  },
1575
1575
  children: `${window.location.origin}/magic-mail/oauth/yahoo/callback`
1576
1576
  }
@@ -1777,7 +1777,7 @@ const AddAccountModal = ({ isOpen, onClose, onAccountAdded, editAccount = null }
1777
1777
  background: formData.isPrimary ? "#FEF3C7" : "neutral100",
1778
1778
  hasRadius: true,
1779
1779
  style: {
1780
- border: formData.isPrimary ? `2px solid #F59E0B` : `1px solid ${colors.border}`,
1780
+ border: formData.isPrimary ? `2px solid #F59E0B` : `1px solid ${colors$1.border}`,
1781
1781
  borderRadius: "8px",
1782
1782
  transition: "all 0.2s ease"
1783
1783
  },
@@ -1835,7 +1835,7 @@ const AddAccountModal = ({ isOpen, onClose, onAccountAdded, editAccount = null }
1835
1835
  ] }) })
1836
1836
  ] }) });
1837
1837
  };
1838
- const fadeIn$4 = keyframes`
1838
+ const fadeIn$5 = keyframes`
1839
1839
  from { opacity: 0; transform: translateY(10px); }
1840
1840
  to { opacity: 1; transform: translateY(0); }
1841
1841
  `;
@@ -1847,7 +1847,7 @@ const float$3 = keyframes`
1847
1847
  0%, 100% { transform: translateY(0px); }
1848
1848
  50% { transform: translateY(-5px); }
1849
1849
  `;
1850
- const pulse$1 = keyframes`
1850
+ const pulse$2 = keyframes`
1851
1851
  0%, 100% { opacity: 1; }
1852
1852
  50% { opacity: 0.5; }
1853
1853
  `;
@@ -1863,7 +1863,7 @@ const breakpoints$3 = {
1863
1863
  mobile: "768px"
1864
1864
  };
1865
1865
  const Container$4 = styled(Box)`
1866
- ${css`animation: ${fadeIn$4} ${theme$3.transitions.slow};`}
1866
+ ${css`animation: ${fadeIn$5} ${theme$3.transitions.slow};`}
1867
1867
  min-height: 100vh;
1868
1868
  max-width: 1440px;
1869
1869
  margin: 0 auto;
@@ -1981,7 +1981,7 @@ const StatCard$3 = styled(Box)`
1981
1981
  position: relative;
1982
1982
  overflow: hidden;
1983
1983
  transition: all ${theme$3.transitions.normal};
1984
- ${css`animation: ${fadeIn$4} ${theme$3.transitions.slow} backwards;`}
1984
+ ${css`animation: ${fadeIn$5} ${theme$3.transitions.slow} backwards;`}
1985
1985
  animation-delay: ${(props) => props.$delay || "0s"};
1986
1986
  box-shadow: ${theme$3.shadows.sm};
1987
1987
  border: 1px solid ${(props) => props.theme.colors.neutral200};
@@ -2107,7 +2107,7 @@ const OnlineBadge$1 = styled.div`
2107
2107
  background: ${(props) => props.$active ? theme$3.colors.success[500] : props.theme.colors.neutral400};
2108
2108
  display: inline-block;
2109
2109
  margin-right: 8px;
2110
- ${css`animation: ${(props) => props.$active ? pulse$1 : "none"} 2s ease-in-out infinite;`}
2110
+ ${css`animation: ${(props) => props.$active ? pulse$2 : "none"} 2s ease-in-out infinite;`}
2111
2111
  `;
2112
2112
  const StyledTable$3 = styled(Table)`
2113
2113
  thead {
@@ -2798,6 +2798,10 @@ const theme$2 = {
2798
2798
  danger: {
2799
2799
  100: "#FEE2E2",
2800
2800
  600: "#DC2626"
2801
+ },
2802
+ neutral: {
2803
+ 100: "#F3F4F6",
2804
+ 200: "#E5E7EB"
2801
2805
  }
2802
2806
  },
2803
2807
  shadows: {
@@ -2823,7 +2827,7 @@ const theme$2 = {
2823
2827
  xl: "16px"
2824
2828
  }
2825
2829
  };
2826
- const fadeIn$3 = keyframes`
2830
+ const fadeIn$4 = keyframes`
2827
2831
  from { opacity: 0; transform: translateY(10px); }
2828
2832
  to { opacity: 1; transform: translateY(0); }
2829
2833
  `;
@@ -2835,7 +2839,7 @@ const float$2 = keyframes`
2835
2839
  0%, 100% { transform: translateY(0px); }
2836
2840
  50% { transform: translateY(-5px); }
2837
2841
  `;
2838
- const pulse = keyframes`
2842
+ const pulse$1 = keyframes`
2839
2843
  0%, 100% { opacity: 1; }
2840
2844
  50% { opacity: 0.5; }
2841
2845
  `;
@@ -2851,7 +2855,7 @@ const breakpoints$2 = {
2851
2855
  mobile: "768px"
2852
2856
  };
2853
2857
  const Container$3 = styled(Box)`
2854
- ${css`animation: ${fadeIn$3} ${theme$2.transitions.slow};`}
2858
+ ${css`animation: ${fadeIn$4} ${theme$2.transitions.slow};`}
2855
2859
  min-height: 100vh;
2856
2860
  max-width: 1440px;
2857
2861
  margin: 0 auto;
@@ -2969,7 +2973,7 @@ const StatCard$2 = styled(Box)`
2969
2973
  position: relative;
2970
2974
  overflow: hidden;
2971
2975
  transition: all ${theme$2.transitions.normal};
2972
- ${css`animation: ${fadeIn$3} ${theme$2.transitions.slow} backwards;`}
2976
+ ${css`animation: ${fadeIn$4} ${theme$2.transitions.slow} backwards;`}
2973
2977
  animation-delay: ${(props) => props.$delay || "0s"};
2974
2978
  box-shadow: ${theme$2.shadows.sm};
2975
2979
  border: 1px solid ${(props) => props.theme.colors.neutral200};
@@ -3095,7 +3099,7 @@ const OnlineBadge = styled.div`
3095
3099
  background: ${(props) => props.$active ? theme$2.colors.success[500] : props.theme.colors.neutral400};
3096
3100
  display: inline-block;
3097
3101
  margin-right: 8px;
3098
- ${css`animation: ${(props) => props.$active ? pulse : "none"} 2s ease-in-out infinite;`}
3102
+ ${css`animation: ${(props) => props.$active ? pulse$1 : "none"} 2s ease-in-out infinite;`}
3099
3103
  `;
3100
3104
  const StyledTable$2 = styled(Table)`
3101
3105
  thead {
@@ -3394,7 +3398,8 @@ const RoutingRulesPage = () => {
3394
3398
  rule.fallbackAccountName && /* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "neutral600", children: [
3395
3399
  "Fallback: ",
3396
3400
  rule.fallbackAccountName
3397
- ] })
3401
+ ] }),
3402
+ rule.whatsappFallback && /* @__PURE__ */ jsx(Badge, { backgroundColor: "success100", textColor: "success700", size: "S", children: "+ WhatsApp" })
3398
3403
  ] }) }),
3399
3404
  /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsxs(
3400
3405
  Badge,
@@ -3461,7 +3466,8 @@ const RuleModal = ({ rule, accounts, onClose, onSave }) => {
3461
3466
  matchType: rule?.matchType || "emailType",
3462
3467
  matchValue: rule?.matchValue || "",
3463
3468
  accountName: rule?.accountName || "",
3464
- fallbackAccountName: rule?.fallbackAccountName || ""
3469
+ fallbackAccountName: rule?.fallbackAccountName || "",
3470
+ whatsappFallback: rule?.whatsappFallback || false
3465
3471
  });
3466
3472
  const handleChange = (field, value) => {
3467
3473
  setFormData((prev) => ({ ...prev, [field]: value }));
@@ -3616,6 +3622,36 @@ const RuleModal = ({ rule, accounts, onClose, onSave }) => {
3616
3622
  ),
3617
3623
  /* @__PURE__ */ jsx(Field.Hint, { children: "Use this account if the target account is unavailable or rate-limited" })
3618
3624
  ] }),
3625
+ /* @__PURE__ */ jsx(
3626
+ Box,
3627
+ {
3628
+ padding: 4,
3629
+ background: formData.whatsappFallback ? theme$2.colors.success[100] : theme$2.colors.neutral[100],
3630
+ hasRadius: true,
3631
+ style: {
3632
+ width: "100%",
3633
+ border: formData.whatsappFallback ? `2px solid ${theme$2.colors.success[600]}` : `1px solid ${theme$2.colors.neutral[200]}`,
3634
+ borderRadius: theme$2.borderRadius.md,
3635
+ transition: "all 0.2s ease"
3636
+ },
3637
+ children: /* @__PURE__ */ jsxs(Flex, { gap: 3, alignItems: "center", children: [
3638
+ /* @__PURE__ */ jsx(
3639
+ Toggle,
3640
+ {
3641
+ checked: formData.whatsappFallback,
3642
+ onChange: () => handleChange("whatsappFallback", !formData.whatsappFallback)
3643
+ }
3644
+ ),
3645
+ /* @__PURE__ */ jsxs(Box, { style: { flex: 1 }, children: [
3646
+ /* @__PURE__ */ jsxs(Flex, { alignItems: "center", gap: 2, children: [
3647
+ /* @__PURE__ */ jsx(Typography, { fontWeight: "semiBold", children: "WhatsApp Fallback" }),
3648
+ formData.whatsappFallback && /* @__PURE__ */ jsx(Badge, { backgroundColor: "success600", textColor: "neutral0", size: "S", children: "ENABLED" })
3649
+ ] }),
3650
+ /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", marginTop: 1, children: formData.whatsappFallback ? "If ALL email accounts fail, message will be sent via WhatsApp (requires connected WhatsApp & phone number in email data)" : "Enable to use WhatsApp as last-resort fallback when email delivery fails" })
3651
+ ] })
3652
+ ] })
3653
+ }
3654
+ ),
3619
3655
  /* @__PURE__ */ jsxs(Field.Root, { style: { width: "100%" }, children: [
3620
3656
  /* @__PURE__ */ jsx(Field.Label, { children: "Rule Priority" }),
3621
3657
  /* @__PURE__ */ jsx(
@@ -3819,7 +3855,7 @@ const theme$1 = {
3819
3855
  spacing: { xs: "4px", sm: "8px", md: "16px", lg: "24px", xl: "32px", "2xl": "48px" },
3820
3856
  borderRadius: { md: "8px", lg: "12px", xl: "16px" }
3821
3857
  };
3822
- const fadeIn$2 = keyframes`
3858
+ const fadeIn$3 = keyframes`
3823
3859
  from { opacity: 0; transform: translateY(10px); }
3824
3860
  to { opacity: 1; transform: translateY(0); }
3825
3861
  `;
@@ -3972,7 +4008,7 @@ const CopyButton = styled(Button)`
3972
4008
  height: 14px;
3973
4009
  }
3974
4010
  `;
3975
- const InfoBox = styled(Box)`
4011
+ const InfoBox$1 = styled(Box)`
3976
4012
  background: linear-gradient(135deg, ${theme$1.colors.primary[50]}, ${theme$1.colors.primary[100]});
3977
4013
  border-left: 4px solid ${theme$1.colors.primary[500]};
3978
4014
  border-radius: 8px;
@@ -4019,7 +4055,7 @@ const breakpoints$1 = {
4019
4055
  tablet: "1024px"
4020
4056
  };
4021
4057
  const Container$2 = styled(Box)`
4022
- ${css`animation: ${fadeIn$2} ${theme$1.transitions.slow};`}
4058
+ ${css`animation: ${fadeIn$3} ${theme$1.transitions.slow};`}
4023
4059
  min-height: 100vh;
4024
4060
  max-width: 1440px;
4025
4061
  margin: 0 auto;
@@ -4132,7 +4168,7 @@ const StatCard$1 = styled(Box)`
4132
4168
  position: relative;
4133
4169
  overflow: hidden;
4134
4170
  transition: all ${theme$1.transitions.normal};
4135
- ${css`animation: ${fadeIn$2} ${theme$1.transitions.slow} backwards;`}
4171
+ ${css`animation: ${fadeIn$3} ${theme$1.transitions.slow} backwards;`}
4136
4172
  animation-delay: ${(props) => props.$delay || "0s"};
4137
4173
  box-shadow: ${theme$1.shadows.sm};
4138
4174
  border: 1px solid ${(props) => props.theme.colors.neutral200};
@@ -5212,7 +5248,7 @@ const TemplateList = () => {
5212
5248
  )
5213
5249
  ] })
5214
5250
  ] }),
5215
- /* @__PURE__ */ jsx(InfoBox, { children: /* @__PURE__ */ jsxs(Flex, { alignItems: "center", justifyContent: "space-between", children: [
5251
+ /* @__PURE__ */ jsx(InfoBox$1, { children: /* @__PURE__ */ jsxs(Flex, { alignItems: "center", justifyContent: "space-between", children: [
5216
5252
  /* @__PURE__ */ jsxs(Typography, { variant: "pi", style: { color: theme$1.colors.primary[700] }, children: [
5217
5253
  /* @__PURE__ */ jsx("strong", { children: "Template ID:" }),
5218
5254
  " #",
@@ -6512,7 +6548,7 @@ const theme = {
6512
6548
  spacing: { xs: "4px", sm: "8px", md: "16px", lg: "24px", xl: "32px", "2xl": "48px" },
6513
6549
  borderRadius: { lg: "12px", xl: "16px" }
6514
6550
  };
6515
- const fadeIn$1 = keyframes`
6551
+ const fadeIn$2 = keyframes`
6516
6552
  from { opacity: 0; transform: translateY(10px); }
6517
6553
  to { opacity: 1; transform: translateY(0); }
6518
6554
  `;
@@ -6528,7 +6564,7 @@ const breakpoints = {
6528
6564
  mobile: "768px"
6529
6565
  };
6530
6566
  const Container = styled(Box)`
6531
- ${css`animation: ${fadeIn$1} ${theme.transitions.slow};`}
6567
+ ${css`animation: ${fadeIn$2} ${theme.transitions.slow};`}
6532
6568
  min-height: 100vh;
6533
6569
  max-width: 1440px;
6534
6570
  margin: 0 auto;
@@ -6641,7 +6677,7 @@ const StatCard = styled(Box)`
6641
6677
  position: relative;
6642
6678
  overflow: hidden;
6643
6679
  transition: all ${theme.transitions.normal};
6644
- ${css`animation: ${fadeIn$1} ${theme.transitions.slow} backwards;`}
6680
+ ${css`animation: ${fadeIn$2} ${theme.transitions.slow} backwards;`}
6645
6681
  animation-delay: ${(props) => props.$delay || "0s"};
6646
6682
  box-shadow: ${theme.shadows.sm};
6647
6683
  border: 1px solid ${(props) => props.theme.colors.neutral200};
@@ -7077,6 +7113,679 @@ const Analytics = () => {
7077
7113
  ] }) })
7078
7114
  ] });
7079
7115
  };
7116
+ const fadeIn$1 = keyframes`
7117
+ from {
7118
+ opacity: 0;
7119
+ transform: translateY(10px);
7120
+ }
7121
+ to {
7122
+ opacity: 1;
7123
+ transform: translateY(0);
7124
+ }
7125
+ `;
7126
+ const pulse = keyframes`
7127
+ 0%, 100% {
7128
+ transform: scale(1);
7129
+ }
7130
+ 50% {
7131
+ transform: scale(1.05);
7132
+ }
7133
+ `;
7134
+ const spin = keyframes`
7135
+ from {
7136
+ transform: rotate(0deg);
7137
+ }
7138
+ to {
7139
+ transform: rotate(360deg);
7140
+ }
7141
+ `;
7142
+ const colors = {
7143
+ whatsapp: "#25D366",
7144
+ whatsappDark: "#128C7E",
7145
+ whatsappLight: "#DCF8C6",
7146
+ primary: "#4945ff",
7147
+ primaryLight: "#f0f0ff",
7148
+ success: "#5cb176",
7149
+ successLight: "#eafaf1",
7150
+ danger: "#d02b20",
7151
+ neutral: "#8e8ea9",
7152
+ neutralLight: "#f6f6f9",
7153
+ white: "#ffffff",
7154
+ border: "#dcdce4",
7155
+ textLight: "#666687"
7156
+ };
7157
+ const PageContainer = styled(Box)`
7158
+ padding: 40px;
7159
+ max-width: 900px;
7160
+ margin: 0 auto;
7161
+ animation: ${fadeIn$1} 0.4s ease;
7162
+ `;
7163
+ const HeaderSection = styled(Box)`
7164
+ text-align: center;
7165
+ margin-bottom: 48px;
7166
+ `;
7167
+ const WhatsAppLogo = styled.div`
7168
+ width: 80px;
7169
+ height: 80px;
7170
+ border-radius: 50%;
7171
+ background: linear-gradient(135deg, ${colors.whatsapp}, ${colors.whatsappDark});
7172
+ display: flex;
7173
+ align-items: center;
7174
+ justify-content: center;
7175
+ margin: 0 auto 24px;
7176
+ box-shadow: 0 8px 32px ${colors.whatsapp}40;
7177
+ `;
7178
+ const PhoneIcon = styled.div`
7179
+ width: 40px;
7180
+ height: 40px;
7181
+ color: white;
7182
+ font-size: 32px;
7183
+ `;
7184
+ const StepperContainer = styled(Box)`
7185
+ display: flex;
7186
+ align-items: flex-start;
7187
+ justify-content: center;
7188
+ gap: 0;
7189
+ margin-bottom: 48px;
7190
+ position: relative;
7191
+ padding: 0 40px;
7192
+ `;
7193
+ const StepWrapper = styled.div`
7194
+ flex: 1;
7195
+ display: flex;
7196
+ flex-direction: column;
7197
+ align-items: center;
7198
+ position: relative;
7199
+
7200
+ &:not(:last-child)::after {
7201
+ content: '';
7202
+ position: absolute;
7203
+ top: 28px;
7204
+ left: 50%;
7205
+ width: 100%;
7206
+ height: 3px;
7207
+ background: ${(props) => props.$completed ? colors.success : colors.neutralLight};
7208
+ transition: all 0.4s ease;
7209
+ z-index: 0;
7210
+ }
7211
+ `;
7212
+ const StepDot = styled.div`
7213
+ width: 56px;
7214
+ height: 56px;
7215
+ border-radius: 50%;
7216
+ background: ${(props) => props.$active ? colors.whatsapp : props.$completed ? colors.success : colors.white};
7217
+ color: ${(props) => props.$active || props.$completed ? colors.white : colors.textLight};
7218
+ border: 4px solid ${(props) => props.$active ? colors.whatsapp : props.$completed ? colors.success : colors.border};
7219
+ display: flex;
7220
+ align-items: center;
7221
+ justify-content: center;
7222
+ font-weight: 700;
7223
+ font-size: 18px;
7224
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
7225
+ position: relative;
7226
+ z-index: 1;
7227
+ cursor: ${(props) => props.$completed ? "pointer" : "default"};
7228
+ box-shadow: ${(props) => props.$active ? `0 4px 16px ${colors.whatsapp}40, 0 0 0 8px ${colors.whatsappLight}` : props.$completed ? `0 4px 12px ${colors.success}30` : "0 2px 8px rgba(0,0,0,0.08)"};
7229
+
7230
+ ${(props) => props.$active && css`
7231
+ animation: ${pulse} 2s infinite;
7232
+ `}
7233
+
7234
+ &:hover {
7235
+ transform: ${(props) => props.$completed ? "scale(1.1)" : props.$active ? "scale(1.05)" : "scale(1)"};
7236
+ }
7237
+ `;
7238
+ const StepLabel = styled(Typography)`
7239
+ margin-top: 12px;
7240
+ font-size: 13px;
7241
+ color: ${(props) => props.$active ? colors.whatsapp : props.$completed ? colors.success : colors.textLight};
7242
+ white-space: nowrap;
7243
+ font-weight: ${(props) => props.$active ? 600 : 500};
7244
+ text-align: center;
7245
+ transition: all 0.3s ease;
7246
+ `;
7247
+ const ContentCard = styled(Box)`
7248
+ background: ${colors.white};
7249
+ border: 1px solid ${colors.border};
7250
+ border-radius: 16px;
7251
+ padding: 32px;
7252
+ margin-bottom: 24px;
7253
+ animation: ${fadeIn$1} 0.4s ease;
7254
+ box-shadow: 0 4px 24px rgba(0,0,0,0.06);
7255
+ `;
7256
+ const QRCodeContainer = styled.div`
7257
+ display: flex;
7258
+ flex-direction: column;
7259
+ align-items: center;
7260
+ padding: 32px;
7261
+ background: ${colors.neutralLight};
7262
+ border-radius: 16px;
7263
+ margin: 24px 0;
7264
+ `;
7265
+ const QRImage = styled.img`
7266
+ width: 280px;
7267
+ height: 280px;
7268
+ border-radius: 12px;
7269
+ box-shadow: 0 4px 24px rgba(0,0,0,0.1);
7270
+ `;
7271
+ const StatusBadge = styled.div`
7272
+ display: inline-flex;
7273
+ align-items: center;
7274
+ gap: 8px;
7275
+ padding: 8px 16px;
7276
+ border-radius: 20px;
7277
+ font-weight: 600;
7278
+ font-size: 14px;
7279
+ background: ${(props) => {
7280
+ switch (props.$status) {
7281
+ case "connected":
7282
+ return colors.successLight;
7283
+ case "connecting":
7284
+ return colors.primaryLight;
7285
+ case "qr_pending":
7286
+ return colors.whatsappLight;
7287
+ case "disconnected":
7288
+ return colors.neutralLight;
7289
+ default:
7290
+ return colors.neutralLight;
7291
+ }
7292
+ }};
7293
+ color: ${(props) => {
7294
+ switch (props.$status) {
7295
+ case "connected":
7296
+ return colors.success;
7297
+ case "connecting":
7298
+ return colors.primary;
7299
+ case "qr_pending":
7300
+ return colors.whatsappDark;
7301
+ case "disconnected":
7302
+ return colors.neutral;
7303
+ default:
7304
+ return colors.neutral;
7305
+ }
7306
+ }};
7307
+ `;
7308
+ const SpinningLoader = styled.div`
7309
+ width: 20px;
7310
+ height: 20px;
7311
+ border: 2px solid ${colors.primary}40;
7312
+ border-top-color: ${colors.primary};
7313
+ border-radius: 50%;
7314
+ animation: ${spin} 1s linear infinite;
7315
+ `;
7316
+ const ConnectedCard = styled(Box)`
7317
+ background: linear-gradient(135deg, ${colors.successLight}, ${colors.whatsappLight});
7318
+ border: 2px solid ${colors.success};
7319
+ border-radius: 16px;
7320
+ padding: 32px;
7321
+ text-align: center;
7322
+ `;
7323
+ const InfoBox = styled(Box)`
7324
+ background: ${colors.primaryLight};
7325
+ border: 1px solid ${colors.primary}33;
7326
+ border-radius: 12px;
7327
+ padding: 20px;
7328
+ margin: 16px 0;
7329
+ `;
7330
+ const TestSection = styled(Box)`
7331
+ background: ${colors.neutralLight};
7332
+ border-radius: 12px;
7333
+ padding: 24px;
7334
+ margin-top: 24px;
7335
+ `;
7336
+ const UseCaseCard = styled(Box)`
7337
+ background: linear-gradient(135deg, ${colors.primaryLight}, ${colors.whatsappLight});
7338
+ border: 2px solid ${colors.whatsapp};
7339
+ border-radius: 16px;
7340
+ padding: 24px;
7341
+ margin-bottom: 32px;
7342
+ `;
7343
+ const ButtonRow = styled(Flex)`
7344
+ margin-top: 32px;
7345
+ padding-top: 24px;
7346
+ border-top: 1px solid ${colors.border};
7347
+ `;
7348
+ const NotInstalledCard = styled(Box)`
7349
+ background: linear-gradient(135deg, #FEF3C7, #FEE2E2);
7350
+ border: 2px solid #F59E0B;
7351
+ border-radius: 16px;
7352
+ padding: 32px;
7353
+ text-align: center;
7354
+ `;
7355
+ const WhatsAppPage = () => {
7356
+ const { get, post } = useFetchClient();
7357
+ const { toggleNotification } = useNotification();
7358
+ const [currentStep, setCurrentStep] = useState(1);
7359
+ const [loading, setLoading] = useState(true);
7360
+ const [connecting, setConnecting] = useState(false);
7361
+ const [isAvailable, setIsAvailable] = useState(false);
7362
+ const [status, setStatus] = useState({
7363
+ status: "disconnected",
7364
+ qrCode: null,
7365
+ isConnected: false,
7366
+ session: null
7367
+ });
7368
+ const [testPhone, setTestPhone] = useState("");
7369
+ const [testMessage, setTestMessage] = useState("");
7370
+ const [sendingTest, setSendingTest] = useState(false);
7371
+ const stepTitles = ["Check Installation", "Connect WhatsApp", "Scan QR Code", "Ready to Use"];
7372
+ const checkAvailability = useCallback(async () => {
7373
+ try {
7374
+ const { data } = await get("/magic-mail/whatsapp/available");
7375
+ setIsAvailable(data.data.available);
7376
+ return data.data.available;
7377
+ } catch (error) {
7378
+ console.error("[MagicMail WhatsApp] Error checking availability:", error);
7379
+ setIsAvailable(false);
7380
+ return false;
7381
+ }
7382
+ }, [get]);
7383
+ const fetchStatus = useCallback(async () => {
7384
+ try {
7385
+ const { data } = await get("/magic-mail/whatsapp/status");
7386
+ setStatus(data.data);
7387
+ if (data.data.isConnected) {
7388
+ setCurrentStep(4);
7389
+ } else if (data.data.qrCode) {
7390
+ setCurrentStep(3);
7391
+ } else if (isAvailable) {
7392
+ setCurrentStep(2);
7393
+ }
7394
+ return data.data;
7395
+ } catch (error) {
7396
+ console.error("[MagicMail WhatsApp] Error fetching status:", error);
7397
+ return null;
7398
+ }
7399
+ }, [get, isAvailable]);
7400
+ useEffect(() => {
7401
+ const init = async () => {
7402
+ setLoading(true);
7403
+ const available = await checkAvailability();
7404
+ if (available) {
7405
+ await fetchStatus();
7406
+ }
7407
+ setLoading(false);
7408
+ };
7409
+ init();
7410
+ }, [checkAvailability, fetchStatus]);
7411
+ useEffect(() => {
7412
+ let pollInterval;
7413
+ if (connecting || status.status === "connecting" || status.status === "qr_pending") {
7414
+ pollInterval = setInterval(async () => {
7415
+ const newStatus = await fetchStatus();
7416
+ if (newStatus?.isConnected) {
7417
+ setConnecting(false);
7418
+ setCurrentStep(4);
7419
+ toggleNotification({
7420
+ type: "success",
7421
+ message: "[SUCCESS] WhatsApp connected successfully!"
7422
+ });
7423
+ }
7424
+ }, 2e3);
7425
+ }
7426
+ return () => {
7427
+ if (pollInterval) clearInterval(pollInterval);
7428
+ };
7429
+ }, [connecting, status.status, fetchStatus, toggleNotification]);
7430
+ const handleConnect = async () => {
7431
+ setConnecting(true);
7432
+ try {
7433
+ const { data } = await post("/magic-mail/whatsapp/connect", {});
7434
+ if (data.data.qrCode) {
7435
+ setStatus((prev) => ({ ...prev, qrCode: data.data.qrCode, status: "qr_pending" }));
7436
+ setCurrentStep(3);
7437
+ } else if (data.data.status === "connected") {
7438
+ setStatus((prev) => ({ ...prev, isConnected: true, status: "connected" }));
7439
+ setCurrentStep(4);
7440
+ toggleNotification({
7441
+ type: "success",
7442
+ message: "[SUCCESS] WhatsApp already connected!"
7443
+ });
7444
+ }
7445
+ } catch (error) {
7446
+ toggleNotification({
7447
+ type: "danger",
7448
+ message: "[ERROR] Failed to connect: " + (error.response?.data?.error?.message || error.message)
7449
+ });
7450
+ setConnecting(false);
7451
+ }
7452
+ };
7453
+ const handleDisconnect = async () => {
7454
+ try {
7455
+ await post("/magic-mail/whatsapp/disconnect", {});
7456
+ setStatus({
7457
+ status: "disconnected",
7458
+ qrCode: null,
7459
+ isConnected: false,
7460
+ session: null
7461
+ });
7462
+ setCurrentStep(2);
7463
+ toggleNotification({
7464
+ type: "success",
7465
+ message: "[SUCCESS] WhatsApp disconnected"
7466
+ });
7467
+ } catch (error) {
7468
+ toggleNotification({
7469
+ type: "danger",
7470
+ message: "[ERROR] Failed to disconnect"
7471
+ });
7472
+ }
7473
+ };
7474
+ const handleSendTest = async () => {
7475
+ if (!testPhone) {
7476
+ toggleNotification({
7477
+ type: "warning",
7478
+ message: "Please enter a phone number"
7479
+ });
7480
+ return;
7481
+ }
7482
+ setSendingTest(true);
7483
+ try {
7484
+ const { data } = await post("/magic-mail/whatsapp/send-test", {
7485
+ phoneNumber: testPhone,
7486
+ message: testMessage || void 0
7487
+ });
7488
+ if (data.success) {
7489
+ toggleNotification({
7490
+ type: "success",
7491
+ message: "[SUCCESS] Test message sent!"
7492
+ });
7493
+ setTestPhone("");
7494
+ setTestMessage("");
7495
+ } else {
7496
+ toggleNotification({
7497
+ type: "danger",
7498
+ message: "[ERROR] " + (data.data.error || "Failed to send message")
7499
+ });
7500
+ }
7501
+ } catch (error) {
7502
+ toggleNotification({
7503
+ type: "danger",
7504
+ message: "[ERROR] " + (error.response?.data?.error?.message || error.message)
7505
+ });
7506
+ } finally {
7507
+ setSendingTest(false);
7508
+ }
7509
+ };
7510
+ const renderStatusBadge = () => {
7511
+ const statusText = {
7512
+ connected: "Connected",
7513
+ connecting: "Connecting...",
7514
+ qr_pending: "Waiting for QR Scan",
7515
+ disconnected: "Disconnected"
7516
+ };
7517
+ return /* @__PURE__ */ jsxs(StatusBadge, { $status: status.status, children: [
7518
+ status.status === "connecting" && /* @__PURE__ */ jsx(SpinningLoader, {}),
7519
+ status.status === "connected" && /* @__PURE__ */ jsx(Check, {}),
7520
+ statusText[status.status] || "Unknown"
7521
+ ] });
7522
+ };
7523
+ if (loading) {
7524
+ return /* @__PURE__ */ jsx(PageContainer, { children: /* @__PURE__ */ jsx(Flex, { justifyContent: "center", alignItems: "center", style: { minHeight: "400px" }, children: /* @__PURE__ */ jsx(Loader, {}) }) });
7525
+ }
7526
+ return /* @__PURE__ */ jsxs(PageContainer, { children: [
7527
+ /* @__PURE__ */ jsxs(HeaderSection, { children: [
7528
+ /* @__PURE__ */ jsx(WhatsAppLogo, { children: /* @__PURE__ */ jsx(PhoneIcon, { children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: "40", height: "40", children: /* @__PURE__ */ jsx("path", { d: "M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z" }) }) }) }),
7529
+ /* @__PURE__ */ jsx(Typography, { variant: "alpha", fontWeight: "bold", style: { display: "block", marginBottom: "8px" }, children: "WhatsApp Integration" }),
7530
+ /* @__PURE__ */ jsx(Typography, { variant: "epsilon", textColor: "neutral600", style: { display: "block" }, children: "Send messages via WhatsApp - completely free!" }),
7531
+ /* @__PURE__ */ jsx(Box, { marginTop: 3, children: renderStatusBadge() })
7532
+ ] }),
7533
+ /* @__PURE__ */ jsx(StepperContainer, { children: [1, 2, 3, 4].map((step) => /* @__PURE__ */ jsxs(
7534
+ StepWrapper,
7535
+ {
7536
+ $completed: currentStep > step,
7537
+ children: [
7538
+ /* @__PURE__ */ jsx(
7539
+ StepDot,
7540
+ {
7541
+ $active: currentStep === step,
7542
+ $completed: currentStep > step,
7543
+ onClick: () => currentStep > step && setCurrentStep(step),
7544
+ children: currentStep > step ? /* @__PURE__ */ jsx(Check, {}) : step
7545
+ }
7546
+ ),
7547
+ /* @__PURE__ */ jsx(
7548
+ StepLabel,
7549
+ {
7550
+ $active: currentStep === step,
7551
+ $completed: currentStep > step,
7552
+ children: stepTitles[step - 1]
7553
+ }
7554
+ )
7555
+ ]
7556
+ },
7557
+ step
7558
+ )) }),
7559
+ /* @__PURE__ */ jsxs(UseCaseCard, { children: [
7560
+ /* @__PURE__ */ jsx(Typography, { variant: "delta", fontWeight: "bold", style: { display: "block", marginBottom: "12px" }, children: "What can you do with WhatsApp?" }),
7561
+ /* @__PURE__ */ jsx(Typography, { variant: "omega", textColor: "neutral700", style: { display: "block", marginBottom: "16px" }, children: "WhatsApp integration provides free messaging as an alternative or backup to email delivery." }),
7562
+ /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 3, children: [
7563
+ /* @__PURE__ */ jsxs(Box, { padding: 3, background: "neutral0", hasRadius: true, style: { border: `1px solid ${colors.border}` }, children: [
7564
+ /* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", style: { display: "block", marginBottom: "4px" }, children: "1. FALLBACK-KANAL" }),
7565
+ /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", style: { display: "block" }, children: "Wenn alle Email-Accounts fehlschlagen, wird die Nachricht automatisch via WhatsApp zugestellt." })
7566
+ ] }),
7567
+ /* @__PURE__ */ jsxs(Box, { padding: 3, background: "neutral0", hasRadius: true, style: { border: `1px solid ${colors.border}` }, children: [
7568
+ /* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", style: { display: "block", marginBottom: "4px" }, children: "2. ADMIN-BENACHRICHTIGUNGEN" }),
7569
+ /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", style: { display: "block" }, children: "Bei Email-Bounces, Quota-Limits oder Account-Fehlern wird der Admin via WhatsApp benachrichtigt." })
7570
+ ] }),
7571
+ /* @__PURE__ */ jsxs(Box, { padding: 3, background: "neutral0", hasRadius: true, style: { border: `1px solid ${colors.border}` }, children: [
7572
+ /* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", style: { display: "block", marginBottom: "4px" }, children: "3. ROUTING-INTEGRATION" }),
7573
+ /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", style: { display: "block" }, children: "In Routing-Regeln kann WhatsApp als Fallback-Kanal definiert werden (Routing Rules Tab)." })
7574
+ ] })
7575
+ ] })
7576
+ ] }),
7577
+ currentStep === 1 && /* @__PURE__ */ jsxs(ContentCard, { children: [
7578
+ /* @__PURE__ */ jsx(Typography, { variant: "beta", fontWeight: "bold", style: { display: "block", marginBottom: "8px" }, children: "Check Installation" }),
7579
+ /* @__PURE__ */ jsx(Typography, { variant: "omega", textColor: "neutral600", style: { display: "block", marginBottom: "24px" }, children: "First, we need to verify that the required dependencies are installed." }),
7580
+ isAvailable ? /* @__PURE__ */ jsx(Alert, { variant: "success", title: "[SUCCESS] Dependencies Installed", children: /* @__PURE__ */ jsx(Typography, { variant: "pi", style: { display: "block" }, children: "Baileys library is installed and ready to use. You can proceed to connect your WhatsApp account." }) }) : /* @__PURE__ */ jsxs(NotInstalledCard, { children: [
7581
+ /* @__PURE__ */ jsx(Typography, { variant: "beta", fontWeight: "bold", style: { display: "block", marginBottom: "12px", color: colors.danger }, children: "[WARNING] Dependencies Not Installed" }),
7582
+ /* @__PURE__ */ jsx(Typography, { variant: "omega", textColor: "neutral600", style: { display: "block", marginBottom: "16px" }, children: "The WhatsApp integration requires additional dependencies. Please install them:" }),
7583
+ /* @__PURE__ */ jsx(
7584
+ Box,
7585
+ {
7586
+ padding: 4,
7587
+ background: "neutral0",
7588
+ hasRadius: true,
7589
+ style: {
7590
+ fontFamily: "monospace",
7591
+ fontSize: "14px",
7592
+ border: `1px solid ${colors.border}`,
7593
+ marginBottom: "16px"
7594
+ },
7595
+ children: "npm install @whiskeysockets/baileys pino qrcode"
7596
+ }
7597
+ ),
7598
+ /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: "After installing, restart your Strapi server and refresh this page." })
7599
+ ] }),
7600
+ /* @__PURE__ */ jsxs(ButtonRow, { justifyContent: "flex-end", children: [
7601
+ /* @__PURE__ */ jsx(
7602
+ Button,
7603
+ {
7604
+ onClick: () => {
7605
+ checkAvailability();
7606
+ },
7607
+ variant: "secondary",
7608
+ startIcon: /* @__PURE__ */ jsx(ArrowClockwise, {}),
7609
+ style: { marginRight: "12px" },
7610
+ children: "Refresh"
7611
+ }
7612
+ ),
7613
+ /* @__PURE__ */ jsx(
7614
+ Button,
7615
+ {
7616
+ onClick: () => setCurrentStep(2),
7617
+ disabled: !isAvailable,
7618
+ endIcon: /* @__PURE__ */ jsx(ArrowRight, {}),
7619
+ children: "Continue"
7620
+ }
7621
+ )
7622
+ ] })
7623
+ ] }),
7624
+ currentStep === 2 && /* @__PURE__ */ jsxs(ContentCard, { children: [
7625
+ /* @__PURE__ */ jsx(Typography, { variant: "beta", fontWeight: "bold", style: { display: "block", marginBottom: "8px" }, children: "Connect Your WhatsApp" }),
7626
+ /* @__PURE__ */ jsx(Typography, { variant: "omega", textColor: "neutral600", style: { display: "block", marginBottom: "24px" }, children: "Click the button below to start the connection process. A QR code will be generated for you to scan." }),
7627
+ /* @__PURE__ */ jsxs(InfoBox, { children: [
7628
+ /* @__PURE__ */ jsx(Typography, { variant: "delta", fontWeight: "bold", style: { display: "block", marginBottom: "12px" }, children: "How it works" }),
7629
+ /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, children: [
7630
+ /* @__PURE__ */ jsx(Typography, { variant: "omega", children: '1. Click "Connect WhatsApp" to generate a QR code' }),
7631
+ /* @__PURE__ */ jsx(Typography, { variant: "omega", children: "2. Open WhatsApp on your phone" }),
7632
+ /* @__PURE__ */ jsx(Typography, { variant: "omega", children: "3. Go to Settings - Linked Devices - Link a Device" }),
7633
+ /* @__PURE__ */ jsx(Typography, { variant: "omega", children: "4. Scan the QR code with your phone" })
7634
+ ] })
7635
+ ] }),
7636
+ /* @__PURE__ */ jsx(Alert, { variant: "default", title: "Session Persistence", style: { marginTop: "16px" }, children: /* @__PURE__ */ jsx(Typography, { variant: "pi", children: "Your WhatsApp session will be saved. You won't need to scan the QR code again unless you manually disconnect or your session expires." }) }),
7637
+ /* @__PURE__ */ jsxs(ButtonRow, { justifyContent: "space-between", children: [
7638
+ /* @__PURE__ */ jsx(
7639
+ Button,
7640
+ {
7641
+ onClick: () => setCurrentStep(1),
7642
+ variant: "tertiary",
7643
+ startIcon: /* @__PURE__ */ jsx(ArrowLeft, {}),
7644
+ children: "Back"
7645
+ }
7646
+ ),
7647
+ /* @__PURE__ */ jsx(
7648
+ Button,
7649
+ {
7650
+ onClick: handleConnect,
7651
+ loading: connecting,
7652
+ style: { background: colors.whatsapp },
7653
+ startIcon: /* @__PURE__ */ jsx(Play, {}),
7654
+ children: "Connect WhatsApp"
7655
+ }
7656
+ )
7657
+ ] })
7658
+ ] }),
7659
+ currentStep === 3 && /* @__PURE__ */ jsxs(ContentCard, { children: [
7660
+ /* @__PURE__ */ jsx(Typography, { variant: "beta", fontWeight: "bold", style: { display: "block", marginBottom: "8px" }, children: "Scan QR Code" }),
7661
+ /* @__PURE__ */ jsx(Typography, { variant: "omega", textColor: "neutral600", style: { display: "block", marginBottom: "24px" }, children: "Open WhatsApp on your phone and scan this QR code to connect." }),
7662
+ /* @__PURE__ */ jsx(QRCodeContainer, { children: status.qrCode ? /* @__PURE__ */ jsxs(Fragment, { children: [
7663
+ /* @__PURE__ */ jsx(QRImage, { src: status.qrCode, alt: "WhatsApp QR Code" }),
7664
+ /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", style: { marginTop: "16px" }, children: 'QR code expires in 60 seconds. If it expires, click "Refresh QR".' })
7665
+ ] }) : /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "center", gap: 3, children: [
7666
+ /* @__PURE__ */ jsx(SpinningLoader, { style: { width: "40px", height: "40px" } }),
7667
+ /* @__PURE__ */ jsx(Typography, { variant: "omega", children: "Generating QR code..." })
7668
+ ] }) }),
7669
+ /* @__PURE__ */ jsxs(Alert, { variant: "default", title: "Instructions", children: [
7670
+ /* @__PURE__ */ jsx(Typography, { variant: "pi", children: "1. Open WhatsApp on your phone" }),
7671
+ /* @__PURE__ */ jsx(Typography, { variant: "pi", children: "2. Tap Menu or Settings" }),
7672
+ /* @__PURE__ */ jsx(Typography, { variant: "pi", children: '3. Select "Linked Devices"' }),
7673
+ /* @__PURE__ */ jsx(Typography, { variant: "pi", children: '4. Tap "Link a Device"' }),
7674
+ /* @__PURE__ */ jsx(Typography, { variant: "pi", children: "5. Point your phone camera at this QR code" })
7675
+ ] }),
7676
+ /* @__PURE__ */ jsxs(ButtonRow, { justifyContent: "space-between", children: [
7677
+ /* @__PURE__ */ jsx(
7678
+ Button,
7679
+ {
7680
+ onClick: () => setCurrentStep(2),
7681
+ variant: "tertiary",
7682
+ startIcon: /* @__PURE__ */ jsx(ArrowLeft, {}),
7683
+ children: "Back"
7684
+ }
7685
+ ),
7686
+ /* @__PURE__ */ jsx(
7687
+ Button,
7688
+ {
7689
+ onClick: handleConnect,
7690
+ variant: "secondary",
7691
+ startIcon: /* @__PURE__ */ jsx(ArrowClockwise, {}),
7692
+ children: "Refresh QR"
7693
+ }
7694
+ )
7695
+ ] })
7696
+ ] }),
7697
+ currentStep === 4 && /* @__PURE__ */ jsxs(Fragment, { children: [
7698
+ /* @__PURE__ */ jsxs(ConnectedCard, { children: [
7699
+ /* @__PURE__ */ jsx(Box, { marginBottom: 4, children: /* @__PURE__ */ jsx(Check, { style: { width: "48px", height: "48px", color: colors.success } }) }),
7700
+ /* @__PURE__ */ jsx(Typography, { variant: "alpha", fontWeight: "bold", style: { display: "block", marginBottom: "8px" }, children: "WhatsApp Connected" }),
7701
+ status.session && /* @__PURE__ */ jsxs(Typography, { variant: "omega", textColor: "neutral600", style: { display: "block" }, children: [
7702
+ "Connected as: ",
7703
+ status.session.phoneNumber,
7704
+ " ",
7705
+ status.session.name && `(${status.session.name})`
7706
+ ] })
7707
+ ] }),
7708
+ /* @__PURE__ */ jsxs(ContentCard, { style: { marginTop: "24px" }, children: [
7709
+ /* @__PURE__ */ jsx(Typography, { variant: "beta", fontWeight: "bold", style: { display: "block", marginBottom: "8px" }, children: "Send Test Message" }),
7710
+ /* @__PURE__ */ jsx(Typography, { variant: "omega", textColor: "neutral600", style: { display: "block", marginBottom: "24px" }, children: "Test your WhatsApp connection by sending a message." }),
7711
+ /* @__PURE__ */ jsx(TestSection, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 4, children: [
7712
+ /* @__PURE__ */ jsxs(Field.Root, { children: [
7713
+ /* @__PURE__ */ jsx(Field.Label, { children: "Phone Number" }),
7714
+ /* @__PURE__ */ jsx(
7715
+ TextInput,
7716
+ {
7717
+ placeholder: "49123456789 (with country code, no +)",
7718
+ value: testPhone,
7719
+ onChange: (e) => setTestPhone(e.target.value)
7720
+ }
7721
+ ),
7722
+ /* @__PURE__ */ jsx(Field.Hint, { children: "Enter phone number with country code (e.g., 49 for Germany)" })
7723
+ ] }),
7724
+ /* @__PURE__ */ jsxs(Field.Root, { children: [
7725
+ /* @__PURE__ */ jsx(Field.Label, { children: "Message (optional)" }),
7726
+ /* @__PURE__ */ jsx(
7727
+ TextInput,
7728
+ {
7729
+ placeholder: "Leave empty for default test message",
7730
+ value: testMessage,
7731
+ onChange: (e) => setTestMessage(e.target.value)
7732
+ }
7733
+ )
7734
+ ] }),
7735
+ /* @__PURE__ */ jsx(
7736
+ Button,
7737
+ {
7738
+ onClick: handleSendTest,
7739
+ loading: sendingTest,
7740
+ style: { background: colors.whatsapp },
7741
+ children: "Send Test Message"
7742
+ }
7743
+ )
7744
+ ] }) }),
7745
+ /* @__PURE__ */ jsx(Divider, { style: { margin: "24px 0" } }),
7746
+ /* @__PURE__ */ jsx(Typography, { variant: "beta", fontWeight: "bold", style: { display: "block", marginBottom: "8px" }, children: "Using WhatsApp in Your Code" }),
7747
+ /* @__PURE__ */ jsx(Typography, { variant: "omega", textColor: "neutral600", style: { display: "block", marginBottom: "16px" }, children: "Use the WhatsApp service programmatically in your Strapi code." }),
7748
+ /* @__PURE__ */ jsx(
7749
+ Box,
7750
+ {
7751
+ padding: 4,
7752
+ background: "neutral100",
7753
+ hasRadius: true,
7754
+ style: {
7755
+ fontFamily: "monospace",
7756
+ fontSize: "13px",
7757
+ lineHeight: "1.6",
7758
+ overflow: "auto"
7759
+ },
7760
+ children: /* @__PURE__ */ jsx("pre", { style: { margin: 0 }, children: `// Send a message via WhatsApp
7761
+ const whatsapp = strapi.plugin('magic-mail').service('whatsapp');
7762
+
7763
+ // Send simple message
7764
+ await whatsapp.sendMessage('49123456789', 'Hello from MagicMail!');
7765
+
7766
+ // Send template message
7767
+ await whatsapp.sendTemplateMessage('49123456789', 'welcome', {
7768
+ name: 'John',
7769
+ company: 'ACME Corp',
7770
+ });` })
7771
+ }
7772
+ ),
7773
+ /* @__PURE__ */ jsxs(ButtonRow, { justifyContent: "space-between", children: [
7774
+ /* @__PURE__ */ jsx(
7775
+ Button,
7776
+ {
7777
+ onClick: handleDisconnect,
7778
+ variant: "danger",
7779
+ startIcon: /* @__PURE__ */ jsx(Cross, {}),
7780
+ children: "Disconnect WhatsApp"
7781
+ }
7782
+ ),
7783
+ /* @__PURE__ */ jsx(Badge, { backgroundColor: "success600", textColor: "neutral0", children: "FREE - No API costs!" })
7784
+ ] })
7785
+ ] })
7786
+ ] })
7787
+ ] });
7788
+ };
7080
7789
  const fadeIn = keyframes`
7081
7790
  from { opacity: 0; }
7082
7791
  to { opacity: 1; }
@@ -7500,6 +8209,7 @@ const App = () => {
7500
8209
  if (location.pathname.includes("/analytics")) return "analytics";
7501
8210
  if (location.pathname.includes("/routing")) return "routing";
7502
8211
  if (location.pathname.includes("/designer") && !isEditorRoute) return "templates";
8212
+ if (location.pathname.includes("/whatsapp")) return "whatsapp";
7503
8213
  return "accounts";
7504
8214
  };
7505
8215
  const [activeTab, setActiveTab] = useState(getActiveTab());
@@ -7509,6 +8219,7 @@ const App = () => {
7509
8219
  if (tab === "routing") navigate("/plugins/magic-mail/routing");
7510
8220
  if (tab === "templates") navigate("/plugins/magic-mail/designer");
7511
8221
  if (tab === "analytics") navigate("/plugins/magic-mail/analytics");
8222
+ if (tab === "whatsapp") navigate("/plugins/magic-mail/whatsapp");
7512
8223
  };
7513
8224
  if (isEditorRoute) {
7514
8225
  return /* @__PURE__ */ jsx(LicenseGuard, { children: /* @__PURE__ */ jsx(EditorPage, {}) });
@@ -7530,12 +8241,17 @@ const App = () => {
7530
8241
  hasAnalytics && /* @__PURE__ */ jsx(Tabs.Trigger, { value: "analytics", children: /* @__PURE__ */ jsxs(Flex, { gap: 2, alignItems: "center", children: [
7531
8242
  /* @__PURE__ */ jsx(ChartBarIcon, { style: { width: 16, height: 16 } }),
7532
8243
  "Analytics"
8244
+ ] }) }),
8245
+ /* @__PURE__ */ jsx(Tabs.Trigger, { value: "whatsapp", children: /* @__PURE__ */ jsxs(Flex, { gap: 2, alignItems: "center", children: [
8246
+ /* @__PURE__ */ jsx(ChatBubbleLeftIcon, { style: { width: 16, height: 16 } }),
8247
+ "WhatsApp"
7533
8248
  ] }) })
7534
8249
  ] }),
7535
8250
  /* @__PURE__ */ jsx(Tabs.Content, { value: "accounts", children: /* @__PURE__ */ jsx(HomePage, {}) }),
7536
8251
  /* @__PURE__ */ jsx(Tabs.Content, { value: "routing", children: /* @__PURE__ */ jsx(RoutingRulesPage, {}) }),
7537
8252
  hasEmailDesigner && /* @__PURE__ */ jsx(Tabs.Content, { value: "templates", children: /* @__PURE__ */ jsx(TemplateList, {}) }),
7538
- hasAnalytics && /* @__PURE__ */ jsx(Tabs.Content, { value: "analytics", children: /* @__PURE__ */ jsx(Analytics, {}) })
8253
+ hasAnalytics && /* @__PURE__ */ jsx(Tabs.Content, { value: "analytics", children: /* @__PURE__ */ jsx(Analytics, {}) }),
8254
+ /* @__PURE__ */ jsx(Tabs.Content, { value: "whatsapp", children: /* @__PURE__ */ jsx(WhatsAppPage, {}) })
7539
8255
  ] }) }) });
7540
8256
  };
7541
8257
  export {