strapi-plugin-magic-sessionmanager 4.0.1 → 4.0.3

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 (57) hide show
  1. package/README.md +2 -2
  2. package/admin/src/components/OnlineUsersWidget.jsx +11 -7
  3. package/admin/src/components/SessionDetailModal.jsx +42 -38
  4. package/admin/src/components/SessionInfoPanel.jsx +29 -20
  5. package/admin/src/index.js +9 -0
  6. package/admin/src/pages/HomePage.jsx +128 -161
  7. package/admin/src/pages/License.jsx +3 -3
  8. package/admin/src/pages/Settings.jsx +139 -135
  9. package/admin/src/pages/UpgradePage.jsx +448 -0
  10. package/admin/src/pluginId.js +1 -0
  11. package/admin/src/translations/de.json +294 -15
  12. package/admin/src/translations/en.json +293 -14
  13. package/admin/src/translations/es.json +284 -18
  14. package/admin/src/translations/fr.json +284 -18
  15. package/admin/src/translations/pt.json +284 -18
  16. package/admin/src/utils/theme.js +85 -0
  17. package/dist/_chunks/{Analytics-Dv9f_0eZ.mjs → Analytics-DTE_zmRV.mjs} +2 -2
  18. package/dist/_chunks/{Analytics-BBdv1I5y.js → Analytics-lw_JaOVy.js} +2 -2
  19. package/dist/_chunks/{App-CJaZPNjt.js → App-DDKYCjKw.js} +216 -206
  20. package/dist/_chunks/{App-CIQ-7sa7.mjs → App-DJW1ZNl5.mjs} +216 -206
  21. package/dist/_chunks/{License-nrmFxoBm.mjs → License-DaOFuImm.mjs} +4 -8
  22. package/dist/_chunks/{License-D24rgaZQ.js → License-Tk-6UfPl.js} +4 -8
  23. package/dist/_chunks/{OnlineUsersWidget-B8JS1xZu.js → OnlineUsersWidget-C1qTpsws.js} +11 -7
  24. package/dist/_chunks/{OnlineUsersWidget-ArMl0nen.mjs → OnlineUsersWidget-CADphbXG.mjs} +11 -7
  25. package/dist/_chunks/{Settings-D5dLEGc_.mjs → Settings-C9xvckgq.mjs} +191 -179
  26. package/dist/_chunks/{Settings-CqxgjU0y.js → Settings-DyEAuTNQ.js} +191 -179
  27. package/dist/_chunks/UpgradePage-Dssk8A0Z.js +354 -0
  28. package/dist/_chunks/UpgradePage-cINvE9zY.mjs +352 -0
  29. package/dist/_chunks/de-CDA1V0rF.mjs +292 -0
  30. package/dist/_chunks/de-I-Q-pWqu.js +292 -0
  31. package/dist/_chunks/en-Bd7_h-4e.js +292 -0
  32. package/dist/_chunks/en-DzmOCyzQ.mjs +292 -0
  33. package/dist/_chunks/es-BcAx18XG.js +277 -0
  34. package/dist/_chunks/es-Cx-SN6qV.mjs +277 -0
  35. package/dist/_chunks/fr-DCzYMuJ-.js +277 -0
  36. package/dist/_chunks/fr-DXlXE5Eo.mjs +277 -0
  37. package/dist/_chunks/{index-WH04CS1c.js → index-CWcvrfXc.js} +45 -42
  38. package/dist/_chunks/{index-Duk1_Wrz.mjs → index-DQO9bNP7.mjs} +45 -42
  39. package/dist/_chunks/pt-21-MAb72.js +277 -0
  40. package/dist/_chunks/pt-zsdTSjba.mjs +277 -0
  41. package/dist/_chunks/{useLicense-BwOlCyhc.js → useLicense-DtvJOszr.js} +1 -1
  42. package/dist/_chunks/{useLicense-Ce8GaxB0.mjs → useLicense-DxbD4Wf8.mjs} +1 -1
  43. package/dist/admin/index.js +1 -1
  44. package/dist/admin/index.mjs +1 -1
  45. package/dist/server/index.js +1 -1
  46. package/dist/server/index.mjs +1 -1
  47. package/package.json +1 -1
  48. package/dist/_chunks/de-BxFx1pwE.js +0 -23
  49. package/dist/_chunks/de-CdO3s01z.mjs +0 -23
  50. package/dist/_chunks/en-CsPpPJL3.mjs +0 -23
  51. package/dist/_chunks/en-RqmpDHdS.js +0 -23
  52. package/dist/_chunks/es-CuLHazN1.js +0 -23
  53. package/dist/_chunks/es-Dkmjhy9c.mjs +0 -23
  54. package/dist/_chunks/fr-BAJp2yhI.js +0 -23
  55. package/dist/_chunks/fr-Bssg_3UF.mjs +0 -23
  56. package/dist/_chunks/pt-BAP9cKs3.js +0 -23
  57. package/dist/_chunks/pt-BVNoNcuY.mjs +0 -23
@@ -1,12 +1,67 @@
1
1
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
2
  import { useState, useEffect } from "react";
3
+ import { useIntl } from "react-intl";
3
4
  import { useFetchClient, useNotification } from "@strapi/strapi/admin";
4
5
  import styled, { css, keyframes } from "styled-components";
6
+ import { p as parseUserAgent, a as pluginId, g as getTranslation } from "./index-DQO9bNP7.mjs";
5
7
  import { Modal, Flex, Box, Typography, Badge, Divider, Button, Loader, SingleSelect, SingleSelectOption, Thead, Tr, Th, Tbody, Td, Table, TextInput } from "@strapi/design-system";
6
8
  import { Check, Information, Monitor, Server, Clock, Cross, Earth, Shield, Crown, Phone, Download, User, Eye, Trash, Search, Key } from "@strapi/icons";
7
- import { p as parseUserAgent, a as pluginId } from "./index-Duk1_Wrz.mjs";
8
- import { u as useLicense } from "./useLicense-Ce8GaxB0.mjs";
9
+ import { u as useLicense } from "./useLicense-DxbD4Wf8.mjs";
9
10
  import { useNavigate } from "react-router-dom";
11
+ const theme = {
12
+ colors: {
13
+ primary: {
14
+ 50: "#F0F9FF",
15
+ 100: "#E0F2FE",
16
+ 600: "#0284C7"
17
+ },
18
+ secondary: {
19
+ 50: "#FAF5FF",
20
+ 100: "#F3E8FF",
21
+ 600: "#9333EA"
22
+ },
23
+ success: {
24
+ 50: "#F0FDF4",
25
+ 100: "#DCFCE7",
26
+ 500: "#22C55E",
27
+ 600: "#16A34A"
28
+ },
29
+ warning: {
30
+ 50: "#FFFBEB",
31
+ 100: "#FEF3C7",
32
+ 500: "#F59E0B",
33
+ 600: "#D97706"
34
+ },
35
+ danger: {
36
+ 50: "#FEF2F2",
37
+ 100: "#FEE2E2",
38
+ 500: "#EF4444",
39
+ 600: "#DC2626"
40
+ }
41
+ },
42
+ shadows: {
43
+ sm: "0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px -1px rgba(0, 0, 0, 0.1)",
44
+ xl: "0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1)"
45
+ },
46
+ transitions: {
47
+ fast: "150ms cubic-bezier(0.4, 0, 0.2, 1)",
48
+ normal: "300ms cubic-bezier(0.4, 0, 0.2, 1)",
49
+ slow: "500ms cubic-bezier(0.4, 0, 0.2, 1)"
50
+ },
51
+ spacing: {
52
+ xs: "4px",
53
+ sm: "8px",
54
+ md: "16px",
55
+ lg: "24px",
56
+ xl: "32px",
57
+ "2xl": "48px"
58
+ },
59
+ borderRadius: {
60
+ md: "8px",
61
+ lg: "12px",
62
+ xl: "16px"
63
+ }
64
+ };
10
65
  const TwoColumnGrid = styled.div`
11
66
  display: grid;
12
67
  grid-template-columns: 1fr 1fr;
@@ -31,6 +86,7 @@ const Section = styled(Box)`
31
86
  margin-bottom: 24px;
