[deploy] Manage listing categories in dashboard (#10506)
* Displaying all listing * Edit listing form * Editing listing * Searching listing categories * Creating new listing category * Deleting listing category * Fixing error message and roles * Tests * Fixing aria label * Fixing link class * Fixing error message of destroy * Changing placeholder text
This commit is contained in:
parent
4e352020a9
commit
4a9f27163e
10 changed files with 291 additions and 2 deletions
69
app/controllers/admin/listing_categories_controller.rb
Normal file
69
app/controllers/admin/listing_categories_controller.rb
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
module Admin
|
||||
class ListingCategoriesController < Admin::ApplicationController
|
||||
include ListingsToolkit
|
||||
layout "admin"
|
||||
|
||||
def index
|
||||
@listing_categories = ListingCategory.order(id: :desc)
|
||||
.page(params[:page]).per(50)
|
||||
|
||||
return if params[:search].blank?
|
||||
|
||||
@listing_categories = @listing_categories.where("name ILIKE :search", search: "%#{params[:search]}%")
|
||||
end
|
||||
|
||||
def new
|
||||
@listing_category = ListingCategory.new
|
||||
end
|
||||
|
||||
def edit
|
||||
@listing_category = ListingCategory.find(params[:id])
|
||||
end
|
||||
|
||||
def create
|
||||
@listing_category = ListingCategory.new(listing_category_params)
|
||||
|
||||
if @listing_category.save
|
||||
flash[:success] = "Listing Category has been created!"
|
||||
redirect_to admin_listing_categories_path
|
||||
else
|
||||
flash[:danger] = @listing_category.errors_as_sentence
|
||||
render new_admin_listing_category_path
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
@listing_category = ListingCategory.find(params[:id])
|
||||
|
||||
if @listing_category.update(listing_category_params)
|
||||
flash[:success] = "Listing Category has been updated!"
|
||||
redirect_to admin_listing_categories_path
|
||||
else
|
||||
flash[:danger] = @listing_category.errors_as_sentence
|
||||
render :edit
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@listing_category = ListingCategory.find(params[:id])
|
||||
|
||||
if @listing_category.destroy
|
||||
flash[:success] = "Listing Category has been deleted!"
|
||||
redirect_to admin_listing_categories_path
|
||||
else
|
||||
flash[:danger] = @listing_category.errors.full_messages.to_sentence
|
||||
render :edit
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def listing_category_params
|
||||
params.permit(:name, :cost, :rules, :slug, :social_preview_color, :social_preview_description)
|
||||
end
|
||||
|
||||
def authorize_admin
|
||||
authorize ListingCategory, :access?, policy_class: InternalPolicy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -18,6 +18,7 @@ module Constants
|
|||
"Resource Admin: Config",
|
||||
"Resource Admin: Broadcast",
|
||||
"Resource Admin: HtmlVariant",
|
||||
"Resource Admin: DisplayAd"].freeze
|
||||
"Resource Admin: DisplayAd",
|
||||
"Resource Admin: ListingCategory"].freeze
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
class ListingCategory < ApplicationRecord
|
||||
resourcify
|
||||
|
||||
# We used to use both "classified listing" and "listing" throughout the app.
|
||||
# We standardized on the latter, but keeping the table name was easier.
|
||||
self.table_name = "classified_listing_categories"
|
||||
|
|
|
|||
29
app/views/admin/listing_categories/_form.html.erb
Normal file
29
app/views/admin/listing_categories/_form.html.erb
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
<div class="form-group">
|
||||
<%= label_tag :name, "Name" %>
|
||||
<%= text_field_tag :name, @listing_category.name, class: "form-control" %>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<%= label_tag :cost, "Cost" %>
|
||||
<%= number_field_tag :cost, @listing_category.cost, class: "form-control" %>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<%= label_tag :rules, "Rules" %>
|
||||
<%= text_field_tag :rules, @listing_category.rules, class: "form-control" %>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<%= label_tag :slug, "Slug" %>
|
||||
<%= text_field_tag :slug, @listing_category.slug, class: "form-control" %>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<%= label_tag :social_preview_color, "Color hex" %>
|
||||
<%= text_field_tag :social_preview_color, @listing_category.social_preview_color, class: "form-control" %>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<%= label_tag :social_preview_description, "Description" %>
|
||||
<%= text_area_tag :social_preview_description, @listing_category.social_preview_description, size: "100x10", class: "form-control" %>
|
||||
</div>
|
||||
7
app/views/admin/listing_categories/edit.html.erb
Normal file
7
app/views/admin/listing_categories/edit.html.erb
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<h2 class="fs-2xl s:fs-3xl mb-6">Edit Listing Category:</h2>
|
||||
<div class="crayons-card p-6">
|
||||
<%= form_for([:admin, @listing_category], method: :patch) do %>
|
||||
<%= render "form" %>
|
||||
<%= submit_tag "Update Listing Category", class: "btn btn-primary" %>
|
||||
<% end %>
|
||||
</div>
|
||||
43
app/views/admin/listing_categories/index.html.erb
Normal file
43
app/views/admin/listing_categories/index.html.erb
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
<nav class="flex mb-4" aria-label="Listing Category navigation">
|
||||
<%= form_tag("/admin/listings/categories", method: "get") do %>
|
||||
<%= text_field_tag(:search, params[:search], aria: { label: "Search" }, class: "top-bar--search-input crayons-textfield", placeholder: "Search by name") %>
|
||||
<% end %>
|
||||
<div class="ml-auto">
|
||||
<div class="justify-content-end">
|
||||
<%= link_to "Make A Listing Category", new_admin_listing_category_path, class: "crayons-btn" %>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<%= paginate @listing_categories %>
|
||||
|
||||
<table class="crayons-table" width="100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">ID</th>
|
||||
<th scope="col">Name</th>
|
||||
<th scope="col">Cost</th>
|
||||
<th scope="col">Rules</th>
|
||||
<th scope="col">Slug</th>
|
||||
<th scope="col">Color</th>
|
||||
<th scope="col">Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="crayons-card">
|
||||
<% @listing_categories.each do |category| %>
|
||||
<tr>
|
||||
<td><%= link_to category.id, edit_admin_listing_category_path(category) %></td>
|
||||
<td><%= category.name %></td>
|
||||
<td><%= category.cost %></td>
|
||||
<td><%= category.rules %></td>
|
||||
<td><%= category.slug %></td>
|
||||
<td><%= category.social_preview_color %></td>
|
||||
<td><%= category.social_preview_description %></td>
|
||||
<td><%= link_to "Edit", edit_admin_listing_category_path(category), class: "crayons-btn" %></td>
|
||||
<td><%= link_to "Destroy", admin_listing_category_path(category), class: "crayons-btn crayons-btn--danger", method: :delete, data: { confirm: "Are you sure?" } %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<%= paginate @listing_categories %>
|
||||
7
app/views/admin/listing_categories/new.html.erb
Normal file
7
app/views/admin/listing_categories/new.html.erb
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<h2 class="fs-2xl s:fs-3xl mb-6">Make a new Listing Category:</h2>
|
||||
<div class="crayons-card p-6">
|
||||
<%= form_for([:admin, @listing_category], method: :post) do %>
|
||||
<%= render "form" %>
|
||||
<%= submit_tag "Create Listing Category", class: "btn btn-primary" %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
@ -1,5 +1,11 @@
|
|||
<header class="mb-6">
|
||||
|
||||
<header class="flex items-center mb-6">
|
||||
<h2 class="crayons-title mb-4">Listings</h2>
|
||||
<a href="/admin/listings/categories"
|
||||
aria-label="Listing Categories"
|
||||
class="ml-auto crayons-btn">
|
||||
Listing Categories
|
||||
</a>
|
||||
</header>
|
||||
|
||||
<%= form_tag(admin_listings_path, method: "get", role: "search", class: "crayons-card crayons-card--secondary p-4 flex items-center") do %>
|
||||
|
|
|
|||
|
|
@ -62,6 +62,9 @@ Rails.application.routes.draw do
|
|||
resources :broadcasts
|
||||
resources :buffer_updates, only: %i[create update]
|
||||
resources :listings, only: %i[index edit update destroy]
|
||||
resources :listing_categories, only: %i[index edit update new create
|
||||
destroy], path: "listings/categories"
|
||||
|
||||
resources :comments, only: [:index]
|
||||
resources :events, only: %i[index create update]
|
||||
resources :feedback_messages, only: %i[index show]
|
||||
|
|
@ -126,6 +129,7 @@ Rails.application.routes.draw do
|
|||
resource :config
|
||||
resources :badges, only: %i[index edit update new create]
|
||||
resources :display_ads, only: %i[index edit update new create destroy]
|
||||
|
||||
resources :html_variants, only: %i[index edit update new create show destroy]
|
||||
# These redirects serve as a safegaurd to prevent 404s for any Admins
|
||||
# who have the old badge_achievement URLs bookmarked.
|
||||
|
|
|
|||
121
spec/requests/admin/listings_catogires_spec.rb
Normal file
121
spec/requests/admin/listings_catogires_spec.rb
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
require "rails_helper"
|
||||
require "requests/shared_examples/internal_policy_dependant_request"
|
||||
|
||||
RSpec.describe "/admin/listings/categories", type: :request do
|
||||
let(:get_resource) { get "/admin/listings/categories" }
|
||||
let(:params) do
|
||||
{ name: "Computer stuff", cost: 22, rules: "Things computers do",
|
||||
slug: "computer", social_preview_color: "#000", social_preview_description: "Computer things" }
|
||||
end
|
||||
let(:post_resource) { post "/admin/listings/categories", params: params }
|
||||
|
||||
it_behaves_like "an InternalPolicy dependant request", ListingCategory do
|
||||
let(:request) { get_resource }
|
||||
end
|
||||
|
||||
context "when the user is not an admin" do
|
||||
let(:user) { create(:user) }
|
||||
|
||||
before { sign_in user }
|
||||
|
||||
describe "GET /admin/listings/categories" do
|
||||
it "blocks the request" do
|
||||
expect { get_resource }.to raise_error(Pundit::NotAuthorizedError)
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST /admin/listings/categories" do
|
||||
it "blocks the request" do
|
||||
expect { post_resource }.to raise_error(Pundit::NotAuthorizedError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when the user is a super admin" do
|
||||
let(:super_admin) { create(:user, :super_admin) }
|
||||
|
||||
before { sign_in super_admin }
|
||||
|
||||
describe "GET /admin/listings/categories" do
|
||||
it "allows the request" do
|
||||
get_resource
|
||||
expect(response).to have_http_status(:ok)
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST /admin/listings/categories" do
|
||||
it "creates a new listing_category" do
|
||||
expect do
|
||||
post_resource
|
||||
end.to change { ListingCategory.all.count }.by(1)
|
||||
end
|
||||
end
|
||||
|
||||
describe "PUT /admin/listings/categories" do
|
||||
let!(:listing_category) { create(:listing_category, name: "Computers") }
|
||||
|
||||
it "updates Listing Category name" do
|
||||
Timecop.freeze(Time.current) do
|
||||
expect do
|
||||
put "/admin/listings/categories/#{listing_category.id}", params: params
|
||||
end.to change { listing_category.reload.name }.from("Computers").to("Computer stuff")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "DELETE /admin/listing/categories/:id" do
|
||||
let!(:listing_category) { create(:listing_category) }
|
||||
|
||||
it "deletes the Listing Category" do
|
||||
expect do
|
||||
delete "/admin/listings/categories/#{listing_category.id}"
|
||||
end.to change { ListingCategory.all.count }.by(-1)
|
||||
expect(response.body).to redirect_to "/admin/listings/categories"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when the user is a single resource admin" do
|
||||
let(:single_resource_admin) { create(:user, :single_resource_admin, resource: ListingCategory) }
|
||||
|
||||
before { sign_in single_resource_admin }
|
||||
|
||||
describe "GET /admin/listings/categories" do
|
||||
it "allows the request" do
|
||||
get_resource
|
||||
expect(response).to have_http_status(:ok)
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST /admin/listings/categories" do
|
||||
it "creates a new listing_category" do
|
||||
expect do
|
||||
post_resource
|
||||
end.to change { ListingCategory.all.count }.by(1)
|
||||
end
|
||||
end
|
||||
|
||||
describe "PUT /admin/listings/categories" do
|
||||
let!(:listing_category) { create(:listing_category, name: "Computers") }
|
||||
|
||||
it "updates Listing Category name" do
|
||||
Timecop.freeze(Time.current) do
|
||||
expect do
|
||||
put "/admin/listings/categories/#{listing_category.id}", params: params
|
||||
end.to change { listing_category.reload.name }.from("Computers").to("Computer stuff")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "DELETE /admin/listing/categories/:id" do
|
||||
let!(:listing_category) { create(:listing_category) }
|
||||
|
||||
it "deletes the Listing Category" do
|
||||
expect do
|
||||
delete "/admin/listings/categories/#{listing_category.id}"
|
||||
end.to change { ListingCategory.all.count }.by(-1)
|
||||
expect(response.body).to redirect_to "/admin/listings/categories"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Reference in a new issue