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..fe304167 --- /dev/null +++ b/app/controllers/admin/admins_controller.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +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] = t(".admin_created_successfully") + redirect_to action: :show, id: @admin + rescue ActiveRecord::RecordInvalid + flash.now[:danger] = t(".admin_creation_failed") + render action: :new + end + + def update + @admin.update!(admin_params) + flash[:success] = t(".admin_updated_successfully") + redirect_to action: :show, id: @admin + rescue ActiveRecord::RecordInvalid + flash.now[:danger] = t(".admin_update_failed") + render action: :edit + end + + def destroy + @admin.destroy + flash[:success] = t(".admin_deleted_successfully") + 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] = t("admin.admins.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/locales/en.yml b/config/locales/en.yml index decc5a85..ec832d2c 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -31,3 +31,14 @@ en: hello: "Hello world" + admin: + admins: + admin_not_found: "Admin not found" + create: + admin_created_successfully: "Admin created successfully" + admin_creation_failed: "Admin creation failed" + update: + admin_updated_successfully: "Admin updated successfully" + admin_update_failed: "Admin update failed" + destroy: + admin_deleted_successfully: "Admin deleted successfully" 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..aa25673c --- /dev/null +++ b/test/controllers/admin/admins_controller_test.rb @@ -0,0 +1,102 @@ +# frozen_string_literal: true + +require_relative "../../test_helper" + +class Admin::AdminsControllerTest < ActionDispatch::IntegrationTest + setup do + @admin = admins(:admin) + sign_in @admin + end + + def test_get_index + get admin_admins_path + + assert_response :success + end + + def test_get_show + get admin_admin_path(@admin) + + assert_response :success + end + + def test_get_show_failure + 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 + get new_admin_admin_path + + assert_response :success + assert_select "form[action='/admin/admins']" + end + + def test_get_edit + get edit_admin_admin_path(@admin) + + assert_response :success + assert_select "form[action='/admin/admins/#{@admin.id}']" + end + + def test_creation + assert_difference "Admin.count" do + post admin_admins_path, params: {admin: { + email: "new_admin@example.com", + password: "password" + }} + admin = Admin.last + + assert_response :redirect + assert_redirected_to action: :show, id: admin + assert_equal "Admin created successfully", flash[:success] + end + end + + def test_creation_failure + assert_no_difference "Admin.count" do + post admin_admins_path, params: {admin: {}} + + assert_response :success + assert_equal "Admin creation failed", flash[:danger] + end + end + + def test_update + put admin_admin_path(@admin), params: {admin: { + email: "new_email@example.com" + }} + + assert_response :redirect + assert_redirected_to action: :show, id: @admin + assert_equal "Admin updated successfully", flash[:success] + @admin.reload + + assert_equal "new_email@example.com", @admin.email + end + + def test_update_failure + put admin_admin_path(@admin), params: {admin: { + email: "" + }} + + assert_response :success + assert_equal "Admin update failed", flash[:danger] + @admin.reload + + assert_not_equal "", @admin.email + end + + def test_destroy + assert_difference "Admin.count", -1 do + delete admin_admin_path(@admin) + + assert_response :redirect + assert_redirected_to action: :index + assert_equal "Admin deleted successfully", flash[:success] + end + end +end