strapi-plugin-magic-mail 3.0.3 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,11 +1,11 @@
1
1
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
- import React, { useRef, useEffect, useState, useCallback } from "react";
3
2
  import { useNavigate, useLocation } from "react-router-dom";
4
3
  import { Modal, Typography, Flex, Box, Field, TextInput, Alert, Textarea, NumberInput, Divider, Switch, Button, Loader, SingleSelect, SingleSelectOption, Thead, Tr, Th, Tbody, Td, Badge, Table, Tabs, Accordion } from "@strapi/design-system";
5
4
  import { useFetchClient, useNotification, Page } from "@strapi/strapi/admin";
6
- import { EnvelopeIcon, ServerIcon, SparklesIcon, PlusIcon, PencilIcon, PlayIcon, TrashIcon, MagnifyingGlassIcon, FunnelIcon, CheckIcon, Cog6ToothIcon, DocumentTextIcon, ChartBarIcon, CheckCircleIcon, ArrowUpTrayIcon, ArrowDownTrayIcon, DocumentArrowDownIcon, CodeBracketIcon, DocumentDuplicateIcon, BoltIcon, PaperAirplaneIcon, ClipboardDocumentIcon, ArrowLeftIcon, ClockIcon, XMarkIcon, ArrowUturnLeftIcon, EnvelopeOpenIcon, CursorArrowRaysIcon, ExclamationTriangleIcon, XCircleIcon, ChatBubbleLeftIcon } from "@heroicons/react/24/outline";
5
+ import { EnvelopeIcon, ServerIcon, SparklesIcon, PlusIcon, PencilIcon, PlayIcon, TrashIcon, MagnifyingGlassIcon, FunnelIcon, CheckIcon, Cog6ToothIcon, DocumentTextIcon, ChartBarIcon, CheckCircleIcon, ArrowUpTrayIcon, ArrowDownTrayIcon, DocumentArrowDownIcon, CodeBracketIcon, DocumentDuplicateIcon, BoltIcon, PaperAirplaneIcon, ClipboardDocumentIcon, ArrowLeftIcon, ClockIcon, XMarkIcon, ArrowUturnLeftIcon, EnvelopeOpenIcon, CursorArrowRaysIcon, ExclamationTriangleIcon, XCircleIcon } from "@heroicons/react/24/outline";
6
+ import React, { useRef, useEffect, useState } from "react";
7
7
  import styled, { css, keyframes } from "styled-components";
8
- import { Star, Mail, Server, Lock, Cog, Check, Cloud, Key, ArrowLeft, ArrowRight, ArrowClockwise, Play, Cross } from "@strapi/icons";
8
+ import { Star, Mail, Server, Lock, Cog, Check, Cloud, Key, ArrowLeft, ArrowRight } from "@strapi/icons";
9
9
  import { T as TertiaryButton, G as GradientButton, C as CTAButton, I as IconButton, a as IconButtonPrimary, b as IconButtonDanger, S as SecondaryButton, c as IconButtonPurple, d as IconButtonSuccess, D as DangerButton } from "./StyledButtons-aq1EWrQ-.mjs";
10
10
  import * as ReactEmailEditor from "react-email-editor";
11
11
  const useAuthRefresh = () => {
@@ -61,7 +61,7 @@ const theme$3 = {
61
61
  xl: "16px"
62
62
  }
63
63
  };
64
- const fadeIn$5 = keyframes`
64
+ const fadeIn$4 = keyframes`
65
65
  from {
66
66
  opacity: 0;
67
67
  transform: translateY(10px);
@@ -71,7 +71,7 @@ const fadeIn$5 = keyframes`
71
71
  transform: translateY(0);
72
72
  }
73
73
  `;
74
- const pulse$3 = keyframes`
74
+ const pulse$2 = keyframes`
75
75
  0%, 100% {
76
76
  transform: scale(1);
77
77
  }
@@ -89,7 +89,7 @@ const slideIn = keyframes`
89
89
  opacity: 1;
90
90
  }
91
91
  `;
92
- const colors$1 = {
92
+ const colors = {
93
93
  primary: "#4945ff",
94
94
  // Strapi Primary Blue
95
95
  primaryLight: "rgba(73, 69, 255, 0.06)",
@@ -107,7 +107,7 @@ const StepHeader = styled(Box)`
107
107
  padding-bottom: 24px;
108
108
  margin-bottom: 32px;
109
109
  position: relative;
110
- animation: ${fadeIn$5} 0.4s ease;
110
+ animation: ${fadeIn$4} 0.4s ease;
111
111
 
112
112
  &::after {
113
113
  content: '';
@@ -116,11 +116,11 @@ const StepHeader = styled(Box)`
116
116
  left: -24px;
117
117
  right: -24px;
118
118
  height: 1px;
119
- background: linear-gradient(90deg, transparent, ${colors$1.border}, transparent);
119
+ background: linear-gradient(90deg, transparent, ${colors.border}, transparent);
120
120
  }
121
121
  `;
122
122
  const StepTitle = styled(Typography)`
123
- color: ${colors$1.text};
123
+ color: ${colors.text};
124
124
  font-size: 24px;
125
125
  font-weight: 600;
126
126
  margin-bottom: 8px;
@@ -129,11 +129,11 @@ const StepTitle = styled(Typography)`
129
129
  gap: 12px;
130
130
  `;
131
131
  const StepSubtitle = styled(Typography)`
132
- color: ${colors$1.textLight};
132
+ color: ${colors.textLight};
133
133
  font-size: 14px;
134
134
  line-height: 1.5;
135
135
  `;
136
- const StepperContainer$1 = styled(Box)`
136
+ const StepperContainer = styled(Box)`
137
137
  display: flex;
138
138
  align-items: flex-start;
139
139
  justify-content: center;
@@ -143,7 +143,7 @@ const StepperContainer$1 = styled(Box)`
143
143
  position: relative;
144
144
  padding: 0 40px;
145
145
  `;
146
- const StepWrapper$1 = styled.div`
146
+ const StepWrapper = styled.div`
147
147
  flex: 1;
148
148
  display: flex;
149
149
  flex-direction: column;
@@ -157,18 +157,18 @@ const StepWrapper$1 = styled.div`
157
157
  left: 50%;
158
158
  width: 100%;
159
159
  height: 3px;
160
- background: ${(props) => props.$completed ? colors$1.success : colors$1.neutralLight};
160
+ background: ${(props) => props.$completed ? colors.success : colors.neutralLight};
161
161
  transition: all 0.4s ease;
162
162
  z-index: 0;
163
163
  }
164
164
  `;
165
- const StepDot$1 = styled.div`
165
+ const StepDot = styled.div`
166
166
  width: 56px;
167
167
  height: 56px;
168
168
  border-radius: 50%;
169
- background: ${(props) => props.$active ? colors$1.primary : props.$completed ? colors$1.success : props.theme.colors.neutral0};
170
- color: ${(props) => props.$active || props.$completed ? "#ffffff" : colors$1.textLight};
171
- border: 4px solid ${(props) => props.$active ? colors$1.primary : props.$completed ? colors$1.success : colors$1.border};
169
+ background: ${(props) => props.$active ? colors.primary : props.$completed ? colors.success : props.theme.colors.neutral0};
170
+ color: ${(props) => props.$active || props.$completed ? "#ffffff" : colors.textLight};
171
+ border: 4px solid ${(props) => props.$active ? colors.primary : props.$completed ? colors.success : colors.border};
172
172
  display: flex;
173
173
  align-items: center;
174
174
  justify-content: center;
@@ -178,20 +178,20 @@ const StepDot$1 = styled.div`
178
178
  position: relative;
179
179
  z-index: 1;
180
180
  cursor: ${(props) => props.$completed ? "pointer" : "default"};
181
- 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)"};
181
+ 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)"};
182
182
 
183
183
  ${(props) => props.$active && css`
184
- animation: ${pulse$3} 2s infinite;
184
+ animation: ${pulse$2} 2s infinite;
185
185
  `}
186
186
 
187
187
  &:hover {
188
188
  transform: ${(props) => props.$completed ? "scale(1.1)" : props.$active ? "scale(1.05)" : "scale(1)"};
189
189
  }
190
190
  `;
191
- const StepLabel$1 = styled(Typography)`
191
+ const StepLabel = styled(Typography)`
192
192
  margin-top: 12px;
193
193
  font-size: 13px;
194
- color: ${(props) => props.$active ? colors$1.primary : props.$completed ? colors$1.success : colors$1.textLight};
194
+ color: ${(props) => props.$active ? colors.primary : props.$completed ? colors.success : colors.textLight};
195
195
  white-space: nowrap;
196
196
  font-weight: ${(props) => props.$active ? 600 : 500};
197
197
  text-align: center;
@@ -202,13 +202,13 @@ const ProviderCategoryHeader = styled(Box)`
202
202
  align-items: center;
203
203
  gap: 12px;
204
204
  margin: 0 0 16px;
205
- animation: ${fadeIn$5} 0.4s ease;
205
+ animation: ${fadeIn$4} 0.4s ease;
206
206
 
207
207
  &::after {
208
208
  content: '';
209
209
  flex: 1;
210
210
  height: 1px;
211
- background: linear-gradient(90deg, ${colors$1.border}, transparent);
211
+ background: linear-gradient(90deg, ${colors.border}, transparent);
212
212
  }
213
213
  `;
214
214
  const ProviderCategoryLabel = styled(Typography)`
@@ -216,15 +216,15 @@ const ProviderCategoryLabel = styled(Typography)`
216
216
  font-weight: 600;
217
217
  letter-spacing: 0.08em;
218
218
  text-transform: uppercase;
219
- color: ${colors$1.textLight};
219
+ color: ${colors.textLight};
220
220
  `;
221
221
  const ProviderCategoryHint = styled.span`
222
222
  font-size: 11px;
223
223
  font-weight: 500;
224
224
  padding: 3px 10px;
225
225
  border-radius: 999px;
226
- background: ${colors$1.primaryLight};
227
- color: ${colors$1.primary};
226
+ background: ${colors.primaryLight};
227
+ color: ${colors.primary};
228
228
  letter-spacing: 0.02em;
229
229
  text-transform: none;
230
230
  `;
@@ -244,8 +244,8 @@ const ProvidersGrid = styled(Box)`
244
244
  }
245
245
  `;
246
246
  const ProviderCard = styled(Box)`
247
- background: ${(props) => props.$selected ? `linear-gradient(180deg, ${colors$1.successLight}, rgba(92, 177, 118, 0.04))` : "var(--colors-neutral100, rgba(255,255,255,0.02))"};
248
- border: 1.5px solid ${(props) => props.$selected ? colors$1.success : colors$1.border};
247
+ background: ${(props) => props.$selected ? `linear-gradient(180deg, ${colors.successLight}, rgba(92, 177, 118, 0.04))` : "var(--colors-neutral100, rgba(255,255,255,0.02))"};
248
+ border: 1.5px solid ${(props) => props.$selected ? colors.success : colors.border};
249
249
  border-radius: 14px;
250
250
  padding: 22px 20px 20px;
251
251
  cursor: pointer;
@@ -271,7 +271,7 @@ const ProviderCard = styled(Box)`
271
271
  &:hover {
272
272
  transform: translateY(-3px);
273
273
  box-shadow: 0 10px 28px rgba(73, 69, 255, 0.18);
274
- border-color: ${(props) => props.$selected ? colors$1.success : colors$1.primary};
274
+ border-color: ${(props) => props.$selected ? colors.success : colors.primary};
275
275
 
276
276
  &::before {
277
277
  opacity: 1;
@@ -279,12 +279,12 @@ const ProviderCard = styled(Box)`
279
279
  }
