diff --git a/app/actions/players/profile.rb b/app/actions/players/profile.rb new file mode 100644 index 0000000..302fc6f --- /dev/null +++ b/app/actions/players/profile.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true + +module EuchreCamp + module Actions + module Players + class Profile < EuchreCamp::Action + include Deps[players_repo: 'repositories.players'] + + def handle(request, response) + player_id = request.params[:id] + player = players_repo.by_id(player_id) + + # Get partnership statistics + partnerships = EuchreCamp::Services::PartnershipTracker.get_player_partnerships(player_id) + + # Get recent games (last 10) + recent_games = get_recent_games(player_id) + + response.render(view, + player: player, + partnerships: partnerships, + recent_games: recent_games + ) + end + + private + + def get_recent_games(player_id) + rom = EuchreCamp::App["persistence.rom"] + + # Get matches where this player participated + matches = rom.relations[:matches] + .where( + Sequel.|( + { team_1_p1_id: player_id }, + { team_1_p2_id: player_id }, + { team_2_p1_id: player_id }, + { team_2_p2_id: player_id } + ) + ) + .order(Sequel.desc(:played_at)) + .limit(10) + .to_a + + # Get player names for display + all_players = rom.relations[:players].to_a.to_h { |p| [p[:id], p] } + + matches.map do |match| + team_1_players = [ + all_players[match[:team_1_p1_id]], + all_players[match[:team_1_p2_id]] + ] + team_2_players = [ + all_players[match[:team_2_p1_id]], + all_players[match[:team_2_p2_id]] + ] + + # Determine if this player won + player_on_team_1 = match[:team_1_p1_id] == player_id || match[:team_1_p2_id] == player_id + won = player_on_team_1 ? (match[:team_1_score] > match[:team_2_score]) : (match[:team_2_score] > match[:team_1_score]) + + { + date: match[:played_at] || match[:created_at], + team_1: team_1_players, + team_2: team_2_players, + score: "#{match[:team_1_score]}-#{match[:team_2_score]}", + won: won, + player_partner: player_on_team_1 ? team_1_players.find { |p| p[:id] != player_id } : team_2_players.find { |p| p[:id] != player_id } + } + end + end + end + end + end +end diff --git a/app/actions/players/schedule.rb b/app/actions/players/schedule.rb new file mode 100644 index 0000000..0cc48fd --- /dev/null +++ b/app/actions/players/schedule.rb @@ -0,0 +1,128 @@ +# frozen_string_literal: true + +module EuchreCamp + module Actions + module Players + class Schedule < EuchreCamp::Action + include Deps[players_repo: 'repositories.players'] + + def handle(request, response) + player_id = request.params[:id] + player = players_repo.by_id(player_id) + + # Get upcoming matches for this player + upcoming_matches = get_upcoming_matches(player_id) + + # Get active tournaments for this player + active_tournaments = get_active_tournaments(player_id) + + # Get tournament schedule + tournament_schedule = get_tournament_schedule(player_id) + + response.render(view, + player: player, + upcoming_matches: upcoming_matches, + active_tournaments: active_tournaments, + tournament_schedule: tournament_schedule + ) + end + + private + + def get_upcoming_matches(player_id) + rom = EuchreCamp::App["persistence.rom"] + + # Get upcoming matches where this player participates + matches = rom.relations[:matches] + .where( + Sequel.|( + { team_1_p1_id: player_id }, + { team_1_p2_id: player_id }, + { team_2_p1_id: player_id }, + { team_2_p2_id: player_id } + ) + ) + .where(status: 'scheduled') + .order(:played_at) + .limit(10) + .to_a + + # Get player names for display + all_players = rom.relations[:players].to_a.to_h { |p| [p[:id], p] } + + matches.map do |match| + team_1_players = [ + all_players[match[:team_1_p1_id]], + all_players[match[:team_1_p2_id]] + ] + team_2_players = [ + all_players[match[:team_2_p1_id]], + all_players[match[:team_2_p2_id]] + ] + + player_on_team_1 = match[:team_1_p1_id] == player_id || match[:team_1_p2_id] == player_id + + { + id: match[:id], + date: match[:played_at], + team_1: team_1_players, + team_2: team_2_players, + opponent_team: player_on_team_1 ? team_2_players : team_1_players, + player_team: player_on_team_1 ? team_1_players : team_2_players, + event_id: match[:event_id] + } + end + end + + def get_active_tournaments(player_id) + rom = EuchreCamp::App["persistence.rom"] + + # Get tournaments where player is participating + event_ids = rom.relations[:event_participants] + .where(player_id: player_id) + .select(:event_id) + .to_a + .map { |e| e[:event_id] } + + return [] if event_ids.empty? + + # Get active tournaments + rom.relations[:events] + .where(id: event_ids, status: 'active') + .to_a + end + + def get_tournament_schedule(player_id) + rom = EuchreCamp::App["persistence.rom"] + + # Get all tournaments where player participates + event_ids = rom.relations[:event_participants] + .where(player_id: player_id) + .select(:event_id) + .to_a + .map { |e| e[:event_id] } + + return [] if event_ids.empty? + + # Get tournaments and their schedules + tournaments = rom.relations[:events] + .where(id: event_ids) + .to_a + + tournaments.map do |tournament| + # Get tournament rounds + rounds = rom.relations[:tournament_rounds] + .where(event_id: tournament[:id]) + .order(:round_number) + .to_a + + { + tournament: tournament, + rounds: rounds + } + end + end + end + end + end +end diff --git a/app/templates/players/profile.html.erb b/app/templates/players/profile.html.erb new file mode 100644 index 0000000..ac49488 --- /dev/null +++ b/app/templates/players/profile.html.erb @@ -0,0 +1,94 @@ +
| Partner | +Games | +Win Rate | +ELO Change | +Avg/Match | +Last Played | +
|---|---|---|---|---|---|
| <%= p[:partner][:name] %> | +<%= p[:games_played] %> | +
+ <%= (p[:win_rate] * 100).round(1) %>%
+
+ <% if p[:games_played] < 15 %>
+ (low confidence)
+ <% end %>
+
+ |
+ <%= p[:total_elo_change] > 0 ? "+" : "" %><%= p[:total_elo_change] %> | +<%= p[:avg_elo_change] > 0 ? "+" : "" %><%= p[:avg_elo_change] %> | +<%= p[:last_played]&.strftime('%Y-%m-%d') || '-' %> | +
No partnership data available yet.
+<% end %> + +No games played yet.
+<% end %> + + diff --git a/app/templates/players/schedule.html.erb b/app/templates/players/schedule.html.erb new file mode 100644 index 0000000..f34360a --- /dev/null +++ b/app/templates/players/schedule.html.erb @@ -0,0 +1,90 @@ +No upcoming matches scheduled.
+ <% end %> +<%= tournament[:format].capitalize %> Tournament
+No active tournaments.
+ <% end %> +No tournament schedule available.
+ <% end %> +