Skip to content

Commit

Permalink
Add basic admin UI to create, edit and generate new door codes (#598)
Browse files Browse the repository at this point in the history
* Add pages to show existing door codes and input new ones.

* Make it possible to edit existing codes.

* Add capability to autogenerate 10 new codes.

* Small improvements to the UI, code organization.
  • Loading branch information
anaulin authored Dec 11, 2021
1 parent fc22025 commit 10835fe
Show file tree
Hide file tree
Showing 10 changed files with 223 additions and 17 deletions.
5 changes: 0 additions & 5 deletions app/controllers/admin/door_code_controller.rb

This file was deleted.

55 changes: 55 additions & 0 deletions app/controllers/admin/door_codes_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
class Admin::DoorCodesController < ApplicationController
before_action :ensure_admin

def index
@door_codes = DoorCode.all.includes(:user).order(created_at: :asc)
end

def new
end

def edit
end

def create
if door_code.save
flash[:notice] = "You have successfully created door code #{door_code.code}"
redirect_to action: :index
else
flash[:warning] = "Errors saving code. See details below."
render :new
end
end

def update
if door_code.update(door_code_params)
flash[:notice] = "You have successfully updated door code #{door_code.code}"
redirect_to action: :index
else
flash[:warning] = "Errors saving code. See details below."
render :edit
end
end

def generate_new
num_codes_to_generate = 10
num_codes_to_generate.times do
DoorCode.create!(code: DoorCode.make_random_code)
end

flash[:notice] = "Autogenerated #{num_codes_to_generate} new codes (see table below for details)"
redirect_to action: :index
end

private

def door_code_params
return {} unless params.key?(:door_code)

params.require(:door_code).permit(:code, :status, :user_id, :id)
end

helper_method def door_code
@door_code ||= params.key?(:id) ? DoorCode.find(params[:id]) : DoorCode.new(door_code_params)
end
end
28 changes: 28 additions & 0 deletions app/views/admin/door_codes/_form.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<%= form_with(model: [:admin, door_code], local: true) do |door_code_form| %>
<p class="bg-danger">
<% door_code.errors.messages.each do |field, msgs| %>
<strong><%= field.to_s.humanize %>:</strong>
<%= msgs.join(', ') %>
<% end %>
</p>

<div class="form-group">
<%= door_code_form.label :code %>
<%= door_code_form.text_field :code %>
</div>

<div class="form-group">
<%= door_code_form.label :status %>
<%= door_code_form.select :status, DoorCode.statuses.keys.to_a %>
</div>

<div class="form-group">
<%= door_code_form.label :user_id %>
<%= door_code_form.select :user_id, User.all.collect { |u| [u.name, u.id] }, { include_blank: true} %>
<p class="help-block">Optional. Use only if you want to assign this code to an existing user.</p>
</div>

<div>
<%= door_code_form.submit %>
</div>
<% end %>
3 changes: 3 additions & 0 deletions app/views/admin/door_codes/edit.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<h1>Edit Door Code</h1>

<%= render partial: 'form', locals: { door_code: door_code} %>
42 changes: 42 additions & 0 deletions app/views/admin/door_codes/index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<h1>Manage Door Codes</h1>

<%= link_to 'Add New Door Code', new_admin_door_code_path(), class: "btn btn-primary" %>

<%= form_with url: generate_new_admin_door_codes_path(), method: :post, local: true do |form| %>
<%= form.submit "Autogenerate New Door Codes", class: "btn btn-primary" %>
<% end %>

<h2>Existing Door Codes</h2>

<% if @door_codes.empty? %>
There are no door codes in the database yet!
<% end %>

<table class="table table-striped">
<thead>
<tr>
<th>Code</th>
<th>Status</th>
<th>Assigned To</th>
<th></th>
</tr>
</thead>
<tbody>
<% @door_codes.each do |door_code| %>
<tr>
<td>
<%= door_code.code %>
</td>
<td>
<%= door_code.status %>
</td>
<td>
<%= door_code.user_id.present? ? door_code.user.name : "unassigned" %>
</td>
<td>
<%= link_to 'Edit', edit_admin_door_code_path(door_code), class: "btn btn-primary" %>
</td>
</tr>
<% end %>
<tbody>
</table>
3 changes: 3 additions & 0 deletions app/views/admin/door_codes/new.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<h1>Add New Door Code</h1>

<%= render partial: 'form', locals: { door_code: door_code} %>
1 change: 1 addition & 0 deletions app/views/layouts/_member_nav.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
%ul.dropdown-menu
%li= link_to 'Manage Applications', admin_applications_path
%li= link_to 'Manage Members', admin_memberships_path
%li= link_to 'Manage Door Codes', admin_door_codes_path
%li= link_to 'Manage Dues', admin_dues_path
%li= link_to 'New Members', admin_new_members_path
%li= link_to 'Configure app', admin_configurable_path
Expand Down
3 changes: 3 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
end

namespace :admin do
resources :door_codes, only: [:index, :new, :create, :edit, :update] do
post :generate_new, on: :collection
end
resource :exceptions, only: :show
resources :memberships, only: [:index, :update]
patch "memberships/:id/change_membership_state" => "memberships#change_membership_state", :as => "change_membership_state"
Expand Down
12 changes: 0 additions & 12 deletions spec/controllers/admin/door_code_controller_spec.rb

This file was deleted.

88 changes: 88 additions & 0 deletions spec/controllers/admin/door_codes_controller_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# frozen_string_literal: true

require 'spec_helper'

describe Admin::DoorCodesController do
include AuthHelper

render_views

let(:door_code) { create(:door_code) }
let(:params) { { id: door_code.id } }

describe "GET :index" do
context "logged in as a non-admin member" do
before { login_as(:member) }

it "redirects to root" do
get :index
expect(response).to redirect_to :root
end
end

context "when logged in as an admin" do
let!(:door_codes) { create_list(:door_code, 5)}

before { login_as(:voting_member, is_admin: true) }

it "shows the index" do
get :index

door_codes.each do |door_code|
expect(response.body).to include(door_code.code)
expect(response.body).to include(door_code.status.to_s)
end
end
end
end

describe "POST :create" do
context "when logged in as an admin" do
let!(:existing_member) { create(:member) }
let!(:existing_door_code) { create(:door_code) }

before { login_as(:voting_member, is_admin: true) }

it "saves the new door code" do
expect {
post :create, params: { door_code: { code: "1234567", status: "in_lock", user_id: existing_member.id } }
}.to change(DoorCode, :count).from(1).to(2)
expect(existing_member.door_code.code).to eq("1234567")
end

it "doesn't save a duplicated door code" do
expect {
post :create, params: { door_code: { code: existing_door_code.code, status: "in_lock" } }
}.not_to change(DoorCode, :count)
end
end
end

describe "PATCH :update" do
context "when logged in as an admin" do
let!(:member) { create(:member) }
let!(:door_code) { create(:door_code) }

before { login_as(:voting_member, is_admin: true) }

it "updates the door code" do
expect {
patch :update, params: { id: door_code.id, door_code: { user_id: member.id } }
}.not_to change(DoorCode, :count)
expect(door_code.reload.user.id).to eq(member.id)
end
end
end

describe "POST :generate_new" do
context "when logged in as an admin" do
before { login_as(:voting_member, is_admin: true) }

it "updates the door code" do
expect {
post :generate_new
}.to change(DoorCode, :count).by(10)
end
end
end
end

0 comments on commit 10835fe

Please sign in to comment.