32
87
  `;
33
88
  const SessionDetailModal = ({ session, onClose, onSessionTerminated }) => {
89
+ const { formatMessage } = useIntl();
34
90
  const { get, post } = useFetchClient();
35
91
  const { toggleNotification } = useNotification();
36
92
  const { isPremium } = useLicense();
@@ -38,6 +94,7 @@ const SessionDetailModal = ({ session, onClose, onSessionTerminated }) => {
38
94
  const [showUserAgent, setShowUserAgent] = useState(false);
39
95
  const [geoData, setGeoData] = useState(null);
40
96
  const [geoLoading, setGeoLoading] = useState(false);
97
+ const t = (id, defaultMessage, values) => formatMessage({ id: getTranslation(id), defaultMessage }, values);
41
98
  if (!session) return null;
42
99
  const deviceInfo = parseUserAgent(session.userAgent);
43
100
  const isOnline = session.isTrulyActive;
@@ -84,7 +141,7 @@ const SessionDetailModal = ({ session, onClose, onSessionTerminated }) => {
84
141
  };
85
142
  const DeviceIcon = getDeviceIcon(deviceInfo.device);
86
143
  const handleTerminate = async () => {
87
- if (!confirm("Are you sure you want to terminate this session?")) {
144
+ if (!confirm(t("modal.confirm.terminate", "Are you sure you want to terminate this session?"))) {
88
145
  return;
89
146
  }
90
147
  setTerminating(true);
@@ -92,7 +149,7 @@ const SessionDetailModal = ({ session, onClose, onSessionTerminated }) => {
92
149
  await post(`/${pluginId}/sessions/${session.id}/terminate`);
93
150
  toggleNotification({
94
151
  type: "success",
95
- message: "Session terminated successfully"
152
+ message: t("notifications.success.terminated", "Session terminated successfully")
96
153
  });
97
154
  onSessionTerminated();
98
155
  onClose();
@@ -100,7 +157,7 @@ const SessionDetailModal = ({ session, onClose, onSessionTerminated }) => {
100
157
  console.error("[SessionDetailModal] Error:", err);
101
158
  toggleNotification({
102
159
  type: "danger",
103
- message: "Failed to terminate session"
160
+ message: t("notifications.error.terminate", "Failed to terminate session")
104
161
  });
105
162
  } finally {
106
163
  setTerminating(false);
@@ -134,11 +191,8 @@ const SessionDetailModal = ({ session, onClose, onSessionTerminated }) => {
134
191
  justifyContent: "center"
135
192
  }, children: /* @__PURE__ */ jsx(DeviceIcon, { width: "24px", height: "24px" }) }),
136
193
  /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", children: [
137
- /* @__PURE__ */ jsx(Typography, { variant: "beta", fontWeight: "bold", children: "Session Details" }),
138
- /* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "neutral600", children: [
139
- "ID: ",
140
- session.id
141
- ] })
194
+ /* @__PURE__ */ jsx(Typography, { variant: "beta", fontWeight: "bold", children: t("modal.title", "Session Details") }),
195
+ /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: t("modal.id", "ID: {id}", { id: session.id }) })
142
196
  ] })
143
197
  ] }) }),
144
198
  /* @__PURE__ */ jsx(Modal.Body, { children: /* @__PURE__ */ jsxs(Box, { padding: 6, children: [
@@ -149,34 +203,34 @@ const SessionDetailModal = ({ session, onClose, onSessionTerminated }) => {
149
203
  textColor: "neutral0",
150
204
  size: "M",
151
205
  style: { fontSize: "14px", padding: "8px 20px", fontWeight: "600" },
152
- children: isOnline ? "ONLINE" : "OFFLINE"
206
+ children: isOnline ? t("modal.status.online", "ONLINE") : t("modal.status.offline", "OFFLINE")
153
207
  }
154
208
  ) }),
155
209
  /* @__PURE__ */ jsx(Divider, { style: { marginBottom: "24px" } }),
156
210
  /* @__PURE__ */ jsxs(TwoColumnGrid, { children: [
157
211
  /* @__PURE__ */ jsxs(Box, { children: [
158
212
  /* @__PURE__ */ jsxs(Section, { children: [
159
- /* @__PURE__ */ jsx(SectionTitle, { children: "User" }),
160
- /* @__PURE__ */ jsx(DetailRow, { compact: true, icon: Check, label: "Username", value: session.user?.username || "N/A" }),
161
- /* @__PURE__ */ jsx(DetailRow, { compact: true, icon: Information, label: "Email", value: session.user?.email || "N/A" }),
162
- /* @__PURE__ */ jsx(DetailRow, { compact: true, icon: Information, label: "User ID", value: session.user?.id || "N/A" })
213
+ /* @__PURE__ */ jsx(SectionTitle, { children: t("modal.section.user", "User") }),
214
+ /* @__PURE__ */ jsx(DetailRow, { compact: true, icon: Check, label: t("modal.user.username", "Username"), value: session.user?.username || t("modal.user.na", "N/A") }),
215
+ /* @__PURE__ */ jsx(DetailRow, { compact: true, icon: Information, label: t("modal.user.email", "Email"), value: session.user?.email || t("modal.user.na", "N/A") }),
216
+ /* @__PURE__ */ jsx(DetailRow, { compact: true, icon: Information, label: t("modal.user.id", "User ID"), value: session.user?.id || t("modal.user.na", "N/A") })
163
217
  ] }),
164
218
  /* @__PURE__ */ jsxs(Section, { children: [
165
- /* @__PURE__ */ jsx(SectionTitle, { children: "Device" }),
166
- /* @__PURE__ */ jsx(DetailRow, { compact: true, icon: DeviceIcon, label: "Device", value: deviceInfo.device }),
167
- /* @__PURE__ */ jsx(DetailRow, { compact: true, icon: Monitor, label: "Browser", value: `${deviceInfo.browser} ${deviceInfo.browserVersion || ""}` }),
168
- /* @__PURE__ */ jsx(DetailRow, { compact: true, icon: Server, label: "OS", value: deviceInfo.os }),
169
- /* @__PURE__ */ jsx(DetailRow, { compact: true, icon: Information, label: "IP", value: session.ipAddress })
219
+ /* @__PURE__ */ jsx(SectionTitle, { children: t("modal.section.device", "Device") }),
220
+ /* @__PURE__ */ jsx(DetailRow, { compact: true, icon: DeviceIcon, label: t("modal.device.device", "Device"), value: deviceInfo.device }),
221
+ /* @__PURE__ */ jsx(DetailRow, { compact: true, icon: Monitor, label: t("modal.device.browser", "Browser"), value: `${deviceInfo.browser} ${deviceInfo.browserVersion || ""}` }),
222
+ /* @__PURE__ */ jsx(DetailRow, { compact: true, icon: Server, label: t("modal.device.os", "OS"), value: deviceInfo.os }),
223
+ /* @__PURE__ */ jsx(DetailRow, { compact: true, icon: Information, label: t("modal.device.ip", "IP"), value: session.ipAddress })
170
224
  ] })
171
225
  ] }),
172
226
  /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Section, { children: [
173
- /* @__PURE__ */ jsx(SectionTitle, { children: "Timeline" }),
227
+ /* @__PURE__ */ jsx(SectionTitle, { children: t("modal.section.timeline", "Timeline") }),
174
228
  /* @__PURE__ */ jsx(
175
229
  DetailRow,
176
230
  {
177
231
  compact: true,
178
232
  icon: Clock,
179
- label: "Login",
233
+ label: t("modal.timeline.login", "Login"),
180
234
  value: new Date(session.loginTime).toLocaleString("de-DE", {
181
235
  day: "2-digit",
182
236
  month: "short",
@@ -190,7 +244,7 @@ const SessionDetailModal = ({ session, onClose, onSessionTerminated }) => {
190
244
  {
191
245
  compact: true,
192
246
  icon: Clock,
193
- label: "Last Active",
247
+ label: t("modal.timeline.lastActive", "Last Active"),
194
248
  value: new Date(session.lastActive || session.loginTime).toLocaleString("de-DE", {
195
249
  day: "2-digit",
196
250
  month: "short",
@@ -204,8 +258,8 @@ const SessionDetailModal = ({ session, onClose, onSessionTerminated }) => {
204
258
  {
205
259
  compact: true,
206
260
  icon: Clock,
207
- label: "Idle Time",
208
- value: `${session.minutesSinceActive} min`
261
+ label: t("modal.timeline.idleTime", "Idle Time"),
262
+ value: t("modal.timeline.minutes", "{minutes} min", { minutes: session.minutesSinceActive })
209
263
  }
210
264
  ),
211
265
  session.logoutTime && /* @__PURE__ */ jsx(
@@ -213,7 +267,7 @@ const SessionDetailModal = ({ session, onClose, onSessionTerminated }) => {
213
267
  {
214
268
  compact: true,
215
269
  icon: Cross,
216
- label: "Logout",
270
+ label: t("modal.timeline.logout", "Logout"),
217
271
  value: new Date(session.logoutTime).toLocaleString("de-DE", {
218
272
  day: "2-digit",
219
273
  month: "short",
@@ -225,20 +279,20 @@ const SessionDetailModal = ({ session, onClose, onSessionTerminated }) => {
225
279
  ] }) })
226
280
  ] }),
227
281
  isPremium ? /* @__PURE__ */ jsxs(Section, { children: [
228
- /* @__PURE__ */ jsx(SectionTitle, { children: "Location and Security" }),
229
- geoLoading ? /* @__PURE__ */ jsx(Box, { padding: 4, style: { textAlign: "center" }, children: /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: "Loading location data..." }) }) : /* @__PURE__ */ jsxs(TwoColumnGrid, { children: [
282
+ /* @__PURE__ */ jsx(SectionTitle, { children: t("modal.section.security", "Location and Security") }),
283
+ geoLoading ? /* @__PURE__ */ jsx(Box, { padding: 4, style: { textAlign: "center" }, children: /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: t("modal.security.loading", "Loading location data...") }) }) : /* @__PURE__ */ jsxs(TwoColumnGrid, { children: [
230
284
  /* @__PURE__ */ jsxs(Box, { children: [
231
285
  /* @__PURE__ */ jsx(
232
286
  DetailRow,
233
287
  {
234
288
  compact: true,
235
289
  icon: Earth,
236
- label: "Country",
290
+ label: t("modal.security.country", "Country"),
237
291
  value: `${premiumData.country_flag || ""} ${premiumData.country}`.trim()
238
292
  }
239
293
  ),
240
- /* @__PURE__ */ jsx(DetailRow, { compact: true, icon: Earth, label: "City", value: premiumData.city }),
241
- /* @__PURE__ */ jsx(DetailRow, { compact: true, icon: Clock, label: "Timezone", value: premiumData.timezone })
294
+ /* @__PURE__ */ jsx(DetailRow, { compact: true, icon: Earth, label: t("modal.security.city", "City"), value: premiumData.city }),
295
+ /* @__PURE__ */ jsx(DetailRow, { compact: true, icon: Clock, label: t("modal.security.timezone", "Timezone"), value: premiumData.timezone })
242
296
  ] }),
243
297
  /* @__PURE__ */ jsxs(Box, { children: [
244
298
  /* @__PURE__ */ jsx(
@@ -246,7 +300,7 @@ const SessionDetailModal = ({ session, onClose, onSessionTerminated }) => {
246
300
  {
247
301
  compact: true,
248
302
  icon: Shield,
249
- label: "Security",
303
+ label: t("modal.security.score", "Security"),
250
304
  value: `${premiumData.securityScore}/100 (${premiumData.riskLevel})`
251
305
  }
252
306
  ),
@@ -255,8 +309,8 @@ const SessionDetailModal = ({ session, onClose, onSessionTerminated }) => {
255
309
  {
256
310
  compact: true,
257
311
  icon: Shield,
258
- label: "VPN",
259
- value: premiumData.isVpn ? "[WARNING] Yes" : "No"
312
+ label: t("modal.security.vpn", "VPN"),
313
+ value: premiumData.isVpn ? t("modal.security.vpnWarning", "[WARNING] Yes") : t("modal.security.no", "No")
260
314
  }
261
315
  ),
262
316
  /* @__PURE__ */ jsx(
@@ -264,8 +318,8 @@ const SessionDetailModal = ({ session, onClose, onSessionTerminated }) => {
264
318
  {
265
319
  compact: true,
266
320
  icon: Shield,
267
- label: "Proxy",
268
- value: premiumData.isProxy ? "[WARNING] Yes" : "No"
321
+ label: t("modal.security.proxy", "Proxy"),
322
+ value: premiumData.isProxy ? t("modal.security.vpnWarning", "[WARNING] Yes") : t("modal.security.no", "No")
269
323
  }
270
324
  )
271
325
  ] })
@@ -282,8 +336,8 @@ const SessionDetailModal = ({ session, onClose, onSessionTerminated }) => {
282
336
  },
283
337
  children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "center", gap: 3, children: [
284
338
  /* @__PURE__ */ jsx(Crown, { style: { width: "40px", height: "40px", color: "#d97706" } }),
285
- /* @__PURE__ */ jsx(Typography, { variant: "beta", style: { color: "#92400e", fontWeight: "700" }, children: "Location and Security Analysis" }),
286
- /* @__PURE__ */ jsx(Typography, { variant: "omega", style: { color: "#78350f", fontSize: "14px", lineHeight: "1.6" }, children: "Unlock premium features to get IP geolocation, security scoring, and VPN/Proxy detection for every session" }),
339
+ /* @__PURE__ */ jsx(Typography, { variant: "beta", style: { color: "#92400e", fontWeight: "700" }, children: t("modal.premium.title", "Location and Security Analysis") }),
340
+ /* @__PURE__ */ jsx(Typography, { variant: "omega", style: { color: "#78350f", fontSize: "14px", lineHeight: "1.6" }, children: t("modal.premium.description", "Unlock premium features to get IP geolocation, security scoring, and VPN/Proxy detection for every session") }),
287
341
  /* @__PURE__ */ jsx(
288
342
  Button,
289
343
  {
@@ -298,7 +352,7 @@ const SessionDetailModal = ({ session, onClose, onSessionTerminated }) => {
298
352
  marginTop: "8px",
299
353
  boxShadow: "0 4px 12px rgba(245, 158, 11, 0.3)"
300
354
  },
301
- children: "Upgrade to Premium"
355
+ children: t("modal.premium.upgrade", "Upgrade to Premium")
302
356
  }
303
357
  )
304
358
  ] })
@@ -306,7 +360,7 @@ const SessionDetailModal = ({ session, onClose, onSessionTerminated }) => {
306
360
  ) }),
307
361
  /* @__PURE__ */ jsxs(Section, { children: [
308
362
  /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", style: { marginBottom: "12px" }, children: [
309
- /* @__PURE__ */ jsx(SectionTitle, { style: { marginBottom: 0, paddingBottom: 0, border: "none" }, children: "Technical Details" }),
363
+ /* @__PURE__ */ jsx(SectionTitle, { style: { marginBottom: 0, paddingBottom: 0, border: "none" }, children: t("modal.section.technical", "Technical Details") }),
310
364
  /* @__PURE__ */ jsx(
311
365
  Button,
312
366
  {
@@ -314,7 +368,7 @@ const SessionDetailModal = ({ session, onClose, onSessionTerminated }) => {
314
368
  size: "S",
315
369
  onClick: () => setShowUserAgent(!showUserAgent),
316
370
  style: { fontSize: "12px" },
317
- children: showUserAgent ? " Hide Details" : " Show Details"
371
+ children: showUserAgent ? `▲ ${t("modal.technical.hide", "Hide Details")}` : `▼ ${t("modal.technical.show", "Show Details")}`
318
372
  }
319
373
  )
320
374
  ] }),
@@ -339,7 +393,7 @@ const SessionDetailModal = ({ session, onClose, onSessionTerminated }) => {
339
393
  ] })
340
394
  ] }) }),
341
395
  /* @__PURE__ */ jsx(Modal.Footer, { children: /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", style: { width: "100%" }, children: [
342
- /* @__PURE__ */ jsx(Button, { onClick: onClose, variant: "tertiary", children: "Close" }),
396
+ /* @__PURE__ */ jsx(Button, { onClick: onClose, variant: "tertiary", children: t("modal.actions.close", "Close") }),
343
397
  /* @__PURE__ */ jsx(
344
398
  Button,
345
399
  {
@@ -348,72 +402,12 @@ const SessionDetailModal = ({ session, onClose, onSessionTerminated }) => {
348
402
  disabled: !session.isActive || terminating,
349
403
  loading: terminating,
350
404
  startIcon: /* @__PURE__ */ jsx(Cross, {}),
351
- children: "Terminate Session"
405
+ children: t("modal.actions.terminate", "Terminate Session")
352
406
  }
353
407
  )
354
408
  ] }) })
355
409
  ] }) });
356
410
  };
357
- const theme = {
358
- colors: {
359
- primary: {
360
- 50: "#F0F9FF",
361
- 100: "#E0F2FE",
362
- 500: "#0EA5E9",
363
- 600: "#0284C7"
364
- },
365
- secondary: {
366
- 500: "#A855F7",
367
- 600: "#9333EA"
368
- },
369
- success: {
370
- 100: "#DCFCE7",
371
- 500: "#22C55E",
372
- 600: "#16A34A"
373
- },
374
- warning: {
375
- 100: "#FEF3C7",
376
- 500: "#F59E0B",
377
- 600: "#D97706"
378
- },
379
- danger: {
380
- 100: "#FEE2E2",
381
- 500: "#EF4444",
382
- 600: "#DC2626"
383
- },
384
- neutral: {
385
- 0: "#FFFFFF",
386
- 50: "#F9FAFB",
387
- 100: "#F3F4F6",
388
- 200: "#E5E7EB",
389
- 600: "#4B5563",
390
- 700: "#374151",
391
- 800: "#1F2937"
392
- }
393
- },
394
- shadows: {
395
- sm: "0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px -1px rgba(0, 0, 0, 0.1)",
396
- xl: "0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1)"
397
- },
398
- transitions: {
399
- fast: "150ms cubic-bezier(0.4, 0, 0.2, 1)",
400
- normal: "300ms cubic-bezier(0.4, 0, 0.2, 1)",
401
- slow: "500ms cubic-bezier(0.4, 0, 0.2, 1)"
402
- },
403
- spacing: {
404
- xs: "4px",
405
- sm: "8px",
406
- md: "16px",
407
- lg: "24px",
408
- xl: "32px",
409
- "2xl": "48px"
410
- },
411
- borderRadius: {
412
- md: "8px",
413
- lg: "12px",
414
- xl: "16px"
415
- }
416
- };
417
411
  const fadeIn$1 = keyframes`
