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,174 @@
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 icons = require("@strapi/icons");
7
+ const admin = require("@strapi/strapi/admin");
8
+ const OnlineUsersWidget = () => {
9
+ const { get } = admin.useFetchClient();
10
+ const [stats, setStats] = react.useState({
11
+ onlineNow: 0,
12
+ offline: 0,
13
+ last15min: 0,
14
+ last30min: 0,
15
+ totalUsers: 0,
16
+ blocked: 0
17
+ });
18
+ const [loading, setLoading] = react.useState(true);
19
+ const fetchStats = react.useCallback(async () => {
20
+ try {
21
+ const { data } = await get("/magic-sessionmanager/sessions");
22
+ const sessions = data.data || [];
23
+ const now = Date.now();
24
+ const fifteenMin = 15 * 60 * 1e3;
25
+ const thirtyMin = 30 * 60 * 1e3;
26
+ const onlineNow = /* @__PURE__ */ new Set();
27
+ const last15min = /* @__PURE__ */ new Set();
28
+ const last30min = /* @__PURE__ */ new Set();
29
+ sessions.forEach((session) => {
30
+ const userId = session.user?.id;
31
+ if (!userId) return;
32
+ const lastActive = session.lastActive ? new Date(session.lastActive) : new Date(session.loginTime);
33
+ const timeSinceActive = now - lastActive.getTime();
34
+ if (timeSinceActive < fifteenMin) {
35
+ onlineNow.add(userId);
36
+ last15min.add(userId);
37
+ last30min.add(userId);
38
+ } else if (timeSinceActive < thirtyMin) {
39
+ last15min.add(userId);
40
+ last30min.add(userId);
41
+ }
42
+ });
43
+ try {
44
+ const { data: usersData } = await get("/content-manager/collection-types/plugin::users-permissions.user?pageSize=1");
45
+ const totalUsers = usersData?.pagination?.total || 0;
46
+ const { data: blockedData } = await get("/content-manager/collection-types/plugin::users-permissions.user?filters[$and][0][blocked][$eq]=true&pageSize=1");
47
+ const blockedUsers = blockedData?.pagination?.total || 0;
48
+ setStats({
49
+ onlineNow: onlineNow.size,
50
+ last15min: last15min.size,
51
+ last30min: last30min.size,
52
+ offline: totalUsers - onlineNow.size,
53
+ totalUsers,
54
+ blocked: blockedUsers
55
+ });
56
+ } catch (err) {
57
+ console.error("[OnlineUsersWidget] Error fetching user count:", err);
58
+ setStats({
59
+ onlineNow: onlineNow.size,
60
+ last15min: last15min.size,
61
+ last30min: last30min.size,
62
+ offline: 0,
63
+ totalUsers: onlineNow.size,
64
+ blocked: 0
65
+ });
66
+ }
67
+ } catch (err) {
68
+ console.error("[OnlineUsersWidget] Error:", err);
69
+ } finally {
70
+ setLoading(false);
71
+ }
72
+ }, [get]);
73
+ react.useEffect(() => {
74
+ fetchStats();
75
+ const interval = setInterval(fetchStats, 3e4);
76
+ return () => clearInterval(interval);
77
+ }, [fetchStats]);
78
+ const StatCard = ({ icon: Icon, label, value, color }) => /* @__PURE__ */ jsxRuntime.jsx(
79
+ designSystem.Box,
80
+ {
81
+ as: "a",
82
+ padding: 4,
83
+ background: "neutral0",
84
+ hasRadius: true,
85
+ shadow: "tableShadow",
86
+ style: {
87
+ textDecoration: "none",
88
+ cursor: "default",
89
+ transition: "box-shadow 0.2s",
90
+ border: "1px solid #f0f0ff"
91
+ },
92
+ children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "space-between", alignItems: "flex-start", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 3, alignItems: "center", children: [
93
+ /* @__PURE__ */ jsxRuntime.jsx(
94
+ designSystem.Box,
95
+ {
96
+ padding: 2,
97
+ background: `${color}100`,
98
+ hasRadius: true,
99
+ style: {
100
+ display: "flex",
101
+ alignItems: "center",
102
+ justifyContent: "center"
103
+ },
104
+ children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { width: "16px", height: "16px", fill: `${color}600` })
105
+ }
106
+ ),
107
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 1, alignItems: "flex-start", children: [
108
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: label }),
109
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "delta", fontWeight: "bold", textColor: "neutral800", children: value })
110
+ ] })
111
+ ] }) })
112
+ }
113
+ );
114
+ if (loading) {
115
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 4, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: "Loading..." }) });
116
+ }
117
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 0, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "column", gap: 3, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Grid.Root, { gap: 3, gridCols: 2, children: [
118
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 1, children: /* @__PURE__ */ jsxRuntime.jsx(
119
+ StatCard,
120
+ {
121
+ icon: icons.Check,
122
+ label: "Online Now",
123
+ value: stats.onlineNow,
124
+ color: "success"
125
+ }
126
+ ) }),
127
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 1, children: /* @__PURE__ */ jsxRuntime.jsx(
128
+ StatCard,
129
+ {
130
+ icon: icons.Cross,
131
+ label: "Offline",
132
+ value: stats.offline,
133
+ color: "neutral"
134
+ }
135
+ ) }),
136
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 1, children: /* @__PURE__ */ jsxRuntime.jsx(
137
+ StatCard,
138
+ {
139
+ icon: icons.Clock,
140
+ label: "Last 15 min",
141
+ value: stats.last15min,
142
+ color: "primary"
143
+ }
144
+ ) }),
145
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 1, children: /* @__PURE__ */ jsxRuntime.jsx(
146
+ StatCard,
147
+ {
148
+ icon: icons.Clock,
149
+ label: "Last 30 min",
150
+ value: stats.last30min,
151
+ color: "secondary"
152
+ }
153
+ ) }),
154
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 1, children: /* @__PURE__ */ jsxRuntime.jsx(
155
+ StatCard,
156
+ {
157
+ icon: icons.User,
158
+ label: "Total Users",
159
+ value: stats.totalUsers,
160
+ color: "neutral"
161
+ }
162
+ ) }),
163
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 1, children: /* @__PURE__ */ jsxRuntime.jsx(
164
+ StatCard,
165
+ {
166
+ icon: icons.Cross,
167
+ label: "Blocked",
168
+ value: stats.blocked,
169
+ color: "danger"
170
+ }
171
+ ) })
172
+ ] }) }) });
173
+ };
174
+ exports.default = OnlineUsersWidget;