@hed-hog/core 0.0.168 → 0.0.170

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 (44) hide show
  1. package/dist/dashboard/dashboard/dashboard.controller.d.ts +3 -15
  2. package/dist/dashboard/dashboard/dashboard.controller.d.ts.map +1 -1
  3. package/dist/dashboard/dashboard/dashboard.service.d.ts +3 -15
  4. package/dist/dashboard/dashboard/dashboard.service.d.ts.map +1 -1
  5. package/dist/dashboard/dashboard-component/dashboard-component.controller.d.ts +6 -78
  6. package/dist/dashboard/dashboard-component/dashboard-component.controller.d.ts.map +1 -1
  7. package/dist/dashboard/dashboard-component/dashboard-component.controller.js +8 -6
  8. package/dist/dashboard/dashboard-component/dashboard-component.controller.js.map +1 -1
  9. package/dist/dashboard/dashboard-component/dashboard-component.service.d.ts +3 -79
  10. package/dist/dashboard/dashboard-component/dashboard-component.service.d.ts.map +1 -1
  11. package/dist/dashboard/dashboard-component/dashboard-component.service.js +55 -13
  12. package/dist/dashboard/dashboard-component/dashboard-component.service.js.map +1 -1
  13. package/dist/dashboard/dashboard-component/dto/create.dto.d.ts +0 -4
  14. package/dist/dashboard/dashboard-component/dto/create.dto.d.ts.map +1 -1
  15. package/dist/dashboard/dashboard-component/dto/create.dto.js +0 -19
  16. package/dist/dashboard/dashboard-component/dto/create.dto.js.map +1 -1
  17. package/dist/dashboard/dashboard-component/dto/update.dto.d.ts +0 -4
  18. package/dist/dashboard/dashboard-component/dto/update.dto.d.ts.map +1 -1
  19. package/dist/dashboard/dashboard-component/dto/update.dto.js +0 -20
  20. package/dist/dashboard/dashboard-component/dto/update.dto.js.map +1 -1
  21. package/dist/dashboard/dashboard-core/dashboard-core.controller.d.ts +36 -22
  22. package/dist/dashboard/dashboard-core/dashboard-core.controller.d.ts.map +1 -1
  23. package/dist/dashboard/dashboard-core/dashboard-core.controller.js +0 -9
  24. package/dist/dashboard/dashboard-core/dashboard-core.controller.js.map +1 -1
  25. package/dist/dashboard/dashboard-core/dashboard-core.service.d.ts +36 -22
  26. package/dist/dashboard/dashboard-core/dashboard-core.service.d.ts.map +1 -1
  27. package/dist/dashboard/dashboard-core/dashboard-core.service.js +123 -51
  28. package/dist/dashboard/dashboard-core/dashboard-core.service.js.map +1 -1
  29. package/dist/dashboard/dashboard-item/dashboard-item.controller.d.ts +0 -4
  30. package/dist/dashboard/dashboard-item/dashboard-item.controller.d.ts.map +1 -1
  31. package/dist/dashboard/dashboard-item/dashboard-item.service.d.ts +0 -4
  32. package/dist/dashboard/dashboard-item/dashboard-item.service.d.ts.map +1 -1
  33. package/hedhog/data/dashboard_component.yaml +16 -16
  34. package/hedhog/data/dashboard_component_role.yaml +48 -0
  35. package/hedhog/data/dashboard_item.yaml +55 -15
  36. package/hedhog/data/menu.yaml +3 -3
  37. package/hedhog/table/dashboard_component_role.yaml +16 -0
  38. package/package.json +3 -3
  39. package/src/dashboard/dashboard-component/dashboard-component.controller.ts +9 -5
  40. package/src/dashboard/dashboard-component/dashboard-component.service.ts +64 -14
  41. package/src/dashboard/dashboard-component/dto/create.dto.ts +0 -15
  42. package/src/dashboard/dashboard-component/dto/update.dto.ts +0 -16
  43. package/src/dashboard/dashboard-core/dashboard-core.controller.ts +0 -5
  44. package/src/dashboard/dashboard-core/dashboard-core.service.ts +152 -54