418
412
  from { opacity: 0; transform: translateY(10px); }
419
413
  to { opacity: 1; transform: translateY(0); }
@@ -502,7 +496,7 @@ const HeaderContent = styled(Flex)`
502
496
  z-index: 1;
503
497
  `;
504
498
  const Title = styled(Typography)`
505
- color: ${theme.colors.neutral[0]};
499
+ color: white;
506
500
  font-size: 2rem;
507
501
  font-weight: 700;
508
502
  letter-spacing: -0.025em;
@@ -554,7 +548,7 @@ const StatsGrid = styled.div`
554
548
  }
555
549
  `;
556
550
  const StatCard = styled(Box)`
557
- background: ${theme.colors.neutral[0]};
551
+ background: ${(props) => props.theme.colors.neutral0};
558
552
  border-radius: ${theme.borderRadius.lg};
559
553
  padding: 28px ${theme.spacing.lg};
560
554
  position: relative;
@@ -563,7 +557,7 @@ const StatCard = styled(Box)`
563
557
  ${css`animation: ${fadeIn$1} ${theme.transitions.slow} backwards;`}
564
558
  animation-delay: ${(props) => props.$delay || "0s"};
565
559
  box-shadow: ${theme.shadows.sm};
566
- border: 1px solid ${theme.colors.neutral[200]};
560
+ border: 1px solid ${(props) => props.theme.colors.neutral200};
567
561
  min-width: 200px;
568
562
  flex: 1;
569
563
  text-align: center;
@@ -584,7 +578,7 @@ const StatCard = styled(Box)`
584
578
  &:hover {
585
579
  transform: translateY(-6px);
586
580
  box-shadow: ${theme.shadows.xl};
587
- border-color: ${(props) => props.$color || theme.colors.primary[500]};
581
+ border-color: ${(props) => props.$color || props.theme.colors.primary600};
588
582
 
589
583
  .stat-icon {
590
584
  transform: scale(1.15) rotate(5deg);
@@ -592,7 +586,7 @@ const StatCard = styled(Box)`
592
586
 
593
587
  .stat-value {
594
588
  transform: scale(1.08);
595
- color: ${(props) => props.$color || theme.colors.primary[600]};
589
+ color: ${(props) => props.$color || props.theme.colors.primary600};
596
590
  }
597
591
  }
598
592
  `;
@@ -603,7 +597,7 @@ const StatIcon = styled(Box)`
603
597
  display: flex;
604
598
  align-items: center;
605
599
  justify-content: center;
606
- background: ${(props) => props.$bg || theme.colors.primary[100]};
600
+ background: ${(props) => props.$bg || props.theme.colors.primary100};
607
601
  transition: all ${theme.transitions.normal};
608
602
  margin: 0 auto 20px;
609
603
  box-shadow: ${theme.shadows.sm};
@@ -611,7 +605,7 @@ const StatIcon = styled(Box)`
611
605
  svg {
612
606
  width: 34px;
613
607
  height: 34px;
614
- color: ${(props) => props.$color || theme.colors.primary[600]};
608
+ color: ${(props) => props.$color || props.theme.colors.primary600};
615
609
  }
616
610
 
617
611
  @media screen and (max-width: ${breakpoints.mobile}) {
@@ -628,7 +622,7 @@ const StatIcon = styled(Box)`
628
622
  const StatValue = styled(Typography)`
629
623
  font-size: 2.75rem;
630
624
  font-weight: 700;
631
- color: ${theme.colors.neutral[800]};
625
+ color: ${(props) => props.theme.colors.neutral800};
632
626
  line-height: 1;
633
627
  margin-bottom: 10px;
634
628
  transition: all ${theme.transitions.normal};
@@ -641,7 +635,7 @@ const StatValue = styled(Typography)`
641
635
  `;
642
636
  const StatLabel = styled(Typography)`
643
637
  font-size: 0.95rem;
644
- color: ${theme.colors.neutral[600]};
638
+ color: ${(props) => props.theme.colors.neutral600};
645
639
  font-weight: 500;
646
640
  letter-spacing: 0.025em;
647
641
  text-align: center;
@@ -651,21 +645,21 @@ const StatLabel = styled(Typography)`
651
645
  }
652
646
  `;
653
647
  const DataTable = styled(Box)`
654
- background: ${theme.colors.neutral[0]};
648
+ background: ${(props) => props.theme.colors.neutral0};
655
649
  border-radius: ${theme.borderRadius.lg};
656
650
  overflow: hidden;
657
651
  box-shadow: ${theme.shadows.sm};
658
- border: 1px solid ${theme.colors.neutral[200]};
652
+ border: 1px solid ${(props) => props.theme.colors.neutral200};
659
653
  margin-bottom: ${theme.spacing.xl};
660
654
  `;
661
655
  const StyledTable = styled(Table)`
662
656
  thead {
663
- background: ${theme.colors.neutral[50]};
664
- border-bottom: 2px solid ${theme.colors.neutral[200]};
657
+ background: ${(props) => props.theme.colors.neutral100};
658
+ border-bottom: 2px solid ${(props) => props.theme.colors.neutral200};
665
659
 
666
660
  th {
667
661
  font-weight: 600;
668
- color: ${theme.colors.neutral[700]};
662
+ color: ${(props) => props.theme.colors.neutral800};
669
663
  font-size: 0.875rem;
670
664
  text-transform: uppercase;
671
665
  letter-spacing: 0.025em;
@@ -675,14 +669,14 @@ const StyledTable = styled(Table)`
675
669
 
676
670
  tbody tr {
677
671
  transition: all ${theme.transitions.fast};
678
- border-bottom: 1px solid ${theme.colors.neutral[100]};
672
+ border-bottom: 1px solid ${(props) => props.theme.colors.neutral150};
679
673
 
680
674
  &:last-child {
681
675
  border-bottom: none;
682
676
  }
683
677
 
684
678
  &:hover {
685
- background: ${theme.colors.neutral[50]};
679
+ background: ${(props) => props.theme.colors.primary100};
686
680
 
687
681
  .action-buttons {
688
682
  opacity: 1;
@@ -691,7 +685,7 @@ const StyledTable = styled(Table)`
691
685
 
692
686
  td {
693
687
  padding: ${theme.spacing.lg} ${theme.spacing.lg};
694
- color: ${theme.colors.neutral[700]};
688
+ color: ${(props) => props.theme.colors.neutral800};
695
689
  vertical-align: middle;
696
690
  }
697
691
  }
@@ -700,18 +694,18 @@ const OnlineIndicator = styled.div`
700
694
  width: 10px;
701
695
  height: 10px;
702
696
  border-radius: 50%;
703
- background: ${(props) => props.$online ? theme.colors.success[500] : theme.colors.neutral[400]};
697
+ background: ${(props) => props.$online ? theme.colors.success[500] : props.theme.colors.neutral400};
704
698
  display: inline-block;
705
699
  margin-right: 8px;
706
700
  ${css`animation: ${(props) => props.$online ? pulse : "none"} 2s ease-in-out infinite;`}
707
701
  `;
708
702
  const FilterBar = styled(Flex)`
709
- background: ${theme.colors.neutral[0]};
703
+ background: ${(props) => props.theme.colors.neutral0};
710
704
  padding: ${theme.spacing.md} ${theme.spacing.lg};
711
705
  border-radius: ${theme.borderRadius.lg};
712
706
  margin-bottom: ${theme.spacing.lg};
713
707
  box-shadow: ${theme.shadows.sm};
714
- border: 1px solid ${theme.colors.neutral[200]};
708
+ border: 1px solid ${(props) => props.theme.colors.neutral200};
715
709
  gap: ${theme.spacing.md};
716
710
  align-items: center;
717
711
  `;
@@ -726,27 +720,27 @@ const SearchIcon = styled(Search)`
726
720
  left: 12px;
727
721
  width: 16px;
728
722
  height: 16px;
729
- color: ${theme.colors.neutral[600]};
723
+ color: ${(props) => props.theme.colors.neutral600};
730
724
  pointer-events: none;
731
725
  `;
732
726
  const StyledSearchInput = styled.input`
733
727
  width: 100%;
734
728
  padding: ${theme.spacing.sm} ${theme.spacing.sm} ${theme.spacing.sm} 36px;
735
- border: 1px solid ${theme.colors.neutral[200]};
729
+ border: 1px solid ${(props) => props.theme.colors.neutral200};
736
730
  border-radius: ${theme.borderRadius.md};
737
731
  font-size: 0.875rem;
738
732
  transition: all ${theme.transitions.fast};
739
- background: ${theme.colors.neutral[0]};
740
- color: ${theme.colors.neutral[800]};
733
+ background: ${(props) => props.theme.colors.neutral0};
734
+ color: ${(props) => props.theme.colors.neutral800};
741
735
 
742
736
  &:focus {
743
737
  outline: none;
744
- border-color: ${theme.colors.primary[500]};
745
- box-shadow: 0 0 0 3px ${theme.colors.primary[100]};
738
+ border-color: ${(props) => props.theme.colors.primary600};
739
+ box-shadow: 0 0 0 3px ${(props) => props.theme.colors.primary100};
746
740
  }
747
741
 
748
742
  &::placeholder {
749
- color: ${theme.colors.neutral[600]};
743
+ color: ${(props) => props.theme.colors.neutral500};
750
744
  }
751
745
  `;
752
746
  const ActionButtons = styled(Flex)`
@@ -759,13 +753,38 @@ const ClickableRow = styled(Tr)`
759
753
  cursor: pointer;
760
754
 
761
755
  &:hover {
762
- background: ${theme.colors.primary[50]} !important;
756
+ background: ${(props) => props.theme.colors.primary100} !important;
763
757
  }
764
758
  `;
759
+ styled(Box)`
760
+ background: ${(props) => props.theme.colors.neutral0};
761
+ border-radius: ${theme.borderRadius.xl};
762
+ border: 2px dashed ${(props) => props.theme.colors.neutral300};
763
+ padding: 80px 32px;
764
+ text-align: center;
765
+ position: relative;
766
+ overflow: hidden;
767
+ min-height: 400px;
768
+ display: flex;
769
+ align-items: center;
770
+ justify-content: center;
771
+ `;
772
+ styled.div`
773
+ position: absolute;
774
+ top: 0;
775
+ left: 0;
776
+ right: 0;
777
+ bottom: 0;
778
+ background: linear-gradient(135deg, ${theme.colors.primary[50]} 0%, ${theme.colors.secondary[50]} 100%);
779
+ opacity: 0.3;
780
+ z-index: 0;
781
+ `;
765
782
  const HomePage = () => {
783
+ const { formatMessage } = useIntl();
766
784
  const { get, post, del } = useFetchClient();
767
785
  const { toggleNotification } = useNotification();
768
786
  const { isPremium } = useLicense();
787
+ const t = (id, defaultMessage, values) => formatMessage({ id: getTranslation(id), defaultMessage }, values);
769
788
  const [sessions, setSessions] = useState([]);
770
789
  const [loading, setLoading] = useState(true);
771
790
  const [filterStatus, setFilterStatus] = useState("active");
@@ -794,7 +813,7 @@ const HomePage = () => {
794
813
  }
795
814
  };
796
815
  const handleTerminateSession = async (sessionId) => {
797
- if (!confirm("Are you sure you want to terminate this session?\n\nThis will set isActive to false (user will be logged out).")) {
816
+ if (!confirm(t("homepage.confirm.terminate", "Are you sure you want to terminate this session?\n\nThis will set isActive to false (user will be logged out)."))) {
798
817
  return;
799
818
  }
800
819
  try {
@@ -805,7 +824,7 @@ const HomePage = () => {
805
824
  }
806
825
  };
807
826
  const handleDeleteSession = async (sessionId) => {
808
- if (!confirm("[WARNING] This will PERMANENTLY delete this session from the database!\n\nThis action cannot be undone.\n\nAre you sure?")) {
827
+ if (!confirm(t("homepage.confirm.delete", "[WARNING] This will PERMANENTLY delete this session from the database!\n\nThis action cannot be undone.\n\nAre you sure?"))) {
809
828
  return;
810
829
  }
811
830
  try {
@@ -813,13 +832,13 @@ const HomePage = () => {
813
832
  fetchSessions();
814
833
  toggleNotification({
815
834
  type: "success",
816
- message: "Session permanently deleted"
835
+ message: t("notifications.success.deleted", "Session permanently deleted")
817
836
  });
818
837
  } catch (err) {
819
838
  console.error("[SessionManager] Error deleting session:", err);
820
839
  toggleNotification({
821
840
  type: "danger",
822
- message: "Failed to delete session"
841
+ message: t("notifications.error.delete", "Failed to delete session")
823
842
  });
824
843
  }
825
844
  };
@@ -827,7 +846,7 @@ const HomePage = () => {
827
846
  if (!isPremium) {
828
847
  toggleNotification({
829
848
  type: "warning",
830
- message: "Premium license required for export functionality"
849
+ message: t("notifications.warning.premiumRequired", "Premium license required for export functionality")
831
850
  });
832
851
  return;
833
852
  }
@@ -862,13 +881,13 @@ const HomePage = () => {
862
881
  link.click();
863
882
  toggleNotification({
864
883
  type: "success",
865
- message: `Exported ${filteredSessions.length} sessions to CSV`
884
+ message: t("notifications.success.exported", "Exported {count} sessions to {format}", { count: filteredSessions.length, format: "CSV" })
866
885
  });
867
886
  } catch (err) {
868
887
  console.error("[SessionManager] Export error:", err);
869
888
  toggleNotification({
870
889
  type: "danger",
871
- message: "Failed to export sessions"
890
+ message: t("notifications.error.export", "Failed to export sessions")
872
891
  });
873
892
  }
874
893
  };
@@ -876,7 +895,7 @@ const HomePage = () => {
876
895
  if (!isPremium) {
877
896
  toggleNotification({
878
897
  type: "warning",
879
- message: "Premium license required for export functionality"
898
+ message: t("notifications.warning.premiumRequired", "Premium license required for export functionality")
880
899
  });
881
900
  return;
882
901
  }
@@ -919,13 +938,13 @@ const HomePage = () => {
919
938
  link.click();
920
939
  toggleNotification({
921
940
  type: "success",
922
- message: `Exported ${filteredSessions.length} sessions to JSON`
941
+ message: t("notifications.success.exported", "Exported {count} sessions to {format}", { count: filteredSessions.length, format: "JSON" })
923
942
  });
924
943
  } catch (err) {
925
944
  console.error("[SessionManager] Export error:", err);
926
945
  toggleNotification({
927
946
  type: "danger",
928
- message: "Failed to export sessions"
947
+ message: t("notifications.error.export", "Failed to export sessions")
929
948
  });
930
949
  }
931
950
  };
@@ -976,9 +995,10 @@ const HomePage = () => {
976
995
  /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", gap: 2, children: [
977
996
  /* @__PURE__ */ jsxs(Title, { children: [
978
997
  /* @__PURE__ */ jsx(Monitor, {}),
979
- " Session Manager"
998
+ " ",
999
+ t("homepage.title", "Session Manager")
980
1000
  ] }),
981
- /* @__PURE__ */ jsx(Subtitle, { children: "Monitor and manage user sessions in real-time" })
1001
+ /* @__PURE__ */ jsx(Subtitle, { children: t("homepage.subtitle", "Monitor and manage user sessions in real-time") })
982
1002
  ] }),
983
1003
  isPremium && filteredSessions.length > 0 && /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
984
1004
  /* @__PURE__ */ jsx(
@@ -994,7 +1014,7 @@ const HomePage = () => {
994
1014
  border: "1px solid rgba(255,255,255,0.3)",
995
1015
  fontWeight: "600"
996
1016
  },
997
- children: "Export CSV"
1017
+ children: t("homepage.export.csv", "Export CSV")
998
1018
  }
999
1019
  ),
1000
1020
  /* @__PURE__ */ jsx(
@@ -1010,7 +1030,7 @@ const HomePage = () => {
1010
1030
  border: "1px solid rgba(255,255,255,0.3)",
1011
1031
  fontWeight: "600"
1012
1032
  },
1013
- children: "Export JSON"
1033
+ children: t("homepage.export.json", "Export JSON")
1014
1034
  }
1015
1035
  )
1016
1036
  ] })
@@ -1019,32 +1039,32 @@ const HomePage = () => {
1019
1039
  /* @__PURE__ */ jsxs(StatCard, { $delay: "0.1s", $color: theme.colors.success[500], children: [
1020
1040
  /* @__PURE__ */ jsx(StatIcon, { className: "stat-icon", $bg: theme.colors.success[100], $color: theme.colors.success[600], children: /* @__PURE__ */ jsx(Check, {}) }),
1021
1041
  /* @__PURE__ */ jsx(StatValue, { className: "stat-value", children: activeSessions.length }),
1022
- /* @__PURE__ */ jsx(StatLabel, { children: "Active" })
1042
+ /* @__PURE__ */ jsx(StatLabel, { children: t("homepage.stats.active", "Active") })
1023
1043
  ] }),
1024
1044
  /* @__PURE__ */ jsxs(StatCard, { $delay: "0.2s", $color: theme.colors.warning[500], children: [
1025
1045
  /* @__PURE__ */ jsx(StatIcon, { className: "stat-icon", $bg: theme.colors.warning[100], $color: theme.colors.warning[600], children: /* @__PURE__ */ jsx(Clock, {}) }),
1026
1046
  /* @__PURE__ */ jsx(StatValue, { className: "stat-value", children: idleSessions.length }),
1027
- /* @__PURE__ */ jsx(StatLabel, { children: "Idle" })
1047
+ /* @__PURE__ */ jsx(StatLabel, { children: t("homepage.stats.idle", "Idle") })
1028
1048
  ] }),
1029
1049
  /* @__PURE__ */ jsxs(StatCard, { $delay: "0.3s", $color: theme.colors.danger[500], children: [
1030
1050
  /* @__PURE__ */ jsx(StatIcon, { className: "stat-icon", $bg: theme.colors.danger[100], $color: theme.colors.danger[600], children: /* @__PURE__ */ jsx(Cross, {}) }),
1031
1051
  /* @__PURE__ */ jsx(StatValue, { className: "stat-value", children: loggedOutSessions.length }),
1032
- /* @__PURE__ */ jsx(StatLabel, { children: "Logged Out" })
1052
+ /* @__PURE__ */ jsx(StatLabel, { children: t("homepage.stats.loggedOut", "Logged Out") })
1033
1053
  ] }),
1034
- /* @__PURE__ */ jsxs(StatCard, { $delay: "0.4s", $color: theme.colors.neutral[600], children: [
1035
- /* @__PURE__ */ jsx(StatIcon, { className: "stat-icon", $bg: theme.colors.neutral[100], $color: theme.colors.neutral[600], children: /* @__PURE__ */ jsx(Cross, {}) }),
1054
+ /* @__PURE__ */ jsxs(StatCard, { $delay: "0.4s", $color: "#4B5563", children: [
1055
+ /* @__PURE__ */ jsx(StatIcon, { className: "stat-icon", $bg: "#F3F4F6", $color: "#4B5563", children: /* @__PURE__ */ jsx(Cross, {}) }),
1036
1056
  /* @__PURE__ */ jsx(StatValue, { className: "stat-value", children: terminatedSessions.length }),
1037
- /* @__PURE__ */ jsx(StatLabel, { children: "Terminated" })
1057
+ /* @__PURE__ */ jsx(StatLabel, { children: t("homepage.stats.terminated", "Terminated") })
1038
1058
  ] }),
1039
- /* @__PURE__ */ jsxs(StatCard, { $delay: "0.5s", $color: theme.colors.secondary[500], children: [
1040
- /* @__PURE__ */ jsx(StatIcon, { className: "stat-icon", $bg: theme.colors.secondary[100], $color: theme.colors.secondary[600], children: /* @__PURE__ */ jsx(User, {}) }),
1059
+ /* @__PURE__ */ jsxs(StatCard, { $delay: "0.5s", $color: "#A855F7", children: [
1060
+ /* @__PURE__ */ jsx(StatIcon, { className: "stat-icon", $bg: "#EDE9FE", $color: "#9333EA", children: /* @__PURE__ */ jsx(User, {}) }),
1041
1061
  /* @__PURE__ */ jsx(StatValue, { className: "stat-value", children: sessions.length }),
1042
- /* @__PURE__ */ jsx(StatLabel, { children: "Total" })
1062
+ /* @__PURE__ */ jsx(StatLabel, { children: t("homepage.stats.total", "Total") })
1043
1063
  ] })
1044
1064
  ] }),
1045
- loading && /* @__PURE__ */ jsx(Flex, { justifyContent: "center", padding: 8, children: /* @__PURE__ */ jsx(Loader, { children: "Loading sessions..." }) }),
1065
+ loading && /* @__PURE__ */ jsx(Flex, { justifyContent: "center", padding: 8, children: /* @__PURE__ */ jsx(Loader, { children: t("homepage.loading", "Loading sessions...") }) }),
1046
1066
  !loading && sessions.length > 0 && /* @__PURE__ */ jsxs(Box, { children: [
1047
- /* @__PURE__ */ jsx(Box, { style: { marginBottom: theme.spacing.md }, children: /* @__PURE__ */ jsx(Typography, { variant: "delta", style: { marginBottom: theme.spacing.md, color: theme.colors.neutral[700] }, children: "All Sessions" }) }),
1067
+ /* @__PURE__ */ jsx(Box, { style: { marginBottom: theme.spacing.md }, children: /* @__PURE__ */ jsx(Typography, { variant: "delta", textColor: "neutral700", style: { marginBottom: theme.spacing.md }, children: t("homepage.allSessions", "All Sessions") }) }),
1048
1068
  /* @__PURE__ */ jsxs(FilterBar, { children: [
1049
1069
  /* @__PURE__ */ jsxs(SearchInputWrapper, { children: [
1050
1070
  /* @__PURE__ */ jsx(SearchIcon, {}),
@@ -1053,7 +1073,7 @@ const HomePage = () => {
1053
1073
  {
1054
1074
  value: searchQuery,
1055
1075
  onChange: (e) => setSearchQuery(e.target.value),
1056
- placeholder: "Search by user, IP address, or device...",
1076
+ placeholder: t("homepage.search.placeholder", "Search by user, IP address, or device..."),
1057
1077
  type: "text"
1058
1078
  }
1059
1079
  )
@@ -1066,11 +1086,11 @@ const HomePage = () => {
1066
1086
  placeholder: "Filter",
1067
1087
  size: "S",
1068
1088
  children: [
1069
- /* @__PURE__ */ jsx(SingleSelectOption, { value: "all", children: "All Sessions" }),
1070
- /* @__PURE__ */ jsx(SingleSelectOption, { value: "active", children: "Active (less than 15 min)" }),
1071
- /* @__PURE__ */ jsx(SingleSelectOption, { value: "idle", children: "Idle (more than 15 min)" }),
1072
- /* @__PURE__ */ jsx(SingleSelectOption, { value: "loggedout", children: "Logged Out" }),
1073
- /* @__PURE__ */ jsx(SingleSelectOption, { value: "terminated", children: "Terminated" })
1089
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "all", children: t("homepage.filter.all", "All Sessions") }),
1090
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "active", children: t("homepage.filter.active", "Active (less than 15 min)") }),
1091
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "idle", children: t("homepage.filter.idle", "Idle (more than 15 min)") }),
1092
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "loggedout", children: t("homepage.filter.loggedout", "Logged Out") }),
1093
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "terminated", children: t("homepage.filter.terminated", "Terminated") })
1074
1094
  ]
1075
1095
  }
1076
1096
  ) }),
@@ -1082,31 +1102,24 @@ const HomePage = () => {
1082
1102
  placeholder: "Entries",
1083
1103
  size: "S",
1084
1104
  children: [
1085
- /* @__PURE__ */ jsx(SingleSelectOption, { value: "10", children: "10 entries" }),
1086
- /* @__PURE__ */ jsx(SingleSelectOption, { value: "25", children: "25 entries" }),
1087
- /* @__PURE__ */ jsx(SingleSelectOption, { value: "50", children: "50 entries" }),
1088
- /* @__PURE__ */ jsx(SingleSelectOption, { value: "100", children: "100 entries" })
1105
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "10", children: t("homepage.entries.10", "10 entries") }),
1106
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "25", children: t("homepage.entries.25", "25 entries") }),
1107
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "50", children: t("homepage.entries.50", "50 entries") }),
1108
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "100", children: t("homepage.entries.100", "100 entries") })
1089
1109
  ]
1090
1110
  }
1091
1111
  ) })
1092
1112
  ] }),
1093
- /* @__PURE__ */ jsx(Box, { style: { marginBottom: theme.spacing.md }, children: /* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "neutral600", children: [
1094
- "Showing ",
1095
- filteredSessions.length,
1096
- " of ",
1097
- sessions.length,
1098
- " sessions",
1099
- searchQuery && ` (filtered by "${searchQuery}")`
1100
- ] }) }),
1113
+ /* @__PURE__ */ jsx(Box, { style: { marginBottom: theme.spacing.md }, children: /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: searchQuery ? t("homepage.showingFiltered", 'Showing {count} of {total} sessions (filtered by "{query}")', { count: filteredSessions.length, total: sessions.length, query: searchQuery }) : t("homepage.showing", "Showing {count} of {total} sessions", { count: filteredSessions.length, total: sessions.length }) }) }),
1101
1114
  filteredSessions.length > 0 ? /* @__PURE__ */ jsx(DataTable, { children: /* @__PURE__ */ jsxs(StyledTable, { children: [
1102
1115
  /* @__PURE__ */ jsx(Thead, { children: /* @__PURE__ */ jsxs(Tr, { children: [
1103
- /* @__PURE__ */ jsx(Th, { children: "Status" }),
1104
- /* @__PURE__ */ jsx(Th, { children: "User" }),
1105
- /* @__PURE__ */ jsx(Th, { children: "Device" }),
1106
- /* @__PURE__ */ jsx(Th, { children: "IP Address" }),
1107
- /* @__PURE__ */ jsx(Th, { children: "Login Time" }),
1108
- /* @__PURE__ */ jsx(Th, { children: "Last Active" }),
1109
- /* @__PURE__ */ jsx(Th, { children: "Actions" })
1116
+ /* @__PURE__ */ jsx(Th, { children: t("homepage.table.status", "Status") }),
1117
+ /* @__PURE__ */ jsx(Th, { children: t("homepage.table.user", "User") }),
1118
+ /* @__PURE__ */ jsx(Th, { children: t("homepage.table.device", "Device") }),
1119
+ /* @__PURE__ */ jsx(Th, { children: t("homepage.table.ipAddress", "IP Address") }),
1120
+ /* @__PURE__ */ jsx(Th, { children: t("homepage.table.loginTime", "Login Time") }),
1121
+ /* @__PURE__ */ jsx(Th, { children: t("homepage.table.lastActive", "Last Active") }),
1122
+ /* @__PURE__ */ jsx(Th, { children: t("homepage.table.actions", "Actions") })
1110
1123
  ] }) }),
1111
1124
  /* @__PURE__ */ jsx(Tbody, { children: filteredSessions.map((session) => {
1112
1125
  const deviceInfo = parseUserAgent(session.userAgent);
@@ -1116,26 +1129,26 @@ const HomePage = () => {
1116
1129
  active: {
1117
1130
  bg: theme.colors.success[50],
1118
1131
  badgeColor: "success600",
1119
- label: "Active",
1132
+ label: t("homepage.status.active", "Active"),
1120
1133
  indicator: true
1121
1134
  },
1122
1135
  idle: {
1123
1136
  bg: theme.colors.warning[50],
1124
1137
  badgeColor: "warning600",
1125
- label: "Idle",
1138
+ label: t("homepage.status.idle", "Idle"),
1126
1139
  indicator: false
1127
1140
  },
1128
1141
  loggedout: {
1129
1142
  bg: theme.colors.danger[50],
1130
1143
  badgeColor: "danger600",
1131
- label: "Logged Out",
1144
+ label: t("homepage.status.loggedOut", "Logged Out"),
1132
1145
  indicator: false,
1133
1146
  opacity: 0.7
1134
1147
  },
1135
1148
  terminated: {
1136
- bg: theme.colors.neutral[100],
1149
+ bg: "#F3F4F6",
1137
1150
  badgeColor: "neutral600",
1138
- label: "Terminated",
1151
+ label: t("homepage.status.terminated", "Terminated"),
1139
1152
  indicator: false,
1140
1153
  opacity: 0.6
1141
1154
  }
@@ -1163,7 +1176,7 @@ const HomePage = () => {
1163
1176
  )
1164
1177
  ] }) }),
1165
1178
  /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", children: [
1166
- /* @__PURE__ */ jsx(Typography, { fontWeight: "semiBold", ellipsis: true, children: session.user?.username || session.user?.email || "Unknown" }),
1179
+ /* @__PURE__ */ jsx(Typography, { fontWeight: "semiBold", ellipsis: true, children: session.user?.username || session.user?.email || t("homepage.user.unknown", "Unknown") }),
1167
1180
  session.user?.email && session.user?.username && /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", ellipsis: true, children: session.user.email })
1168
1181
  ] }) }),
1169
1182
  /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsxs(Flex, { alignItems: "center", gap: 2, children: [
@@ -1181,10 +1194,7 @@ const HomePage = () => {
1181
1194
  /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral700", children: new Date(session.loginTime).toLocaleString() }) }),
1182
1195
  /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", children: [
1183
1196
  /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral700", children: new Date(session.lastActive || session.loginTime).toLocaleString() }),
1184
- /* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: sessionStatus === "active" ? "success600" : "neutral500", children: [
1185
- session.minutesSinceActive,
1186
- " min ago"
1187
- ] })
1197
+ /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: sessionStatus === "active" ? "success600" : "neutral500", children: t("homepage.time.minAgo", "{minutes} min ago", { minutes: session.minutesSinceActive }) })
1188
1198
  ] }) }),
1189
1199
  /* @__PURE__ */ jsx(Td, { onClick: (e) => e.stopPropagation(), children: /* @__PURE__ */ jsxs(ActionButtons, { className: "action-buttons", children: [
1190
1200
  /* @__PURE__ */ jsx(
@@ -1196,7 +1206,7 @@ const HomePage = () => {
1196
1206
  e.stopPropagation();
1197
1207
  handleSessionClick(session);
1198
1208
  },
1199
- title: "View Details",
1209
+ title: t("homepage.actions.viewDetails", "View Details"),
1200
1210
  children: /* @__PURE__ */ jsx(Eye, {})
1201
1211
  }
1202
1212
  ),
@@ -1210,7 +1220,7 @@ const HomePage = () => {
1210
1220
  handleTerminateSession(session.id);
1211
1221
  },
1212
1222
  disabled: sessionStatus !== "active" && sessionStatus !== "idle",
1213
- title: session.isActive ? "Terminate (Logout)" : "Already inactive",
1223
+ title: session.isActive ? t("homepage.actions.terminate", "Terminate (Logout)") : t("homepage.actions.alreadyInactive", "Already inactive"),
1214
1224
  children: /* @__PURE__ */ jsx(Cross, {})
1215
1225
  }
1216
1226
  ),
@@ -1223,7 +1233,7 @@ const HomePage = () => {
1223
1233
  e.stopPropagation();
1224
1234
  handleDeleteSession(session.id);
1225
1235
  },
1226
- title: "Delete Permanently",
1236
+ title: t("homepage.actions.deletePermanently", "Delete Permanently"),
1227
1237
  children: /* @__PURE__ */ jsx(Trash, {})
1228
1238
  }
1229
1239
  )
@@ -1238,10 +1248,10 @@ const HomePage = () => {
1238
1248
  /* @__PURE__ */ jsxs(
1239
1249
  Box,
1240
1250
  {
1251
+ background: "neutral0",
1241
1252
  style: {
1242
- background: theme.colors.neutral[0],
1243
1253
  borderRadius: theme.borderRadius.xl,
1244
- border: `2px dashed ${theme.colors.neutral[200]}`,
1254
+ border: "2px dashed #E5E7EB",
1245
1255
  padding: "60px 32px",
1246
1256
  textAlign: "center",
1247
1257
  position: "relative",
@@ -1282,20 +1292,20 @@ const HomePage = () => {
1282
1292
  justifyContent: "center",
1283
1293
  boxShadow: theme.shadows.xl
1284
1294
  },
1285
- children: /* @__PURE__ */ jsx(Search, { style: { width: "50px", height: "50px", color: theme.colors.primary[600] } })
1295
+ children: /* @__PURE__ */ jsx(Search, { style: { width: "50px", height: "50px", color: "#0284C7" } })
1286
1296
  }
1287
1297
  ),
1288
1298
  /* @__PURE__ */ jsx(
1289
1299
  Typography,
1290
1300
  {
1291
1301
  variant: "alpha",
1302
+ textColor: "neutral800",
1292
1303
  style: {
1293
1304
  fontSize: "1.5rem",
1294
1305
  fontWeight: "700",
1295
- color: theme.colors.neutral[800],
1296
1306
  marginBottom: "4px"
1297
1307
  },
1298
- children: "No sessions found"
1308
+ children: t("homepage.noResults.title", "No sessions found")
1299
1309
  }
1300
1310
  ),
1301
1311
  /* @__PURE__ */ jsx(
@@ -1308,7 +1318,7 @@ const HomePage = () => {
1308
1318
  maxWidth: "400px",
1309
1319
  lineHeight: "1.6"
1310
1320
  },
1311
- children: "Try adjusting your search query or filters to find sessions"
1321
+ children: t("homepage.noResults.description", "Try adjusting your search query or filters to find sessions")
1312
1322
  }
1313
1323
  )
1314
1324
  ] })
@@ -1320,10 +1330,10 @@ const HomePage = () => {
1320
1330
  !loading && sessions.length === 0 && /* @__PURE__ */ jsxs(
1321
1331
  Box,
1322
1332
  {
1333
+ background: "neutral0",
1323
1334
  style: {
1324
- background: theme.colors.neutral[0],
1325
1335
  borderRadius: theme.borderRadius.xl,
1326
- border: `2px dashed ${theme.colors.neutral[200]}`,
1336
+ border: "2px dashed #E5E7EB",
1327
1337
  padding: "80px 32px",
1328
1338
  textAlign: "center",
1329
1339
  position: "relative",
@@ -1363,20 +1373,20 @@ const HomePage = () => {
1363
1373
  justifyContent: "center",
1364
1374
  boxShadow: theme.shadows.xl
1365
1375
  },
1366
- children: /* @__PURE__ */ jsx(Monitor, { style: { width: "60px", height: "60px", color: theme.colors.primary[600] } })
1376
+ children: /* @__PURE__ */ jsx(Monitor, { style: { width: "60px", height: "60px", color: "#0284C7" } })
1367
1377
  }
1368
1378
  ),
1369
1379
  /* @__PURE__ */ jsx(
1370
1380
  Typography,
1371
1381
  {
1372
1382
  variant: "alpha",
1383
+ textColor: "neutral800",
1373
1384
  style: {
1374
1385
  fontSize: "1.75rem",
1375
1386
  fontWeight: "700",
1376
- color: theme.colors.neutral[800],
1377
1387
  marginBottom: "8px"
1378
1388
  },
1379
- children: "No sessions yet"
1389
+ children: t("homepage.empty.title", "No sessions yet")
1380
1390
  }
1381
1391
  ),
1382
1392
  /* @__PURE__ */ jsx(
@@ -1389,7 +1399,7 @@ const HomePage = () => {
1389
1399
  maxWidth: "500px",
1390
1400
  lineHeight: "1.6"
1391
1401
  },
1392
- children: "Sessions will appear here when users log in to your application"
1402
+ children: t("homepage.empty.description", "Sessions will appear here when users log in to your application")
1393
1403
  }
1394
1404
  )
1395
1405
  ] })