strapi-plugin-magic-mail 2.2.4 → 2.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/README.md +0 -2
  2. package/dist/server/index.js +1 -1
  3. package/dist/server/index.mjs +1 -1
  4. package/package.json +1 -3
  5. package/admin/jsconfig.json +0 -10
  6. package/admin/src/components/AddAccountModal.jsx +0 -1943
  7. package/admin/src/components/Initializer.jsx +0 -14
  8. package/admin/src/components/LicenseGuard.jsx +0 -475
  9. package/admin/src/components/PluginIcon.jsx +0 -5
  10. package/admin/src/hooks/useAuthRefresh.js +0 -44
  11. package/admin/src/hooks/useLicense.js +0 -158
  12. package/admin/src/index.js +0 -87
  13. package/admin/src/pages/Analytics.jsx +0 -762
  14. package/admin/src/pages/App.jsx +0 -111
  15. package/admin/src/pages/EmailDesigner/EditorPage.jsx +0 -1424
  16. package/admin/src/pages/EmailDesigner/TemplateList.jsx +0 -1807
  17. package/admin/src/pages/HomePage.jsx +0 -1170
  18. package/admin/src/pages/LicensePage.jsx +0 -430
  19. package/admin/src/pages/RoutingRules.jsx +0 -1141
  20. package/admin/src/pages/Settings.jsx +0 -603
  21. package/admin/src/pluginId.js +0 -3
  22. package/admin/src/translations/de.json +0 -71
  23. package/admin/src/translations/en.json +0 -70
  24. package/admin/src/translations/es.json +0 -71
  25. package/admin/src/translations/fr.json +0 -71
  26. package/admin/src/translations/pt.json +0 -71
  27. package/admin/src/utils/fetchWithRetry.js +0 -123
  28. package/admin/src/utils/getTranslation.js +0 -5
  29. package/admin/src/utils/theme.js +0 -85
  30. package/server/jsconfig.json +0 -10
  31. package/server/src/bootstrap.js +0 -157
  32. package/server/src/config/features.js +0 -260
  33. package/server/src/config/index.js +0 -9
  34. package/server/src/content-types/email-account/schema.json +0 -93
  35. package/server/src/content-types/email-event/index.js +0 -8
  36. package/server/src/content-types/email-event/schema.json +0 -57
  37. package/server/src/content-types/email-link/index.js +0 -8
  38. package/server/src/content-types/email-link/schema.json +0 -49
  39. package/server/src/content-types/email-log/index.js +0 -8
  40. package/server/src/content-types/email-log/schema.json +0 -106
  41. package/server/src/content-types/email-template/schema.json +0 -74
  42. package/server/src/content-types/email-template-version/schema.json +0 -60
  43. package/server/src/content-types/index.js +0 -33
  44. package/server/src/content-types/routing-rule/schema.json +0 -59
  45. package/server/src/controllers/accounts.js +0 -229
  46. package/server/src/controllers/analytics.js +0 -361
  47. package/server/src/controllers/controller.js +0 -26
  48. package/server/src/controllers/email-designer.js +0 -474
  49. package/server/src/controllers/index.js +0 -21
  50. package/server/src/controllers/license.js +0 -269
  51. package/server/src/controllers/oauth.js +0 -474
  52. package/server/src/controllers/routing-rules.js +0 -129
  53. package/server/src/controllers/test.js +0 -301
  54. package/server/src/destroy.js +0 -27
  55. package/server/src/index.js +0 -25
  56. package/server/src/middlewares/index.js +0 -3
  57. package/server/src/policies/index.js +0 -3
  58. package/server/src/register.js +0 -5
  59. package/server/src/routes/admin.js +0 -469
  60. package/server/src/routes/content-api.js +0 -37
  61. package/server/src/routes/index.js +0 -9
  62. package/server/src/services/account-manager.js +0 -329
  63. package/server/src/services/analytics.js +0 -512
  64. package/server/src/services/email-designer.js +0 -717
  65. package/server/src/services/email-router.js +0 -1446
  66. package/server/src/services/index.js +0 -17
  67. package/server/src/services/license-guard.js +0 -423
  68. package/server/src/services/oauth.js +0 -515
  69. package/server/src/services/service.js +0 -7
  70. package/server/src/utils/encryption.js +0 -81
  71. package/server/src/utils/logger.js +0 -84
