@zumito-team/analytics-module 0.6.0 → 0.8.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.
Files changed (31) hide show
  1. package/dist/events/discord/MessageCreate.js +1 -1
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.js +34 -4
  4. package/dist/models/ChannelMessageStats.d.ts +8 -0
  5. package/dist/models/ChannelMessageStats.js +31 -0
  6. package/dist/routes/AdminAnalytics.d.ts +1 -3
  7. package/dist/routes/AdminAnalytics.js +2 -23
  8. package/dist/routes/AdminAnalyticsCommands.d.ts +7 -0
  9. package/dist/routes/AdminAnalyticsCommands.js +34 -0
  10. package/dist/routes/AdminAnalyticsGrowth.d.ts +7 -0
  11. package/dist/routes/AdminAnalyticsGrowth.js +34 -0
  12. package/dist/routes/AdminAnalyticsMessages.d.ts +7 -0
  13. package/dist/routes/AdminAnalyticsMessages.js +32 -0
  14. package/dist/routes/UserPanelAnalytics.js +1 -17
  15. package/dist/routes/UserPanelAnalyticsCommands.d.ts +8 -0
  16. package/dist/routes/UserPanelAnalyticsCommands.js +48 -0
  17. package/dist/routes/UserPanelAnalyticsMessages.d.ts +8 -0
  18. package/dist/routes/UserPanelAnalyticsMessages.js +52 -0
  19. package/dist/routes/UserPanelAnalyticsVoice.d.ts +8 -0
  20. package/dist/routes/UserPanelAnalyticsVoice.js +53 -0
  21. package/dist/services/AnalyticsCollector.d.ts +5 -1
  22. package/dist/services/AnalyticsCollector.js +61 -3
  23. package/dist/views/admin-analytics-commands.ejs +55 -0
  24. package/dist/views/admin-analytics-growth.ejs +46 -0
  25. package/dist/views/admin-analytics-messages.ejs +30 -0
  26. package/dist/views/admin-analytics.ejs +38 -132
  27. package/dist/views/user-analytics-commands.ejs +55 -0
  28. package/dist/views/user-analytics-messages.ejs +47 -0
  29. package/dist/views/user-analytics-voice.ejs +47 -0
  30. package/dist/views/user-analytics.ejs +25 -166
  31. package/package.json +1 -1
@@ -1,37 +1,28 @@
1
1
  <div class="p-4">
2
- <div class="flex items-center justify-between mb-6">
2
+ <div class="mb-6">
3
3
  <h1 class="text-2xl font-bold text-discord-foreground"><%= t('analytics.serverStats') %></h1>
4
- <div class="flex gap-2">
5
- <button data-days="7" class="date-btn btn-primary text-sm px-3 py-1 rounded"><%= t('analytics.last7days') %></button>
6
- <button data-days="30" class="date-btn text-sm px-3 py-1 rounded bg-discord-dark-100 text-discord-foreground/70 hover:text-discord-foreground"><%= t('analytics.last30days') %></button>
7
- <button data-days="90" class="date-btn text-sm px-3 py-1 rounded bg-discord-dark-100 text-discord-foreground/70 hover:text-discord-foreground"><%= t('analytics.last90days') %></button>
8
- </div>
9
4
  </div>
10
5
 
11
- <div class="grid grid-cols-2 md:grid-cols-5 gap-4 mb-6">
6
+ <div class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-6">
12
7
  <div class="card text-center">
13
- <div class="text-2xl font-bold text-discord-foreground"><%= guildSummary.totalMessages %></div>
8
+ <div class="text-2xl font-bold text-discord-primary"><%= guildSummary.totalMessages %></div>
14
9
  <div class="text-xs text-discord-foreground/60 mt-1"><%= t('analytics.messages') %></div>
15
10
  </div>
16
11
  <div class="card text-center">
17
- <div class="text-2xl font-bold text-discord-foreground"><%= guildSummary.totalCommands %></div>
12
+ <div class="text-2xl font-bold text-discord-success"><%= guildSummary.totalCommands %></div>
18
13
  <div class="text-xs text-discord-foreground/60 mt-1"><%= t('analytics.commands') %></div>
19
14
  </div>
20
- <div class="card text-center">
21
- <div class="text-2xl font-bold text-discord-foreground"><%= guildSummary.totalJoins %></div>
22
- <div class="text-xs text-discord-foreground/60 mt-1"><%= t('analytics.joins') %></div>
23
- </div>
24
- <div class="card text-center">
25
- <div class="text-2xl font-bold text-discord-foreground"><%= guildSummary.totalLeaves %></div>
26
- <div class="text-xs text-discord-foreground/60 mt-1"><%= t('analytics.leaves') %></div>
27
- </div>
28
15
  <div class="card text-center">
29
16
  <div class="text-2xl font-bold text-discord-foreground"><%= Math.round(guildSummary.totalVoiceMinutes) %></div>
