diff --git a/Gemfile b/Gemfile index ae9a2e29..7a46838f 100644 --- a/Gemfile +++ b/Gemfile @@ -23,6 +23,8 @@ gem "stimulus-rails" gem "rollbar" +gem "kaminari" + # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder gem "jbuilder", "~> 2.12" diff --git a/Gemfile.lock b/Gemfile.lock index bfe39ce6..2dc41061 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -170,6 +170,18 @@ GEM jsbundling-rails (1.3.1) railties (>= 6.0.0) json (2.7.2) + kaminari (1.2.2) + activesupport (>= 4.1.0) + kaminari-actionview (= 1.2.2) + kaminari-activerecord (= 1.2.2) + kaminari-core (= 1.2.2) + kaminari-actionview (1.2.2) + actionview + kaminari-core (= 1.2.2) + kaminari-activerecord (1.2.2) + activerecord + kaminari-core (= 1.2.2) + kaminari-core (1.2.2) kramdown (2.4.0) rexml language_server-protocol (3.17.0.3) @@ -403,6 +415,7 @@ DEPENDENCIES image_processing (~> 1.13) jbuilder (~> 2.12) jsbundling-rails + kaminari listen (>= 3.0.5, < 3.10) mysql2 (~> 0.5.6) puma (~> 6.4) diff --git a/app/controllers/admin/admins_controller.rb b/app/controllers/admin/admins_controller.rb new file mode 100644 index 00000000..f2d40af4 --- /dev/null +++ b/app/controllers/admin/admins_controller.rb @@ -0,0 +1,61 @@ +class Admin::AdminsController < Comfy::Admin::BaseController + before_action :build_admin, only: [:new, :create] + before_action :load_admin, only: [:show, :edit, :update, :destroy] + + def index + @admins = Admin.page(params[:page]) + end + + def show + render + end + + def new + render + end + + def edit + render + end + + def create + @admin.save! + flash[:success] = "Admin created" + redirect_to action: :show, id: @admin + rescue ActiveRecord::RecordInvalid + flash.now[:danger] = "Failed to create Admin" + render action: :new + end + + def update + @admin.update!(admin_params) + flash[:success] = "Admin updated" + redirect_to action: :show, id: @admin + rescue ActiveRecord::RecordInvalid + flash.now[:danger] = "Failed to update Admin" + render action: :edit + end + + def destroy + @admin.destroy + flash[:success] = "Admin deleted" + redirect_to action: :index + end + + protected + + def build_admin + @admin = Admin.new(admin_params) + end + + def load_admin + @admin = Admin.find(params[:id]) + rescue ActiveRecord::RecordNotFound + flash[:danger] = "Admin not found" + redirect_to action: :index + end + + def admin_params + params.fetch(:admin, {}).permit(:email, :password) + end +end diff --git a/app/views/admin/admins/_form.html.erb b/app/views/admin/admins/_form.html.erb new file mode 100644 index 00000000..113d55ef --- /dev/null +++ b/app/views/admin/admins/_form.html.erb @@ -0,0 +1,7 @@ +<%= form.text_field :email %> +<%= form.password_field :password %> + +<%= form.form_actions do %> + <%= form.submit class: "btn btn-primary ml-sm-1" %> + <%= link_to 'Cancel', admin_admins_path, class: "btn btn-link" %> +<% end %> diff --git a/app/views/admin/admins/edit.html.erb b/app/views/admin/admins/edit.html.erb new file mode 100644 index 00000000..bab45d13 --- /dev/null +++ b/app/views/admin/admins/edit.html.erb @@ -0,0 +1,7 @@ + + +<%= comfy_form_with model: @admin, url: [:admin, @admin] do |form| %> + <%= render form %> +<% end %> diff --git a/app/views/admin/admins/index.html.erb b/app/views/admin/admins/index.html.erb new file mode 100644 index 00000000..75a88393 --- /dev/null +++ b/app/views/admin/admins/index.html.erb @@ -0,0 +1,32 @@ + + +<%= paginate @admins, theme: 'comfy' %> + + + + +<%= paginate @admins, theme: 'comfy' %> + diff --git a/app/views/admin/admins/new.html.erb b/app/views/admin/admins/new.html.erb new file mode 100644 index 00000000..868fd237 --- /dev/null +++ b/app/views/admin/admins/new.html.erb @@ -0,0 +1,7 @@ + + +<%= comfy_form_with model: @admin, url: [:admin, @admin] do |form| %> + <%= render form %> +<% end %> diff --git a/app/views/admin/admins/show.html.erb b/app/views/admin/admins/show.html.erb new file mode 100644 index 00000000..3bcc57ce --- /dev/null +++ b/app/views/admin/admins/show.html.erb @@ -0,0 +1,33 @@ + + +
+
Email
+
<%= @admin.email %>
+ +
Created at
+
<%= @admin.created_at %>
+ +
Updated at
+
<%= @admin.updated_at %>
+ +
Sign in count
+
<%= @admin.sign_in_count %>
+ +
Current sign in at
+
<%= @admin.current_sign_in_at %>
+ +
Last sign in at
+
<%= @admin.last_sign_in_at %>
+ +
Current sign in ip
+
<%= @admin.current_sign_in_ip %>
+ +
Last sign in ip
+
<%= @admin.last_sign_in_ip %>
+
+ +<%= link_to 'Edit', edit_admin_admin_path(@admin), class: 'btn btn-secondary' %> +<%= link_to 'Delete', admin_admin_path(@admin), method: :delete, data: {confirm: 'Are you sure?'}, class: 'btn btn-danger' %> +<%= link_to 'Back', admin_admins_path, class: 'btn btn-secondary' %> diff --git a/app/views/comfy/admin/cms/partials/_navigation_inner.html.erb b/app/views/comfy/admin/cms/partials/_navigation_inner.html.erb new file mode 100644 index 00000000..7ad1f914 --- /dev/null +++ b/app/views/comfy/admin/cms/partials/_navigation_inner.html.erb @@ -0,0 +1,6 @@ + + + diff --git a/config/routes.rb b/config/routes.rb index 9b8c1c95..c8b8e7e7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,6 +1,10 @@ # frozen_string_literal: true Rails.application.routes.draw do + namespace :admin do + resources :admins + end + root controller: "comfy/cms/content", cms_path: "", action: "show" devise_for :admins diff --git a/test/controllers/admin/admins_controller_test.rb b/test/controllers/admin/admins_controller_test.rb new file mode 100644 index 00000000..119c590a --- /dev/null +++ b/test/controllers/admin/admins_controller_test.rb @@ -0,0 +1,111 @@ +require_relative '../../test_helper' + +class Admin::AdminsControllerTest < ActionDispatch::IntegrationTest + + setup do + @admin = admins(:default) + end + + # Vanilla CMS has BasicAuth, so we need to send that with each request. + # Change this to fit your app's authentication strategy. + # Move this to test_helper.rb + def r(verb, path, options = {}) + headers = options[:headers] || {} + headers['HTTP_AUTHORIZATION'] = + ActionController::HttpAuthentication::Basic.encode_credentials( + ComfortableMexicanSofa::AccessControl::AdminAuthentication.username, + ComfortableMexicanSofa::AccessControl::AdminAuthentication.password + ) + options.merge!(headers: headers) + send(verb, path, options) + end + + def test_get_index + r :get, admin_admins_path + assert_response :success + assert assigns(:admins) + assert_template :index + end + + def test_get_show + r :get, admin_admin_path(@admin) + assert_response :success + assert assigns(:admin) + assert_template :show + end + + def test_get_show_failure + r :get, admin_admin_path('invalid') + assert_response :redirect + assert_redirected_to action: :index + assert_equal 'Admin not found', flash[:danger] + end + + def test_get_new + r :get, new_admin_admin_path + assert_response :success + assert assigns(:admin) + assert_template :new + assert_select "form[action='/admin/admins']" + end + + def test_get_edit + r :get, edit_admin_admin_path(@admin) + assert_response :success + assert assigns(:admin) + assert_template :edit + assert_select "form[action='/admin/admins/#{@admin.id}']" + end + + def test_creation + assert_difference 'Admin.count' do + r :post, admin_admins_path, params: {admin: { + name: 'test name', + }} + admin = Admin.last + assert_response :redirect + assert_redirected_to action: :show, id: admin + assert_equal 'Admin created', flash[:success] + end + end + + def test_creation_failure + assert_no_difference 'Admin.count' do + r :post, admin_admins_path, params: {admin: { }} + assert_response :success + assert_template :new + assert_equal 'Failed to create Admin', flash[:danger] + end + end + + def test_update + r :put, admin_admin_path(@admin), params: {admin: { + name: 'Updated' + }} + assert_response :redirect + assert_redirected_to action: :show, id: @admin + assert_equal 'Admin updated', flash[:success] + @admin.reload + assert_equal 'Updated', @admin.name + end + + def test_update_failure + r :put, admin_admin_path(@admin), params: {admin: { + name: '' + }} + assert_response :success + assert_template :edit + assert_equal 'Failed to update Admin', flash[:danger] + @admin.reload + refute_equal '', @admin.name + end + + def test_destroy + assert_difference 'Admin.count', -1 do + r :delete, admin_admin_path(@admin) + assert_response :redirect + assert_redirected_to action: :index + assert_equal 'Admin deleted', flash[:success] + end + end +end