280
280
 
281
281
  &:focus-visible {
282
- outline: 2px solid ${colors$1.primary};
282
+ outline: 2px solid ${colors.primary};
283
283
  outline-offset: 2px;
284
284
  }
285
285
 
286
286
  ${(props) => props.$selected && css`
287
- box-shadow: 0 0 0 1px ${colors$1.success}, 0 10px 28px rgba(92, 177, 118, 0.18);
287
+ box-shadow: 0 0 0 1px ${colors.success}, 0 10px 28px rgba(92, 177, 118, 0.18);
288
288
 
289
289
  &::after {
290
290
  content: '✓';
@@ -293,7 +293,7 @@ const ProviderCard = styled(Box)`
293
293
  right: 12px;
294
294
  width: 24px;
295
295
  height: 24px;
296
- background: ${colors$1.success};
296
+ background: ${colors.success};
297
297
  color: #fff;
298
298
  border-radius: 50%;
299
299
  display: flex;
@@ -318,7 +318,7 @@ const ProviderIcon = styled.div`
318
318
  justify-content: center;
319
319
  font-size: ${(props) => props.$fontSize || "22px"};
320
320
  font-weight: 700;
321
- color: ${(props) => props.$color || colors$1.primary};
321
+ color: ${(props) => props.$color || colors.primary};
322
322
  box-shadow: 0 4px 14px ${(props) => props.$shadowColor || "rgba(73, 69, 255, 0.25)"};
323
323
  flex-shrink: 0;
324
324
  `;
@@ -332,22 +332,22 @@ const ProviderName = styled(Typography)`
332
332
  font-weight: 600;
333
333
  font-size: 16px;
334
334
  line-height: 1.25;
335
- color: ${colors$1.text};
335
+ color: ${colors.text};
336
336
  margin: 0;
337
337
  `;
338
338
  const ProviderTagline = styled(Typography)`
339
339
  font-size: 12.5px;
340
340
  line-height: 1.4;
341
- color: ${colors$1.textLight};
341
+ color: ${colors.textLight};
342
342
  margin: 0;
343
343
  `;
344
344
  const InfoAlert = styled(Alert)`
345
- background: ${colors$1.primaryLight};
346
- border: 1px solid ${colors$1.primary}33;
347
- animation: ${fadeIn$5} 0.4s ease;
345
+ background: ${colors.primaryLight};
346
+ border: 1px solid ${colors.primary}33;
347
+ animation: ${fadeIn$4} 0.4s ease;
348
348
 
349
349
  svg {
350
- color: ${colors$1.primary};
350
+ color: ${colors.primary};
351
351
  }
352
352
  `;
353
353
  const FormSection = styled(Box)`
@@ -367,7 +367,7 @@ const FullWidthField = styled(Box)`
367
367
  }
368
368
  `;
369
369
  const SectionTitle = styled(Typography)`
370
- color: ${colors$1.text};
370
+ color: ${colors.text};
371
371
  font-weight: 600;
372
372
  font-size: 16px;
373
373
  margin-bottom: 16px;
@@ -865,13 +865,13 @@ const AddAccountModal = ({ isOpen, onClose, onAccountAdded, editAccount = null }
865
865
  currentStep === 4 && "Set rate limits and priority for this account"
866
866
  ] })
867
867
  ] }),