30
17
  <div class="text-xs text-discord-foreground/60 mt-1"><%= t('analytics.voice') %> (min)</div>
31
18
  </div>
19
+ <div class="card text-center">
20
+ <div class="text-2xl font-bold"><span class="text-discord-success"><%= guildSummary.totalJoins %></span> / <span class="text-discord-danger"><%= guildSummary.totalLeaves %></span></div>
21
+ <div class="text-xs text-discord-foreground/60 mt-1"><%= t('analytics.joins') %> / <%= t('analytics.leaves') %></div>
22
+ </div>
32
23
  </div>
33
24
 
34
- <div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-6">
25
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
35
26
  <div class="card">
36
27
  <h3 class="text-lg font-semibold mb-4 text-discord-foreground"><%= t('analytics.messagesPerDay') %></h3>
37
28
  <canvas id="chartMessages" width="400" height="200"></canvas>
@@ -40,170 +31,38 @@
40
31
  <h3 class="text-lg font-semibold mb-4 text-discord-foreground"><%= t('analytics.joinsVsLeaves') %></h3>
41
32
  <canvas id="chartMembers" width="400" height="200"></canvas>
42
33
  </div>
43
- <div class="card">
44
- <h3 class="text-lg font-semibold mb-4 text-discord-foreground"><%= t('analytics.voiceActivity') %></h3>
45
- <canvas id="chartVoice" width="400" height="200"></canvas>
46
- </div>
47
- <div class="card">
48
- <h3 class="text-lg font-semibold mb-4 text-discord-foreground"><%= t('analytics.commandsPerDay') %></h3>
49
- <canvas id="chartCommands" width="400" height="200"></canvas>
50
- </div>
51
- </div>
52
-
53
- <div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-6">
54
- <div class="card">
55
- <h3 class="text-lg font-semibold mb-4 text-discord-foreground"><%= t('analytics.topCommands') %></h3>
56
- <canvas id="chartTopCommands" width="400" height="200"></canvas>
57
- </div>
58
- <% if (typeof slowestCommands !== 'undefined' && slowestCommands.length > 0) { %>
59
- <div class="card">
60
- <h3 class="text-lg font-semibold mb-4 text-discord-foreground"><%= t('analytics.slowestCommands') %></h3>
61
- <canvas id="chartSlowestCommands" width="400" height="200"></canvas>
62
- </div>
63
- <% } %>
64
34
  </div>
65
-
66
- <% if (typeof channelVoice !== 'undefined' && channelVoice.length > 0) { %>
67
- <div class="card mb-6">
68
- <h3 class="text-lg font-semibold mb-4 text-discord-foreground"><%= t('analytics.perChannelVoice') %></h3>
69
- <canvas id="chartChannelVoice" width="600" height="200"></canvas>
70
- </div>
71
- <% } %>
72
35
  </div>
73
36
 
74
37
  <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
75
38
  <script>
