Skip to content
Merged
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
34 changes: 14 additions & 20 deletions app/controllers/admin/games_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ class Admin::GamesController < AdminController
before_action :set_game, only: %i[ show edit update destroy ]

def index
@games = Game.all
@games = Game.includes(:content_modules).order(:title)
end

def show
@content_modules = @game.content_modules.order(:name)
end

def new
Expand All @@ -15,34 +19,24 @@ def edit
def create
@game = Game.new(game_params)

respond_to do |format|
if @game.save
format.html { redirect_back(fallback_location: admin_games_path, notice: "Game was successfully created.") }
else
format.html { render :new, status: :unprocessable_content }
end
if @game.save
redirect_to [ :admin, @game ], notice: "Game was successfully created."
else
render :new, status: :unprocessable_content
end
end

def update
respond_to do |format|
if @game.update(game_params)
format.html { redirect_to [ :admin, @game ], notice: "Game was successfully updated.", status: :see_other }
format.json { render :show, status: :ok, location: [ :admin, @game ] }
else
format.html { render :edit, status: :unprocessable_content }
format.json { render json: @game.errors, status: :unprocessable_content }
end
if @game.update(game_params)
redirect_to [ :admin, @game ], notice: "Game was successfully updated."
else
render :edit, status: :unprocessable_content
end
end

def destroy
@game.destroy!

respond_to do |format|
format.html { redirect_to admin_games_path, notice: "Game was successfully destroyed.", status: :see_other }
format.json { head :no_content }
end
redirect_to admin_games_path, notice: "Game was successfully deleted.", status: :see_other
end

private
Expand Down
13 changes: 13 additions & 0 deletions app/helpers/admin/games_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module Admin::GamesHelper
def delete_game_confirmation(game)
module_count = game.content_modules.size
attempt_count = game.game_attempts.size

consequences = []
consequences << "It will be removed from #{pluralize(module_count, "module")}" if module_count.positive?
consequences << "#{pluralize(attempt_count, "student attempt")} will be deleted" if attempt_count.positive?
return "Delete this game?" if consequences.empty?

"Delete this game? #{consequences.join(" and ")}."
end
end
3 changes: 3 additions & 0 deletions app/views/admin/games/_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
<%= form.label :slug, "Slug", class: "label" %>
<%= form.text_field :slug, class: "input w-full" %>

<%= form.label :description, class: "label" %>
<%= form.text_area :description, rows: 4, class: "textarea w-full" %>

<%= form.submit class: "btn btn-primary" %>
</div>
<% end %>
14 changes: 0 additions & 14 deletions app/views/admin/games/_game.html.erb

This file was deleted.

25 changes: 16 additions & 9 deletions app/views/admin/games/edit.html.erb
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
<% content_for :title, "Editing game" %>
<% content_for :title, "Edit Game" %>

<div class="md:w-2/3 w-full">
<h1 class="font-bold text-4xl">Editing game</h1>

<%= render "form", game: @game %>

<%= link_to "Show this game", [:admin, @game], class: "w-full sm:w-auto text-center mt-2 sm:mt-0 sm:ml-2 rounded-md px-3.5 py-2.5 bg-gray-100 hover:bg-gray-50 inline-block font-medium" %>
<%= link_to "Back to games", admin_games_path, class: "w-full sm:w-auto text-center mt-2 sm:mt-0 sm:ml-2 rounded-md px-3.5 py-2.5 bg-gray-100 hover:bg-gray-50 inline-block font-medium" %>
</div>
<nav class="breadcrumbs text-sm">
<ul>
<li><%= link_to "Games", admin_games_path %></li>
<li><%= link_to @game.title, [:admin, @game] %></li>
<li>Edit</li>
</ul>
</nav>
<section class="py-10 flex items-center justify-center">
<div class="card card-border bg-base-100 shadow-md w-96">
<div class="card-body">
<h1 class="card-title">Edit Game</h1>
<%= render "form", game: @game %>
</div>
</div>
</section>
62 changes: 38 additions & 24 deletions app/views/admin/games/index.html.erb
Original file line number Diff line number Diff line change
@@ -1,29 +1,43 @@
<% content_for :title, "Games" %>

