Skip to content

Commit 6a03023

Browse files
committed
feat: implement Dashboard controller with team analytics
- Add dashboard index with comprehensive stats - Calculate team performance metrics (win rate, KDA, form) - Include recent matches, upcoming events, and active goals - Add roster status breakdown by role and status - Implement recent activities from audit logs
1 parent e1b6b93 commit 6a03023

File tree

1 file changed

+147
-0
lines changed

1 file changed

+147
-0
lines changed
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
class Api::V1::DashboardController < Api::V1::BaseController
2+
def index
3+
dashboard_data = {
4+
stats: calculate_stats,
5+
recent_matches: recent_matches_data,
6+
upcoming_events: upcoming_events_data,
7+
active_goals: active_goals_data,
8+
roster_status: roster_status_data
9+
}
10+
11+
render_success(dashboard_data)
12+
end
13+
14+
def stats
15+
render_success(calculate_stats)
16+
end
17+
18+
def activities
19+
recent_activities = fetch_recent_activities
20+
21+
render_success({
22+
activities: recent_activities,
23+
count: recent_activities.size
24+
})
25+
end
26+
27+
def schedule
28+
events = organization_scoped(Schedule)
29+
.where('start_time >= ?', Time.current)
30+
.order(start_time: :asc)
31+
.limit(10)
32+
33+
render_success({
34+
events: ScheduleSerializer.render_as_hash(events),
35+
count: events.size
36+
})
37+
end
38+
39+
private
40+
41+
def calculate_stats
42+
matches = organization_scoped(Match).recent(30)
43+
players = organization_scoped(Player).active
44+
45+
{
46+
total_players: players.count,
47+
active_players: players.where(status: 'active').count,
48+
total_matches: matches.count,
49+
wins: matches.victories.count,
50+
losses: matches.defeats.count,
51+
win_rate: calculate_win_rate(matches),
52+
recent_form: calculate_recent_form(matches.order(game_start: :desc).limit(5)),
53+
avg_kda: calculate_average_kda(matches),
54+
active_goals: organization_scoped(TeamGoal).active.count,
55+
completed_goals: organization_scoped(TeamGoal).where(status: 'completed').count,
56+
upcoming_matches: organization_scoped(Schedule).where('start_time >= ? AND event_type = ?', Time.current, 'match').count
57+
}
58+
end
59+
60+
def calculate_win_rate(matches)
61+
return 0 if matches.empty?
62+
((matches.victories.count.to_f / matches.count) * 100).round(1)
63+
end
64+
65+
def calculate_recent_form(matches)
66+
matches.map { |m| m.victory? ? 'W' : 'L' }.join('')
67+
end
68+
69+
def calculate_average_kda(matches)
70+
stats = PlayerMatchStat.where(match: matches)
71+
return 0 if stats.empty?
72+
73+
total_kills = stats.sum(:kills)
74+
total_deaths = stats.sum(:deaths)
75+
total_assists = stats.sum(:assists)
76+
77+
deaths = total_deaths.zero? ? 1 : total_deaths
78+
((total_kills + total_assists).to_f / deaths).round(2)
79+
end
80+
81+
def recent_matches_data
82+
matches = organization_scoped(Match)
83+
.order(game_start: :desc)
84+
.limit(5)
85+
86+
MatchSerializer.render_as_hash(matches)
87+
end
88+
89+
def upcoming_events_data
90+
events = organization_scoped(Schedule)
91+
.where('start_time >= ?', Time.current)
92+
.order(start_time: :asc)
93+
.limit(5)
94+
95+
ScheduleSerializer.render_as_hash(events)
96+
end
97+
98+
def active_goals_data
99+
goals = organization_scoped(TeamGoal)
100+
.active
101+
.order(end_date: :asc)
102+
.limit(5)
103+
104+
TeamGoalSerializer.render_as_hash(goals)
105+
end
106+
107+
def roster_status_data
108+
players = organization_scoped(Player).includes(:champion_pools)
109+
110+
{
111+
by_role: players.group(:role).count,
112+
by_status: players.group(:status).count,
113+
contracts_expiring: players.contracts_expiring_soon.count
114+
}
115+
end
116+
117+
def fetch_recent_activities
118+
# Fetch recent audit logs and format them
119+
activities = AuditLog
120+
.where(organization: current_organization)
121+
.order(created_at: :desc)
122+
.limit(20)
123+
124+
activities.map do |log|
125+
{
126+
id: log.id,
127+
action: log.action,
128+
entity_type: log.entity_type,
129+
entity_id: log.entity_id,
130+
user: log.user&.email,
131+
timestamp: log.created_at,
132+
changes: summarize_changes(log)
133+
}
134+
end
135+
end
136+
137+
def summarize_changes(log)
138+
return nil unless log.new_values.present?
139+
140+
# Only show important field changes
141+
important_fields = %w[status role summoner_name title victory]
142+
changes = log.new_values.slice(*important_fields)
143+
144+
return nil if changes.empty?
145+
changes
146+
end
147+
end

0 commit comments

Comments
 (0)