strapi-plugin-magic-mail 2.2.3 → 2.2.5

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 (70) hide show
  1. package/dist/server/index.js +1 -1
  2. package/dist/server/index.mjs +1 -1
  3. package/package.json +1 -3
  4. package/admin/jsconfig.json +0 -10
  5. package/admin/src/components/AddAccountModal.jsx +0 -1943
  6. package/admin/src/components/Initializer.jsx +0 -14
  7. package/admin/src/components/LicenseGuard.jsx +0 -475
  8. package/admin/src/components/PluginIcon.jsx +0 -5
  9. package/admin/src/hooks/useAuthRefresh.js +0 -44
  10. package/admin/src/hooks/useLicense.js +0 -158
  11. package/admin/src/index.js +0 -87
  12. package/admin/src/pages/Analytics.jsx +0 -762
  13. package/admin/src/pages/App.jsx +0 -111
  14. package/admin/src/pages/EmailDesigner/EditorPage.jsx +0 -1424
  15. package/admin/src/pages/EmailDesigner/TemplateList.jsx +0 -1807
  16. package/admin/src/pages/HomePage.jsx +0 -1170
  17. package/admin/src/pages/LicensePage.jsx +0 -430
  18. package/admin/src/pages/RoutingRules.jsx +0 -1141
  19. package/admin/src/pages/Settings.jsx +0 -603
  20. package/admin/src/pluginId.js +0 -3
  21. package/admin/src/translations/de.json +0 -71
  22. package/admin/src/translations/en.json +0 -70
  23. package/admin/src/translations/es.json +0 -71
  24. package/admin/src/translations/fr.json +0 -71
  25. package/admin/src/translations/pt.json +0 -71
  26. package/admin/src/utils/fetchWithRetry.js +0 -123
  27. package/admin/src/utils/getTranslation.js +0 -5
  28. package/admin/src/utils/theme.js +0 -85
  29. package/server/jsconfig.json +0 -10
  30. package/server/src/bootstrap.js +0 -157
  31. package/server/src/config/features.js +0 -260
  32. package/server/src/config/index.js +0 -9
  33. package/server/src/content-types/email-account/schema.json +0 -93
  34. package/server/src/content-types/email-event/index.js +0 -8
  35. package/server/src/content-types/email-event/schema.json +0 -57
  36. package/server/src/content-types/email-link/index.js +0 -8
  37. package/server/src/content-types/email-link/schema.json +0 -49
  38. package/server/src/content-types/email-log/index.js +0 -8
  39. package/server/src/content-types/email-log/schema.json +0 -106
  40. package/server/src/content-types/email-template/schema.json +0 -74
  41. package/server/src/content-types/email-template-version/schema.json +0 -60
  42. package/server/src/content-types/index.js +0 -33
  43. package/server/src/content-types/routing-rule/schema.json +0 -59
  44. package/server/src/controllers/accounts.js +0 -229
  45. package/server/src/controllers/analytics.js +0 -361
  46. package/server/src/controllers/controller.js +0 -26
  47. package/server/src/controllers/email-designer.js +0 -474
  48. package/server/src/controllers/index.js +0 -21
  49. package/server/src/controllers/license.js +0 -269
  50. package/server/src/controllers/oauth.js +0 -474
  51. package/server/src/controllers/routing-rules.js +0 -129
  52. package/server/src/controllers/test.js +0 -301
  53. package/server/src/destroy.js +0 -27
  54. package/server/src/index.js +0 -25
  55. package/server/src/middlewares/index.js +0 -3
  56. package/server/src/policies/index.js +0 -3
  57. package/server/src/register.js +0 -5
  58. package/server/src/routes/admin.js +0 -469
  59. package/server/src/routes/content-api.js +0 -37
  60. package/server/src/routes/index.js +0 -9
  61. package/server/src/services/account-manager.js +0 -329
  62. package/server/src/services/analytics.js +0 -512
  63. package/server/src/services/email-designer.js +0 -717
  64. package/server/src/services/email-router.js +0 -1446
  65. package/server/src/services/index.js +0 -17
  66. package/server/src/services/license-guard.js +0 -423
  67. package/server/src/services/oauth.js +0 -515
  68. package/server/src/services/service.js +0 -7
  69. package/server/src/utils/encryption.js +0 -81
  70. package/server/src/utils/logger.js +0 -84