<div class="w-full">
<% if notice.present? %>
<p class="py-2 px-3 bg-green-50 mb-5 text-green-500 font-medium rounded-md inline-block" id="notice"><%= notice %></p>
<% end %>
<p style="color: green"><%= notice %></p>
<p style="color: red"><%= alert %></p>

<div class="flex justify-between items-center">
<h1 class="font-bold text-4xl">Games</h1>
<%= link_to "New game", new_admin_game_path, class: "rounded-md px-3.5 py-2.5 bg-blue-600 hover:bg-blue-500 text-white block font-medium" %>
</div>
<header class="flex justify-between items-center mb-4">
<h1 class="text-2xl">Games</h1>
<%= link_to "New game", new_admin_game_path, class: "btn btn-primary" %>
</header>

<div id="games" class="min-w-full divide-y divide-gray-200 space-y-5">
<% if @games.any? %>
<% @games.each do |game| %>
<div class="flex flex-col sm:flex-row justify-between items-center pb-5 sm:pb-0">
<%= render game %>
<div class="w-full sm:w-auto flex flex-col sm:flex-row space-x-2 space-y-2">
<%= link_to "Show", [:admin, game], class: "w-full sm:w-auto text-center rounded-md px-3.5 py-2.5 bg-gray-100 hover:bg-gray-50 inline-block font-medium" %>
<%= link_to "Edit", edit_admin_game_path(game), class: "w-full sm:w-auto text-center rounded-md px-3.5 py-2.5 bg-gray-100 hover:bg-gray-50 inline-block font-medium" %>
<%= button_to "Destroy", [:admin, game], method: :delete, class: "w-full sm:w-auto rounded-md px-3.5 py-2.5 text-white bg-red-600 hover:bg-red-500 font-medium cursor-pointer", data: { turbo_confirm: "Are you sure?" } %>
</div>
</div>
<% end %>
<% else %>
<p class="text-center my-10">No games found.</p>
<% end %>
<% if @games.any? %>
<div class="overflow-x-auto rounded-box border border-base-content/5 bg-base-100">
<table class="table">
<thead>
<tr>
<th>Title</th>
<th>Slug</th>
<th>Modules</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<% @games.each do |game| %>
<%= tag.tr id: dom_id(game) do %>
<td><%= link_to game.title, [:admin, game], class: "link" %></td>
<td><%= game.slug %></td>
<td><%= game.content_modules.size %></td>
<td>
<div class="flex gap-2">
<%= link_to "Edit", edit_admin_game_path(game), class: "btn btn-sm btn-primary" %>
<%= button_to "Delete", [:admin, game], method: :delete,
data: { "turbo-confirm": delete_game_confirmation(game) },
class: "btn btn-sm btn-error" %>
</div>
</td>
<% end %>
<% end %>
</tbody>
</table>
</div>
</div>
<% else %>
<p class="text-sm opacity-60">No games yet.</p>
<% end %>
4 changes: 2 additions & 2 deletions app/views/admin/games/new.html.erb
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<% content_for :title, "New game" %>
<% content_for :title, "New Game" %>

<nav class="breadcrumbs text-sm">
<ul>
<li><%= link_to "Content Modules", admin_content_modules_path %></li>
<li><%= link_to "Games", admin_games_path %></li>
<li>New Game</li>
</ul>
</nav>
Expand Down
52 changes: 41 additions & 11 deletions app/views/admin/games/show.html.erb
Original file line number Diff line number Diff line change
@@ -1,15 +1,45 @@
<% content_for :title, "Showing game" %>
<% content_for :title, @game.title %>

<div class="md:w-2/3 w-full">
<% if notice.present? %>
<p class="py-2 px-3 bg-green-50 mb-5 text-green-500 font-medium rounded-md inline-block" id="notice"><%= notice %></p>
<% end %>
<p style="color: green"><%= notice %></p>
<p style="color: red"><%= alert %></p>

<nav class="breadcrumbs text-sm">
<ul>
<li><%= link_to "Games", admin_games_path %></li>
<li><%= @game.title %></li>
</ul>
</nav>

<h1 class="font-bold text-4xl">Showing game</h1>
<header class="flex items-center justify-between mb-4">
<h1 class="text-2xl"><%= @game.title %></h1>
<div class="flex gap-2">
<%= link_to "Edit this game", edit_admin_game_path(@game), class: "btn btn-primary" %>
<%= button_to "Delete this game", [:admin, @game], method: :delete,
data: { "turbo-confirm": delete_game_confirmation(@game) },
class: "btn btn-error" %>
</div>
</header>

