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