@@ -27,68 +27,170 @@ export class DashboardCoreService {
27
27
 
28
28
  async getStatistics() {
29
29
  const now = new Date();
30
+ const todayStart = new Date(now.getFullYear(), now.getMonth(), now.getDate());
30
31
  const sevenDaysAgo = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
31
- const thirtyDaysAgo = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000);
32
- const totalUsers = await this.prismaService.user.count();
33
- const recentUsers = await this.prismaService.user.count({
34
- where: {
35
- created_at: {
36
- gte: sevenDaysAgo,
37
- },
38
- },
39
- });
32
+ const twelveMonthsAgo = new Date(now.getFullYear() - 1, now.getMonth(), 1);
33
+ const currentMonthStart = new Date(now.getFullYear(), now.getMonth(), 1);
34
+ const lastMonthStart = new Date(now.getFullYear(), now.getMonth() - 1, 1);
35
+ const lastMonthEnd = new Date(now.getFullYear(), now.getMonth(), 0, 23, 59, 59);
36
+
37
+ const [
38
+ sessionsTodayCount,
39
+ activeUsersCount,
40
+ emailsSentCount,
41
+ rolesCount,
42
+ sessionsCurrentMonth,
43
+ usersCurrentMonth,
44
+ emailsCurrentMonth,
45
+ rolesCurrentMonth,
46
+ sessionsLastMonth,
47
+ usersLastMonth,
48
+ emailsLastMonth,
49
+ rolesLastMonth,
50
+ ] = await Promise.all([
51
+ this.prismaService.user_session.count({ where: { created_at: { gte: todayStart } } }),
52
+ this.prismaService.user.count(),
53
+ this.prismaService.mail_sent.count(),
54
+ this.prismaService.role.count(),
55
+ this.prismaService.user_session.count({ where: { created_at: { gte: currentMonthStart } } }),
56
+ this.prismaService.user.count({ where: { created_at: { gte: currentMonthStart } } }),
57
+ this.prismaService.mail_sent.count({ where: { created_at: { gte: currentMonthStart } } }),
58
+ this.prismaService.role.count({ where: { created_at: { gte: currentMonthStart } } }),
59
+ this.prismaService.user_session.count({ where: { created_at: { gte: lastMonthStart, lte: lastMonthEnd } } }),
60
+ this.prismaService.user.count({ where: { created_at: { gte: lastMonthStart, lte: lastMonthEnd } } }),
61
+ this.prismaService.mail_sent.count({ where: { created_at: { gte: lastMonthStart, lte: lastMonthEnd } } }),
62
+ this.prismaService.role.count({ where: { created_at: { gte: lastMonthStart, lte: lastMonthEnd } } }),
63
+ ]);
64
+
65
+ const calculateChange = (current: number, previous: number) => {
66
+ if (previous === 0) {
67
+ return current === 0 ? 0 : 100;
68
+ }
69
+ return Number((((current - previous) / previous) * 100).toFixed(1));
70
+ };
40
71
 
41
- const activeUsers = await this.prismaService.user.count({
42
- where: {
43
- created_at: {
44
- gte: thirtyDaysAgo,
45
- },
46
- },
47
- });
72
+ const sessionsChange = calculateChange(sessionsCurrentMonth, sessionsLastMonth);
73
+ const usersChange = calculateChange(usersCurrentMonth, usersLastMonth);
74
+ const emailsChange = calculateChange(emailsCurrentMonth, emailsLastMonth);
75
+ const rolesChange = calculateChange(rolesCurrentMonth, rolesLastMonth);
48
76
 
49
- const totalRoles = await this.prismaService.role.count();
50
- const totalMenus = await this.prismaService.menu.count();
51
- const totalRoutes = await this.prismaService.route.count();
52
- const totalModules = await this.prismaService.dashboard_component.count();
53
- const totalSettings = await this.prismaService.setting.count();
54
- const totalContacts = await this.prismaService.person.count().catch(() => 0);
77
+ const emailsPerWeek = await this.prismaService.$queryRaw<
78
+ Array<{ day: Date; sent: bigint }>
79
+ >`
80
+ SELECT
81
+ DATE("created_at") as day,
82
+ COUNT(*) as sent
83
+ FROM "mail_sent"
84
+ WHERE "created_at" >= ${sevenDaysAgo}
85
+ GROUP BY DATE("created_at")
86
+ ORDER BY day ASC
87
+ `;
55
88
 
56
- return {
57
- totalUsers,
58
- recentUsers,
59
- activeUsers,
60
- totalRoles,
61
- totalMenus,
62
- totalRoutes,
63
- totalModules,
64
- totalSettings,
65
- totalContacts,
66
- };
67
- }
89
+ const weekDays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
90
+ const emailWeekData = emailsPerWeek.map((item) => {
91
+ const dayOfWeek = new Date(item.day).getDay();
92
+ return {
93
+ day: weekDays[dayOfWeek],
94
+ sent: Number(item.sent),
95
+ };
96
+ });
68
97
 
69
- async getUserGrowth() {
70
- const now = new Date();
71
- const thirtyDaysAgo = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000);
72
- const usersByDay = await this.prismaService.$queryRaw<
73
- Array<{ date: Date; count: bigint }>
98
+ const permissionDistribution = await this.prismaService.$queryRaw<
99
+ Array<{ name: string; value: bigint }>
74
100
  >`
75
- SELECT DATE("created_at") as date, COUNT(*) as count
76
- FROM "user"
77
- WHERE "created_at" >= ${thirtyDaysAgo}
78
- GROUP BY DATE("created_at")
79
- ORDER BY date ASC
101
+ SELECT
102
+ r.slug as name,
103
+ COUNT(ru.user_id) as value
104
+ FROM "role" r
105
+ LEFT JOIN "role_user" ru ON r.id = ru.role_id
106
+ GROUP BY r.id, r.slug
107
+ ORDER BY value DESC
80
108
  `;
