Skip to content
Snippets Groups Projects
Verified Commit 4d55119c authored by tribut's avatar tribut :man_dancing:
Browse files

Add leaderboard

parent 6ff31080
No related branches found
No related tags found
No related merge requests found
class UsersController < ApplicationController class UsersController < ApplicationController
def leaderboard
@workload_data = User.leaderboard
end
end end
...@@ -56,6 +56,10 @@ class Session < ApplicationRecord ...@@ -56,6 +56,10 @@ class Session < ApplicationRecord
return filedrop_files.exists? || filedrop_comments.exists? return filedrop_files.exists? || filedrop_comments.exists?
end end
def duration_minutes
return (ends_at - starts_at) / 60.0
end
private private
def notify_if_changed def notify_if_changed
......
...@@ -30,6 +30,23 @@ class User < ApplicationRecord ...@@ -30,6 +30,23 @@ class User < ApplicationRecord
end end
end end
def self.leaderboard
all.map { |u| [u.name, u.workload_minutes] }
.sort_by { |_, workload| -workload }
.reject { |_, workload| workload.zero? }
.to_h
end
class Session < ApplicationRecord
has_many :assignments
def workload_minutes
# Logic to calculate workload in minutes
60 # This is just a placeholder
end
end
def errors def errors
super.tap { |errors| errors.delete(:password, :blank) if password.nil? } super.tap { |errors| errors.delete(:password, :blank) if password.nil? }
end end
...@@ -66,6 +83,10 @@ class User < ApplicationRecord ...@@ -66,6 +83,10 @@ class User < ApplicationRecord
self.avatar_color = "##{r.to_s(16).rjust(2, '0')}#{g.to_s(16).rjust(2, '0')}#{b.to_s(16).rjust(2, '0')}" self.avatar_color = "##{r.to_s(16).rjust(2, '0')}#{g.to_s(16).rjust(2, '0')}#{b.to_s(16).rjust(2, '0')}"
end end
def workload_minutes
Assignment.includes(:session).where(user: self).sum { | a | a.session.duration_minutes }
end
private private
def valid_invitation_token def valid_invitation_token
......
<div class="w-full">
<h1 class="text-xl my-4">Leaderboard</h1>
<dl class="w-full max-w-4xl mx-auto">
<% top_workload = @workload_data.values.max %>
<% @workload_data.each_with_index do |(username, workload), index| %>
<% hours, minutes = workload.divmod(60) %>
<div class="bg-gray-50 px-4 py-2 sm:flex sm:items-center sm:gap-4">
<dt class="text-sm font-medium text-gray-500 flex-none w-1/4 sm:w-1/6"><%= username %><%= " 👑" if index == 0 %></dt>
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:flex-1">
<div class="relative pt-1">
<div class="overflow-hidden h-2 mb-1 text-xs flex rounded bg-green-200">
<div style="width:<%= (100 * workload / top_workload).round %>%;" class="shadow-none flex flex-col text-center whitespace-nowrap text-white justify-center bg-green-500"></div>
</div>
<span class="text-xs font-semibold inline-block py-1 px-2 uppercase rounded text-green-600 bg-green-200 last:mr-0 mr-1">
<%= hours > 0 ? "#{hours}h #{minutes.round}m" : "#{minutes.round} minutes" %>
</span>
</div>
</dd>
</div>
<% end %>
</dl>
</div>
...@@ -4,6 +4,7 @@ Rails.application.routes.draw do ...@@ -4,6 +4,7 @@ Rails.application.routes.draw do
mount ActionCable.server => '/cable' mount ActionCable.server => '/cable'
get 'speakers/show' get 'speakers/show'
get 'users/leaderboard'
# Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500. # Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500.
# Can be used by load balancers and uptime monitors to verify that the app is live. # Can be used by load balancers and uptime monitors to verify that the app is live.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment