Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions app/assets/builds/application.css
Original file line number Diff line number Diff line change
Expand Up @@ -2886,6 +2886,10 @@ button, [role="button"], a.btn-game, .btn-game {
margin-top: 2rem;
}

.-mt-1 {
margin-top: -0.25rem;
}

.line-clamp-2 {
overflow: hidden;
display: -webkit-box;
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/admin/teams_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,6 @@ def assign_users
end

def team_params
params.require(:team).permit(:house_id, :captain_id, :number, :airtag_slug, :avatar)
params.require(:team).permit(:house_id, :captain_id, :number, :name, :airtag_slug, :avatar)
end
end
2 changes: 1 addition & 1 deletion app/controllers/static_pages_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def map
{
lat: ping.latitude,
lng: ping.longitude,
teamName: team.name,
teamName: "#{team.house.name} ##{team.number}#{team.custom_name? ? " – #{team[:name]}" : ""}",
timeAgo: helpers.distance_of_time_in_words(ping.pinged_at, Time.now),
avatarUrl: team.avatar_url,
backgroundUrl: "https://placehold.co/500/#{house_color}/#{house_color}",
Expand Down
30 changes: 29 additions & 1 deletion app/controllers/teams_controller.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,38 @@
class TeamsController < ApplicationController
before_action :set_team
before_action :require_captain!, only: [ :edit, :update ]

def show
@team = Team.includes(:house, users: []).find(params[:id])
@submissions = Submission.where(team: @team)
.where.not(status: :pending)
.includes(:challenge, :user, { zone: :challenge })
.order(created_at: :desc)
@pings = @team.location_pings.order(:pinged_at)
end

def edit; end

def update
if @team.update(team_name_params)
redirect_to team_path(@team), notice: "Team name updated."
else
render :edit, status: :unprocessable_entity
end
end

private

def set_team
@team = Team.includes(:house, users: []).find(params[:id])
end

def require_captain!
unless current_user == @team.captain
redirect_to team_path(@team), alert: "Only the team captain can do that."
end
end

def team_name_params
params.require(:team).permit(:name)
end
end
6 changes: 6 additions & 0 deletions app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
module ApplicationHelper
def team_label(team)
label = "Team ##{team.number}"
label += " – #{team[:name]}" if team.custom_name?
label
end

def admin_tool(class_name: "", element: "div", **options, &block)
return unless current_user&.admin?
concat content_tag(element, class: "admin-tool #{class_name}", **options, &block)
Expand Down
1 change: 1 addition & 0 deletions app/models/airtag_api_log.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# == Schema Information
#
# Table name: airtag_api_logs
# Database name: primary
#
# id :bigint not null, primary key
# fetched_at :datetime not null
Expand Down
1 change: 1 addition & 0 deletions app/models/allowed_email.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# == Schema Information
#
# Table name: allowed_emails
# Database name: primary
#
# id :bigint not null, primary key
# email :string not null
Expand Down
1 change: 1 addition & 0 deletions app/models/challenge.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# == Schema Information
#
# Table name: challenges
# Database name: primary
#
# id :bigint not null, primary key
# description :text
Expand Down
1 change: 1 addition & 0 deletions app/models/game_setting.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# == Schema Information
#
# Table name: game_settings
# Database name: primary
#
# id :bigint not null, primary key
# game_started :boolean default(FALSE), not null
Expand Down
1 change: 1 addition & 0 deletions app/models/house.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# == Schema Information
#
# Table name: houses
# Database name: primary
#
# id :bigint not null, primary key
# color :string
Expand Down
1 change: 1 addition & 0 deletions app/models/location_ping.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# == Schema Information
#
# Table name: location_pings
# Database name: primary
#
# id :bigint not null, primary key
# latitude :decimal(10, 7) not null
Expand Down
1 change: 1 addition & 0 deletions app/models/notification.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# == Schema Information
#
# Table name: notifications
# Database name: primary
#
# id :bigint not null, primary key
# link :string
Expand Down
1 change: 1 addition & 0 deletions app/models/submission.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# == Schema Information
#
# Table name: submissions
# Database name: primary
#
# id :bigint not null, primary key
# admin_notes :text
Expand Down
13 changes: 12 additions & 1 deletion app/models/team.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
# == Schema Information
#
# Table name: teams
# Database name: primary
#
# id :bigint not null, primary key
# airtag_slug :string
# last_synced_at :datetime
# name :string
# number :integer not null
# created_at :datetime not null
# updated_at :datetime not null
Expand Down Expand Up @@ -34,9 +36,18 @@ class Team < ApplicationRecord

validates :number, presence: true, uniqueness: { scope: :house_id }
validates :airtag_slug, uniqueness: { allow_blank: true }
validates :name, length: { maximum: 25 }, allow_blank: true

before_validation do
self[:name] = ActionController::Base.helpers.strip_tags(self[:name]).strip.presence
end

def name
"#{house.name} #{number}"
self[:name].presence || "#{house.name} #{number}"
end

def custom_name?
self[:name].present?
end

def points
Expand Down
1 change: 1 addition & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# == Schema Information
#
# Table name: users
# Database name: primary
#
# id :bigint not null, primary key
# avatar_url :string
Expand Down
1 change: 1 addition & 0 deletions app/models/zone.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# == Schema Information
#
# Table name: zones
# Database name: primary
#
# id :bigint not null, primary key
# coordinates :string
Expand Down
1 change: 1 addition & 0 deletions app/models/zone/claim.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# == Schema Information
#
# Table name: zone_claims
# Database name: primary
#
# id :bigint not null, primary key
# created_at :datetime not null
Expand Down
5 changes: 5 additions & 0 deletions app/views/admin/teams/_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@
class: "filter-input" %>
</div>

<div>
<label class="filter-label">Team Name</label>
<%= f.text_field :name, class: "filter-input", placeholder: "Leave blank to use default (House + number)", maxlength: 25 %>
</div>

<div>
<label class="filter-label">Team Number</label>
<%= f.number_field :number, class: "filter-input", placeholder: "e.g. 1", min: 1 %>
Expand Down
2 changes: 1 addition & 1 deletion app/views/admin/teams/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
<div class="flex items-center gap-2">
<%= image_tag team.avatar_url, alt: "#{team.name} Avatar", class: "h-10 w-10 rounded-full" %>
<div class="flex flex-col">
<span class="font-bold text-lg">Team <%= team.number %></span>
<span class="font-bold text-lg"><%= team_label(team) %></span>
<% if team.airtag_slug.present? %>
<span class="font-mono text-xs text-white/60"><%= team.airtag_slug %></span>
<% end %>
Expand Down
5 changes: 4 additions & 1 deletion app/views/houses/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
<div class="border-b-2 border-gray-100 last:border-0">
<div class="px-5 py-3 bg-gray-50 flex items-center justify-between">
<%= link_to team_path(team), class: "font-black text-black hover:underline text-sm" do %>
Team #<%= team.number %>
<%= team_label(team) %>
<% end %>
<span class="text-xs text-gray-400"><%= team.users.count %> <%= "member".pluralize(team.users.count) %></span>
</div>
Expand All @@ -62,6 +62,9 @@
<span class="text-xs text-gray-400 font-mono truncate block"><%= member.email %></span>
<% end %>
</div>
<% if team.captain_id == member.id %>
<span class="badge-role badge-role-admin text-xs flex-shrink-0">Captain</span>
<% end %>
<% if member.role == "admin" %>
<span class="badge-role badge-role-admin text-xs flex-shrink-0">Admin</span>
<% end %>
Expand Down
39 changes: 37 additions & 2 deletions app/views/layouts/application.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@
on_admin = request.path.start_with?('/admin')
team = current_user&.team
house = current_user&.house
on_house = house.present? && current_page?(house_path(house))
on_team = team.present? && current_page?(team_path(team))
fullscreen = content_for?(:fullscreen)
show_house_tab = house.present?
show_team_tab = team.present?
%>

<%# ─── Desktop sidebar ─── %>
Expand All @@ -55,6 +59,20 @@
<span>Schedule</span>
<% end %>

<% if show_house_tab %>
<%= link_to house_path(house), class: "nav-item #{on_house ? 'active' : ''}" do %>
<svg class="nav-icon" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M10 1.944A11.954 11.954 0 012.166 5C2.056 5.649 2 6.319 2 7c0 5.225 3.34 9.67 8 11.317C14.66 16.67 18 12.225 18 7c0-.682-.057-1.35-.166-2.001A11.954 11.954 0 0110 1.944zM10 12a1 1 0 100-2 1 1 0 000 2zm1-5a1 1 0 10-2 0v2a1 1 0 102 0V7z" clip-rule="evenodd"/></svg>
<span>House</span>
<% end %>
<% end %>

<% if show_team_tab %>
<%= link_to team_path(team), class: "nav-item #{on_team ? 'active' : ''}" do %>
<svg class="nav-icon" fill="currentColor" viewBox="0 0 20 20"><path d="M13 6a3 3 0 11-6 0 3 3 0 016 0zM18 8a2 2 0 11-4 0 2 2 0 014 0zM14 15a4 4 0 00-8 0v3h8v-3zM6 8a2 2 0 11-4 0 2 2 0 014 0zM16 18v-3a5.972 5.972 0 00-.75-2.906A3.005 3.005 0 0119 15v3h-3zM4.75 12.094A5.973 5.973 0 004 15v3H1v-3a3 3 0 013.75-2.906z"/></svg>
<span>Team</span>
<% end %>
<% end %>

<% if current_user&.admin? %>
<%= link_to admin_root_path, class: "nav-item #{on_admin ? 'active' : ''}" do %>
<svg class="nav-icon" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M11.49 3.17c-.38-1.56-2.6-1.56-2.98 0a1.532 1.532 0 01-2.286.948c-1.372-.836-2.942.734-2.106 2.106.54.886.061 2.042-.947 2.287-1.561.379-1.561 2.6 0 2.978a1.532 1.532 0 01.947 2.287c-.836 1.372.734 2.942 2.106 2.106a1.532 1.532 0 012.287.947c.379 1.561 2.6 1.561 2.978 0a1.533 1.533 0 012.287-.947c1.372.836 2.942-.734 2.106-2.106a1.533 1.533 0 01.947-2.287c1.561-.379 1.561-2.6 0-2.978a1.532 1.532 0 01-.947-2.287c.836-1.372-.734-2.942-2.106-2.106a1.532 1.532 0 01-2.287-.947zM10 13a3 3 0 100-6 3 3 0 000 6z" clip-rule="evenodd"/></svg>
Expand All @@ -79,7 +97,7 @@
<p class="font-black text-sm truncate"><%= current_user.display_name %></p>
<% if team %>
<p class="text-xs text-black/70 font-medium truncate">
<%= house&.name %> · #<%= team.number %> · <%= team.points %>pts
<%= house&.name %> · <%= team_label(team) %> · <%= team.points %>pts
</p>
<% else %>
<p class="text-xs text-black/70 font-medium">No team</p>
Expand Down Expand Up @@ -159,7 +177,7 @@
<div class="flex-1 min-w-0">
<p class="font-black text-lg truncate"><%= current_user.display_name %></p>
<% if team %>
<p class="text-sm text-gray-600 truncate"><%= house&.name %> · Team #<%= team.number %></p>
<p class="text-sm text-gray-600 truncate"><%= house&.name %> · <%= team_label(team) %></p>
<% else %>
<p class="text-sm text-gray-600">No team assigned</p>
<% end %>
Expand All @@ -171,6 +189,23 @@
</span>
<% end %>
</div>
<% if show_house_tab || show_team_tab %>
<div class="flex gap-3 mb-4">
<% if show_house_tab %>
<%= link_to house_path(house), class: "flex-1 flex items-center gap-2 px-4 py-3 rounded-xl border-2 border-black font-bold text-sm hover:bg-gray-50 transition-colors #{on_house ? 'bg-black text-white hover:bg-black' : ''}", onclick: "closeProfileSheet()" do %>
<svg class="w-4 h-4 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M10 1.944A11.954 11.954 0 012.166 5C2.056 5.649 2 6.319 2 7c0 5.225 3.34 9.67 8 11.317C14.66 16.67 18 12.225 18 7c0-.682-.057-1.35-.166-2.001A11.954 11.954 0 0110 1.944zM10 12a1 1 0 100-2 1 1 0 000 2zm1-5a1 1 0 10-2 0v2a1 1 0 102 0V7z" clip-rule="evenodd"/></svg>
<span>House</span>
<% end %>
<% end %>
<% if show_team_tab %>
<%= link_to team_path(team), class: "flex-1 flex items-center gap-2 px-4 py-3 rounded-xl border-2 border-black font-bold text-sm hover:bg-gray-50 transition-colors #{on_team ? 'bg-black text-white hover:bg-black' : ''}", onclick: "closeProfileSheet()" do %>
<svg class="w-4 h-4 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20"><path d="M13 6a3 3 0 11-6 0 3 3 0 016 0zM18 8a2 2 0 11-4 0 2 2 0 014 0zM14 15a4 4 0 00-8 0v3h8v-3zM6 8a2 2 0 11-4 0 2 2 0 014 0zM16 18v-3a5.972 5.972 0 00-.75-2.906A3.005 3.005 0 0119 15v3h-3zM4.75 12.094A5.973 5.973 0 004 15v3H1v-3a3 3 0 013.75-2.906z"/></svg>
<span>Team</span>
<% end %>
<% end %>
</div>
<% end %>

<%= button_to logout_path, method: :delete,
class: "btn-game-dark w-full",
data: { turbo: false } do %>
Expand Down
3 changes: 2 additions & 1 deletion app/views/static_pages/home.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@
<div class="hero-stat">
<p class="hero-stat-label">Team</p>
<p class="hero-stat-value">#<%= team.number %></p>
<% if team.custom_name? %><p class="text-xs font-bold text-black/60 -mt-1"><%= team[:name] %></p><% end %>
</div>
<div class="hero-stat">
<p class="hero-stat-label">Points</p>
Expand Down Expand Up @@ -585,7 +586,7 @@
<%= team.number %>
</div>
<div class="flex-1 min-w-0">
<p class="lb-name">Team #<%= team.number %><% if is_yours %><span class="ml-2 text-[10px] uppercase tracking-[0.18em] font-black text-gray-500">You</span><% end %></p>
<p class="lb-name"><%= team_label(team) %><% if is_yours %><span class="ml-2 text-[10px] uppercase tracking-[0.18em] font-black text-gray-500">You</span><% end %></p>
<p class="lb-sub"><%= @current_house.name %></p>
</div>
<div class="text-right flex-shrink-0">
Expand Down
37 changes: 37 additions & 0 deletions app/views/teams/edit.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<div class="flex items-center justify-between mb-6">
<div class="flex items-center gap-3 min-w-0">
<%= image_tag @team.avatar_url, alt: "#{@team.name} Avatar", class: "h-10 w-10 rounded-full flex-shrink-0" %>
<div class="min-w-0">
<p class="text-xs font-bold uppercase tracking-widest text-gray-400 mb-0.5">
<%= link_to @team.house.name, house_path(@team.house), class: "hover:underline" %>
</p>
<h1 class="text-2xl font-black text-black">Edit Team Name</h1>
</div>
</div>
<%= link_to "←", team_path(@team), class: "btn-game-ghost text-sm px-3 py-2 flex-shrink-0" %>
</div>

<div class="neo-card max-w-lg">
<%= form_with model: @team, url: team_path(@team), method: :patch do |f| %>
<% if @team.errors.any? %>
<div class="mb-4 p-3 bg-red-50 border border-red-300 rounded-lg text-red-700 text-sm">
<%= @team.errors.full_messages.first %>
</div>
<% end %>

<div class="mb-4">
<label class="filter-label">Team Name</label>
<%= f.text_field :name,
class: "filter-input",
placeholder: "#{@team.house.name} #{@team.number}",
value: @team[:name],
maxlength: 25 %>
<p class="text-xs text-gray-400 mt-1">Max 25 characters. Leave blank to use the default: "<%= @team.house.name %> <%= @team.number %>".</p>
</div>

<div class="flex gap-3">
<%= f.submit "Save", class: "btn-dark" %>
<%= link_to "Cancel", team_path(@team), class: "px-6 py-3 border-2 border-black text-black font-bold rounded-lg hover:bg-gray-100 transition-colors" %>
</div>
<% end %>
</div>
4 changes: 3 additions & 1 deletion app/views/teams/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@
<p class="text-xs font-bold uppercase tracking-widest text-gray-400 mb-0.5">
<%= link_to @team.house.name, house_path(@team.house), class: "hover:underline" %>
</p>
<h1 class="text-2xl font-black text-black">Team #<%= @team.number %></h1>
<h1 class="text-2xl font-black text-black"><%= team_label(@team) %></h1>
</div>
</div>

<div class="flex items-center gap-2 flex-shrink-0">
<% if current_user.admin? %>
<%= link_to "Admin", admin_team_path(@team), class: "btn-game-ghost text-sm px-3 py-2" %>
<%= link_to "Edit", edit_admin_team_path(@team), class: "btn-game-ghost text-sm px-3 py-2" %>
<% elsif @team.captain == current_user %>
<%= link_to "Edit Name", edit_team_path(@team), class: "btn-game-ghost text-sm px-3 py-2" %>
<% end %>
<%= link_to "←", :back, class: "btn-game-ghost text-sm px-3 py-2" %>
</div>
Expand Down
4 changes: 1 addition & 3 deletions app/views/users/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,7 @@
<div class="px-5 py-4">
<p class="text-xs font-bold uppercase tracking-wide text-gray-400 mb-1">Team</p>
<% if @user.team %>
<%= link_to team_path(@user.team), class: "font-black text-black hover:underline" do %>
#<%= @user.team.number %>
<% end %>
<%= link_to team_label(@user.team), team_path(@user.team), class: "font-black text-black hover:underline" %>
<% else %>
<span class="text-gray-400 font-medium">—</span>
<% end %>
Expand Down
Loading