@@ -1,603 +0,0 @@
1
- import { useState, useEffect } from 'react';
2
- import {
3
- Box,
4
- Typography,
5
- Badge,
6
- Flex,
7
- Alert,
8
- Button,
9
- Loader,
10
- Accordion,
11
- } from '@strapi/design-system';
12
- import { useFetchClient, useNotification } from '@strapi/strapi/admin';
13
- import {
14
- ArrowPathIcon,
15
- KeyIcon,
16
- UserIcon,
17
- ShieldCheckIcon,
18
- SparklesIcon,
19
- ChartBarIcon,
20
- DocumentDuplicateIcon,
21
- ArrowDownTrayIcon,
22
- } from '@heroicons/react/24/outline';
23
- import styled, { keyframes, css } from 'styled-components';
24
-
25
- // ================ THEME ================
26
- const theme = {
27
- colors: {
28
- primary: { 600: '#0EA5E9', 100: '#E0F2FE', 50: '#F0F9FF' },
29
- success: { 600: '#16A34A', 50: '#DCFCE7' },
30
- warning: { 50: '#FEF3C7' },
31
- danger: { 50: '#FEE2E2' },
32
- neutral: { 0: '#FFFFFF', 100: '#F3F4F6', 200: '#E5E7EB', 600: '#4B5563', 800: '#1F2937' }
33
- },
34
- shadows: { sm: '0 1px 3px rgba(0,0,0,0.1)' },
35
- borderRadius: { lg: '12px' }
36
- };
37
-
38
- // ================ ANIMATIONS ================
39
- const fadeIn = keyframes`
40
- from { opacity: 0; transform: translateY(10px); }
41
- to { opacity: 1; transform: translateY(0); }
42
- `;
43
-
44
- const shimmer = keyframes`
45
- 0% { background-position: -200% 0; }
46
- 100% { background-position: 200% 0; }
47
- `;
48
-
49
- // ================ STYLED COMPONENTS ================
50
- const Container = styled(Box)`
51
- ${css`animation: ${fadeIn} 0.5s;`}
52
- max-width: 1400px;
53
- margin: 0 auto;
54
- `;
55
-
56
- const StickySaveBar = styled(Box)`
57
- position: sticky;
58
- top: 0;
59
- z-index: 10;
60
- background: ${props => props.theme.colors.neutral0};
61
- border-bottom: 1px solid ${props => props.theme.colors.neutral200};
62
- box-shadow: 0 1px 3px rgba(0,0,0,0.1);
63
- `;
64
-
65
- const LicenseKeyBanner = styled(Box)`
66
- background: linear-gradient(135deg, #0EA5E9 0%, #A855F7 100%);
67
- border-radius: ${theme.borderRadius.lg};
68
- padding: 28px 32px;
69
- color: white;
70
- position: relative;
71
- overflow: hidden;
72
- box-shadow: 0 4px 20px rgba(14, 165, 233, 0.25);
73
- margin-bottom: 24px;
74
-
75
- &::after {
76
- content: '';
77
- position: absolute;
78
- top: -50%;
79
- right: -50%;
80
- width: 200%;
81
- height: 200%;
82
- background: linear-gradient(
83
- 45deg,
84
- transparent,
85
- rgba(255, 255, 255, 0.08),
86
- transparent
87
- );
88
- ${css`animation: ${shimmer} 3s infinite;`}
89
- pointer-events: none;
90
- z-index: 0;
91
- }
92
-
93
- & > * {
94
- position: relative;
95
- z-index: 1;
96
- }
97
- `;
98
-
99
- const LoaderContainer = styled(Flex)`
100
- min-height: 400px;
101
- align-items: center;
102
- justify-content: center;
103
- flex-direction: column;
104
- gap: 16px;
105
- `;
106
-
107
- // ================ MAIN COMPONENT ================
108
- const LicensePage = () => {
109
- const { get } = useFetchClient();
110
- const { toggleNotification } = useNotification();
111
- const [loading, setLoading] = useState(true);
112
- const [licenseData, setLicenseData] = useState(null);
113
- const [error, setError] = useState(null);
114
-
115
- const fetchLicenseStatus = async () => {
116
- setLoading(true);
117
- setError(null);
118
-
119
- try {
120
- const response = await get('/magic-mail/license/status');
121
- setLicenseData(response.data);
122
- } catch (err) {
123
- console.error('[MagicMail] Error fetching license:', err);
124
- setError('Failed to load license information');
125
- } finally {
126
- setLoading(false);
127
- }
128
- };
129
-
130
- const handleCopyLicenseKey = async () => {
131
- try {
132
- await navigator.clipboard.writeText(licenseData?.data?.licenseKey || '');
133
- toggleNotification({
134
- type: 'success',
135
- message: 'License key copied to clipboard!',
136
- });
137
- } catch (err) {
138
- toggleNotification({
139
- type: 'danger',
140
- message: 'Failed to copy license key',
141
- });
142
- }
143
- };
144
-
145
- const handleDownloadLicenseKey = () => {
146
- try {
147
- const data = licenseData?.data || {};
148
- const licenseKey = data.licenseKey || '';
149
- const email = data.email || 'N/A';
150
- const firstName = data.firstName || '';
151
- const lastName = data.lastName || '';
152
- const fullName = `${firstName} ${lastName}`.trim() || 'N/A';
153
-
154
- const content = `MagicMail - Email Business Suite - License Key
155
- ═══════════════════════════════════════
156
-
157
- License Key: ${licenseKey}
158
-
159
- License Holder Information:
160
- ──────────────────────────────────────
161
- Name: ${fullName}
162
- Email: ${email}
163
-
164
- License Status:
165
- ──────────────────────────────────────
166
- Status: ${data.isActive ? 'ACTIVE' : 'INACTIVE'}
167
- Expires: ${data.expiresAt ? new Date(data.expiresAt).toLocaleDateString() : 'Never'}
168
-
169
- Features:
170
- ──────────────────────────────────────
171
- Premium: ${data.features?.premium ? 'Enabled' : 'Disabled'}
172
- Advanced: ${data.features?.advanced ? 'Enabled' : 'Disabled'}
173
- Enterprise: ${data.features?.enterprise ? 'Enabled' : 'Disabled'}
174
-
175
- ═══════════════════════════════════════
176
- Generated: ${new Date().toLocaleString()}
177
- `;
178
-
179
- const blob = new Blob([content], { type: 'text/plain' });
180
- const url = window.URL.createObjectURL(blob);
181
- const link = document.createElement('a');
182
- link.href = url;
183
- link.download = `magicmail-license-${licenseKey.substring(0, 8)}.txt`;
184
- document.body.appendChild(link);
185
- link.click();
186
- document.body.removeChild(link);
187
- window.URL.revokeObjectURL(url);
188
-
189
- toggleNotification({
190
- type: 'success',
191
- message: 'License key downloaded successfully!',
192
- });
193
- } catch (err) {
194
- toggleNotification({
195
- type: 'danger',
196
- message: 'Failed to download license key',
197
- });
198
- }
199
- };
200
-
201
- useEffect(() => {
202
- fetchLicenseStatus();
203
- }, []);
204
-
205
- if (loading) {
206
- return (
207
- <Container>
208
- <LoaderContainer>
209
- <Loader>Loading license information...</Loader>
210
- </LoaderContainer>
211
- </Container>
212
- );
213
- }
214
-
215
- if (error) {
216
- return (
217
- <Container>
218
- <Box padding={8}>
219
- <Alert variant="danger" title="Error" closeLabel="Close">
220
- {error}
221
- </Alert>
222
- </Box>
223
- </Container>
224
- );
225
- }
226
-
227
- const isValid = licenseData?.valid;
228
- const isDemo = licenseData?.demo;
229
- const data = licenseData?.data || {};
230
-
231
- return (
232
- <Container>
233
- {/* Sticky Header */}
234
- <StickySaveBar paddingTop={5} paddingBottom={5} paddingLeft={6} paddingRight={6}>
235
- <Flex justifyContent="space-between" alignItems="flex-start">
236
- <Flex direction="column" gap={1} alignItems="flex-start">
237
- <Typography variant="alpha" fontWeight="bold">
238
- License Management
239
- </Typography>
240
- <Typography variant="epsilon" textColor="neutral600">
241
- View your MagicMail plugin license
242
- </Typography>
243
- </Flex>
244
- <Button
245
- startIcon={<ArrowPathIcon style={{ width: 20, height: 20 }} />}
246
- onClick={fetchLicenseStatus}
247
- size="L"
248
- style={{
249
- background: 'linear-gradient(135deg, #0EA5E9 0%, #A855F7 100%)',
250
- color: 'white',
251
- fontWeight: '600',
252
- border: 'none',
253
- }}
254
- >
255
- Refresh Status
256
- </Button>
257
- </Flex>
258
- </StickySaveBar>
259
-
260
- {/* Content */}
261
- <Box paddingTop={6} paddingLeft={6} paddingRight={6} paddingBottom={10}>
262
- {/* Status Alert */}
263
- {isDemo ? (
264
- <Alert variant="warning" title="Demo Mode" closeLabel="Close">
265
- You're using the demo version. Create a license to unlock all features.
266
- </Alert>
267
- ) : isValid ? (
268
- <Alert variant="success" title="License Active" closeLabel="Close">
269
- Your license is active and all features are unlocked.
270
- </Alert>
271
- ) : (
272
- <Alert variant="danger" title="License Issue" closeLabel="Close">
273
- There's an issue with your license. Please check your license status.
274
- </Alert>
275
- )}
276
-
277
- {/* License Key */}
278
- {data.licenseKey && (
279
- <Box marginTop={6}>
280
- <LicenseKeyBanner>
281
- <Flex justifyContent="space-between" alignItems="flex-start">
282
- <Box style={{ flex: 1 }}>
283
- <Typography variant="pi" style={{ color: 'rgba(255,255,255,0.8)', marginBottom: '12px', textTransform: 'uppercase', fontSize: '11px', letterSpacing: '0.5px', display: 'block' }}>
284
- License Key
285
- </Typography>
286
- <Typography style={{ color: 'white', fontFamily: 'monospace', fontSize: '28px', fontWeight: 'bold', wordBreak: 'break-all', marginBottom: '16px' }}>
287
- {data.licenseKey}
288
- </Typography>
289
- <Flex gap={2}>
290
- <Button
291
- onClick={handleCopyLicenseKey}
292
- startIcon={<DocumentDuplicateIcon style={{ width: 16, height: 16 }} />}
293
- size="S"
294
- variant="secondary"
295
- style={{
296
- backgroundColor: 'rgba(255,255,255,0.2)',
297
- color: 'white',
298
- border: '1px solid rgba(255,255,255,0.3)',
299
- fontWeight: '600',
300
- }}
301
- >
302
- Copy Key
303
- </Button>
304
- <Button
305
- onClick={handleDownloadLicenseKey}
306
- startIcon={<ArrowDownTrayIcon style={{ width: 16, height: 16 }} />}
307
- size="S"
308
- variant="secondary"
309
- style={{
310
- backgroundColor: 'rgba(255,255,255,0.2)',
311
- color: 'white',
312
- border: '1px solid rgba(255,255,255,0.3)',
313
- fontWeight: '600',
314
- }}
315
- >
316
- Download as TXT
317
- </Button>
318
- </Flex>
319
- </Box>
320
- <Badge
321
- backgroundColor={data.isActive ? "success100" : "danger100"}
322
- textColor={data.isActive ? "success700" : "danger700"}
323
- style={{ fontSize: '11px', fontWeight: '700', padding: '6px 12px', marginLeft: '16px', flexShrink: 0 }}
324
- >
325
- {data.isActive ? 'ACTIVE' : 'INACTIVE'}
326
- </Badge>
327
- </Flex>
328
- </LicenseKeyBanner>
329
- </Box>
330
- )}
331
-
332
- {/* Details Section */}
333
- <Box marginTop={6}>
334
- <Accordion.Root defaultValue="account" collapsible>
335
- {/* Account Information */}
336
- <Accordion.Item value="account">
337
- <Accordion.Header>
338
- <Accordion.Trigger icon={() => <UserIcon style={{ width: 16, height: 16 }} />}>
339
- Account Information
340
- </Accordion.Trigger>
341
- </Accordion.Header>
342
- <Accordion.Content>
343
- <Box padding={6}>
344
- <Flex gap={8} wrap="wrap">
345
- <Box style={{ flex: '1', minWidth: '200px' }}>
346
- <Typography variant="sigma" textColor="neutral600" textTransform="uppercase" style={{ marginBottom: '8px', display: 'block' }}>
347
- Email Address
348
- </Typography>
349
- <Typography variant="omega" fontWeight="semiBold">
350
- {data.email || 'Not provided'}
351
- </Typography>
352
- </Box>
353
- <Box style={{ flex: '1', minWidth: '200px' }}>
354
- <Typography variant="sigma" textColor="neutral600" textTransform="uppercase" style={{ marginBottom: '8px', display: 'block' }}>
355
- License Holder
356
- </Typography>
357
- <Typography variant="omega" fontWeight="semiBold">
358
- {data.firstName && data.lastName
359
- ? `${data.firstName} ${data.lastName}`
360
- : 'Not specified'
361
- }
362
- </Typography>
363
- </Box>
364
- </Flex>
365
- </Box>
366
- </Accordion.Content>
367
- </Accordion.Item>
368
-
369
- {/* License Details */}
370
- <Accordion.Item value="details">
371
- <Accordion.Header>
372
- <Accordion.Trigger icon={() => <ShieldCheckIcon style={{ width: 16, height: 16 }} />}>
373
- License Details
374
- </Accordion.Trigger>
375
- </Accordion.Header>
376
- <Accordion.Content>
377
- <Box padding={6}>
378
- <Flex gap={8} wrap="wrap">
379
- <Box style={{ flex: '1', minWidth: '180px' }}>
380
- <Typography variant="sigma" textColor="neutral600" textTransform="uppercase" style={{ marginBottom: '8px', display: 'block' }}>
381
- {data.isExpired ? 'Expired On' : 'Expires On'}
382
- </Typography>
383
- <Typography variant="omega" fontWeight="semiBold">
384
- {data.expiresAt
385
- ? new Date(data.expiresAt).toLocaleDateString('en-US', {
386
- year: 'numeric',
387
- month: 'long',
388
- day: 'numeric',
389
- })
390
- : 'Never'}
391
- </Typography>
392
- </Box>
393
- <Box style={{ flex: '1', minWidth: '180px' }}>
394
- <Typography variant="sigma" textColor="neutral600" textTransform="uppercase" style={{ marginBottom: '8px', display: 'block' }}>
395
- Device Name
396
- </Typography>
397
- <Typography variant="omega" fontWeight="semiBold">
398
- {data.deviceName || 'Unknown'}
399
- </Typography>
400
- </Box>
401
- <Box style={{ flex: '1', minWidth: '180px' }}>
402
- <Typography variant="sigma" textColor="neutral600" textTransform="uppercase" style={{ marginBottom: '8px', display: 'block' }}>
403
- IP Address
404
- </Typography>
405
- <Typography variant="omega" fontWeight="semiBold">
406
- {data.ipAddress || 'Not detected'}
407
- </Typography>
408
- </Box>
409
- </Flex>
410
- </Box>
411
- </Accordion.Content>
412
- </Accordion.Item>
413
-
414
- {/* Features */}
415
- <Accordion.Item value="features">
416
- <Accordion.Header>
417
- <Accordion.Trigger icon={() => <SparklesIcon style={{ width: 16, height: 16 }} />}>
418
- Features & Capabilities
419
- </Accordion.Trigger>
420
- </Accordion.Header>
421
- <Accordion.Content>
422
- <Box padding={6}>
423
- {/* Feature Tier Badges */}
424
- <Flex gap={3} style={{ marginBottom: '32px' }}>
425
- <Badge
426
- backgroundColor={data.features?.premium ? "success100" : "neutral100"}
427
- textColor={data.features?.premium ? "success700" : "neutral600"}
428
- style={{
429
- fontSize: '13px',
430
- fontWeight: '700',
431
- padding: '8px 16px',
432
- border: data.features?.premium ? '2px solid #dcfce7' : '2px solid #e5e7eb'
433
- }}
434
- >
435
- {data.features?.premium ? '✓' : '✗'} PREMIUM FEATURES
436
- </Badge>
437
- <Badge
438
- backgroundColor={data.features?.advanced ? "primary100" : "neutral100"}
439
- textColor={data.features?.advanced ? "primary700" : "neutral600"}
440
- style={{
441
- fontSize: '13px',
442
- fontWeight: '700',
443
- padding: '8px 16px',
444
- border: data.features?.advanced ? '2px solid #bae6fd' : '2px solid #e5e7eb'
445
- }}
446
- >
447
- {data.features?.advanced ? '✓' : '✗'} ADVANCED FEATURES
448
- </Badge>
449
- <Badge
450
- backgroundColor={data.features?.enterprise ? "secondary100" : "neutral100"}
451
- textColor={data.features?.enterprise ? "secondary700" : "neutral600"}
452
- style={{
453
- fontSize: '13px',
454
- fontWeight: '700',
455
- padding: '8px 16px',
456
- border: data.features?.enterprise ? '2px solid #ddd6fe' : '2px solid #e5e7eb'
457
- }}
458
- >
459
- {data.features?.enterprise ? '✓' : '✗'} ENTERPRISE FEATURES
460
- </Badge>
461
- </Flex>
462
-
463
- {/* Premium Features */}
464
- {data.features?.premium && (
465
- <Box marginBottom={5} padding={5} background="success50" hasRadius style={{ border: '2px solid #dcfce7' }}>
466
- <Typography variant="delta" fontWeight="bold" textColor="success700" style={{ marginBottom: '16px', display: 'flex', alignItems: 'center', gap: '8px' }}>
467
- ✨ Premium Features Active
468
- </Typography>
469
- <Flex direction="column" gap={2}>
470
- <Typography variant="omega" textColor="success700" style={{ fontSize: '14px', display: 'flex', alignItems: 'center', gap: '8px' }}>
471
- ✓ Gmail OAuth 2.0 (Unlimited accounts)
472
- </Typography>
473
- <Typography variant="omega" textColor="success700" style={{ fontSize: '14px', display: 'flex', alignItems: 'center', gap: '8px' }}>
474
- ✓ Microsoft 365 OAuth Integration
475
- </Typography>
476
- <Typography variant="omega" textColor="success700" style={{ fontSize: '14px', display: 'flex', alignItems: 'center', gap: '8px' }}>
477
- ✓ Yahoo Mail OAuth
478
- </Typography>
479
- <Typography variant="omega" textColor="success700" style={{ fontSize: '14px', display: 'flex', alignItems: 'center', gap: '8px' }}>
480
- ✓ SendGrid & Mailgun Integration
481
- </Typography>
482
- <Typography variant="omega" textColor="success700" style={{ fontSize: '14px', display: 'flex', alignItems: 'center', gap: '8px' }}>
483
- ✓ Smart Routing Rules (Unlimited)
484
- </Typography>
485
- <Typography variant="omega" textColor="success700" style={{ fontSize: '14px', display: 'flex', alignItems: 'center', gap: '8px' }}>
486
- ✓ Email Analytics Dashboard
487
- </Typography>
488
- </Flex>
489
- </Box>
490
- )}
491
-
492
- {/* Advanced Features */}
493
- {data.features?.advanced && (
494
- <Box marginBottom={5} padding={5} background="primary50" hasRadius style={{ border: '2px solid #bae6fd' }}>
495
- <Typography variant="delta" fontWeight="bold" textColor="primary700" style={{ marginBottom: '16px', display: 'flex', alignItems: 'center', gap: '8px' }}>
496
- 🚀 Advanced Features Active
497
- </Typography>
498
- <Flex direction="column" gap={2}>
499
- <Typography variant="omega" textColor="primary700" style={{ fontSize: '14px', display: 'flex', alignItems: 'center', gap: '8px' }}>
500
- ✓ DKIM Signing for SMTP
501
- </Typography>
502
- <Typography variant="omega" textColor="primary700" style={{ fontSize: '14px', display: 'flex', alignItems: 'center', gap: '8px' }}>
503
- ✓ Email Designer Integration
504
- </Typography>
505
- <Typography variant="omega" textColor="primary700" style={{ fontSize: '14px', display: 'flex', alignItems: 'center', gap: '8px' }}>
506
- ✓ Priority Email Headers
507
- </Typography>
508
- <Typography variant="omega" textColor="primary700" style={{ fontSize: '14px', display: 'flex', alignItems: 'center', gap: '8px' }}>
509
- ✓ List-Unsubscribe Headers (GDPR)
510
- </Typography>
511
- <Typography variant="omega" textColor="primary700" style={{ fontSize: '14px', display: 'flex', alignItems: 'center', gap: '8px' }}>
512
- ✓ Enhanced Security Validation
513
- </Typography>
514
- </Flex>
515
- </Box>
516
- )}
517
-
518
- {/* Enterprise Features */}
519
- {data.features?.enterprise && (
520
- <Box padding={5} background="secondary50" hasRadius style={{ border: '2px solid #ddd6fe' }}>
521
- <Typography variant="delta" fontWeight="bold" textColor="secondary700" style={{ marginBottom: '16px', display: 'flex', alignItems: 'center', gap: '8px' }}>
522
- 🏢 Enterprise Features Active
523
- </Typography>
524
- <Flex direction="column" gap={2}>
525
- <Typography variant="omega" textColor="secondary700" style={{ fontSize: '14px', display: 'flex', alignItems: 'center', gap: '8px' }}>
526
- ✓ Multi-tenant Email Management
527
- </Typography>
528
- <Typography variant="omega" textColor="secondary700" style={{ fontSize: '14px', display: 'flex', alignItems: 'center', gap: '8px' }}>
529
- ✓ Compliance Reports (GDPR, CAN-SPAM)
530
- </Typography>
531
- <Typography variant="omega" textColor="secondary700" style={{ fontSize: '14px', display: 'flex', alignItems: 'center', gap: '8px' }}>
532
- ✓ Custom Routing Rules Engine
533
- </Typography>
534
- <Typography variant="omega" textColor="secondary700" style={{ fontSize: '14px', display: 'flex', alignItems: 'center', gap: '8px' }}>
535
- ✓ Advanced Rate Limiting
536
- </Typography>
537
- <Typography variant="omega" textColor="secondary700" style={{ fontSize: '14px', display: 'flex', alignItems: 'center', gap: '8px' }}>
538
- ✓ Priority Support
539
- </Typography>
540
- </Flex>
541
- </Box>
542
- )}
543
- </Box>
544
- </Accordion.Content>
545
- </Accordion.Item>
546
-
547
- {/* System Status */}
548
- <Accordion.Item value="status">
549
- <Accordion.Header>
550
- <Accordion.Trigger icon={() => <ChartBarIcon style={{ width: 16, height: 16 }} />}>
551
- System Status
552
- </Accordion.Trigger>
553
- </Accordion.Header>
554
- <Accordion.Content>
555
- <Box padding={6}>
556
- <Flex gap={8} wrap="wrap">
557
- <Box style={{ flex: '1', minWidth: '150px' }}>
558
- <Typography variant="sigma" textColor="neutral600" textTransform="uppercase" style={{ marginBottom: '8px', display: 'block' }}>
559
- License Status
560
- </Typography>
561
- <Typography variant="omega" fontWeight="semiBold">
562
- {data.isActive ? 'Active' : 'Inactive'}
563
- </Typography>
564
- </Box>
565
- <Box style={{ flex: '1', minWidth: '150px' }}>
566
- <Typography variant="sigma" textColor="neutral600" textTransform="uppercase" style={{ marginBottom: '8px', display: 'block' }}>
567
- Connection
568
- </Typography>
569
- <Typography variant="omega" fontWeight="semiBold">
570
- {data.isOnline ? 'Online' : 'Offline'}
571
- </Typography>
572
- </Box>
573
- <Box style={{ flex: '1', minWidth: '150px' }}>
574
- <Typography variant="sigma" textColor="neutral600" textTransform="uppercase" style={{ marginBottom: '8px', display: 'block' }}>
575
- Last Sync
576
- </Typography>
577
- <Typography variant="omega" fontWeight="semiBold">
578
- {data.lastPingAt
579
- ? new Date(data.lastPingAt).toLocaleTimeString()
580
- : 'Never'}
581
- </Typography>
582
- </Box>
583
- <Box style={{ flex: '1', minWidth: '150px' }}>
584
- <Typography variant="sigma" textColor="neutral600" textTransform="uppercase" style={{ marginBottom: '8px', display: 'block' }}>
585
- Device Limit
586
- </Typography>
587
- <Typography variant="omega" fontWeight="semiBold">
588
- {data.currentDevices || 0} / {data.maxDevices || 1}
589
- </Typography>
590
- </Box>
591
- </Flex>
592
- </Box>
593
- </Accordion.Content>
594
- </Accordion.Item>
595
- </Accordion.Root>
596
- </Box>
597
- </Box>
598
- </Container>
599
- );
600
- };
601
-
602
- export default LicensePage;
603
-
@@ -1,3 +0,0 @@
1
- const pluginId = 'magic-mail';
2
-
3
- export default pluginId;
@@ -1,71 +0,0 @@
1
- {
2
- "plugin.name": "MagicMail",
3
- "plugin.description": "Email Business Suite für Strapi v5",
4
-
5
- "tabs.accounts": "Email-Konten",
6
- "tabs.routing": "Routing-Regeln",
7
- "tabs.license": "Lizenz",
8
-
9
- "accounts.title": "Email-Konten",
10
- "accounts.subtitle": "Verwalte mehrere Email-Konten mit Smart Routing",
11
- "accounts.add": "Konto hinzufügen",
12
- "accounts.edit": "Konto bearbeiten",
13
- "accounts.delete": "Konto löschen",
14
- "accounts.test": "Testen",
15
- "accounts.empty": "Keine Email-Konten vorhanden",
16
- "accounts.emptyDescription": "Füge dein erstes Email-Konto hinzu um zu starten",
17
-
18
- "stats.emailsToday": "Heute versendet",
19
- "stats.totalSent": "Gesamt versendet",
20
- "stats.activeAccounts": "Aktive Konten",
21
-
22
- "providers.smtp": "SMTP",
23
- "providers.gmail": "Gmail OAuth",
24
- "providers.microsoft": "Microsoft OAuth",
25
- "providers.yahoo": "Yahoo Mail OAuth",
26
- "providers.sendgrid": "SendGrid",
27
- "providers.mailgun": "Mailgun",
28
-
29
- "routing.title": "Routing-Regeln",
30
- "routing.subtitle": "Definiere intelligente Routing-Regeln für Email-Versand",
31
- "routing.add": "Regel erstellen",
32
- "routing.edit": "Regel bearbeiten",
33
- "routing.delete": "Regel löschen",
34
- "routing.empty": "Keine Routing-Regeln vorhanden",
35
- "routing.emptyDescription": "Erstelle deine erste Routing-Regel",
36
-
37
- "license.title": "Lizenzverwaltung",
38
- "license.subtitle": "Verwalte deine MagicMail Lizenz",
39
- "license.active": "Lizenz aktiv",
40
- "license.inactive": "Keine aktive Lizenz",
41
- "license.demo": "Demo-Modus",
42
- "license.generate": "Kostenlose Lizenz generieren",
43
- "license.activate": "Lizenz aktivieren",
44
- "license.key": "Lizenzschlüssel",
45
- "license.email": "E-Mail-Adresse",
46
- "license.copyKey": "Schlüssel kopieren",
47
- "license.download": "Als TXT herunterladen",
48
- "license.refresh": "Status aktualisieren",
49
-
50
- "features.premium": "Premium Features",
51
- "features.advanced": "Erweiterte Features",
52
- "features.enterprise": "Enterprise Features",
53
-
54
- "notifications.accountCreated": "Email-Konto erfolgreich erstellt",
55
- "notifications.accountUpdated": "Email-Konto erfolgreich aktualisiert",
56
- "notifications.accountDeleted": "Email-Konto erfolgreich gelöscht",
57
- "notifications.testSuccess": "Test-Email erfolgreich versendet",
58
- "notifications.testFailed": "Test-Email fehlgeschlagen",
59
- "notifications.ruleCreated": "Routing-Regel erfolgreich erstellt",
60
- "notifications.ruleUpdated": "Routing-Regel erfolgreich aktualisiert",
61
- "notifications.ruleDeleted": "Routing-Regel erfolgreich gelöscht",
62
- "notifications.licenseActivated": "Lizenz erfolgreich aktiviert",
63
- "notifications.licenseCopied": "Lizenzschlüssel kopiert",
64
- "notifications.error": "Ein Fehler ist aufgetreten",
65
-
66
- "errors.noAccounts": "Keine Email-Konten verfügbar",
67
- "errors.providerNotAllowed": "Dieser Provider erfordert eine höhere Lizenz",
68
- "errors.accountLimitReached": "Konto-Limit erreicht. Upgrade erforderlich",
69
- "errors.ruleLimitReached": "Regel-Limit erreicht. Upgrade erforderlich"
70
- }
71
-