strapi-plugin-magic-sessionmanager 1.0.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.
@@ -0,0 +1,1324 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const react = require("react");
5
+ const designSystem = require("@strapi/design-system");
6
+ const admin = require("@strapi/strapi/admin");
7
+ const icons = require("@strapi/icons");
8
+ const styled = require("styled-components");
9
+ const index = require("./index-Dd_SkI79.js");
10
+ const useLicense = require("./useLicense-Bw66_4CW.js");
11
+ const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
12
+ const styled__default = /* @__PURE__ */ _interopDefault(styled);
13
+ const theme = {
14
+ colors: {
15
+ primary: { 600: "#0284C7", 700: "#075985" },
16
+ success: { 600: "#16A34A", 700: "#15803D" },
17
+ danger: { 600: "#DC2626" },
18
+ neutral: { 200: "#E5E7EB", 400: "#9CA3AF", 700: "#374151" }
19
+ },
20
+ shadows: { sm: "0 1px 3px rgba(0,0,0,0.1)" },
21
+ borderRadius: { md: "8px", lg: "12px" }
22
+ };
23
+ const fadeIn = styled.keyframes`
24
+ from { opacity: 0; transform: translateY(10px); }
25
+ to { opacity: 1; transform: translateY(0); }
26
+ `;
27
+ styled.keyframes`
28
+ 0% { background-position: -200% 0; }
29
+ 100% { background-position: 200% 0; }
30
+ `;
31
+ const Container = styled__default.default(designSystem.Box)`
32
+ animation: ${fadeIn} 0.5s;
33
+ max-width: 1400px;
34
+ margin: 0 auto;
35
+ `;
36
+ const StickySaveBar = styled__default.default(designSystem.Box)`
37
+ position: sticky;
38
+ top: 0;
39
+ z-index: 10;
40
+ background: white;
41
+ border-bottom: 1px solid ${theme.colors.neutral[200]};
42
+ box-shadow: ${theme.shadows.sm};
43
+ `;
44
+ const ToggleCard = styled__default.default(designSystem.Box)`
45
+ background: ${(props) => props.$active ? "linear-gradient(135deg, #f0fdf4 0%, #dcfce7 100%)" : "linear-gradient(135deg, #fafafa 0%, #f3f4f6 100%)"};
46
+ border-radius: ${theme.borderRadius.lg};
47
+ padding: 24px;
48
+ min-height: 120px;
49
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
50
+ border: 2px solid ${(props) => props.$active ? theme.colors.success[600] : theme.colors.neutral[200]};
51
+ box-shadow: ${(props) => props.$active ? "0 4px 20px rgba(34, 197, 94, 0.15)" : "0 2px 8px rgba(0, 0, 0, 0.06)"};
52
+ position: relative;
53
+ cursor: pointer;
54
+ display: flex;
55
+ align-items: center;
56
+
57
+ &:hover {
58
+ transform: translateY(-4px);
59
+ box-shadow: ${(props) => props.$active ? "0 8px 30px rgba(34, 197, 94, 0.25)" : "0 6px 16px rgba(0, 0, 0, 0.12)"};
60
+ border-color: ${(props) => props.$active ? theme.colors.success[700] : theme.colors.neutral[300]};
61
+ }
62
+
63
+ &:active {
64
+ transform: translateY(-2px);
65
+ }
66
+
67
+ ${(props) => props.$active && `
68
+ &::before {
69
+ content: 'ACTIVE';
70
+ position: absolute;
71
+ top: 12px;
72
+ right: 12px;
73
+ background: ${theme.colors.success[600]};
74
+ color: white;
75
+ padding: 4px 10px;
76
+ border-radius: 6px;
77
+ font-size: 10px;
78
+ font-weight: 700;
79
+ letter-spacing: 0.5px;
80
+ box-shadow: 0 2px 6px rgba(22, 163, 74, 0.3);
81
+ }
82
+ `}
83
+
84
+ ${(props) => !props.$active && `
85
+ &::before {
86
+ content: 'INACTIVE';
87
+ position: absolute;
88
+ top: 12px;
89
+ right: 12px;
90
+ background: ${theme.colors.neutral[400]};
91
+ color: white;
92
+ padding: 4px 10px;
93
+ border-radius: 6px;
94
+ font-size: 10px;
95
+ font-weight: 700;
96
+ letter-spacing: 0.5px;
97
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
98
+ }
99
+ `}
100
+ `;
101
+ const GreenToggle = styled__default.default.div`
102
+ ${(props) => props.$isActive && `
103
+ button[role="switch"] {
104
+ background-color: #16A34A !important;
105
+ border-color: #16A34A !important;
106
+
107
+ &:hover {
108
+ background-color: #15803D !important;
109
+ border-color: #15803D !important;
110
+ }
111
+
112
+ &:focus {
113
+ background-color: #16A34A !important;
114
+ border-color: #16A34A !important;
115
+ box-shadow: 0 0 0 3px rgba(22, 163, 74, 0.2) !important;
116
+ }
117
+ }
118
+
119
+ /* Toggle handle */
120
+ button[role="switch"] > span {
121
+ background-color: white !important;
122
+ }
123
+ `}
124
+
125
+ ${(props) => !props.$isActive && `
126
+ button[role="switch"] {
127
+ background-color: #E5E7EB;
128
+
129
+ &:hover {
130
+ background-color: #D1D5DB;
131
+ }
132
+ }
133
+ `}
134
+ `;
135
+ const TEMPLATE_VARIABLES = {
136
+ suspiciousLogin: [
137
+ { var: "{{user.email}}", desc: "User email address" },
138
+ { var: "{{user.username}}", desc: "Username" },
139
+ { var: "{{session.loginTime}}", desc: "Login timestamp" },
140
+ { var: "{{session.ipAddress}}", desc: "IP address" },
141
+ { var: "{{geo.city}}", desc: "City (if available)" },
142
+ { var: "{{geo.country}}", desc: "Country (if available)" },
143
+ { var: "{{geo.timezone}}", desc: "Timezone (if available)" },
144
+ { var: "{{session.userAgent}}", desc: "Browser/Device info" },
145
+ { var: "{{reason.isVpn}}", desc: "VPN detected (true/false)" },
146
+ { var: "{{reason.isProxy}}", desc: "Proxy detected (true/false)" },
147
+ { var: "{{reason.isThreat}}", desc: "Threat detected (true/false)" },
148
+ { var: "{{reason.securityScore}}", desc: "Security score (0-100)" }
149
+ ],
150
+ newLocation: [
151
+ { var: "{{user.email}}", desc: "User email address" },
152
+ { var: "{{user.username}}", desc: "Username" },
153
+ { var: "{{session.loginTime}}", desc: "Login timestamp" },
154
+ { var: "{{session.ipAddress}}", desc: "IP address" },
155
+ { var: "{{geo.city}}", desc: "City" },
156
+ { var: "{{geo.country}}", desc: "Country" },
157
+ { var: "{{geo.timezone}}", desc: "Timezone" },
158
+ { var: "{{session.userAgent}}", desc: "Browser/Device info" }
159
+ ],
160
+ vpnProxy: [
161
+ { var: "{{user.email}}", desc: "User email address" },
162
+ { var: "{{user.username}}", desc: "Username" },
163
+ { var: "{{session.loginTime}}", desc: "Login timestamp" },
164
+ { var: "{{session.ipAddress}}", desc: "IP address" },
165
+ { var: "{{geo.city}}", desc: "City (if available)" },
166
+ { var: "{{geo.country}}", desc: "Country (if available)" },
167
+ { var: "{{session.userAgent}}", desc: "Browser/Device info" },
168
+ { var: "{{reason.isVpn}}", desc: "VPN detected (true/false)" },
169
+ { var: "{{reason.isProxy}}", desc: "Proxy detected (true/false)" }
170
+ ]
171
+ };
172
+ const validateTemplate = (template, templateType) => {
173
+ const requiredVars = TEMPLATE_VARIABLES[templateType];
174
+ const foundVars = [];
175
+ requiredVars.forEach(({ var: variable }) => {
176
+ if (template.includes(variable)) {
177
+ foundVars.push(variable);
178
+ }
179
+ });
180
+ return {
181
+ isValid: foundVars.length > 0,
182
+ foundVars,
183
+ totalAvailable: requiredVars.length
184
+ };
185
+ };
186
+ const getDefaultTemplates = () => ({
187
+ suspiciousLogin: {
188
+ subject: "🚨 Suspicious Login Alert - Session Manager",
189
+ html: `
190
+ <html>
191
+ <body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
192
+ <div style="max-width: 600px; margin: 0 auto; padding: 20px; background-color: #f9fafb; border-radius: 10px;">
193
+ <h2 style="color: #dc2626;">🚨 Suspicious Login Detected</h2>
194
+ <p>A potentially suspicious login was detected for your account.</p>
195
+
196
+ <div style="background: white; padding: 15px; border-radius: 8px; margin: 20px 0;">
197
+ <h3 style="margin-top: 0;">Account Information:</h3>
198
+ <ul>
199
+ <li><strong>Email:</strong> {{user.email}}</li>
200
+ <li><strong>Username:</strong> {{user.username}}</li>
201
+ </ul>
202
+
203
+ <h3>Login Details:</h3>
204
+ <ul>
205
+ <li><strong>Time:</strong> {{session.loginTime}}</li>
206
+ <li><strong>IP Address:</strong> {{session.ipAddress}}</li>
207
+ <li><strong>Location:</strong> {{geo.city}}, {{geo.country}}</li>
208
+ <li><strong>Timezone:</strong> {{geo.timezone}}</li>
209
+ <li><strong>Device:</strong> {{session.userAgent}}</li>
210
+ </ul>
211
+
212
+ <h3 style="color: #dc2626;">Security Alert:</h3>
213
+ <ul>
214
+ <li>VPN Detected: {{reason.isVpn}}</li>
215
+ <li>Proxy Detected: {{reason.isProxy}}</li>
216
+ <li>Threat Detected: {{reason.isThreat}}</li>
217
+ <li>Security Score: {{reason.securityScore}}/100</li>
218
+ </ul>
219
+ </div>
220
+
221
+ <p>If this was you, you can safely ignore this email. If you don't recognize this activity, please secure your account immediately.</p>
222
+
223
+ <hr style="border: none; border-top: 1px solid #e5e7eb; margin: 20px 0;"/>
224
+ <p style="color: #666; font-size: 12px;">This is an automated security notification from Magic Session Manager.</p>
225
+ </div>
226
+ </body>
227
+ </html>`,
228
+ text: `🚨 Suspicious Login Detected
229
+
230
+ A potentially suspicious login was detected for your account.
231
+
232
+ Account: {{user.email}}
233
+ Username: {{user.username}}
234
+
235
+ Login Details:
236
+ - Time: {{session.loginTime}}
237
+ - IP: {{session.ipAddress}}
238
+ - Location: {{geo.city}}, {{geo.country}}
239
+
240
+ Security: VPN={{reason.isVpn}}, Proxy={{reason.isProxy}}, Threat={{reason.isThreat}}, Score={{reason.securityScore}}/100`
241
+ },
242
+ newLocation: {
243
+ subject: "📍 New Location Login Detected",
244
+ html: `
245
+ <html>
246
+ <body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
247
+ <div style="max-width: 600px; margin: 0 auto; padding: 20px; background-color: #f0f9ff; border-radius: 10px;">
248
+ <h2 style="color: #0284c7;">📍 Login from New Location</h2>
249
+ <p>Your account was accessed from a new location.</p>
250
+
251
+ <div style="background: white; padding: 15px; border-radius: 8px; margin: 20px 0;">
252
+ <h3 style="margin-top: 0;">Account:</h3>
253
+ <p><strong>{{user.email}}</strong></p>
254
+
255
+ <h3>New Location Details:</h3>
256
+ <ul>
257
+ <li><strong>Time:</strong> {{session.loginTime}}</li>
258
+ <li><strong>Location:</strong> {{geo.city}}, {{geo.country}}</li>
259
+ <li><strong>IP Address:</strong> {{session.ipAddress}}</li>
260
+ <li><strong>Device:</strong> {{session.userAgent}}</li>
261
+ </ul>
262
+ </div>
263
+
264
+ <p>If this was you, no action is needed. If you don't recognize this login, please secure your account.</p>
265
+
266
+ <hr style="border: none; border-top: 1px solid #e5e7eb; margin: 20px 0;"/>
267
+ <p style="color: #666; font-size: 12px;">Magic Session Manager notification</p>
268
+ </div>
269
+ </body>
270
+ </html>`,
271
+ text: `📍 Login from New Location
272
+
273
+ Your account was accessed from a new location.
274
+
275
+ Account: {{user.email}}
276
+
277
+ New Location Details:
278
+ - Time: {{session.loginTime}}
279
+ - Location: {{geo.city}}, {{geo.country}}
280
+ - IP Address: {{session.ipAddress}}
281
+ - Device: {{session.userAgent}}
282
+
283
+ If this was you, no action is needed.`
284
+ },
285
+ vpnProxy: {
286
+ subject: "⚠️ VPN/Proxy Login Detected",
287
+ html: `
288
+ <html>
289
+ <body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
290
+ <div style="max-width: 600px; margin: 0 auto; padding: 20px; background-color: #fffbeb; border-radius: 10px;">
291
+ <h2 style="color: #d97706;">⚠️ VPN/Proxy Detected</h2>
292
+ <p>A login from a VPN or proxy service was detected on your account.</p>
293
+
294
+ <div style="background: white; padding: 15px; border-radius: 8px; margin: 20px 0;">
295
+ <h3 style="margin-top: 0;">Account:</h3>
296
+ <p><strong>{{user.email}}</strong></p>
297
+
298
+ <h3>Login Details:</h3>
299
+ <ul>
300
+ <li><strong>Time:</strong> {{session.loginTime}}</li>
301
+ <li><strong>IP Address:</strong> {{session.ipAddress}}</li>
302
+ <li><strong>Location:</strong> {{geo.city}}, {{geo.country}}</li>
303
+ <li><strong>Device:</strong> {{session.userAgent}}</li>
304
+ <li><strong>VPN:</strong> {{reason.isVpn}}</li>
305
+ <li><strong>Proxy:</strong> {{reason.isProxy}}</li>
306
+ </ul>
307
+ </div>
308
+
309
+ <p>VPN/Proxy usage may indicate suspicious activity. If this was you, you can safely ignore this email.</p>
310
+
311
+ <hr style="border: none; border-top: 1px solid #e5e7eb; margin: 20px 0;"/>
312
+ <p style="color: #666; font-size: 12px;">Magic Session Manager notification</p>
313
+ </div>
314
+ </body>
315
+ </html>`,
316
+ text: `⚠️ VPN/Proxy Detected
317
+
318
+ A login from a VPN or proxy service was detected on your account.
319
+
320
+ Account: {{user.email}}
321
+
322
+ Login Details:
323
+ - Time: {{session.loginTime}}
324
+ - IP Address: {{session.ipAddress}}
325
+ - Location: {{geo.city}}, {{geo.country}}
326
+ - VPN: {{reason.isVpn}}, Proxy: {{reason.isProxy}}`
327
+ }
328
+ });
329
+ const SettingsPage = () => {
330
+ const { get, post, put } = admin.useFetchClient();
331
+ const { toggleNotification } = admin.useNotification();
332
+ const { isPremium, isAdvanced, isEnterprise } = useLicense.useLicense();
333
+ const [loading, setLoading] = react.useState(true);
334
+ const [saving, setSaving] = react.useState(false);
335
+ const [hasChanges, setHasChanges] = react.useState(false);
336
+ const [cleaning, setCleaning] = react.useState(false);
337
+ const [activeTemplateTab, setActiveTemplateTab] = react.useState("suspiciousLogin");
338
+ const [settings, setSettings] = react.useState({
339
+ inactivityTimeout: 15,
340
+ cleanupInterval: 30,
341
+ lastSeenRateLimit: 30,
342
+ retentionDays: 90,
343
+ enableGeolocation: true,
344
+ enableSecurityScoring: true,
345
+ blockSuspiciousSessions: false,
346
+ maxFailedLogins: 5,
347
+ enableEmailAlerts: false,
348
+ alertOnSuspiciousLogin: true,
349
+ alertOnNewLocation: true,
350
+ alertOnVpnProxy: true,
351
+ enableWebhooks: false,
352
+ discordWebhookUrl: "",
353
+ slackWebhookUrl: "",
354
+ enableGeofencing: false,
355
+ allowedCountries: [],
356
+ blockedCountries: [],
357
+ emailTemplates: {
358
+ suspiciousLogin: { subject: "", html: "", text: "" },
359
+ newLocation: { subject: "", html: "", text: "" },
360
+ vpnProxy: { subject: "", html: "", text: "" }
361
+ }
362
+ });
363
+ react.useEffect(() => {
364
+ fetchSettings();
365
+ }, []);
366
+ const fetchSettings = async () => {
367
+ setLoading(true);
368
+ try {
369
+ const response = await get(`/${index.pluginId}/settings`);
370
+ if (response?.data?.settings) {
371
+ const loadedSettings = response.data.settings;
372
+ if (!loadedSettings.emailTemplates || Object.keys(loadedSettings.emailTemplates).length === 0) {
373
+ loadedSettings.emailTemplates = getDefaultTemplates();
374
+ } else {
375
+ const defaultTemplates = getDefaultTemplates();
376
+ Object.keys(defaultTemplates).forEach((key) => {
377
+ if (!loadedSettings.emailTemplates[key]) {
378
+ loadedSettings.emailTemplates[key] = defaultTemplates[key];
379
+ } else {
380
+ loadedSettings.emailTemplates[key] = {
381
+ subject: loadedSettings.emailTemplates[key].subject || defaultTemplates[key].subject,
382
+ html: loadedSettings.emailTemplates[key].html || defaultTemplates[key].html,
383
+ text: loadedSettings.emailTemplates[key].text || defaultTemplates[key].text
384
+ };
385
+ }
386
+ });
387
+ }
388
+ setSettings(loadedSettings);
389
+ } else {
390
+ setSettings((prev) => ({ ...prev, emailTemplates: getDefaultTemplates() }));
391
+ }
392
+ } catch (err) {
393
+ console.error("[Settings] Error loading from backend:", err);
394
+ toggleNotification({
395
+ type: "warning",
396
+ message: "Could not load settings from server. Using defaults."
397
+ });
398
+ setSettings((prev) => ({ ...prev, emailTemplates: getDefaultTemplates() }));
399
+ } finally {
400
+ setLoading(false);
401
+ }
402
+ };
403
+ const handleChange = (key, value) => {
404
+ setSettings((prev) => ({ ...prev, [key]: value }));
405
+ setHasChanges(true);
406
+ };
407
+ const handleSave = async () => {
408
+ setSaving(true);
409
+ try {
410
+ const response = await put(`/${index.pluginId}/settings`, settings);
411
+ if (response?.data?.success) {
412
+ toggleNotification({
413
+ type: "success",
414
+ message: "Settings saved successfully to database!"
415
+ });
416
+ setHasChanges(false);
417
+ try {
418
+ localStorage.setItem(`${index.pluginId}-settings`, JSON.stringify(settings));
419
+ } catch (localErr) {
420
+ console.warn("[Settings] Could not save to localStorage:", localErr);
421
+ }
422
+ } else {
423
+ throw new Error("Save failed");
424
+ }
425
+ } catch (err) {
426
+ console.error("[Settings] Error saving:", err);
427
+ toggleNotification({
428
+ type: "danger",
429
+ message: "Failed to save settings to server"
430
+ });
431
+ } finally {
432
+ setSaving(false);
433
+ }
434
+ };
435
+ const handleReset = () => {
436
+ fetchSettings();
437
+ setHasChanges(false);
438
+ };
439
+ const handleCleanInactive = async () => {
440
+ if (!confirm("⚠️ WARNING: This will permanently delete ALL inactive sessions.\n\nContinue?")) {
441
+ return;
442
+ }
443
+ setCleaning(true);
444
+ try {
445
+ const { data } = await post(`/${index.pluginId}/sessions/clean-inactive`);
446
+ toggleNotification({
447
+ type: "success",
448
+ message: `Successfully deleted ${data.deletedCount} inactive sessions!`
449
+ });
450
+ } catch (err) {
451
+ toggleNotification({
452
+ type: "danger",
453
+ message: "Failed to delete inactive sessions"
454
+ });
455
+ } finally {
456
+ setCleaning(false);
457
+ }
458
+ };
459
+ if (loading) {
460
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", padding: 8, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Loader, { children: "Loading settings..." }) });
461
+ }
462
+ return /* @__PURE__ */ jsxRuntime.jsxs(Container, { children: [
463
+ /* @__PURE__ */ jsxRuntime.jsx(StickySaveBar, { paddingTop: 5, paddingBottom: 5, paddingLeft: 6, paddingRight: 6, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "center", children: [
464
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 1, alignItems: "flex-start", children: [
465
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", fontWeight: "bold", style: { fontSize: "24px" }, children: "⚙️ Session Manager Settings" }),
466
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "epsilon", textColor: "neutral600", children: "Configure session tracking, security, and email notifications" })
467
+ ] }),
468
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
469
+ hasChanges && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleReset, variant: "tertiary", size: "L", children: "Reset" }),
470
+ /* @__PURE__ */ jsxRuntime.jsx(
471
+ designSystem.Button,
472
+ {
473
+ onClick: handleSave,
474
+ loading: saving,
475
+ startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Check, {}),
476
+ size: "L",
477
+ disabled: !hasChanges || saving,
478
+ style: {
479
+ background: hasChanges && !saving ? "linear-gradient(135deg, #667eea 0%, #764ba2 100%)" : "#e5e7eb",
480
+ color: hasChanges && !saving ? "white" : "#9ca3af",
481
+ fontWeight: "600",
482
+ padding: "12px 24px",
483
+ border: "none",
484
+ boxShadow: hasChanges && !saving ? "0 4px 12px rgba(102, 126, 234, 0.4)" : "none",
485
+ transition: "all 0.3s cubic-bezier(0.4, 0, 0.2, 1)"
486
+ },
487
+ onMouseEnter: (e) => {
488
+ if (hasChanges && !saving) {
489
+ e.currentTarget.style.transform = "translateY(-2px)";
490
+ e.currentTarget.style.boxShadow = "0 8px 20px rgba(102, 126, 234, 0.5)";
491
+ }
492
+ },
493
+ onMouseLeave: (e) => {
494
+ e.currentTarget.style.transform = "translateY(0)";
495
+ e.currentTarget.style.boxShadow = hasChanges && !saving ? "0 4px 12px rgba(102, 126, 234, 0.4)" : "none";
496
+ },
497
+ children: saving ? "Saving..." : hasChanges ? "Save Changes" : "No Changes"
498
+ }
499
+ )
500
+ ] })
501
+ ] }) }),
502
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { paddingTop: 6, paddingLeft: 6, paddingRight: 6, paddingBottom: 10, children: [
503
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 4, background: "primary50", hasRadius: true, style: { marginBottom: "24px", border: "1px solid #bae6fd" }, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 3, alignItems: "center", children: [
504
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Information, { style: { width: "20px", height: "20px", color: "#0284C7" } }),
505
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { children: [
506
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "bold", textColor: "primary700", style: { marginBottom: "4px" }, children: "Current License Status" }),
507
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 3, children: [
508
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Badge, { backgroundColor: isPremium ? "success100" : "neutral100", textColor: isPremium ? "success700" : "neutral600", children: [
509
+ isPremium ? "✓" : "✗",
510
+ " Premium"
511
+ ] }),
512
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Badge, { backgroundColor: isAdvanced ? "primary100" : "neutral100", textColor: isAdvanced ? "primary700" : "neutral600", children: [
513
+ isAdvanced ? "✓" : "✗",
514
+ " Advanced"
515
+ ] }),
516
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Badge, { backgroundColor: isEnterprise ? "secondary100" : "neutral100", textColor: isEnterprise ? "secondary700" : "neutral600", children: [
517
+ isEnterprise ? "✓" : "✗",
518
+ " Enterprise"
519
+ ] })
520
+ ] })
521
+ ] })
522
+ ] }) }),
523
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Accordion.Root, { type: "multiple", defaultValue: ["general", "security", "email"], children: [
524
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Accordion.Item, { value: "general", children: [
525
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(
526
+ designSystem.Accordion.Trigger,
527
+ {
528
+ icon: icons.Cog,
529
+ description: "Basic session tracking configuration",
530
+ children: "General Settings"
531
+ }
532
+ ) }),
533
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Content, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { padding: 6, children: [
534
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", fontWeight: "bold", style: { marginBottom: "16px", display: "block", color: theme.colors.neutral[700] }, children: "⏱️ SESSION TIMEOUT" }),
535
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Grid.Root, { gap: 6, style: { marginBottom: "32px" }, children: [
536
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 6, s: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { children: [
537
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: "bold", style: { marginBottom: "8px", display: "block" }, children: "Inactivity Timeout" }),
538
+ /* @__PURE__ */ jsxRuntime.jsxs(
539
+ designSystem.SingleSelect,
540
+ {
541
+ value: String(settings.inactivityTimeout),
542
+ onChange: (value) => handleChange("inactivityTimeout", parseInt(value)),
543
+ children: [
544
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "5", children: "5 minutes (Very Strict)" }),
545
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "10", children: "10 minutes (Strict)" }),
546
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "15", children: "15 minutes (Recommended)" }),
547
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "30", children: "30 minutes (Moderate)" }),
548
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "60", children: "1 hour (Relaxed)" }),
549
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "120", children: "2 hours (Very Relaxed)" })
550
+ ]
551
+ }
552
+ ),
553
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "pi", textColor: "neutral600", style: { fontSize: "11px", marginTop: "8px" }, children: [
554
+ "Sessions inactive for more than ",
555
+ settings.inactivityTimeout,
556
+ " minutes will be marked as offline"
557
+ ] })
558
+ ] }) }),
559
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 6, s: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { children: [
560
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: "bold", style: { marginBottom: "8px", display: "block" }, children: "Last Seen Rate Limit" }),
561
+ /* @__PURE__ */ jsxRuntime.jsxs(
562
+ designSystem.SingleSelect,
563
+ {
564
+ value: String(settings.lastSeenRateLimit),
565
+ onChange: (value) => handleChange("lastSeenRateLimit", parseInt(value)),
566
+ children: [
567
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "10", children: "10 seconds" }),
568
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "30", children: "30 seconds (Recommended)" }),
569
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "60", children: "1 minute" }),
570
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "120", children: "2 minutes" }),
571
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "300", children: "5 minutes" })
572
+ ]
573
+ }
574
+ ),
575
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "pi", textColor: "neutral600", style: { fontSize: "11px", marginTop: "8px" }, children: [
576
+ "Prevents excessive database writes. Updates throttled to once every ",
577
+ settings.lastSeenRateLimit,
578
+ " seconds"
579
+ ] })
580
+ ] }) })
581
+ ] }),
582
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Divider, { style: { marginBottom: "24px" } }),
583
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", fontWeight: "bold", style: { marginBottom: "16px", display: "block", color: theme.colors.neutral[700] }, children: "🧹 AUTO-CLEANUP & RETENTION" }),
584
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Grid.Root, { gap: 6, children: [
585
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 6, s: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { children: [
586
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: "bold", style: { marginBottom: "8px", display: "block" }, children: "Cleanup Interval" }),
587
+ /* @__PURE__ */ jsxRuntime.jsxs(
588
+ designSystem.SingleSelect,
589
+ {
590
+ value: String(settings.cleanupInterval),
591
+ onChange: (value) => handleChange("cleanupInterval", parseInt(value)),
592
+ children: [
593
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "15", children: "15 minutes" }),
594
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "30", children: "30 minutes (Recommended)" }),
595
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "60", children: "1 hour" }),
596
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "120", children: "2 hours" })
597
+ ]
598
+ }
599
+ ),
600
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "pi", textColor: "neutral600", style: { fontSize: "11px", marginTop: "8px" }, children: [
601
+ "Inactive sessions are automatically cleaned every ",
602
+ settings.cleanupInterval,
603
+ " minutes"
604
+ ] })
605
+ ] }) }),
606
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 6, s: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { children: [
607
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: "bold", style: { marginBottom: "8px", display: "block" }, children: "Retention Period" }),
608
+ /* @__PURE__ */ jsxRuntime.jsxs(
609
+ designSystem.SingleSelect,
610
+ {
611
+ value: String(settings.retentionDays),
612
+ onChange: (value) => handleChange("retentionDays", parseInt(value)),
613
+ children: [
614
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "7", children: "7 days" }),
615
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "30", children: "30 days" }),
616
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "60", children: "60 days" }),
617
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "90", children: "90 days (Recommended)" }),
618
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "180", children: "180 days" }),
619
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "365", children: "1 year" }),
620
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "-1", children: "Forever" })
621
+ ]
622
+ }
623
+ ),
624
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "pi", textColor: "neutral600", style: { fontSize: "11px", marginTop: "8px" }, children: [
625
+ "Old sessions deleted after ",
626
+ settings.retentionDays === -1 ? "never" : `${settings.retentionDays} days`
627
+ ] })
628
+ ] }) }),
629
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 12, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 4, background: "danger100", style: { borderRadius: theme.borderRadius.md, border: `2px solid ${theme.colors.danger[200]}` }, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 3, alignItems: "flex-start", children: [
630
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, { style: { width: "18px", height: "18px", color: theme.colors.danger[600], flexShrink: 0, marginTop: "2px" } }),
631
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { style: { flex: 1 }, children: [
632
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "bold", textColor: "danger700", style: { marginBottom: "8px", display: "block" }, children: "Danger Zone" }),
633
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "pi", textColor: "danger600", style: { fontSize: "13px", lineHeight: "1.7" }, children: [
634
+ /* @__PURE__ */ jsxRuntime.jsx("strong", { children: "Clean All Inactive:" }),
635
+ " Permanently deletes all inactive sessions. This cannot be undone."
636
+ ] })
637
+ ] }),
638
+ /* @__PURE__ */ jsxRuntime.jsx(
639
+ designSystem.Button,
640
+ {
641
+ onClick: handleCleanInactive,
642
+ loading: cleaning,
643
+ startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, {}),
644
+ variant: "danger",
645
+ size: "S",
646
+ style: { flexShrink: 0 },
647
+ children: "Clean Now"
648
+ }
649
+ )
650
+ ] }) }) })
651
+ ] })
652
+ ] }) })
653
+ ] }),
654
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Accordion.Item, { value: "security", children: [
655
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(
656
+ designSystem.Accordion.Trigger,
657
+ {
658
+ icon: icons.Shield,
659
+ description: "Security policies and threat protection",
660
+ children: "Security Settings"
661
+ }
662
+ ) }),
663
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Content, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { padding: 6, children: [
664
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", fontWeight: "bold", style: { marginBottom: "16px", display: "block", color: theme.colors.neutral[700] }, children: "🔒 SECURITY OPTIONS" }),
665
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { background: "neutral100", padding: 5, style: { borderRadius: theme.borderRadius.md, marginBottom: "32px" }, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Grid.Root, { gap: 4, children: [
666
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 6, s: 12, children: /* @__PURE__ */ jsxRuntime.jsx(
667
+ ToggleCard,
668
+ {
669
+ $active: settings.blockSuspiciousSessions,
670
+ onClick: () => handleChange("blockSuspiciousSessions", !settings.blockSuspiciousSessions),
671
+ children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 3, style: { width: "100%" }, alignItems: "center", children: [
672
+ /* @__PURE__ */ jsxRuntime.jsx(GreenToggle, { $isActive: settings.blockSuspiciousSessions, children: /* @__PURE__ */ jsxRuntime.jsx(
673
+ designSystem.Toggle,
674
+ {
675
+ checked: settings.blockSuspiciousSessions,
676
+ onChange: () => handleChange("blockSuspiciousSessions", !settings.blockSuspiciousSessions)
677
+ }
678
+ ) }),
679
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, alignItems: "center", style: { textAlign: "center" }, children: [
680
+ /* @__PURE__ */ jsxRuntime.jsx(
681
+ designSystem.Typography,
682
+ {
683
+ variant: "delta",
684
+ fontWeight: "bold",
685
+ textColor: settings.blockSuspiciousSessions ? "success700" : "neutral800",
686
+ style: { fontSize: "16px" },
687
+ children: "Block Suspicious Sessions"
688
+ }
689
+ ),
690
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", style: { fontSize: "13px", lineHeight: "1.6" }, children: "Automatically block sessions from VPNs, proxies, or threat IPs" })
691
+ ] })
692
+ ] })
693
+ }
694
+ ) }),
695
+ isPremium && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
696
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 6, s: 12, children: /* @__PURE__ */ jsxRuntime.jsx(
697
+ ToggleCard,
698
+ {
699
+ $active: settings.enableGeolocation,
700
+ onClick: () => handleChange("enableGeolocation", !settings.enableGeolocation),
701
+ children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 3, style: { width: "100%" }, alignItems: "center", children: [
702
+ /* @__PURE__ */ jsxRuntime.jsx(GreenToggle, { $isActive: settings.enableGeolocation, children: /* @__PURE__ */ jsxRuntime.jsx(
703
+ designSystem.Toggle,
704
+ {
705
+ checked: settings.enableGeolocation,
706
+ onChange: () => handleChange("enableGeolocation", !settings.enableGeolocation)
707
+ }
708
+ ) }),
709
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, alignItems: "center", style: { textAlign: "center" }, children: [
710
+ /* @__PURE__ */ jsxRuntime.jsx(
711
+ designSystem.Typography,
712
+ {
713
+ variant: "delta",
714
+ fontWeight: "bold",
715
+ textColor: settings.enableGeolocation ? "success700" : "neutral800",
716
+ style: { fontSize: "16px" },
717
+ children: "IP Geolocation"
718
+ }
719
+ ),
720
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", style: { fontSize: "13px", lineHeight: "1.6" }, children: "Fetch location data for each session (Premium)" })
721
+ ] })
722
+ ] })
723
+ }
724
+ ) }),
725
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 6, s: 12, children: /* @__PURE__ */ jsxRuntime.jsx(
726
+ ToggleCard,
727
+ {
728
+ $active: settings.enableSecurityScoring,
729
+ onClick: () => handleChange("enableSecurityScoring", !settings.enableSecurityScoring),
730
+ children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 3, style: { width: "100%" }, alignItems: "center", children: [
731
+ /* @__PURE__ */ jsxRuntime.jsx(GreenToggle, { $isActive: settings.enableSecurityScoring, children: /* @__PURE__ */ jsxRuntime.jsx(
732
+ designSystem.Toggle,
733
+ {
734
+ checked: settings.enableSecurityScoring,
735
+ onChange: () => handleChange("enableSecurityScoring", !settings.enableSecurityScoring)
736
+ }
737
+ ) }),
738
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, alignItems: "center", style: { textAlign: "center" }, children: [
739
+ /* @__PURE__ */ jsxRuntime.jsx(
740
+ designSystem.Typography,
741
+ {
742
+ variant: "delta",
743
+ fontWeight: "bold",
744
+ textColor: settings.enableSecurityScoring ? "success700" : "neutral800",
745
+ style: { fontSize: "16px" },
746
+ children: "Security Scoring"
747
+ }
748
+ ),
749
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", style: { fontSize: "13px", lineHeight: "1.6" }, children: "Calculate security scores and detect threats (Premium)" })
750
+ ] })
751
+ ] })
752
+ }
753
+ ) })
754
+ ] })
755
+ ] }) }),
756
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Root, { gap: 6, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 6, s: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { children: [
757
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: "bold", style: { marginBottom: "8px", display: "block" }, children: "🚫 Max Failed Login Attempts" }),
758
+ /* @__PURE__ */ jsxRuntime.jsx(
759
+ designSystem.NumberInput,
760
+ {
761
+ value: settings.maxFailedLogins,
762
+ onValueChange: (val) => handleChange("maxFailedLogins", val),
763
+ min: 1,
764
+ max: 20
765
+ }
766
+ ),
767
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 2, background: "warning50", style: { borderRadius: "4px", marginTop: "8px" }, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "pi", textColor: "warning700", style: { fontSize: "11px" }, children: [
768
+ "User will be blocked after ",
769
+ settings.maxFailedLogins,
770
+ " failed attempts"
771
+ ] }) })
772
+ ] }) }) })
773
+ ] }) })
774
+ ] }),
775
+ isAdvanced && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Accordion.Item, { value: "email", children: [
776
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(
777
+ designSystem.Accordion.Trigger,
778
+ {
779
+ icon: icons.Mail,
780
+ description: "Email alerts for security events",
781
+ children: "Email Notifications (Advanced)"
782
+ }
783
+ ) }),
784
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Content, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { padding: 6, children: [
785
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { background: "neutral100", padding: 5, style: { borderRadius: theme.borderRadius.md, marginBottom: "32px" }, children: [
786
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", fontWeight: "bold", style: { marginBottom: "8px", display: "block", textAlign: "center", color: theme.colors.neutral[700] }, children: "📧 EMAIL ALERTS" }),
787
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", style: { marginBottom: "20px", display: "block", textAlign: "center", fontSize: "12px" }, children: "Send security alerts to users via email" }),
788
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Root, { gap: 4, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 12, children: /* @__PURE__ */ jsxRuntime.jsx(
789
+ ToggleCard,
790
+ {
791
+ $active: settings.enableEmailAlerts,
792
+ onClick: () => handleChange("enableEmailAlerts", !settings.enableEmailAlerts),
793
+ children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 3, style: { width: "100%" }, alignItems: "center", children: [
794
+ /* @__PURE__ */ jsxRuntime.jsx(GreenToggle, { $isActive: settings.enableEmailAlerts, children: /* @__PURE__ */ jsxRuntime.jsx(
795
+ designSystem.Toggle,
796
+ {
797
+ checked: settings.enableEmailAlerts,
798
+ onChange: () => handleChange("enableEmailAlerts", !settings.enableEmailAlerts)
799
+ }
800
+ ) }),
801
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, alignItems: "center", style: { textAlign: "center" }, children: [
802
+ /* @__PURE__ */ jsxRuntime.jsx(
803
+ designSystem.Typography,
804
+ {
805
+ variant: "delta",
806
+ fontWeight: "bold",
807
+ textColor: settings.enableEmailAlerts ? "success700" : "neutral800",
808
+ style: { fontSize: "16px" },
809
+ children: "Enable Email Alerts"
810
+ }
811
+ ),
812
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", style: { fontSize: "13px", lineHeight: "1.6" }, children: "Send security alerts for suspicious logins, new locations, and VPN/Proxy usage" })
813
+ ] })
814
+ ] })
815
+ }
816
+ ) }) })
817
+ ] }),
818
+ settings.enableEmailAlerts && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
819
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", fontWeight: "bold", style: { marginBottom: "16px", display: "block", color: theme.colors.neutral[700] }, children: "⚙️ ALERT TYPES" }),
820
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Grid.Root, { gap: 4, style: { marginBottom: "32px" }, children: [
821
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 4, s: 12, children: /* @__PURE__ */ jsxRuntime.jsx(
822
+ designSystem.Box,
823
+ {
824
+ padding: 4,
825
+ background: settings.alertOnSuspiciousLogin ? "danger50" : "neutral50",
826
+ style: {
827
+ borderRadius: theme.borderRadius.md,
828
+ border: `2px solid ${settings.alertOnSuspiciousLogin ? "#fecaca" : "#E5E7EB"}`,
829
+ transition: "all 0.2s",
830
+ cursor: "pointer"
831
+ },
832
+ onClick: () => handleChange("alertOnSuspiciousLogin", !settings.alertOnSuspiciousLogin),
833
+ children: /* @__PURE__ */ jsxRuntime.jsx(
834
+ designSystem.Checkbox,
835
+ {
836
+ checked: settings.alertOnSuspiciousLogin,
837
+ onChange: () => handleChange("alertOnSuspiciousLogin", !settings.alertOnSuspiciousLogin),
838
+ children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "semiBold", style: { fontSize: "14px" }, children: "🚨 Suspicious Login" })
839
+ }
840
+ )
841
+ }
842
+ ) }),
843
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 4, s: 12, children: /* @__PURE__ */ jsxRuntime.jsx(
844
+ designSystem.Box,
845
+ {
846
+ padding: 4,
847
+ background: settings.alertOnNewLocation ? "primary50" : "neutral50",
848
+ style: {
849
+ borderRadius: theme.borderRadius.md,
850
+ border: `2px solid ${settings.alertOnNewLocation ? "#bae6fd" : "#E5E7EB"}`,
851
+ transition: "all 0.2s",
852
+ cursor: "pointer"
853
+ },
854
+ onClick: () => handleChange("alertOnNewLocation", !settings.alertOnNewLocation),
855
+ children: /* @__PURE__ */ jsxRuntime.jsx(
856
+ designSystem.Checkbox,
857
+ {
858
+ checked: settings.alertOnNewLocation,
859
+ onChange: () => handleChange("alertOnNewLocation", !settings.alertOnNewLocation),
860
+ children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "semiBold", style: { fontSize: "14px" }, children: "📍 New Location" })
861
+ }
862
+ )
863
+ }
864
+ ) }),
865
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 4, s: 12, children: /* @__PURE__ */ jsxRuntime.jsx(
866
+ designSystem.Box,
867
+ {
868
+ padding: 4,
869
+ background: settings.alertOnVpnProxy ? "warning50" : "neutral50",
870
+ style: {
871
+ borderRadius: theme.borderRadius.md,
872
+ border: `2px solid ${settings.alertOnVpnProxy ? "#fde68a" : "#E5E7EB"}`,
873
+ transition: "all 0.2s",
874
+ cursor: "pointer"
875
+ },
876
+ onClick: () => handleChange("alertOnVpnProxy", !settings.alertOnVpnProxy),
877
+ children: /* @__PURE__ */ jsxRuntime.jsx(
878
+ designSystem.Checkbox,
879
+ {
880
+ checked: settings.alertOnVpnProxy,
881
+ onChange: () => handleChange("alertOnVpnProxy", !settings.alertOnVpnProxy),
882
+ children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "semiBold", style: { fontSize: "14px" }, children: "⚠️ VPN/Proxy" })
883
+ }
884
+ )
885
+ }
886
+ ) })
887
+ ] }),
888
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Divider, { style: { marginBottom: "24px" } }),
889
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", fontWeight: "bold", style: { marginBottom: "8px", display: "block", color: theme.colors.neutral[700] }, children: "📝 EMAIL TEMPLATES" }),
890
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", style: { marginBottom: "20px", display: "block", fontSize: "12px" }, children: "Customize email notification templates with dynamic variables" }),
891
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tabs.Root, { value: activeTemplateTab, onValueChange: setActiveTemplateTab, children: [
892
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tabs.List, { "aria-label": "Email Templates", children: [
893
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tabs.Trigger, { value: "suspiciousLogin", children: "🚨 Suspicious Login" }),
894
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tabs.Trigger, { value: "newLocation", children: "📍 New Location" }),
895
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tabs.Trigger, { value: "vpnProxy", children: "⚠️ VPN/Proxy" })
896
+ ] }),
897
+ Object.keys(settings.emailTemplates).map((templateKey) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tabs.Content, { value: templateKey, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { paddingTop: 4, children: [
898
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { style: { marginBottom: "24px" }, children: [
899
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: "bold", style: { marginBottom: "8px", display: "block" }, children: "✉️ Email Subject" }),
900
+ /* @__PURE__ */ jsxRuntime.jsx(
901
+ designSystem.TextInput,
902
+ {
903
+ value: settings.emailTemplates[templateKey].subject,
904
+ onChange: (e) => {
905
+ const newTemplates = { ...settings.emailTemplates };
906
+ newTemplates[templateKey].subject = e.target.value;
907
+ handleChange("emailTemplates", newTemplates);
908
+ },
909
+ placeholder: "Enter email subject..."
910
+ }
911
+ )
912
+ ] }),
913
+ /* @__PURE__ */ jsxRuntime.jsx(
914
+ designSystem.Box,
915
+ {
916
+ padding: 3,
917
+ background: "primary100",
918
+ style: { borderRadius: theme.borderRadius.md, marginBottom: "20px", border: "2px solid #BAE6FD" },
919
+ children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, children: [
920
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { alignItems: "center", gap: 2, children: [
921
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Code, { style: { width: "16px", height: "16px", color: theme.colors.primary[600] } }),
922
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "bold", textColor: "primary600", children: "Available Variables (click to copy)" })
923
+ ] }),
924
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 2, wrap: "wrap", children: TEMPLATE_VARIABLES[templateKey].map(({ var: variable, desc }) => /* @__PURE__ */ jsxRuntime.jsx(
925
+ designSystem.Button,
926
+ {
927
+ size: "S",
928
+ variant: "tertiary",
929
+ onClick: () => {
930
+ navigator.clipboard.writeText(variable);
931
+ toggleNotification({ type: "success", message: `${variable} copied!` });
932
+ },
933
+ style: {
934
+ fontFamily: "monospace",
935
+ fontSize: "11px",
936
+ padding: "4px 8px"
937
+ },
938
+ title: desc,
939
+ children: variable
940
+ },
941
+ variable
942
+ )) })
943
+ ] })
944
+ }
945
+ ),
946
+ /* @__PURE__ */ jsxRuntime.jsxs(
947
+ designSystem.Box,
948
+ {
949
+ background: "neutral0",
950
+ padding: 6,
951
+ style: { borderRadius: theme.borderRadius.lg, border: "2px solid #E5E7EB", width: "100%", marginBottom: "24px" },
952
+ children: [
953
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "center", style: { marginBottom: "16px" }, children: [
954
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { alignItems: "center", gap: 2, children: [
955
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "delta", fontWeight: "bold", style: { fontSize: "18px" }, children: "🎨 HTML Template" }),
956
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { variant: "success", children: "Main Template" })
957
+ ] }),
958
+ /* @__PURE__ */ jsxRuntime.jsx(
959
+ designSystem.Button,
960
+ {
961
+ variant: "tertiary",
962
+ size: "S",
963
+ onClick: () => {
964
+ const defaultTemplates = getDefaultTemplates();
965
+ const newTemplates = { ...settings.emailTemplates };
966
+ newTemplates[templateKey].html = defaultTemplates[templateKey].html;
967
+ handleChange("emailTemplates", newTemplates);
968
+ toggleNotification({ type: "success", message: "Default HTML template loaded!" });
969
+ },
970
+ children: "📋 Load Default"
971
+ }
972
+ )
973
+ ] }),
974
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "pi", textColor: "neutral600", style: { marginBottom: "16px", display: "block", fontSize: "14px" }, children: [
975
+ "HTML template for email notifications. Use variables like ",
976
+ /* @__PURE__ */ jsxRuntime.jsx("code", { children: "{{user.email}}" }),
977
+ " for dynamic content."
978
+ ] }),
979
+ /* @__PURE__ */ jsxRuntime.jsxs(
980
+ designSystem.Box,
981
+ {
982
+ style: {
983
+ border: "2px solid #E5E7EB",
984
+ borderRadius: "6px",
985
+ overflow: "hidden",
986
+ background: "#1e1e1e",
987
+ height: "500px",
988
+ display: "flex",
989
+ flexDirection: "column"
990
+ },
991
+ children: [
992
+ /* @__PURE__ */ jsxRuntime.jsx(
993
+ designSystem.Box,
994
+ {
995
+ padding: 2,
996
+ background: "neutral700",
997
+ style: { borderBottom: "1px solid #333", flexShrink: 0 },
998
+ children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", style: { color: "#888", fontSize: "11px", fontFamily: "monospace" }, children: "template.html" })
999
+ }
1000
+ ),
1001
+ /* @__PURE__ */ jsxRuntime.jsx(
1002
+ "textarea",
1003
+ {
1004
+ value: settings.emailTemplates[templateKey].html,
1005
+ onChange: (e) => {
1006
+ const newTemplates = { ...settings.emailTemplates };
1007
+ newTemplates[templateKey].html = e.target.value;
1008
+ handleChange("emailTemplates", newTemplates);
1009
+ },
1010
+ style: {
1011
+ fontFamily: 'Monaco, Consolas, "Courier New", monospace',
1012
+ height: "100%",
1013
+ fontSize: "14px",
1014
+ lineHeight: "1.8",
1015
+ background: "#1e1e1e",
1016
+ color: "#d4d4d4",
1017
+ border: "none",
1018
+ padding: "20px",
1019
+ resize: "none",
1020
+ width: "100%",
1021
+ boxSizing: "border-box",
1022
+ outline: "none",
1023
+ margin: 0,
1024
+ display: "block",
1025
+ overflow: "auto"
1026
+ },
1027
+ placeholder: "Enter HTML template with variables like {{user.email}}..."
1028
+ }
1029
+ )
1030
+ ]
1031
+ }
1032
+ ),
1033
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, style: { marginTop: "12px" }, wrap: "wrap", children: [
1034
+ /* @__PURE__ */ jsxRuntime.jsx(
1035
+ designSystem.Button,
1036
+ {
1037
+ variant: "secondary",
1038
+ size: "S",
1039
+ onClick: () => {
1040
+ navigator.clipboard.writeText(settings.emailTemplates[templateKey].html);
1041
+ toggleNotification({ type: "success", message: "HTML template copied!" });
1042
+ },
1043
+ children: "📋 Copy Template"
1044
+ }
1045
+ ),
1046
+ /* @__PURE__ */ jsxRuntime.jsx(
1047
+ designSystem.Button,
1048
+ {
1049
+ variant: "tertiary",
1050
+ size: "S",
1051
+ onClick: () => {
1052
+ const validation = validateTemplate(settings.emailTemplates[templateKey].html, templateKey);
1053
+ toggleNotification({
1054
+ type: validation.isValid ? "success" : "warning",
1055
+ message: validation.isValid ? `✓ Template valid! Found ${validation.foundVars.length}/${validation.totalAvailable} variables.` : "⚠️ No variables found. Add at least one variable."
1056
+ });
1057
+ },
1058
+ children: "✓ Validate"
1059
+ }
1060
+ ),
1061
+ /* @__PURE__ */ jsxRuntime.jsx(
1062
+ designSystem.Button,
1063
+ {
1064
+ variant: "tertiary",
1065
+ size: "S",
1066
+ onClick: () => {
1067
+ const lines = settings.emailTemplates[templateKey].html.split("\n").length;
1068
+ const chars = settings.emailTemplates[templateKey].html.length;
1069
+ toggleNotification({
1070
+ type: "info",
1071
+ message: `Template has ${lines} lines and ${chars} characters`
1072
+ });
1073
+ },
1074
+ children: "ℹ️ Template Info"
1075
+ }
1076
+ )
1077
+ ] })
1078
+ ]
1079
+ }
1080
+ ),
1081
+ /* @__PURE__ */ jsxRuntime.jsxs(
1082
+ designSystem.Box,
1083
+ {
1084
+ background: "neutral0",
1085
+ padding: 6,
1086
+ style: { borderRadius: theme.borderRadius.lg, border: "2px solid #E5E7EB", width: "100%", marginBottom: "24px" },
1087
+ children: [
1088
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "center", style: { marginBottom: "16px" }, children: [
1089
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { alignItems: "center", gap: 2, children: [
1090
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "delta", fontWeight: "bold", style: { fontSize: "18px" }, children: "📄 Text Template" }),
1091
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { variant: "secondary", children: "Fallback" })
1092
+ ] }),
1093
+ /* @__PURE__ */ jsxRuntime.jsx(
1094
+ designSystem.Button,
1095
+ {
1096
+ variant: "tertiary",
1097
+ size: "S",
1098
+ onClick: () => {
1099
+ const defaultTemplates = getDefaultTemplates();
1100
+ const newTemplates = { ...settings.emailTemplates };
1101
+ newTemplates[templateKey].text = defaultTemplates[templateKey].text;
1102
+ handleChange("emailTemplates", newTemplates);
1103
+ toggleNotification({ type: "success", message: "Default text template loaded!" });
1104
+ },
1105
+ children: "📋 Load Default"
1106
+ }
1107
+ )
1108
+ ] }),
1109
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", style: { marginBottom: "16px", display: "block", fontSize: "14px" }, children: "Plain text version (no HTML) as fallback for older email clients" }),
1110
+ /* @__PURE__ */ jsxRuntime.jsxs(
1111
+ designSystem.Box,
1112
+ {
1113
+ style: {
1114
+ border: "2px solid #E5E7EB",
1115
+ borderRadius: "6px",
1116
+ overflow: "hidden",
1117
+ background: "#1e1e1e",
1118
+ height: "300px",
1119
+ display: "flex",
1120
+ flexDirection: "column"
1121
+ },
1122
+ children: [
1123
+ /* @__PURE__ */ jsxRuntime.jsx(
1124
+ designSystem.Box,
1125
+ {
1126
+ padding: 2,
1127
+ background: "neutral700",
1128
+ style: { borderBottom: "1px solid #333", flexShrink: 0 },
1129
+ children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", style: { color: "#888", fontSize: "11px", fontFamily: "monospace" }, children: "template.txt" })
1130
+ }
1131
+ ),
1132
+ /* @__PURE__ */ jsxRuntime.jsx(
1133
+ "textarea",
1134
+ {
1135
+ value: settings.emailTemplates[templateKey].text,
1136
+ onChange: (e) => {
1137
+ const newTemplates = { ...settings.emailTemplates };
1138
+ newTemplates[templateKey].text = e.target.value;
1139
+ handleChange("emailTemplates", newTemplates);
1140
+ },
1141
+ style: {
1142
+ fontFamily: 'Monaco, Consolas, "Courier New", monospace',
1143
+ height: "100%",
1144
+ fontSize: "14px",
1145
+ lineHeight: "1.8",
1146
+ background: "#1e1e1e",
1147
+ color: "#d4d4d4",
1148
+ border: "none",
1149
+ padding: "20px",
1150
+ resize: "none",
1151
+ width: "100%",
1152
+ boxSizing: "border-box",
1153
+ outline: "none",
1154
+ margin: 0,
1155
+ display: "block",
1156
+ overflow: "auto"
1157
+ },
1158
+ placeholder: "Plain text version (no HTML)..."
1159
+ }
1160
+ )
1161
+ ]
1162
+ }
1163
+ ),
1164
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 2, style: { marginTop: "12px" }, wrap: "wrap", children: /* @__PURE__ */ jsxRuntime.jsx(
1165
+ designSystem.Button,
1166
+ {
1167
+ variant: "secondary",
1168
+ size: "S",
1169
+ onClick: () => {
1170
+ navigator.clipboard.writeText(settings.emailTemplates[templateKey].text);
1171
+ toggleNotification({ type: "success", message: "Text template copied!" });
1172
+ },
1173
+ children: "📋 Copy Template"
1174
+ }
1175
+ ) })
1176
+ ]
1177
+ }
1178
+ )
1179
+ ] }) }, templateKey))
1180
+ ] })
1181
+ ] })
1182
+ ] }) })
1183
+ ] }),
1184
+ isAdvanced && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Accordion.Item, { value: "webhooks", children: [
1185
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(
1186
+ designSystem.Accordion.Trigger,
1187
+ {
1188
+ icon: icons.Code,
1189
+ description: "Discord & Slack integration",
1190
+ children: "Webhook Integration (Advanced)"
1191
+ }
1192
+ ) }),
1193
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Content, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { padding: 6, children: [
1194
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { background: "neutral100", padding: 5, style: { borderRadius: theme.borderRadius.md, marginBottom: "32px" }, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Root, { gap: 4, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 12, children: /* @__PURE__ */ jsxRuntime.jsx(
1195
+ ToggleCard,
1196
+ {
1197
+ $active: settings.enableWebhooks,
1198
+ onClick: () => handleChange("enableWebhooks", !settings.enableWebhooks),
1199
+ children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 3, style: { width: "100%" }, alignItems: "center", children: [
1200
+ /* @__PURE__ */ jsxRuntime.jsx(GreenToggle, { $isActive: settings.enableWebhooks, children: /* @__PURE__ */ jsxRuntime.jsx(
1201
+ designSystem.Toggle,
1202
+ {
1203
+ checked: settings.enableWebhooks,
1204
+ onChange: () => handleChange("enableWebhooks", !settings.enableWebhooks)
1205
+ }
1206
+ ) }),
1207
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, alignItems: "center", style: { textAlign: "center" }, children: [
1208
+ /* @__PURE__ */ jsxRuntime.jsx(
1209
+ designSystem.Typography,
1210
+ {
1211
+ variant: "delta",
1212
+ fontWeight: "bold",
1213
+ textColor: settings.enableWebhooks ? "success700" : "neutral800",
1214
+ style: { fontSize: "16px" },
1215
+ children: "Enable Webhooks"
1216
+ }
1217
+ ),
1218
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", style: { fontSize: "13px", lineHeight: "1.6" }, children: "Send session events to Discord, Slack, or custom endpoints" })
1219
+ ] })
1220
+ ] })
1221
+ }
1222
+ ) }) }) }),
1223
+ settings.enableWebhooks && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Grid.Root, { gap: 6, children: [
1224
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { children: [
1225
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: "bold", style: { marginBottom: "12px", display: "block" }, children: "🔗 Discord Webhook URL" }),
1226
+ /* @__PURE__ */ jsxRuntime.jsx(
1227
+ designSystem.Box,
1228
+ {
1229
+ style: {
1230
+ border: "2px solid #E5E7EB",
1231
+ borderRadius: theme.borderRadius.md,
1232
+ overflow: "hidden",
1233
+ background: "#fafafa"
1234
+ },
1235
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1236
+ "textarea",
1237
+ {
1238
+ placeholder: "https://discord.com/api/webhooks/123456789/abcdefghijklmnopqrstuvwxyz...",
1239
+ value: settings.discordWebhookUrl,
1240
+ onChange: (e) => handleChange("discordWebhookUrl", e.target.value),
1241
+ rows: 3,
1242
+ style: {
1243
+ width: "100%",
1244
+ padding: "14px 18px",
1245
+ border: "none",
1246
+ outline: "none",
1247
+ fontFamily: "Monaco, Consolas, monospace",
1248
+ fontSize: "14px",
1249
+ lineHeight: "1.8",
1250
+ color: "#374151",
1251
+ background: "white",
1252
+ resize: "vertical",
1253
+ minHeight: "80px"
1254
+ }
1255
+ }
1256
+ )
1257
+ }
1258
+ ),
1259
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "center", style: { marginTop: "10px" }, children: [
1260
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", style: { fontSize: "12px" }, children: "💡 Optional: Post session alerts to your Discord channel" }),
1261
+ settings.discordWebhookUrl && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "pi", textColor: "primary600", style: { fontSize: "11px", fontFamily: "monospace" }, children: [
1262
+ settings.discordWebhookUrl.length,
1263
+ " characters"
1264
+ ] })
1265
+ ] })
1266
+ ] }) }),
1267
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { children: [
1268
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: "bold", style: { marginBottom: "12px", display: "block" }, children: "💬 Slack Webhook URL" }),
1269
+ /* @__PURE__ */ jsxRuntime.jsx(
1270
+ designSystem.Box,
1271
+ {
1272
+ style: {
1273
+ border: "2px solid #E5E7EB",
1274
+ borderRadius: theme.borderRadius.md,
1275
+ overflow: "hidden",
1276
+ background: "#fafafa"
1277
+ },
1278
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1279
+ "textarea",
1280
+ {
1281
+ placeholder: "https://hooks.slack.com/services/XXXX/XXXX/XXXX",
1282
+ value: settings.slackWebhookUrl,
1283
+ onChange: (e) => handleChange("slackWebhookUrl", e.target.value),
1284
+ rows: 3,
1285
+ style: {
1286
+ width: "100%",
1287
+ padding: "14px 18px",
1288
+ border: "none",
1289
+ outline: "none",
1290
+ fontFamily: "Monaco, Consolas, monospace",
1291
+ fontSize: "14px",
1292
+ lineHeight: "1.8",
1293
+ color: "#374151",
1294
+ background: "white",
1295
+ resize: "vertical",
1296
+ minHeight: "80px"
1297
+ }
1298
+ }
1299
+ )
1300
+ }
1301
+ ),
1302
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "center", style: { marginTop: "10px" }, children: [
1303
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", style: { fontSize: "12px" }, children: "💡 Optional: Post session alerts to your Slack workspace" }),
1304
+ settings.slackWebhookUrl && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "pi", textColor: "primary600", style: { fontSize: "11px", fontFamily: "monospace" }, children: [
1305
+ settings.slackWebhookUrl.length,
1306
+ " characters"
1307
+ ] })
1308
+ ] })
1309
+ ] }) })
1310
+ ] })
1311
+ ] }) })
1312
+ ] })
1313
+ ] }),
1314
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 5, background: "primary100", style: { borderRadius: theme.borderRadius.md, marginTop: "32px", border: "2px solid #BAE6FD" }, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 3, alignItems: "flex-start", children: [
1315
+ /* @__PURE__ */ jsxRuntime.jsx(icons.Check, { style: { width: "20px", height: "20px", color: theme.colors.success[600], flexShrink: 0, marginTop: "2px" } }),
1316
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { style: { flex: 1 }, children: [
1317
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "bold", style: { marginBottom: "8px", display: "block", color: theme.colors.primary[700] }, children: "✨ Database-Backed Settings" }),
1318
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "primary700", style: { fontSize: "13px", lineHeight: "1.8" }, children: "All settings are stored in your Strapi database and shared across all admin users. Changes take effect immediately - no server restart required! Email templates, webhooks, and security options are all managed from this interface." })
1319
+ ] })
1320
+ ] }) })
1321
+ ] })
1322
+ ] });
1323
+ };
1324
+ exports.default = SettingsPage;