@@ -1,430 +0,0 @@
1
- import { useState, useEffect } from 'react';
2
- import { useFetchClient, useNotification } from '@strapi/strapi/admin';
3
- import styled from 'styled-components';
4
- import {
5
- Box,
6
- Button,
7
- Flex,
8
- Typography,
9
- Badge,
10
- } from '@strapi/design-system';
11
- import {
12
- Check as CheckIcon,
13
- Cross as XMarkIcon,
14
- Sparkle as SparklesIcon,
15
- Lightning as BoltIcon,
16
- Rocket as RocketLaunchIcon,
17
- } from '@strapi/icons';
18
-
19
- const Container = styled(Box)`
20
- padding: 32px;
21
- max-width: 1400px;
22
- margin: 0 auto;
23
- `;
24
-
25
- const Header = styled(Box)`
26
- text-align: center;
27
- margin-bottom: 48px;
28
- display: flex;
29
- flex-direction: column;
30
- align-items: center;
31
- gap: 8px;
32
- `;
33
-
34
- const Title = styled(Typography)`
35
- font-size: 2.5rem;
36
- font-weight: 700;
37
- margin-bottom: 8px;
38
- background: linear-gradient(135deg, #0EA5E9, #A855F7);
39
- -webkit-background-clip: text;
40
- -webkit-text-fill-color: transparent;
41
- display: block;
42
- `;
43
-
44
- const Subtitle = styled(Typography)`
45
- font-size: 1.125rem;
46
- color: ${props => props.theme.colors.neutral600};
47
- line-height: 1.6;
48
- display: block;
49
- `;
50
-
51
- const TierGrid = styled(Flex)`
52
- gap: 32px;
53
- margin: 0 auto 48px;
54
- max-width: 1080px;
55
- justify-content: center;
56
- flex-wrap: wrap;
57
- align-items: stretch;
58
- `;
59
-
60
- const TierWrapper = styled(Box)`
61
- flex: 1;
62
- min-width: 280px;
63
- max-width: 340px;
64
- display: flex;
65
- `;
66
-
67
- const TierCard = styled(Box)`
68
- background: ${props => props.theme.colors.neutral0};
69
- border-radius: 16px;
70
- padding: 32px;
71
- border: 2px solid ${props => props.$featured ? '#0EA5E9' : props.theme.colors.neutral200};
72
- position: relative;
73
- transition: all 0.3s ease;
74
- box-shadow: ${props => props.$featured
75
- ? '0 20px 25px -5px rgba(14, 165, 233, 0.25), 0 8px 10px -6px rgba(14, 165, 233, 0.2)'
76
- : '0 10px 15px -3px rgba(15, 23, 42, 0.08), 0 4px 6px -4px rgba(15, 23, 42, 0.05)'};
77
- display: flex;
78
- flex-direction: column;
79
- width: 100%;
80
-
81
- &:hover {
82
- transform: translateY(-4px);
83
- box-shadow: 0 20px 25px -5px rgba(15, 23, 42, 0.15), 0 8px 10px -6px rgba(15, 23, 42, 0.1);
84
- }
85
- `;
86
-
87
- const PopularBadge = styled(Badge)`
88
- position: absolute;
89
- top: -12px;
90
- right: 24px;
91
- background: linear-gradient(135deg, #0EA5E9, #0284C7);
92
- color: white;
93
- padding: 4px 16px;
94
- font-size: 12px;
95
- font-weight: 600;
96
- `;
97
-
98
- const TierIcon = styled(Box)`
99
- width: 48px;
100
- height: 48px;
101
- border-radius: 12px;
102
- display: flex;
103
- align-items: center;
104
- justify-content: center;
105
- margin-bottom: 16px;
106
- background: ${props => props.$color};
107
-
108
- svg {
109
- width: 28px;
110
- height: 28px;
111
- color: white;
112
- }
113
- `;
114
-
115
- const TierName = styled(Typography)`
116
- font-size: 1.5rem;
117
- font-weight: 700;
118
- margin-bottom: 8px;
119
- `;
120
-
121
- const TierPrice = styled(Typography)`
122
- font-size: 2rem;
123
- font-weight: 800;
124
- margin-bottom: 4px;
125
- `;
126
-
127
- const TierDescription = styled(Typography)`
128
- color: ${props => props.theme.colors.neutral600};
129
- margin-bottom: 24px;
130
- `;
131
-
132
- const FeatureList = styled(Box)`
133
- margin-bottom: 24px;
134
- flex: 1;
135
- `;
136
-
137
- const Feature = styled(Flex)`
138
- gap: 12px;
139
- margin-bottom: 12px;
140
- align-items: flex-start;
141
- `;
142
-
143
- const FeatureIcon = styled(Box)`
144
- width: 20px;
145
- height: 20px;
146
- border-radius: 50%;
147
- display: flex;
148
- align-items: center;
149
- justify-content: center;
150
- flex-shrink: 0;
151
- margin-top: 2px;
152
-
153
- ${props => props.$included ? `
154
- background: #DCFCE7;
155
- svg { color: #16A34A; }
156
- ` : `
157
- background: #FEE2E2;
158
- svg { color: #DC2626; }
159
- `}
160
- `;
161
-
162
- const UpgradeButton = styled(Button)`
163
- width: 100%;
164
- height: 48px;
165
- font-weight: 600;
166
- font-size: 15px;
167
- background: ${props => props.$gradient};
168
- border: none;
169
- color: white;
170
-
171
- &:hover {
172
- transform: translateY(-2px);
173
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
174
- }
175
- `;
176
-
177
- const CurrentPlanBadge = styled(Badge)`
178
- width: 100%;
179
- height: 48px;
180
- display: flex;
181
- align-items: center;
182
- justify-content: center;
183
- background: ${props => props.theme.colors.neutral100};
184
- color: ${props => props.theme.colors.neutral600};
185
- font-weight: 600;
186
- font-size: 15px;
187
- `;
188
-
189
- const LicensePage = () => {
190
- const { get, post } = useFetchClient();
191
- const { toggleNotification } = useNotification();
192
- const [currentTier, setCurrentTier] = useState('free');
193
- const [limits, setLimits] = useState(null);
194
- const [loading, setLoading] = useState(true);
195
-
196
- useEffect(() => {
197
- fetchLicenseInfo();
198
- }, []);
199
-
200
- const fetchLicenseInfo = async () => {
201
- try {
202
- const response = await get('/magic-mail/license/limits');
203
- const licenseData = response.data || {};
204
-
205
- // Determine tier from features
206
- let tier = 'free';
207
- if (licenseData.tier) {
208
- tier = licenseData.tier;
209
- }
210
-
211
- setCurrentTier(tier);
212
- setLimits(licenseData.limits);
213
- setLoading(false);
214
- } catch (error) {
215
- console.error('Failed to fetch license info:', error);
216
- setLoading(false);
217
- }
218
- };
219
-
220
- // Helper function to compare tier ranks
221
- const getTierRank = (tierId) => {
222
- const ranks = {
223
- 'free': 0,
224
- 'premium': 1,
225
- 'advanced': 2,
226
- 'enterprise': 3,
227
- };
228
- return ranks[tierId] || 0;
229
- };
230
-
231
- // Get button text based on tier comparison
232
- const getButtonText = (tierId) => {
233
- const currentRank = getTierRank(currentTier);
234
- const targetRank = getTierRank(tierId);
235
-
236
- if (currentRank === targetRank) {
237
- return 'Current Plan';
238
- } else if (targetRank > currentRank) {
239
- return 'Upgrade Now';
240
- } else {
241
- return 'Downgrade';
242
- }
243
- };
244
-
245
- const tiers = [
246
- {
247
- id: 'free',
248
- name: 'FREE',
249
- price: '$0',
250
- period: 'forever',
251
- description: 'Perfect for small projects and testing',
252
- icon: <SparklesIcon />,
253
- color: 'linear-gradient(135deg, #6B7280, #4B5563)',
254
- features: [
255
- { name: '25 Email Templates', included: true },
256
- { name: '3 Email Accounts', included: true },
257
- { name: '5 Routing Rules', included: true },
258
- { name: 'All OAuth Providers', included: true },
259
- { name: 'Import/Export Templates', included: true },
260
- { name: 'Template Versioning', included: false },
261
- { name: 'Analytics Dashboard', included: false },
262
- { name: 'Priority Support', included: false },
263
- ],
264
- limits: {
265
- templates: '25',
266
- accounts: '3',
267
- rules: '5',
268
- }
269
- },
270
- {
271
- id: 'premium',
272
- name: 'PREMIUM',
273
- price: '$14.50',
274
- period: '/month',
275
- description: 'Enhanced features for growing teams',
276
- icon: <BoltIcon />,
277
- color: 'linear-gradient(135deg, #8B5CF6, #7C3AED)',
278
- featured: true,
279
- features: [
280
- { name: '100 Email Templates', included: true },
281
- { name: '10 Email Accounts', included: true },
282
- { name: '20 Routing Rules', included: true },
283
- { name: 'All OAuth Providers', included: true },
284
- { name: 'Import/Export Templates', included: true },
285
- { name: 'Template Versioning', included: true },
286
- { name: 'Basic Analytics', included: true },
287
- { name: 'Priority Support', included: true },
288
- ],
289
- limits: {
290
- templates: '100',
291
- accounts: '10',
292
- rules: '20',
293
- }
294
- },
295
- {
296
- id: 'advanced',
297
- name: 'ADVANCED',
298
- price: '$39.50',
299
- period: '/month',
300
- description: 'Maximum features for power users',
301
- icon: <RocketLaunchIcon />,
302
- color: 'linear-gradient(135deg, #0EA5E9, #0284C7)',
303
- features: [
304
- { name: '500 Email Templates', included: true },
305
- { name: 'Unlimited Accounts', included: true },
306
- { name: 'Unlimited Routing Rules', included: true },
307
- { name: 'All OAuth Providers', included: true },
308
- { name: 'Import/Export Templates', included: true },
309
- { name: 'Template Versioning', included: true },
310
- { name: 'Advanced Analytics & Tracking', included: true },
311
- { name: 'SendGrid & Mailgun APIs', included: true },
312
- ],
313
- limits: {
314
- templates: '500',
315
- accounts: 'Unlimited',
316
- rules: 'Unlimited',
317
- }
318
- }
319
- ];
320
-
321
- const handleUpgrade = (tierId) => {
322
- // Navigate to upgrade URL or show upgrade modal
323
- window.open('https://store.magicdx.dev/', '_blank');
324
- };
325
-
326
- if (loading) {
327
- return (
328
- <Container>
329
- <Flex justifyContent="center" alignItems="center" style={{ minHeight: '400px' }}>
330
- <Typography>Loading license information...</Typography>
331
- </Flex>
332
- </Container>
333
- );
334
- }
335
-
336
- return (
337
- <Container>
338
- <Header>
339
- <Title variant="alpha">Choose Your Plan</Title>
340
- <Subtitle variant="omega">
341
- Unlock powerful email management features for your Strapi application
342
- </Subtitle>
343
- </Header>
344
-
345
- <TierGrid>
346
- {tiers.map((tier) => (
347
- <TierWrapper key={tier.id}>
348
- <TierCard $featured={tier.featured}>
349
- {tier.featured && <PopularBadge>MOST POPULAR</PopularBadge>}
350
-
351
- <TierIcon $color={tier.color}>
352
- {tier.icon}
353
- </TierIcon>
354
-
355
- <TierName variant="beta">{tier.name}</TierName>
356
-
357
- <Flex alignItems="baseline" gap={1}>
358
- <TierPrice variant="alpha">{tier.price}</TierPrice>
359
- <Typography variant="omega" style={{ color: '#6B7280' }}>
360
- {tier.period}
361
- </Typography>
362
- </Flex>
363
-
364
- <TierDescription variant="omega">
365
- {tier.description}
366
- </TierDescription>
367
-
368
- {/* Limits Summary */}
369
- <Box style={{
370
- background: '#F9FAFB',
371
- borderRadius: '8px',
372
- padding: '12px',
373
- marginBottom: '20px'
374
- }}>
375
- <Flex direction="column" gap={2}>
376
- <Typography variant="pi" style={{ fontSize: '13px' }}>
377
- <strong>Templates:</strong> {tier.limits.templates}
378
- </Typography>
379
- <Typography variant="pi" style={{ fontSize: '13px' }}>
380
- <strong>Accounts:</strong> {tier.limits.accounts}
381
- </Typography>
382
- <Typography variant="pi" style={{ fontSize: '13px' }}>
383
- <strong>Routing Rules:</strong> {tier.limits.rules}
384
- </Typography>
385
- </Flex>
386
- </Box>
387
-
388
- <FeatureList>
389
- {tier.features.map((feature, index) => (
390
- <Feature key={index}>
391
- <FeatureIcon $included={feature.included}>
392
- {feature.included ? (
393
- <CheckIcon style={{ width: 14, height: 14 }} />
394
- ) : (
395
- <XMarkIcon style={{ width: 14, height: 14 }} />
396
- )}
397
- </FeatureIcon>
398
- <Typography
399
- variant="omega"
400
- style={{
401
- fontSize: '14px',
402
- color: feature.included ? '#374151' : '#9CA3AF',
403
- textDecoration: feature.included ? 'none' : 'line-through'
404
- }}
405
- >
406
- {feature.name}
407
- </Typography>
408
- </Feature>
409
- ))}
410
- </FeatureList>
411
-
412
- {currentTier === tier.id ? (
413
- <CurrentPlanBadge>Current Plan</CurrentPlanBadge>
414
- ) : (
415
- <UpgradeButton
416
- $gradient={tier.color}
417
- onClick={() => handleUpgrade(tier.id)}
418
- >
419
- {getButtonText(tier.id)}
420
- </UpgradeButton>
421
- )}
422
- </TierCard>
423
- </TierWrapper>
424
- ))}
425
- </TierGrid>
426
- </Container>
427
- );
428
- };
429
-
430
- export default LicensePage;