76
39
  (function() {
77
- const colors = {
78
- primary: '#5865f2',
79
- success: '#57f287',
80
- warning: '#fee75c',
81
- danger: '#ed4245',
82
- foreground: '#ffffff',
83
- foreground60: 'rgba(255,255,255,0.6)',
84
- dark100: '#36393f',
85
- dark200: '#2f3136',
86
- };
87
-
88
- Chart.defaults.color = colors.foreground60;
89
- Chart.defaults.borderColor = colors.dark100;
90
- Chart.defaults.plugins.legend.labels.color = colors.foreground60;
40
+ Chart.defaults.color = 'rgba(255,255,255,0.6)';
41
+ Chart.defaults.borderColor = '#36393f';
91
42
 
92
- const data = <%- JSON.stringify(chartData) %>;
43
+ const messages = <%- JSON.stringify(messagesPerDay) %>;
44
+ const joins = <%- JSON.stringify(joinsPerDay) %>;
45
+ const leaves = <%- JSON.stringify(leavesPerDay) %>;
93
46
 
94
- function createBarChart(canvasId, label, values, keyX, keyY) {
95
- new Chart(document.getElementById(canvasId), {
96
- type: 'bar',
97
- data: {
98
- labels: values.map(v => v[keyX]),
99
- datasets: [{
100
- label: label,
101
- data: values.map(v => v[keyY]),
102
- backgroundColor: colors.primary,
103
- borderRadius: 4,
104
- }]
105
- },
106
- options: { responsive: true, plugins: { legend: { display: false } } }
107
- });
108
- }
109
-
110
- function createHorizontalBarChart(canvasId, label, values, keyX, keyY) {
111
- new Chart(document.getElementById(canvasId), {
112
- type: 'bar',
113
- data: {
114
- labels: values.map(v => v[keyX]),
115
- datasets: [{
116
- label: label,
117
- data: values.map(v => v[keyY]),
118
- backgroundColor: values.map((_, i) => {
119
- const alpha = 1 - (i * 0.08);
120
- return `rgba(88,101,242,${Math.max(0.3, alpha)})`;
121
- }),
122
- borderRadius: 4,
123
- }]
124
- },
125
- options: {
126
- indexAxis: 'y',
127
- responsive: true,
128
- plugins: { legend: { display: false } }
129
- }
130
- });
131
- }
132
-
133
- createBarChart('chartMessages', '<%= t("analytics.messagesPerDay") %>', data.messagesPerDay, 'date', 'count');
134
- createBarChart('chartVoice', '<%= t("analytics.voiceActivity") %>', data.voicePerDay, 'date', 'count');
135
- createBarChart('chartCommands', '<%= t("analytics.commandsPerDay") %>', data.commandsPerDay, 'date', 'count');
136
- createHorizontalBarChart('chartTopCommands', '<%= t("analytics.topCommands") %>', data.topCommands, 'command_name', 'usage_count');
47
+ new Chart(document.getElementById('chartMessages'), {
48
+ type: 'bar',
49
+ data: {
50
+ labels: messages.map(v => v.date),
51
+ datasets: [{ label: '<%= t("analytics.messages") %>', data: messages.map(v => v.count), backgroundColor: '#5865f2', borderRadius: 4 }]
52
+ },
53
+ options: { responsive: true, plugins: { legend: { display: false } } }
54
+ });
137
55
 
138
56
  new Chart(document.getElementById('chartMembers'), {
139
57
  type: 'line',
140
58
  data: {
141
- labels: data.joinsPerDay.map(v => v.date),
59
+ labels: joins.map(v => v.date),
142
60
  datasets: [
143
- {
144
- label: '<%= t("analytics.joins") %>',
145
- data: data.joinsPerDay.map(v => v.count),
146
- borderColor: colors.success,
147
- backgroundColor: 'rgba(87,242,135,0.1)',
148
- fill: true,
149
- tension: 0.3,
150
- },
151
- {
152
- label: '<%= t("analytics.leaves") %>',
153
- data: data.leavesPerDay.map(v => v.count),
154
- borderColor: colors.danger,
155
- backgroundColor: 'rgba(237,66,69,0.1)',
156
- fill: true,
157
- tension: 0.3,
158
- }
61
+ { label: '<%= t("analytics.joins") %>', data: joins.map(v => v.count), borderColor: '#57f287', backgroundColor: 'rgba(87,242,135,0.1)', fill: true, tension: 0.3 },
62
+ { label: '<%= t("analytics.leaves") %>', data: leaves.map(v => v.count), borderColor: '#ed4245', backgroundColor: 'rgba(237,66,69,0.1)', fill: true, tension: 0.3 },
159
63
  ]
160
64
  },
161
65
  options: { responsive: true }
162
66
  });
163
-
164
- <% if (typeof slowestCommands !== 'undefined' && slowestCommands.length > 0) { %>
165
- new Chart(document.getElementById('chartSlowestCommands'), {
166
- type: 'bar',
167
- data: {
168
- labels: data.slowestCommands.map(v => v.command_name),
169
- datasets: [{
170
- label: '<%= t("analytics.avgExecutionTime") %> (ms)',
171
- data: data.slowestCommands.map(v => v.avgExecutionTimeMs),
172
- backgroundColor: colors.warning,
173
- borderRadius: 4,
174
- }]
175
- },
176
- options: {
177
- responsive: true,
178
- plugins: { legend: { display: false } },
179
- scales: { y: { title: { display: true, text: 'ms' } } }
180
- }
181
- });
182
- <% } %>
183
-
184
- <% if (typeof channelVoice !== 'undefined' && channelVoice.length > 0) { %>
185
- new Chart(document.getElementById('chartChannelVoice'), {
186
- type: 'bar',
187
- data: {
188
- labels: data.channelVoice.map(v => v.channel_id),
189
- datasets: [{
190
- label: '<%= t("analytics.totalMinutes") %>',
191
- data: data.channelVoice.map(v => v.total_minutes),
192
- backgroundColor: colors.primary,
193
- borderRadius: 4,
194
- }]
195
- },
196
- options: { responsive: true, plugins: { legend: { display: false } } }
197
- });
198
- <% } %>
199
-
200
- document.querySelectorAll('.date-btn').forEach(btn => {
201
- btn.addEventListener('click', () => {
202
- const days = btn.dataset.days;
203
- const currentUrl = new URL(window.location.href);
204
- currentUrl.searchParams.set('days', days);
205
- window.location.href = currentUrl.toString();
206
- });
207
- });
208
67
  })();
209
68
  </script>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zumito-team/analytics-module",
3
- "version": "0.6.0",
3
+ "version": "0.8.0",
4
4
  "description": "Server analytics module with configurable tracking and optional panel integration",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",