<%= render @game %>
<dl class="mb-8 space-y-4">
<div>
<dt class="font-semibold">Slug</dt>
<dd><%= @game.slug %></dd>
</div>
<div>
<dt class="font-semibold">Description</dt>
<dd><%= @game.description.presence || "No description." %></dd>
</div>
</dl>

<%= link_to "Edit this game", edit_admin_game_path(@game), class: "w-full sm:w-auto text-center rounded-md px-3.5 py-2.5 bg-gray-100 hover:bg-gray-50 inline-block font-medium" %>
<%= link_to "Back to games", admin_games_path, class: "w-full sm:w-auto text-center mt-2 sm:mt-0 sm:ml-2 rounded-md px-3.5 py-2.5 bg-gray-100 hover:bg-gray-50 inline-block font-medium" %>
<%= button_to "Destroy this game", [:admin, @game], method: :delete, form_class: "sm:inline-block mt-2 sm:mt-0 sm:ml-2", class: "w-full rounded-md px-3.5 py-2.5 text-white bg-red-600 hover:bg-red-500 font-medium cursor-pointer", data: { turbo_confirm: "Are you sure?" } %>
</div>
<section>
<h2 class="text-lg font-semibold mb-2">Modules</h2>
<% if @content_modules.any? %>
<ul class="list-disc pl-6">
<% @content_modules.each do |content_module| %>
<li><%= link_to content_module.name, edit_admin_content_module_path(content_module), class: "link" %></li>
<% end %>
</ul>
<% else %>
<p class="text-sm opacity-60">Not in any module yet.</p>
<% end %>
</section>
4 changes: 4 additions & 0 deletions app/views/shared/_admin_nav.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
<%= link_to "Content Modules", admin_content_modules_path,
class: "#{controller_path.start_with?("admin/content_modules", "admin/links") ? "active" : ""}" %>
</li>
<li>
<%= link_to "Games", admin_games_path,
class: "#{controller_path.start_with?("admin/games") ? "active" : ""}" %>
</li>
</ul>
<%= button_to "Log out", admin_session_path, method: :delete, class: "btn btn-sm btn-ghost ml-2" %>
</div>
Expand Down
56 changes: 55 additions & 1 deletion test/controllers/admin/games_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ class Admin::GamesControllerTest < ActionDispatch::IntegrationTest
assert_response :success
end

test "index marks the Games nav link as active" do
get admin_games_url

assert_select "nav a.active", text: "Games"
end

test "should get new" do
get new_admin_game_url
assert_response :success
Expand All @@ -23,7 +29,45 @@ class Admin::GamesControllerTest < ActionDispatch::IntegrationTest
end
end

assert_redirected_to admin_games_url
assert_redirected_to admin_game_url(Game.find_by!(slug: "new-game"))
end

test "index shows how many modules use each game" do
game = create_game
2.times { |i| create_module("Module #{i}").contents.create!(contentable: game) }

get admin_games_url

assert_select "##{dom_id(game)} td", text: "2"
end

test "show lists the modules that use the game" do
game = create_game
content_module = create_module("Listed Module")
content_module.contents.create!(contentable: game)

get admin_game_url(game)

assert_select "a[href=?]", edit_admin_content_module_path(content_module), text: "Listed Module"
end

test "show says when the game is in no module" do
game = create_game

get admin_game_url(game)

assert_select "p", text: "Not in any module yet."
end

test "delete confirmation warns when the game is in modules" do
game = create_game
create_module("Module").contents.create!(contentable: game)
GameAttempt.create!(game: game, student: students(:one), token: "attempt-token")

get admin_game_url(game)

assert_select "form[action=?] button[data-turbo-confirm=?]", admin_game_path(game),
"Delete this game? It will be removed from 1 module and 1 student attempt will be deleted."
end

test "should get edit" do
Expand All @@ -43,4 +87,14 @@ class Admin::GamesControllerTest < ActionDispatch::IntegrationTest

assert_redirected_to admin_games_url
end

private

def create_game
Game.create!(title: "Test Game", slug: "test-game")
end

def create_module(name)
ContentModule.create!(program: programs(:one), level: "basic", name: name)
end
end
Loading
Loading