868
- /* @__PURE__ */ jsx(StepperContainer$1, { children: [1, 2, 3, 4].map((step) => /* @__PURE__ */ jsxs(
869
- StepWrapper$1,
868
+ /* @__PURE__ */ jsx(StepperContainer, { children: [1, 2, 3, 4].map((step) => /* @__PURE__ */ jsxs(
869
+ StepWrapper,
870
870
  {
871
871
  $completed: currentStep > step,
872
872
  children: [
873
873
  /* @__PURE__ */ jsx(
874
- StepDot$1,
874
+ StepDot,
875
875
  {
876
876
  $active: currentStep === step,
877
877
  $completed: currentStep > step,
@@ -880,7 +880,7 @@ const AddAccountModal = ({ isOpen, onClose, onAccountAdded, editAccount = null }
880
880
  }
881
881
  ),
882
882
  /* @__PURE__ */ jsx(
883
- StepLabel$1,
883
+ StepLabel,
884
884
  {
885
885
  $active: currentStep === step,
886
886
  $completed: currentStep > step,
@@ -1272,7 +1272,7 @@ const AddAccountModal = ({ isOpen, onClose, onAccountAdded, editAccount = null }
1272
1272
  background: "neutral100",
1273
1273
  hasRadius: true,
1274
1274
  style: {
1275
- border: `1px solid ${colors$1.border}`,
1275
+ border: `1px solid ${colors.border}`,
1276
1276
  borderRadius: "8px"
1277
1277
  },
1278
1278
  children: [
@@ -1289,7 +1289,7 @@ const AddAccountModal = ({ isOpen, onClose, onAccountAdded, editAccount = null }
1289
1289
  /* @__PURE__ */ jsxs(Box, { children: [
1290
1290
  /* @__PURE__ */ jsx("strong", { children: "1." }),
1291
1291
  " Go to ",
1292
- /* @__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" })
1292
+ /* @__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" })
1293
1293
  ] }),
1294
1294
  /* @__PURE__ */ jsxs(Box, { children: [
1295
1295
  /* @__PURE__ */ jsx("strong", { children: "2." }),
@@ -1315,7 +1315,7 @@ const AddAccountModal = ({ isOpen, onClose, onAccountAdded, editAccount = null }
1315
1315
  fontFamily: "monospace",
1316
1316
  fontSize: "13px",
1317
1317
  wordBreak: "break-all",
1318
- border: `1px solid ${colors$1.border}`
1318
+ border: `1px solid ${colors.border}`
1319
1319
  },
1320
1320
  children: [
1321
1321
  window.location.origin,
@@ -1416,7 +1416,7 @@ const AddAccountModal = ({ isOpen, onClose, onAccountAdded, editAccount = null }
1416
1416
  background: "neutral100",
1417
1417
  hasRadius: true,
1418
1418
  style: {
1419
- border: `1px solid ${colors$1.border}`,
1419
+ border: `1px solid ${colors.border}`,
1420
1420
  borderRadius: "8px"
1421
1421
  },
1422
1422
  children: [
@@ -1433,7 +1433,7 @@ const AddAccountModal = ({ isOpen, onClose, onAccountAdded, editAccount = null }
1433
1433
  /* @__PURE__ */ jsxs(Box, { children: [
1434
1434
  /* @__PURE__ */ jsx("strong", { children: "1." }),
1435
1435
  " Go to ",
1436
- /* @__PURE__ */ jsx("a", { href: "https://portal.azure.com", target: "_blank", rel: "noopener noreferrer", style: { color: colors$1.primary, textDecoration: "underline" }, children: "portal.azure.com" })
1436
+ /* @__PURE__ */ jsx("a", { href: "https://portal.azure.com", target: "_blank", rel: "noopener noreferrer", style: { color: colors.primary, textDecoration: "underline" }, children: "portal.azure.com" })
1437
1437
  ] }),
1438
1438
  /* @__PURE__ */ jsxs(Box, { children: [
1439
1439
  /* @__PURE__ */ jsx("strong", { children: "2." }),
@@ -1467,8 +1467,8 @@ const AddAccountModal = ({ isOpen, onClose, onAccountAdded, editAccount = null }
1467
1467
  fontFamily: "monospace",
1468
1468
  fontSize: "13px",
1469
1469
  wordBreak: "break-all",
1470
- color: colors$1.textSecondary,
1471
- border: `1px solid ${colors$1.border}`
1470
+ color: colors.textSecondary,
1471
+ border: `1px solid ${colors.border}`
1472
1472
  },
1473
1473
  children: `${window.location.origin}/magic-mail/oauth/microsoft/callback`
1474
1474
  }
@@ -1593,7 +1593,7 @@ const AddAccountModal = ({ isOpen, onClose, onAccountAdded, editAccount = null }
1593
1593
  background: "neutral100",
1594
1594
  hasRadius: true,
1595
1595
  style: {
1596
- border: `1px solid ${colors$1.border}`,
1596
+ border: `1px solid ${colors.border}`,
1597
1597
  borderRadius: "8px"
1598
1598
  },
1599
1599
  children: [
@@ -1610,7 +1610,7 @@ const AddAccountModal = ({ isOpen, onClose, onAccountAdded, editAccount = null }
1610
1610
  /* @__PURE__ */ jsxs(Box, { children: [
1611
1611
  /* @__PURE__ */ jsx("strong", { children: "1." }),
1612
1612
  " Go to ",
1613
- /* @__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" })
1613
+ /* @__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" })
1614
1614
  ] }),
1615
1615
  /* @__PURE__ */ jsxs(Box, { children: [
1616
1616
  /* @__PURE__ */ jsx("strong", { children: "2." }),
@@ -1636,8 +1636,8 @@ const AddAccountModal = ({ isOpen, onClose, onAccountAdded, editAccount = null }
1636
1636
  fontFamily: "monospace",
1637
1637
  fontSize: "13px",
1638
1638
  wordBreak: "break-all",
1639
- color: colors$1.textSecondary,
1640
- border: `1px solid ${colors$1.border}`
1639
+ color: colors.textSecondary,
1640
+ border: `1px solid ${colors.border}`
1641
1641
  },
1642
1642
  children: `${window.location.origin}/magic-mail/oauth/yahoo/callback`
1643
1643
  }
@@ -1902,7 +1902,7 @@ const AddAccountModal = ({ isOpen, onClose, onAccountAdded, editAccount = null }
1902
1902
  ] }) })
1903
1903
  ] }) });
1904
1904
  };
1905
- const fadeIn$4 = keyframes`
1905
+ const fadeIn$3 = keyframes`
1906
1906
  from { opacity: 0; transform: translateY(10px); }
1907
1907
  to { opacity: 1; transform: translateY(0); }
1908
1908
  `;
@@ -1914,7 +1914,7 @@ const float$3 = keyframes`
1914
1914
  0%, 100% { transform: translateY(0px); }
1915
1915
  50% { transform: translateY(-5px); }
1916
1916
  `;
1917
- const pulse$2 = keyframes`
1917
+ const pulse$1 = keyframes`
1918
1918
  0%, 100% { opacity: 1; }
1919
1919
  50% { opacity: 0.5; }
1920
1920
  `;
@@ -1930,7 +1930,7 @@ const breakpoints$3 = {
1930
1930
  mobile: "768px"
1931
1931
  };
1932
1932
  const Container$4 = styled(Box)`
1933
- ${css`animation: ${fadeIn$4} ${theme$3.transitions.slow};`}
1933
+ ${css`animation: ${fadeIn$3} ${theme$3.transitions.slow};`}
1934
1934
  min-height: 100vh;
1935
1935
  max-width: 1440px;
1936
1936
  margin: 0 auto;
@@ -2048,7 +2048,7 @@ const StatCard$3 = styled(Box)`
2048
2048
  position: relative;
2049
2049
  overflow: hidden;
2050
2050
  transition: all ${theme$3.transitions.normal};
2051
- ${css`animation: ${fadeIn$4} ${theme$3.transitions.slow} backwards;`}
2051
+ ${css`animation: ${fadeIn$3} ${theme$3.transitions.slow} backwards;`}
2052
2052
  animation-delay: ${(props) => props.$delay || "0s"};
2053
2053
  box-shadow: ${theme$3.shadows.sm};
2054
2054
  border: 1px solid rgba(128, 128, 128, 0.2);
@@ -2174,7 +2174,7 @@ const OnlineBadge$1 = styled.div`
2174
2174
  background: ${(props) => props.$active ? "var(--colors-success600, #22C55E)" : "rgba(128, 128, 128, 0.4)"};
2175
2175
  display: inline-block;
2176
2176
  margin-right: 8px;
2177
- ${css`animation: ${(props) => props.$active ? pulse$2 : "none"} 2s ease-in-out infinite;`}
2177
+ ${css`animation: ${(props) => props.$active ? pulse$1 : "none"} 2s ease-in-out infinite;`}
2178
2178
  `;
2179
2179
  const StyledTable$3 = styled(Table)`
2180
2180
  thead {
@@ -2936,7 +2936,7 @@ const theme$2 = {
2936
2936
  xl: "16px"
2937
2937
  }
2938
2938
  };
2939
- const fadeIn$3 = keyframes`
2939
+ const fadeIn$2 = keyframes`
2940
2940
  from { opacity: 0; transform: translateY(10px); }
2941
2941
  to { opacity: 1; transform: translateY(0); }
2942
2942
  `;
@@ -2948,7 +2948,7 @@ const float$2 = keyframes`
2948
2948
  0%, 100% { transform: translateY(0px); }
2949
2949
  50% { transform: translateY(-5px); }
2950
2950
  `;
2951
- const pulse$1 = keyframes`
2951
+ const pulse = keyframes`
2952
2952
  0%, 100% { opacity: 1; }
2953
2953
  50% { opacity: 0.5; }
2954
2954
  `;
@@ -2964,7 +2964,7 @@ const breakpoints$2 = {
2964
2964
  mobile: "768px"
2965
2965
  };
2966
2966
  const Container$3 = styled(Box)`
2967
- ${css`animation: ${fadeIn$3} ${theme$2.transitions.slow};`}
2967
+ ${css`animation: ${fadeIn$2} ${theme$2.transitions.slow};`}
2968
2968
  min-height: 100vh;
2969
2969
  max-width: 1440px;
2970
2970
  margin: 0 auto;
@@ -3082,7 +3082,7 @@ const StatCard$2 = styled(Box)`
3082
3082
  position: relative;
3083
3083
  overflow: hidden;
3084
3084
  transition: all ${theme$2.transitions.normal};
3085
- ${css`animation: ${fadeIn$3} ${theme$2.transitions.slow} backwards;`}
3085
+ ${css`animation: ${fadeIn$2} ${theme$2.transitions.slow} backwards;`}
3086
3086
  animation-delay: ${(props) => props.$delay || "0s"};
3087
3087
  box-shadow: ${theme$2.shadows.sm};
3088
3088
  border: 1px solid rgba(128, 128, 128, 0.2);
@@ -3208,7 +3208,7 @@ const OnlineBadge = styled.div`
3208
3208
  background: ${(props) => props.$active ? "var(--colors-success600, #22C55E)" : "rgba(128, 128, 128, 0.4)"};
3209
3209
  display: inline-block;
3210
3210
  margin-right: 8px;
3211
- ${css`animation: ${(props) => props.$active ? pulse$1 : "none"} 2s ease-in-out infinite;`}
3211
+ ${css`animation: ${(props) => props.$active ? pulse : "none"} 2s ease-in-out infinite;`}
3212
3212
  `;
3213
3213
  const StyledTable$2 = styled(Table)`
3214
3214
  thead {
@@ -3506,8 +3506,7 @@ const RoutingRulesPage = () => {
3506
3506
  rule.fallbackAccountName && /* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "neutral600", children: [
3507
3507
  "Fallback: ",
3508
3508
  rule.fallbackAccountName
3509
- ] }),
3510
- rule.whatsappFallback && /* @__PURE__ */ jsx(Badge, { backgroundColor: "success100", textColor: "success700", size: "S", children: "+ WhatsApp" })
3509
+ ] })
3511
3510
  ] }) }),
3512
3511
  /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsxs(
3513
3512
  Badge,
@@ -3570,8 +3569,7 @@ const RuleModal = ({ rule, accounts, onClose, onSave }) => {
3570
3569
  matchType: rule?.matchType || "emailType",
3571
3570
  matchValue: rule?.matchValue || "",
3572
3571
  accountName: rule?.accountName || "",
3573
- fallbackAccountName: rule?.fallbackAccountName || "",
3574
- whatsappFallback: rule?.whatsappFallback || false
3572
+ fallbackAccountName: rule?.fallbackAccountName || ""
3575
3573
  });
3576
3574
  const handleChange = (field, value) => {
3577
3575
  setFormData((prev) => ({ ...prev, [field]: value }));
@@ -3726,38 +3724,6 @@ const RuleModal = ({ rule, accounts, onClose, onSave }) => {
3726
3724
  ),
3727
3725
  /* @__PURE__ */ jsx(Field.Hint, { children: "Use this account if the target account is unavailable or rate-limited" })
3728
3726
  ] }),
3729
- /* @__PURE__ */ jsx(
3730
- Box,
3731
- {
3732
- padding: 4,
3733
- background: "neutral100",
3734
- hasRadius: true,
3735
- borderColor: "neutral200",
3736
- borderStyle: "solid",
3737
- borderWidth: "1px",
3738
- style: {
3739
- width: "100%",
3740
- borderRadius: theme$2.borderRadius.md
3741
- },
3742
- children: /* @__PURE__ */ jsxs(Flex, { gap: 3, alignItems: "center", justifyContent: "space-between", children: [
3743
- /* @__PURE__ */ jsxs(Box, { style: { flex: 1, minWidth: 0 }, children: [
3744
- /* @__PURE__ */ jsx(Typography, { fontWeight: "semiBold", children: "WhatsApp Fallback" }),
3745
- /* @__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" })
3746
- ] }),
3747
- /* @__PURE__ */ jsx(Box, { style: { flexShrink: 0 }, children: /* @__PURE__ */ jsx(
3748
- Switch,
3749
- {
3750
- checked: formData.whatsappFallback,
3751
- onCheckedChange: (checked) => handleChange("whatsappFallback", checked),
3752
- "aria-label": "WhatsApp fallback",
3753
- onLabel: "Enabled",
3754
- offLabel: "Disabled",
3755
- visibleLabels: false
3756
- }
3757
- ) })
3758
- ] })
3759
- }
3760
- ),
3761
3727
  /* @__PURE__ */ jsxs(Field.Root, { style: { width: "100%" }, children: [
3762
3728
  /* @__PURE__ */ jsx(Field.Label, { children: "Rule Priority" }),
3763
3729
  /* @__PURE__ */ jsx(
@@ -3831,7 +3797,7 @@ const theme$1 = {
3831
3797
  spacing: { xs: "4px", sm: "8px", md: "16px", lg: "24px", xl: "32px", "2xl": "48px" },
3832
3798
  borderRadius: { md: "8px", lg: "12px", xl: "16px" }
3833
3799
  };
3834
- const fadeIn$2 = keyframes`
3800
+ const fadeIn$1 = keyframes`
3835
3801
  from { opacity: 0; transform: translateY(10px); }
3836
3802
  to { opacity: 1; transform: translateY(0); }
3837
3803
  `;
@@ -3985,7 +3951,7 @@ const CopyButton = styled(Button)`
3985
3951
  height: 14px;
3986
3952
  }
3987
3953
  `;
3988
- const InfoBox$1 = styled(Box)`
3954
+ const InfoBox = styled(Box)`
3989
3955
  background: linear-gradient(135deg, ${"rgba(2, 132, 199, 0.06)"}, ${"rgba(2, 132, 199, 0.12)"});
3990
3956
  border-left: 4px solid ${"var(--colors-primary600, #0EA5E9)"};
3991
3957
  border-radius: 8px;
@@ -4007,7 +3973,7 @@ const breakpoints$1 = {
4007
3973
  tablet: "1024px"
4008
3974
  };
4009
3975
  const Container$2 = styled(Box)`
4010
- ${css`animation: ${fadeIn$2} ${theme$1.transitions.slow};`}
3976
+ ${css`animation: ${fadeIn$1} ${theme$1.transitions.slow};`}
4011
3977
  min-height: 100vh;
4012
3978
  max-width: 1440px;
4013
3979
  margin: 0 auto;
@@ -4120,7 +4086,7 @@ const StatCard$1 = styled(Box)`
4120
4086
  position: relative;
4121
4087
  overflow: hidden;
4122
4088
  transition: all ${theme$1.transitions.normal};
4123
- ${css`animation: ${fadeIn$2} ${theme$1.transitions.slow} backwards;`}
4089
+ ${css`animation: ${fadeIn$1} ${theme$1.transitions.slow} backwards;`}
4124
4090
  animation-delay: ${(props) => props.$delay || "0s"};
4125
4091
  box-shadow: ${theme$1.shadows.sm};
4126
4092
  border: 1px solid rgba(128, 128, 128, 0.2);
@@ -5159,7 +5125,7 @@ const TemplateList = () => {
5159
5125
  selectedTemplate.name
5160
5126
  ] }) }),
5161
5127
  /* @__PURE__ */ jsxs(ScrollableDialogBody, { children: [
5162
- /* @__PURE__ */ jsx(InfoBox$1, { style: { marginTop: 0, marginBottom: "20px" }, children: /* @__PURE__ */ jsxs(Flex, { alignItems: "center", justifyContent: "space-between", children: [
5128
+ /* @__PURE__ */ jsx(InfoBox, { style: { marginTop: 0, marginBottom: "20px" }, children: /* @__PURE__ */ jsxs(Flex, { alignItems: "center", justifyContent: "space-between", children: [
5163
5129
  /* @__PURE__ */ jsxs(Typography, { variant: "pi", style: { color: "var(--colors-primary600, #075985)" }, children: [
5164
5130
  /* @__PURE__ */ jsx("strong", { children: "Template ID:" }),
5165
5131
  " #",
@@ -5650,6 +5616,7 @@ const ImportLabel = styled.label`
5650
5616
  const BackButton = styled.button`
5651
5617
  background: ${(p) => p.theme.colors.neutral0};
5652
5618
  border: 1px solid rgba(128, 128, 128, 0.2);
5619
+ color: ${(p) => p.theme.colors.neutral800};
5653
5620
  border-radius: 4px;
5654
5621
  padding: 8px 10px;
5655
5622
  height: 36px;
@@ -6196,7 +6163,15 @@ const EditorPage = () => {
6196
6163
  /* @__PURE__ */ jsxs(Header$1, { children: [
6197
6164
  /* @__PURE__ */ jsxs(HeaderRow, { children: [
6198
6165
  /* @__PURE__ */ jsxs(HeaderLeft, { children: [
6199
- /* @__PURE__ */ jsx(BackButton, { onClick: () => navigate("/plugins/magic-mail/designer"), children: /* @__PURE__ */ jsx(ArrowLeftIcon, {}) }),
6166
+ /* @__PURE__ */ jsx(
6167
+ BackButton,
6168
+ {
6169
+ type: "button",
6170
+ "aria-label": "Back to email templates",
6171
+ onClick: () => navigate("/plugins/magic-mail/designer"),
6172
+ children: /* @__PURE__ */ jsx(ArrowLeftIcon, {})
6173
+ }
6174
+ ),
6200
6175
  /* @__PURE__ */ jsxs(TitleContainer, { children: [
6201
6176
  /* @__PURE__ */ jsx(Typography, { variant: "alpha", children: isCoreEmail ? `${coreEmailType === "reset-password" ? "Reset Password" : "Email Confirmation"}` : isNewTemplate ? "New Template" : `${templateData.name}` }),
6202
6177
  !isNewTemplate && !isCoreEmail && /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: "Versioning enabled" }),
@@ -6589,7 +6564,7 @@ const theme = {
6589
6564
  spacing: { xs: "4px", sm: "8px", md: "16px", lg: "24px", xl: "32px", "2xl": "48px" },
6590
6565
  borderRadius: { lg: "12px", xl: "16px" }
6591
6566
  };
6592
- const fadeIn$1 = keyframes`
6567
+ const fadeIn = keyframes`
6593
6568
  from { opacity: 0; transform: translateY(10px); }
6594
6569
  to { opacity: 1; transform: translateY(0); }
6595
6570
  `;
@@ -6605,7 +6580,7 @@ const breakpoints = {
6605
6580
  mobile: "768px"
6606
6581
  };
6607
6582
  const Container = styled(Box)`
6608
- ${css`animation: ${fadeIn$1} ${theme.transitions.slow};`}
6583
+ ${css`animation: ${fadeIn} ${theme.transitions.slow};`}
6609
6584
  min-height: 100vh;
6610
6585
  max-width: 1440px;
6611
6586
  margin: 0 auto;
@@ -6718,7 +6693,7 @@ const StatCard = styled(Box)`
6718
6693
  position: relative;
6719
6694
  overflow: hidden;
6720
6695
  transition: all ${theme.transitions.normal};
6721
- ${css`animation: ${fadeIn$1} ${theme.transitions.slow} backwards;`}
6696
+ ${css`animation: ${fadeIn} ${theme.transitions.slow} backwards;`}
6722
6697
  animation-delay: ${(props) => props.$delay || "0s"};
6723
6698
  box-shadow: ${theme.shadows.sm};
6724
6699
  border: 1px solid rgba(128, 128, 128, 0.2);
@@ -7127,814 +7102,6 @@ const Analytics = () => {
7127
7102
  ] }) })
7128
7103
  ] });
7129
7104
  };
7130
- const fadeIn = keyframes`
7131
- from {
7132
- opacity: 0;
7133
- transform: translateY(10px);
7134
- }
7135
- to {
7136
- opacity: 1;
7137
- transform: translateY(0);
7138
- }
7139
- `;
7140
- const pulse = keyframes`
7141
- 0%, 100% {
7142
- transform: scale(1);
7143
- }
7144
- 50% {
7145
- transform: scale(1.05);
7146
- }
7147
- `;
7148
- const spin = keyframes`
7149
- from {
7150
- transform: rotate(0deg);
7151
- }
7152
- to {
7153
- transform: rotate(360deg);
7154
- }
7155
- `;
7156
- const colors = {
7157
- whatsapp: "#25D366",
7158
- whatsappDark: "#128C7E",
7159
- whatsappLight: "rgba(37, 211, 102, 0.2)",
7160
- primary: "#4945ff",
7161
- primaryLight: "rgba(73, 69, 255, 0.06)",
7162
- success: "#5cb176",
7163
- successLight: "rgba(92, 177, 118, 0.12)",
7164
- danger: "#d02b20",
7165
- neutral: "#8e8ea9",
7166
- neutralLight: "rgba(142, 142, 169, 0.08)",
7167
- border: "rgba(128, 128, 128, 0.2)",
7168
- textLight: "var(--colors-neutral600, #666687)"
7169
- };
7170
- const PageContainer = styled(Box)`
7171
- padding: 40px;
7172
- max-width: 900px;
7173
- margin: 0 auto;
7174
- animation: ${fadeIn} 0.4s ease;
7175
- `;
7176
- const HeaderSection = styled(Box)`
7177
- text-align: center;
7178
- margin-bottom: 48px;
7179
- `;
7180
- const WhatsAppLogo = styled.div`
7181
- width: 80px;
7182
- height: 80px;
7183
- border-radius: 50%;
7184
- background: linear-gradient(135deg, ${colors.whatsapp}, ${colors.whatsappDark});
7185
- display: flex;
7186
- align-items: center;
7187
- justify-content: center;
7188
- margin: 0 auto 24px;
7189
- box-shadow: 0 8px 32px ${colors.whatsapp}40;
7190
- `;
7191
- const PhoneIcon = styled.div`
7192
- width: 40px;
7193
- height: 40px;
7194
- color: white;
7195
- font-size: 32px;
7196
- `;
7197
- const StepperContainer = styled(Box)`
7198
- display: flex;
7199
- align-items: flex-start;
7200
- justify-content: center;
7201
- gap: 0;
7202
- margin-bottom: 48px;
7203
- position: relative;
7204
- padding: 0 40px;
7205
- `;
7206
- const StepWrapper = styled.div`
7207
- flex: 1;
7208
- display: flex;
7209
- flex-direction: column;
7210
- align-items: center;
7211
- position: relative;
7212
-
7213
- &:not(:last-child)::after {
7214
- content: '';
7215
- position: absolute;
7216
- top: 28px;
7217
- left: 50%;
7218
- width: 100%;
7219
- height: 3px;
7220
- background: ${(props) => props.$completed ? colors.success : colors.neutralLight};
7221
- transition: all 0.4s ease;
7222
- z-index: 0;
7223
- }
7224
- `;
7225
- const StepDot = styled.div`
7226
- width: 56px;
7227
- height: 56px;
7228
- border-radius: 50%;
7229
- background: ${(props) => props.$active ? colors.whatsapp : props.$completed ? colors.success : props.theme.colors.neutral0};
7230
- color: ${(props) => props.$active || props.$completed ? "#ffffff" : colors.textLight};
7231
- border: 4px solid ${(props) => props.$active ? colors.whatsapp : props.$completed ? colors.success : colors.border};
7232
- display: flex;
7233
- align-items: center;
7234
- justify-content: center;
7235
- font-weight: 700;
7236
- font-size: 18px;
7237
- transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
7238
- position: relative;
7239
- z-index: 1;
7240
- cursor: ${(props) => props.$completed ? "pointer" : "default"};
7241
- 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)"};
7242
-
7243
- ${(props) => props.$active && css`
7244
- animation: ${pulse} 2s infinite;
7245
- `}
7246
-
7247
- &:hover {
7248
- transform: ${(props) => props.$completed ? "scale(1.1)" : props.$active ? "scale(1.05)" : "scale(1)"};
7249
- }
7250
- `;
7251
- const StepLabel = styled(Typography)`
7252
- margin-top: 12px;
7253
- font-size: 13px;
7254
- color: ${(props) => props.$active ? colors.whatsapp : props.$completed ? colors.success : colors.textLight};
7255
- white-space: nowrap;
7256
- font-weight: ${(props) => props.$active ? 600 : 500};
7257
- text-align: center;
7258
- transition: all 0.3s ease;
7259
- `;
7260
- const ContentCard = styled(Box)`
7261
- background: ${(p) => p.theme.colors.neutral0};
7262
- border: 1px solid ${colors.border};
7263
- border-radius: 16px;
7264
- padding: 32px;
7265
- margin-bottom: 24px;
7266
- animation: ${fadeIn} 0.4s ease;
7267
- box-shadow: 0 4px 24px rgba(0,0,0,0.06);
7268
- `;
7269
- const QRCodeContainer = styled.div`
7270
- display: flex;
7271
- flex-direction: column;
7272
- align-items: center;
7273
- padding: 32px;
7274
- background: ${colors.neutralLight};
7275
- border-radius: 16px;
7276
- margin: 24px 0;
7277
- `;
7278
- const QRImage = styled.img`
7279
- width: 280px;
7280
- height: 280px;
7281
- border-radius: 12px;
7282
- box-shadow: 0 4px 24px rgba(0,0,0,0.1);
7283
- `;
7284
- const StatusBadge = styled.div`
7285
- display: inline-flex;
7286
- align-items: center;
7287
- gap: 8px;
7288
- padding: 8px 16px;
7289
- border-radius: 20px;
7290
- font-weight: 600;
7291
- font-size: 14px;
7292
- background: ${(props) => {
7293
- switch (props.$status) {
7294
- case "connected":
7295
- return colors.successLight;
7296
- case "connecting":
7297
- return colors.primaryLight;
7298
- case "qr_pending":
7299
- return colors.whatsappLight;
7300
- case "disconnected":
7301
- return colors.neutralLight;
7302
- default:
7303
- return colors.neutralLight;
7304
- }
7305
- }};
7306
- color: ${(props) => {
7307
- switch (props.$status) {
7308
- case "connected":
7309
- return colors.success;
7310
- case "connecting":
7311
- return colors.primary;
7312
- case "qr_pending":
7313
- return colors.whatsappDark;
7314
- case "disconnected":
7315
- return colors.neutral;
7316
- default:
7317
- return colors.neutral;
7318
- }
7319
- }};
7320
- `;
7321
- const SpinningLoader = styled.div`
7322
- width: 20px;
7323
- height: 20px;
7324
- border: 2px solid ${colors.primary}40;
7325
- border-top-color: ${colors.primary};
7326
- border-radius: 50%;
7327
- animation: ${spin} 1s linear infinite;
7328
- `;
7329
- const ConnectedCard = styled(Box)`
7330
- background: linear-gradient(135deg, ${colors.successLight}, ${colors.whatsappLight});
7331
- border: 2px solid ${colors.success};
7332
- border-radius: 16px;
7333
- padding: 32px;
7334
- text-align: center;
7335
- `;
7336
- const InfoBox = styled(Box)`
7337
- background: linear-gradient(135deg, rgba(2, 132, 199, 0.06) 0%, ${colors.whatsappLight} 100%);
7338
- border: 1px solid rgba(2, 132, 199, 0.2);
7339
- border-radius: 12px;
7340
- padding: 24px;
7341
- margin: 20px 0;
7342
- `;
7343
- const TestSection = styled(Box)`
7344
- background: linear-gradient(135deg, ${colors.whatsappLight} 0%, rgba(34, 197, 94, 0.1) 100%);
7345
- border: 1px solid ${colors.whatsapp}40;
7346
- border-radius: 16px;
7347
- padding: 24px;
7348
- margin-top: 24px;
7349
- `;
7350
- const WhatsAppInput = styled.input`
7351
- width: 100%;
7352
- padding: 14px 16px;
7353
- border: 2px solid rgba(128, 128, 128, 0.2);
7354
- border-radius: 12px;
7355
- font-size: 15px;
7356
- background: ${(p) => p.theme.colors.neutral0};
7357
- color: var(--colors-neutral800);
7358
- transition: all 0.2s ease;
7359
- box-sizing: border-box;
7360
-
7361
- &:focus {
7362
- outline: none;
7363
- border-color: ${colors.whatsapp};
7364
- box-shadow: 0 0 0 3px ${colors.whatsapp}20;
7365
- }
7366
-
7367
- &::placeholder {
7368
- color: rgba(128, 128, 128, 0.4);
7369
- }
7370
- `;
7371
- const WhatsAppTextarea = styled.textarea`
7372
- width: 100%;
7373
- padding: 14px 16px;
7374
- border: 2px solid rgba(128, 128, 128, 0.2);
7375
- border-radius: 12px;
7376
- font-size: 15px;
7377
- background: ${(p) => p.theme.colors.neutral0};
7378
- color: var(--colors-neutral800);
7379
- transition: all 0.2s ease;
7380
- box-sizing: border-box;
7381
- resize: vertical;
7382
- min-height: 80px;
7383
- font-family: inherit;
7384
-
7385
- &:focus {
7386
- outline: none;
7387
- border-color: ${colors.whatsapp};
7388
- box-shadow: 0 0 0 3px ${colors.whatsapp}20;
7389
- }
7390
-
7391
- &::placeholder {
7392
- color: rgba(128, 128, 128, 0.4);
7393
- }
7394
- `;
7395
- const InputLabel = styled.label`
7396
- display: flex;
7397
- align-items: center;
7398
- gap: 8px;
7399
- font-size: 14px;
7400
- font-weight: 600;
7401
- color: ${colors.whatsappDark};
7402
- margin-bottom: 8px;
7403
- `;
7404
- const InputHint = styled.span`
7405
- font-size: 12px;
7406
- color: var(--colors-neutral500);
7407
- margin-top: 6px;
7408
- display: block;
7409
- `;
7410
- const PhoneSymbol = styled.span`
7411
- font-size: 16px;
7412
- font-weight: 700;
7413
- `;
7414
- const MessageSymbol = styled.span`
7415
- font-size: 16px;
7416
- `;
7417
- const UseCaseCard = styled(Box)`
7418
- background: linear-gradient(135deg, ${colors.whatsappLight}, rgba(2, 132, 199, 0.06));
7419
- border: 2px solid ${colors.whatsapp};
7420
- border-radius: 16px;
7421
- padding: 24px;
7422
- margin-bottom: 32px;
7423
- `;
7424
- const ButtonRow = styled(Flex)`
7425
- margin-top: 32px;
7426
- padding-top: 24px;
7427
- border-top: 1px solid rgba(128, 128, 128, 0.2);
7428
- `;
7429
- const AlertBox = styled(Box)`
7430
- background: rgba(2, 132, 199, 0.06);
7431
- border: 1px solid rgba(2, 132, 199, 0.2);
7432
- border-radius: 12px;
7433
- padding: 16px 20px;
7434
- margin-top: 20px;
7435
- display: flex;
7436
- align-items: flex-start;
7437
- gap: 12px;
7438
- `;
7439
- const AlertIcon = styled.div`
7440
- width: 24px;
7441
- height: 24px;
7442
- border-radius: 50%;
7443
- background: var(--colors-primary600, #0EA5E9);
7444
- color: white;
7445
- display: flex;
7446
- align-items: center;
7447
- justify-content: center;
7448
- font-size: 14px;
7449
- font-weight: bold;
7450
- flex-shrink: 0;
7451
- `;
7452
- const SuccessBox = styled(Box)`
7453
- background: rgba(22, 163, 74, 0.06);
7454
- border: 1px solid rgba(22, 163, 74, 0.2);
7455
- border-radius: 12px;
7456
- padding: 16px 20px;
7457
- display: flex;
7458
- align-items: flex-start;
7459
- gap: 12px;
7460
- `;
7461
- const SuccessIcon = styled.div`
7462
- width: 24px;
7463
- height: 24px;
7464
- border-radius: 50%;
7465
- background: var(--colors-success600, #22C55E);
7466
- color: white;
7467
- display: flex;
7468
- align-items: center;
7469
- justify-content: center;
7470
- flex-shrink: 0;
7471
- `;
7472
- const WhatsAppButton = styled(GradientButton)`
7473
- && {
7474
- background: linear-gradient(135deg, ${colors.whatsapp} 0%, ${colors.whatsappDark} 100%) !important;
7475
-
7476
- &:hover:not(:disabled) {
7477
- background: linear-gradient(135deg, ${colors.whatsappDark} 0%, ${colors.whatsapp} 100%) !important;
7478
- }
7479
- }
7480
- `;
7481
- const NotInstalledCard = styled(Box)`
7482
- background: linear-gradient(135deg, rgba(245, 158, 11, 0.15), rgba(220, 38, 38, 0.12));
7483
- border: 2px solid var(--colors-warning600, #F59E0B);
7484
- border-radius: 16px;
7485
- padding: 32px;
7486
- text-align: center;
7487
- `;
7488
- const WhatsAppPage = () => {
7489
- const { get, post } = useFetchClient();
7490
- const { toggleNotification } = useNotification();
7491
- const [currentStep, setCurrentStep] = useState(1);
7492
- const [loading, setLoading] = useState(true);
7493
- const [connecting, setConnecting] = useState(false);
7494
- const [isAvailable, setIsAvailable] = useState(false);
7495
- const [status, setStatus] = useState({
7496
- status: "disconnected",
7497
- qrCode: null,
7498
- isConnected: false,
7499
- session: null
7500
- });
7501
- const [testPhone, setTestPhone] = useState("");
7502
- const [testMessage, setTestMessage] = useState("");
7503
- const [sendingTest, setSendingTest] = useState(false);
7504
- const stepTitles = ["Check Installation", "Connect WhatsApp", "Scan QR Code", "Ready to Use"];
7505
- const checkAvailability = useCallback(async () => {
7506
- try {
7507
- const { data } = await get("/magic-mail/whatsapp/available");
7508
- setIsAvailable(data.data.available);
7509
- return data.data.available;
7510
- } catch (error) {
7511
- console.error("[MagicMail WhatsApp] Error checking availability:", error);
7512
- setIsAvailable(false);
7513
- return false;
7514
- }
7515
- }, [get]);
7516
- const fetchStatus = useCallback(async () => {
7517
- try {
7518
- const { data } = await get("/magic-mail/whatsapp/status");
7519
- setStatus(data.data);
7520
- if (data.data.isConnected) {
7521
- setCurrentStep(4);
7522
- } else if (data.data.qrCode) {
7523
- setCurrentStep(3);
7524
- } else if (isAvailable) {
7525
- setCurrentStep(2);
7526
- }
7527
- return data.data;
7528
- } catch (error) {
7529
- console.error("[MagicMail WhatsApp] Error fetching status:", error);
7530
- return null;
7531
- }
7532
- }, [get, isAvailable]);
7533
- useEffect(() => {
7534
- const init = async () => {
7535
- setLoading(true);
7536
- const available = await checkAvailability();
7537
- if (available) {
7538
- await fetchStatus();
7539
- }
7540
- setLoading(false);
7541
- };
7542
- init();
7543
- }, [checkAvailability, fetchStatus]);
7544
- useEffect(() => {
7545
- let pollInterval;
7546
- if (connecting || status.status === "connecting" || status.status === "qr_pending") {
7547
- pollInterval = setInterval(async () => {
7548
- const newStatus = await fetchStatus();
7549
- if (newStatus?.isConnected) {
7550
- setConnecting(false);
7551
- setCurrentStep(4);
7552
- toggleNotification({
7553
- type: "success",
7554
- message: "[SUCCESS] WhatsApp connected successfully!"
7555
- });
7556
- }
7557
- }, 2e3);
7558
- }
7559
- return () => {
7560
- if (pollInterval) clearInterval(pollInterval);
7561
- };
7562
- }, [connecting, status.status, fetchStatus, toggleNotification]);
7563
- const handleConnect = async () => {
7564
- setConnecting(true);
7565
- try {
7566
- const { data } = await post("/magic-mail/whatsapp/connect", {});
7567
- if (data.data.qrCode) {
7568
- setStatus((prev) => ({ ...prev, qrCode: data.data.qrCode, status: "qr_pending" }));
7569
- setCurrentStep(3);
7570
- } else if (data.data.status === "connected") {
7571
- setStatus((prev) => ({ ...prev, isConnected: true, status: "connected" }));
7572
- setCurrentStep(4);
7573
- toggleNotification({
7574
- type: "success",
7575
- message: "[SUCCESS] WhatsApp already connected!"
7576
- });
7577
- }
7578
- } catch (error) {
7579
- toggleNotification({
7580
- type: "danger",
7581
- message: "[ERROR] Failed to connect: " + (error.response?.data?.error?.message || error.message)
7582
- });
7583
- setConnecting(false);
7584
- }
7585
- };
7586
- const handleDisconnect = async () => {
7587
- try {
7588
- await post("/magic-mail/whatsapp/disconnect", {});
7589
- setStatus({
7590
- status: "disconnected",
7591
- qrCode: null,
7592
- isConnected: false,
7593
- session: null
7594
- });
7595
- setCurrentStep(2);
7596
- toggleNotification({
7597
- type: "success",
7598
- message: "[SUCCESS] WhatsApp disconnected"
7599
- });
7600
- } catch (error) {
7601
- toggleNotification({
7602
- type: "danger",
7603
- message: "[ERROR] Failed to disconnect"
7604
- });
7605
- }
7606
- };
7607
- const handleSendTest = async () => {
7608
- if (!testPhone) {
7609
- toggleNotification({
7610
- type: "warning",
7611
- message: "Please enter a phone number"
7612
- });
7613
- return;
7614
- }
7615
- setSendingTest(true);
7616
- try {
7617
- const { data } = await post("/magic-mail/whatsapp/send-test", {
7618
- phoneNumber: testPhone,
7619
- message: testMessage || void 0
7620
- });
7621
- if (data.success) {
7622
- toggleNotification({
7623
- type: "success",
7624
- message: "[SUCCESS] Test message sent!"
7625
- });
7626
- setTestPhone("");
7627
- setTestMessage("");
7628
- } else {
7629
- toggleNotification({
7630
- type: "danger",
7631
- message: "[ERROR] " + (data.data.error || "Failed to send message")
7632
- });
7633
- }
7634
- } catch (error) {
7635
- toggleNotification({
7636
- type: "danger",
7637
- message: "[ERROR] " + (error.response?.data?.error?.message || error.message)
7638
- });
7639
- } finally {
7640
- setSendingTest(false);
7641
- }
7642
- };
7643
- const renderStatusBadge = () => {
7644
- const statusText = {
7645
- connected: "Connected",
7646
- connecting: "Connecting...",
7647
- qr_pending: "Waiting for QR Scan",
7648
- disconnected: "Disconnected"
7649
- };
7650
- return /* @__PURE__ */ jsxs(StatusBadge, { $status: status.status, children: [
7651
- status.status === "connecting" && /* @__PURE__ */ jsx(SpinningLoader, {}),
7652
- status.status === "connected" && /* @__PURE__ */ jsx(Check, {}),
7653
- statusText[status.status] || "Unknown"
7654
- ] });
7655
- };
7656
- if (loading) {
7657
- return /* @__PURE__ */ jsx(PageContainer, { children: /* @__PURE__ */ jsx(Flex, { justifyContent: "center", alignItems: "center", style: { minHeight: "400px" }, children: /* @__PURE__ */ jsx(Loader, {}) }) });
7658
- }
7659
- return /* @__PURE__ */ jsxs(PageContainer, { children: [
7660
- /* @__PURE__ */ jsxs(HeaderSection, { children: [
7661
- /* @__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" }) }) }) }),
7662
- /* @__PURE__ */ jsx(Typography, { variant: "alpha", fontWeight: "bold", style: { display: "block", marginBottom: "8px" }, children: "WhatsApp Integration" }),
7663
- /* @__PURE__ */ jsx(Typography, { variant: "epsilon", textColor: "neutral600", style: { display: "block" }, children: "Send messages via WhatsApp - completely free!" }),
7664
- /* @__PURE__ */ jsx(Box, { marginTop: 3, children: renderStatusBadge() })
7665
- ] }),
7666
- /* @__PURE__ */ jsx(StepperContainer, { children: [1, 2, 3, 4].map((step) => /* @__PURE__ */ jsxs(
7667
- StepWrapper,
7668
- {
7669
- $completed: currentStep > step,
7670
- children: [
7671
- /* @__PURE__ */ jsx(
7672
- StepDot,
7673
- {
7674
- $active: currentStep === step,
7675
- $completed: currentStep > step,
7676
- onClick: () => currentStep > step && setCurrentStep(step),
7677
- children: currentStep > step ? /* @__PURE__ */ jsx(Check, {}) : step
7678
- }
7679
- ),
7680
- /* @__PURE__ */ jsx(
7681
- StepLabel,
7682
- {
7683
- $active: currentStep === step,
7684
- $completed: currentStep > step,
7685
- children: stepTitles[step - 1]
7686
- }
7687
- )
7688
- ]
7689
- },
7690
- step
7691
- )) }),
7692
- /* @__PURE__ */ jsxs(UseCaseCard, { children: [
7693
- /* @__PURE__ */ jsx(Typography, { variant: "delta", fontWeight: "bold", style: { display: "block", marginBottom: "12px" }, children: "What can you do with WhatsApp?" }),
7694
- /* @__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." }),
7695
- /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 3, children: [
7696
- /* @__PURE__ */ jsxs(Box, { padding: 3, background: "neutral0", hasRadius: true, style: { border: `1px solid ${colors.border}` }, children: [
7697
- /* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", style: { display: "block", marginBottom: "4px" }, children: "1. FALLBACK-KANAL" }),
7698
- /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", style: { display: "block" }, children: "Wenn alle Email-Accounts fehlschlagen, wird die Nachricht automatisch via WhatsApp zugestellt." })
7699
- ] }),
7700
- /* @__PURE__ */ jsxs(Box, { padding: 3, background: "neutral0", hasRadius: true, style: { border: `1px solid ${colors.border}` }, children: [
7701
- /* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", style: { display: "block", marginBottom: "4px" }, children: "2. ADMIN-BENACHRICHTIGUNGEN" }),
7702
- /* @__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." })
7703
- ] }),
7704
- /* @__PURE__ */ jsxs(Box, { padding: 3, background: "neutral0", hasRadius: true, style: { border: `1px solid ${colors.border}` }, children: [
7705
- /* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", style: { display: "block", marginBottom: "4px" }, children: "3. ROUTING-INTEGRATION" }),
7706
- /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", style: { display: "block" }, children: "In Routing-Regeln kann WhatsApp als Fallback-Kanal definiert werden (Routing Rules Tab)." })
7707
- ] })
7708
- ] })
7709
- ] }),
7710
- currentStep === 1 && /* @__PURE__ */ jsxs(ContentCard, { children: [
7711
- /* @__PURE__ */ jsx(Typography, { variant: "beta", fontWeight: "bold", style: { display: "block", marginBottom: "8px" }, children: "Check Installation" }),
7712
- /* @__PURE__ */ jsx(Typography, { variant: "omega", textColor: "neutral600", style: { display: "block", marginBottom: "24px" }, children: "First, we need to verify that the required dependencies are installed." }),
7713
- isAvailable ? /* @__PURE__ */ jsxs(SuccessBox, { children: [
7714
- /* @__PURE__ */ jsx(SuccessIcon, { children: /* @__PURE__ */ jsx(Check, { style: { width: 14, height: 14 } }) }),
7715
- /* @__PURE__ */ jsxs(Box, { children: [
7716
- /* @__PURE__ */ jsx(Typography, { variant: "omega", fontWeight: "semiBold", style: { display: "block", marginBottom: "4px", color: "var(--colors-success600, #15803D)" }, children: "Dependencies Installed" }),
7717
- /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: "Baileys library is installed and ready to use. You can proceed to connect your WhatsApp account." })
7718
- ] })
7719
- ] }) : /* @__PURE__ */ jsxs(NotInstalledCard, { children: [
7720
- /* @__PURE__ */ jsx(Typography, { variant: "beta", fontWeight: "bold", style: { display: "block", marginBottom: "12px", color: colors.danger }, children: "[WARNING] Dependencies Not Installed" }),
7721
- /* @__PURE__ */ jsx(Typography, { variant: "omega", textColor: "neutral600", style: { display: "block", marginBottom: "16px" }, children: "The WhatsApp integration requires additional dependencies. Please install them:" }),
7722
- /* @__PURE__ */ jsx(
7723
- Box,
7724
- {
7725
- padding: 4,
7726
- background: "neutral0",
7727
- hasRadius: true,
7728
- style: {
7729
- fontFamily: "monospace",
7730
- fontSize: "14px",
7731
- border: `1px solid ${colors.border}`,
7732
- marginBottom: "16px"
7733
- },
7734
- children: "npm install baileys pino qrcode"
7735
- }
7736
- ),
7737
- /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: "After installing, restart your Strapi server and refresh this page." })
7738
- ] }),
7739
- /* @__PURE__ */ jsxs(ButtonRow, { justifyContent: "flex-end", gap: 3, children: [
7740
- /* @__PURE__ */ jsx(
7741
- SecondaryButton,
7742
- {
7743
- onClick: () => {
7744
- checkAvailability();
7745
- },
7746
- startIcon: /* @__PURE__ */ jsx(ArrowClockwise, {}),
7747
- children: "Refresh"
7748
- }
7749
- ),
7750
- /* @__PURE__ */ jsx(
7751
- GradientButton,
7752
- {
7753
- onClick: () => setCurrentStep(2),
7754
- disabled: !isAvailable,
7755
- endIcon: /* @__PURE__ */ jsx(ArrowRight, {}),
7756
- children: "Continue"
7757
- }
7758
- )
7759
- ] })
7760
- ] }),
7761
- currentStep === 2 && /* @__PURE__ */ jsxs(ContentCard, { children: [
7762
- /* @__PURE__ */ jsx(Typography, { variant: "beta", fontWeight: "bold", style: { display: "block", marginBottom: "8px" }, children: "Connect Your WhatsApp" }),
7763
- /* @__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." }),
7764
- /* @__PURE__ */ jsxs(InfoBox, { children: [
7765
- /* @__PURE__ */ jsx(Typography, { variant: "delta", fontWeight: "bold", style: { display: "block", marginBottom: "16px", color: "var(--colors-primary600, #075985)" }, children: "How it works" }),
7766
- /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 3, children: [
7767
- /* @__PURE__ */ jsx(Typography, { variant: "omega", textColor: "neutral700", children: '1. Click "Connect WhatsApp" to generate a QR code' }),
7768
- /* @__PURE__ */ jsx(Typography, { variant: "omega", textColor: "neutral700", children: "2. Open WhatsApp on your phone" }),
7769
- /* @__PURE__ */ jsx(Typography, { variant: "omega", textColor: "neutral700", children: "3. Go to Settings - Linked Devices - Link a Device" }),
7770
- /* @__PURE__ */ jsx(Typography, { variant: "omega", textColor: "neutral700", children: "4. Scan the QR code with your phone" })
7771
- ] })
7772
- ] }),
7773
- /* @__PURE__ */ jsxs(AlertBox, { children: [
7774
- /* @__PURE__ */ jsx(AlertIcon, { children: "i" }),
7775
- /* @__PURE__ */ jsxs(Box, { children: [
7776
- /* @__PURE__ */ jsx(Typography, { variant: "omega", fontWeight: "semiBold", style: { display: "block", marginBottom: "4px" }, children: "Session Persistence" }),
7777
- /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", 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." })
7778
- ] })
7779
- ] }),
7780
- /* @__PURE__ */ jsxs(ButtonRow, { justifyContent: "space-between", children: [
7781
- /* @__PURE__ */ jsx(
7782
- TertiaryButton,
7783
- {
7784
- onClick: () => setCurrentStep(1),
7785
- startIcon: /* @__PURE__ */ jsx(ArrowLeft, {}),
7786
- children: "Back"
7787
- }
7788
- ),
7789
- /* @__PURE__ */ jsx(
7790
- WhatsAppButton,
7791
- {
7792
- onClick: handleConnect,
7793
- loading: connecting,
7794
- startIcon: /* @__PURE__ */ jsx(Play, {}),
7795
- children: "Connect WhatsApp"
7796
- }
7797
- )
7798
- ] })
7799
- ] }),
7800
- currentStep === 3 && /* @__PURE__ */ jsxs(ContentCard, { children: [
7801
- /* @__PURE__ */ jsx(Typography, { variant: "beta", fontWeight: "bold", style: { display: "block", marginBottom: "8px" }, children: "Scan QR Code" }),
7802
- /* @__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." }),
7803
- /* @__PURE__ */ jsx(QRCodeContainer, { children: status.qrCode ? /* @__PURE__ */ jsxs(Fragment, { children: [
7804
- /* @__PURE__ */ jsx(QRImage, { src: status.qrCode, alt: "WhatsApp QR Code" }),
7805
- /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", style: { marginTop: "16px" }, children: 'QR code expires in 60 seconds. If it expires, click "Refresh QR".' })
7806
- ] }) : /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "center", gap: 3, children: [
7807
- /* @__PURE__ */ jsx(SpinningLoader, { style: { width: "40px", height: "40px" } }),
7808
- /* @__PURE__ */ jsx(Typography, { variant: "omega", children: "Generating QR code..." })
7809
- ] }) }),
7810
- /* @__PURE__ */ jsxs(InfoBox, { children: [
7811
- /* @__PURE__ */ jsx(Typography, { variant: "delta", fontWeight: "bold", style: { display: "block", marginBottom: "16px", color: "var(--colors-primary600, #075985)" }, children: "Instructions" }),
7812
- /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, children: [
7813
- /* @__PURE__ */ jsx(Typography, { variant: "omega", textColor: "neutral700", children: "1. Open WhatsApp on your phone" }),
7814
- /* @__PURE__ */ jsx(Typography, { variant: "omega", textColor: "neutral700", children: "2. Tap Menu or Settings" }),
7815
- /* @__PURE__ */ jsx(Typography, { variant: "omega", textColor: "neutral700", children: '3. Select "Linked Devices"' }),
7816
- /* @__PURE__ */ jsx(Typography, { variant: "omega", textColor: "neutral700", children: '4. Tap "Link a Device"' }),
7817
- /* @__PURE__ */ jsx(Typography, { variant: "omega", textColor: "neutral700", children: "5. Point your phone camera at this QR code" })
7818
- ] })
7819
- ] }),
7820
- /* @__PURE__ */ jsxs(ButtonRow, { justifyContent: "space-between", children: [
7821
- /* @__PURE__ */ jsx(
7822
- TertiaryButton,
7823
- {
7824
- onClick: () => setCurrentStep(2),
7825
- startIcon: /* @__PURE__ */ jsx(ArrowLeft, {}),
7826
- children: "Back"
7827
- }
7828
- ),
7829
- /* @__PURE__ */ jsx(
7830
- SecondaryButton,
7831
- {
7832
- onClick: handleConnect,
7833
- startIcon: /* @__PURE__ */ jsx(ArrowClockwise, {}),
7834
- children: "Refresh QR"
7835
- }
7836
- )
7837
- ] })
7838
- ] }),
7839
- currentStep === 4 && /* @__PURE__ */ jsxs(Fragment, { children: [
7840
- /* @__PURE__ */ jsxs(ConnectedCard, { children: [
7841
- /* @__PURE__ */ jsx(Box, { marginBottom: 4, children: /* @__PURE__ */ jsx(Check, { style: { width: "48px", height: "48px", color: colors.success } }) }),
7842
- /* @__PURE__ */ jsx(Typography, { variant: "alpha", fontWeight: "bold", style: { display: "block", marginBottom: "8px" }, children: "WhatsApp Connected" }),
7843
- status.session && /* @__PURE__ */ jsxs(Typography, { variant: "omega", textColor: "neutral600", style: { display: "block" }, children: [
7844
- "Connected as: ",
7845
- status.session.phoneNumber,
7846
- " ",
7847
- status.session.name && `(${status.session.name})`
7848
- ] })
7849
- ] }),
7850
- /* @__PURE__ */ jsxs(ContentCard, { style: { marginTop: "24px" }, children: [
7851
- /* @__PURE__ */ jsx(Typography, { variant: "beta", fontWeight: "bold", style: { display: "block", marginBottom: "8px" }, children: "Send Test Message" }),
7852
- /* @__PURE__ */ jsx(Typography, { variant: "omega", textColor: "neutral600", style: { display: "block", marginBottom: "24px" }, children: "Test your WhatsApp connection by sending a message." }),
7853
- /* @__PURE__ */ jsxs(TestSection, { children: [
7854
- /* @__PURE__ */ jsxs(Box, { style: { marginBottom: "20px" }, children: [
7855
- /* @__PURE__ */ jsxs(InputLabel, { children: [
7856
- /* @__PURE__ */ jsx(PhoneSymbol, { children: "+" }),
7857
- "Phone Number"
7858
- ] }),
7859
- /* @__PURE__ */ jsx(
7860
- WhatsAppInput,
7861
- {
7862
- placeholder: "49123456789",
7863
- value: testPhone,
7864
- onChange: (e) => setTestPhone(e.target.value)
7865
- }
7866
- ),
7867
- /* @__PURE__ */ jsx(InputHint, { children: "Enter with country code, without + (e.g., 49 for Germany, 1 for USA)" })
7868
- ] }),
7869
- /* @__PURE__ */ jsxs(Box, { style: { marginBottom: "24px" }, children: [
7870
- /* @__PURE__ */ jsxs(InputLabel, { children: [
7871
- /* @__PURE__ */ jsx(MessageSymbol, { children: "@" }),
7872
- "Message (optional)"
7873
- ] }),
7874
- /* @__PURE__ */ jsx(
7875
- WhatsAppTextarea,
7876
- {
7877
- placeholder: "Type your message here... or leave empty for default test message",
7878
- value: testMessage,
7879
- onChange: (e) => setTestMessage(e.target.value),
7880
- rows: 3
7881
- }
7882
- )
7883
- ] }),
7884
- /* @__PURE__ */ jsx(
7885
- WhatsAppButton,
7886
- {
7887
- onClick: handleSendTest,
7888
- loading: sendingTest,
7889
- disabled: !testPhone,
7890
- style: { width: "100%" },
7891
- children: "Send Test Message"
7892
- }
7893
- )
7894
- ] }),
7895
- /* @__PURE__ */ jsx(Divider, { style: { margin: "24px 0" } }),
7896
- /* @__PURE__ */ jsx(Typography, { variant: "beta", fontWeight: "bold", style: { display: "block", marginBottom: "8px" }, children: "Using WhatsApp in Your Code" }),
7897
- /* @__PURE__ */ jsx(Typography, { variant: "omega", textColor: "neutral600", style: { display: "block", marginBottom: "16px" }, children: "Use the WhatsApp service programmatically in your Strapi code." }),
7898
- /* @__PURE__ */ jsx(
7899
- Box,
7900
- {
7901
- padding: 4,
7902
- background: "neutral100",
7903
- hasRadius: true,
7904
- style: {
7905
- fontFamily: "monospace",
7906
- fontSize: "13px",
7907
- lineHeight: "1.6",
7908
- overflow: "auto"
7909
- },
7910
- children: /* @__PURE__ */ jsx("pre", { style: { margin: 0 }, children: `// Send a message via WhatsApp
7911
- const whatsapp = strapi.plugin('magic-mail').service('whatsapp');
7912
-
7913
- // Send simple message
7914
- await whatsapp.sendMessage('49123456789', 'Hello from MagicMail!');
7915
-
7916
- // Send template message
7917
- await whatsapp.sendTemplateMessage('49123456789', 'welcome', {
7918
- name: 'John',
7919
- company: 'ACME Corp',
7920
- });` })
7921
- }
7922
- ),
7923
- /* @__PURE__ */ jsxs(ButtonRow, { justifyContent: "space-between", alignItems: "center", children: [
7924
- /* @__PURE__ */ jsx(
7925
- DangerButton,
7926
- {
7927
- onClick: handleDisconnect,
7928
- startIcon: /* @__PURE__ */ jsx(Cross, {}),
7929
- children: "Disconnect WhatsApp"
7930
- }
7931
- ),
7932
- /* @__PURE__ */ jsx(Badge, { backgroundColor: "success600", textColor: "neutral0", style: { padding: "8px 16px", fontSize: "13px" }, children: "FREE - No API costs!" })
7933
- ] })
7934
- ] })
7935
- ] })
7936
- ] });
7937
- };
7938
7105
  const pluginId = "magic-mail";
7939
7106
  const pluginPermissions = {
7940
7107
  access: [{ action: `plugin::${pluginId}.access`, subject: null }]
@@ -7948,22 +7115,18 @@ const App = () => {
7948
7115
  if (location.pathname.includes("/analytics")) return "analytics";
7949
7116
  if (location.pathname.includes("/routing")) return "routing";
7950
7117
  if (location.pathname.includes("/designer") && !isEditorRoute) return "templates";
7951
- if (location.pathname.includes("/whatsapp")) return "whatsapp";
7952
7118
  return "accounts";
7953
7119
  };
7954
- const [activeTab, setActiveTab] = useState(getActiveTab());
7955
7120
  const handleTabChange = (tab) => {
7956
- setActiveTab(tab);
7957
7121
  if (tab === "accounts") navigate("/plugins/magic-mail");
7958
7122
  if (tab === "routing") navigate("/plugins/magic-mail/routing");
7959
7123
  if (tab === "templates") navigate("/plugins/magic-mail/designer");
7960
7124
  if (tab === "analytics") navigate("/plugins/magic-mail/analytics");
7961
- if (tab === "whatsapp") navigate("/plugins/magic-mail/whatsapp");
7962
7125
  };
7963
7126
  if (isEditorRoute) {
7964
7127
  return /* @__PURE__ */ jsx(Page.Protect, { permissions: pluginPermissions.access, children: /* @__PURE__ */ jsx(EditorPage, {}) });
7965
7128
  }
7966
- return /* @__PURE__ */ jsx(Page.Protect, { permissions: pluginPermissions.access, children: /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Tabs.Root, { value: activeTab, onValueChange: handleTabChange, children: [
7129
+ return /* @__PURE__ */ jsx(Page.Protect, { permissions: pluginPermissions.access, children: /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Tabs.Root, { value: getActiveTab(), onValueChange: handleTabChange, children: [
7967
7130
  /* @__PURE__ */ jsxs(Tabs.List, { children: [
7968
7131
  /* @__PURE__ */ jsx(Tabs.Trigger, { value: "accounts", children: /* @__PURE__ */ jsxs(Flex, { gap: 2, alignItems: "center", children: [
7969
7132
  /* @__PURE__ */ jsx(EnvelopeIcon, { style: { width: 16, height: 16 } }),
@@ -7980,17 +7143,12 @@ const App = () => {
7980
7143
  /* @__PURE__ */ jsx(Tabs.Trigger, { value: "analytics", children: /* @__PURE__ */ jsxs(Flex, { gap: 2, alignItems: "center", children: [
7981
7144
  /* @__PURE__ */ jsx(ChartBarIcon, { style: { width: 16, height: 16 } }),
7982
7145
  "Analytics"
7983
- ] }) }),
7984
- /* @__PURE__ */ jsx(Tabs.Trigger, { value: "whatsapp", children: /* @__PURE__ */ jsxs(Flex, { gap: 2, alignItems: "center", children: [
7985
- /* @__PURE__ */ jsx(ChatBubbleLeftIcon, { style: { width: 16, height: 16 } }),
7986
- "WhatsApp"
7987
7146
  ] }) })
7988
7147
  ] }),
7989
7148
  /* @__PURE__ */ jsx(Tabs.Content, { value: "accounts", children: /* @__PURE__ */ jsx(HomePage, {}) }),
7990
7149
  /* @__PURE__ */ jsx(Tabs.Content, { value: "routing", children: /* @__PURE__ */ jsx(RoutingRulesPage, {}) }),
7991
7150
  /* @__PURE__ */ jsx(Tabs.Content, { value: "templates", children: /* @__PURE__ */ jsx(TemplateList, {}) }),
7992
- /* @__PURE__ */ jsx(Tabs.Content, { value: "analytics", children: /* @__PURE__ */ jsx(Analytics, {}) }),
7993
- /* @__PURE__ */ jsx(Tabs.Content, { value: "whatsapp", children: /* @__PURE__ */ jsx(WhatsAppPage, {}) })
7151
+ /* @__PURE__ */ jsx(Tabs.Content, { value: "analytics", children: /* @__PURE__ */ jsx(Analytics, {}) })
7994
7152
  ] }) }) });
7995
7153
  };
7996
7154
  export {