81
109
 
82
- return usersByDay.map((item) => ({
83
- date: item.date,
84
- count: Number(item.count),
110
+ const colors = ['#6366f1', '#10b981', '#f59e0b', '#8b5cf6', '#ec4899', '#14b8a6'];
111
+ const permissionsData = permissionDistribution.map((item, index) => ({
112
+ name: item.name,
113
+ value: Number(item.value),
114
+ color: colors[index % colors.length],
85
115
  }));
116
+
117
+ const sessionActivity = await this.prismaService.$queryRaw<
118
+ Array<{ hour: number; active: bigint; expired: bigint }>
119
+ >`
120
+ SELECT
121
+ FLOOR(EXTRACT(HOUR FROM "created_at" AT TIME ZONE 'America/Sao_Paulo') / 2) * 2 as hour,
122
+ COUNT(CASE WHEN "expires_at" > NOW() THEN 1 END) as active,
123
+ COUNT(CASE WHEN "expires_at" <= NOW() THEN 1 END) as expired
124
+ FROM "user_session"
125
+ WHERE "created_at" >= ${todayStart}
126
+ GROUP BY FLOOR(EXTRACT(HOUR FROM "created_at" AT TIME ZONE 'America/Sao_Paulo') / 2)
127
+ ORDER BY hour ASC
128
+ `;
129
+
130
+ const sessionActivityData = [];
131
+ for (let h = 0; h < 24; h += 2) {
132
+ const found = sessionActivity.find((s) => Number(s.hour) === h);
133
+ sessionActivityData.push({
134
+ hour: `${h.toString().padStart(2, '0')}h`,
135
+ active: found ? Number(found.active) : 0,
136
+ expired: found ? Number(found.expired) : 0,
137
+ });
138
+ }
139
+
140
+ const userGrowth = await this.prismaService.$queryRaw<
141
+ Array<{ month: Date; users: bigint; sessions: bigint }>
142
+ >`
143
+ SELECT
144
+ DATE_TRUNC('month', u."created_at") as month,
145
+ COUNT(DISTINCT u.id) as users,
146
+ COUNT(s.id) as sessions
147
+ FROM "user" u
148
+ LEFT JOIN "user_session" s ON u.id = s.user_id AND DATE_TRUNC('month', u."created_at") = DATE_TRUNC('month', s."created_at")
149
+ WHERE u."created_at" >= ${twelveMonthsAgo}
150
+ GROUP BY DATE_TRUNC('month', u."created_at")
151
+ ORDER BY month ASC
152
+ `;
153
+
154
+ const monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
155
+ const userGrowthData = userGrowth.map((item) => {
156
+ const monthIndex = new Date(item.month).getMonth() + 1;
157
+ return {
158
+ month: monthNames[monthIndex],
159
+ users: Number(item.users),
160
+ sessions: Number(item.sessions),
161
+ };
162
+ });
163
+
164
+ return {
165
+ cards: {
166
+ sessionsToday: {
167
+ value: sessionsTodayCount,
168
+ change: sessionsChange,
169
+ },
170
+ activeUsers: {
171
+ value: activeUsersCount,
172
+ change: usersChange,
173
+ },
174
+ emailsSent: {
175
+ value: emailsSentCount,
176
+ change: emailsChange,
177
+ },
178
+ roles: {
179
+ value: rolesCount,
180
+ change: rolesChange,
181
+ },
182
+ },
183
+ charts: {
184
+ emailsPerWeek: emailWeekData,
185
+ permissionDistribution: permissionsData,
186
+ sessionActivity: sessionActivityData,
187
+ userGrowth: userGrowthData,
188
+ },
189
+ };
86
190
  }
87
191
 
88
192
  async getUserLayout(userId: number, slug: string, localeCode: string) {
89
- const dashboard = await this.prismaService.dashboard.findFirst({
90
- where: { slug },
91
- });
193
+ const dashboard = await this.prismaService.dashboard.findFirst({ where: { slug } });
92
194
 
93
195
  if (!dashboard) {
94
196
  return [];
@@ -318,10 +420,6 @@ export class DashboardCoreService {
318
420
  slug: component.slug,
319
421
  name: locale?.name || component.slug,
320
422
  description: locale?.description || '',
321
- path: component.path,
322
- icon: (component as any).icon || null,
323
- stat_key: (component as any).stat_key || null,
324
- color: (component as any).color || null,
325
423
  x: userLayout.x_axis,
326
424
  y: userLayout.y_axis,
327
425
  w: userLayout.width,