Skip to content

Commit

Permalink
Convert description to rich text
Browse files Browse the repository at this point in the history
  • Loading branch information
binos30 committed Aug 3, 2024
1 parent 5a732dd commit f0c156f
Show file tree
Hide file tree
Showing 31 changed files with 274 additions and 49 deletions.
42 changes: 42 additions & 0 deletions app/assets/stylesheets/actiontext.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Provides a drop-in pointer for the default Trix stylesheet that will format the toolbar and
* the trix-editor content (whether displayed or under editing). Feel free to incorporate this
* inclusion directly in any other asset bundle and remove this file.
*
*= require trix
*/

/*
* We need to override trix.css’s image gallery styles to accommodate the
* <action-text-attachment> element we wrap around attachments. Otherwise,
* images in galleries will be squished by the max-width: 33%; rule.
*/
.trix-content .attachment-gallery > action-text-attachment,
.trix-content .attachment-gallery > .attachment {
flex: 1 0 33%;
padding: 0 0.5em;
max-width: 33%;
}

.trix-content .attachment-gallery.attachment-gallery--2 > action-text-attachment,
.trix-content .attachment-gallery.attachment-gallery--2 > .attachment,
.trix-content .attachment-gallery.attachment-gallery--4 > action-text-attachment,
.trix-content .attachment-gallery.attachment-gallery--4 > .attachment {
flex-basis: 50%;
max-width: 50%;
}

.trix-content action-text-attachment .attachment {
padding: 0 !important;
max-width: 100% !important;
}

.trix-content ul {
list-style-type: disc;
padding-left: 1rem;
}

.trix-content ol {
list-style-type: decimal;
padding-left: 1rem;
}
16 changes: 16 additions & 0 deletions app/assets/stylesheets/application.css
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,19 @@
*= require_tree .
*= require_self
*/

.line-clamp {
display: -webkit-box;
line-clamp: 3; /* number of lines */
-webkit-line-clamp: 3; /* number of lines */
-webkit-box-orient: vertical;
overflow: hidden;
}

.line-clamp-1 {
display: -webkit-box;
line-clamp: 1; /* number of lines */
-webkit-line-clamp: 1; /* number of lines */
-webkit-box-orient: vertical;
overflow: hidden;
}
50 changes: 50 additions & 0 deletions app/assets/stylesheets/application.tailwind.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,56 @@
@tailwind components;
@tailwind utilities;

@layer base {
trix-editor {
@apply w-full;
}

trix-editor h1 {
font-size: 1.25rem !important;
line-height: 1.25rem !important;
@apply leading-5 font-semibold mb-4;
}

trix-editor a:not(.no-underline) {
@apply underline;
}

trix-editor a:visited {
color: green;
}

trix-editor ul {
list-style-type: disc;
padding-left: 1rem;
}

trix-editor ol {
list-style-type: decimal;
padding-left: 1rem;
}

trix-editor pre {
display: inline-block;
width: 100%;
vertical-align: top;
font-family: monospace;
font-size: 1.5em;
padding: 0.5em;
white-space: pre;
background-color: #eee;
overflow-x: auto;
}

trix-editor blockquote {
border: 0 solid #ccc;
border-left-width: 0px;
border-left-width: 0.3em;
margin-left: 0.3em;
padding-left: 0.6em;
}
}

@layer components {
#navbar-links {
@apply flex flex-col font-medium p-4 md:p-0 mt-4 border border-gray-100 rounded-lg bg-gray-50 md:space-x-8 rtl:space-x-reverse md:flex-row md:mt-0 md:border-0 md:bg-white;
Expand Down
15 changes: 13 additions & 2 deletions app/controllers/admin/categories_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ class CategoriesController < AdminController

# GET /admin/categories or /admin/categories.json
def index
@categories = Category.filters(params.slice(:name)).includes(image_attachment: :blob).order(:name)
@categories =
Category
.filters(params.slice(:name))
.includes([:rich_text_description, { image_attachment: :blob }])
.order(:name)
@pagy, @categories = pagy(@categories, limit: count_per_page)
end

Expand Down Expand Up @@ -87,12 +91,19 @@ def destroy # rubocop:disable Metrics/AbcSize
private

# Use callbacks to share common setup or constraints between actions.
# rubocop:disable Rails/DynamicFindBy
def set_category
@category = Category.find_by_friendly_id(params[:slug]) # rubocop:disable Rails/DynamicFindBy
@category =
if action_name == "show" || action_name == "edit"
Category.includes(:rich_text_description).find_by_friendly_id(params[:slug])
else
Category.find_by_friendly_id(params[:slug])
end
rescue ActiveRecord::RecordNotFound
logger.error "Category not found #{params[:slug]}"
redirect_back(fallback_location: admin_categories_url)
end
# rubocop:enable Rails/DynamicFindBy

# Only allow a list of trusted parameters through.
def category_params
Expand Down
8 changes: 6 additions & 2 deletions app/controllers/admin/products_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,13 @@ def set_lookups
def set_product # rubocop:disable Metrics/AbcSize
@product =
if action_name == "show"
Product.includes([:category, { images_attachments: :blob }]).find_by_friendly_id(params[:slug])
Product.includes([:category, :rich_text_description, { images_attachments: :blob }]).find_by_friendly_id(
params[:slug]
)
elsif action_name == "edit"
Product.includes([{ images_attachments: :blob }]).find_by_friendly_id(params[:slug])
Product.includes([:rich_text_description, { images_attachments: :blob }]).find_by_friendly_id(
params[:slug]
)
else
Product.find_by_friendly_id(params[:slug])
end
Expand Down
9 changes: 7 additions & 2 deletions app/controllers/site/categories_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@
module Site
class CategoriesController < SiteController
def index
@categories = Category.includes(image_attachment: :blob).filters(params.slice(:name)).active.order(:name)
@categories =
Category
.includes([:rich_text_description, { image_attachment: :blob }])
.filters(params.slice(:name))
.active
.order(:name)
@pagy, @categories = pagy_countless(@categories, limit: 10)

respond_to do |format|
Expand All @@ -13,7 +18,7 @@ def index
end

def show # rubocop:disable Metrics/AbcSize
@category = Category.active.find_by_friendly_id(params[:slug]) # rubocop:disable Rails/DynamicFindBy
@category = Category.includes(:rich_text_description).active.find_by_friendly_id(params[:slug]) # rubocop:disable Rails/DynamicFindBy
@products =
@category
.products
Expand Down
1 change: 0 additions & 1 deletion app/controllers/site/checkout_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ def create # rubocop:disable Metrics/AbcSize,Metrics/MethodLength,Metrics/Cyclom
price_data: {
product_data: {
name: item["name"],
description: product.description.presence || nil,
images: product.images.map { |img| url_for(img) },
metadata: {
product_id: product.id,
Expand Down
3 changes: 2 additions & 1 deletion app/controllers/site/home_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
module Site
class HomeController < SiteController
def index
@categories = Category.includes(image_attachment: :blob).active.order(:name).take(5)
@categories =
Category.includes([:rich_text_description, { image_attachment: :blob }]).active.order(:name).take(5)
end
end
end
5 changes: 4 additions & 1 deletion app/controllers/site/products_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ def index

def show
@product =
Product.includes([:stocks, { images_attachments: :blob }]).active.find_by_friendly_id(params[:slug]) # rubocop:disable Rails/DynamicFindBy
Product
.includes([:rich_text_description, :stocks, { images_attachments: :blob }])
.active
.find_by_friendly_id(params[:slug]) # rubocop:disable Rails/DynamicFindBy
rescue ActiveRecord::RecordNotFound
logger.error "Product not found #{params[:slug]}"
redirect_back(fallback_location: root_url)
Expand Down
2 changes: 2 additions & 0 deletions app/javascript/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import "@fortawesome/fontawesome-free/js/all.min";
import "@hotwired/turbo-rails";
import "./controllers";
import "flowbite/dist/flowbite.turbo.min";
import "trix";
import "@rails/actiontext";
import LocalTime from "local-time";

LocalTime.start();
Expand Down
11 changes: 2 additions & 9 deletions app/models/category.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

class Category < ApplicationRecord
include Filterable
include Sanitizable
include Sluggable

# Set the attribute from which the slug would be generated
Expand All @@ -13,18 +12,12 @@ class Category < ApplicationRecord
end
has_many :products, dependent: :destroy

has_rich_text :description

broadcasts_refreshes

validates :name, presence: true, uniqueness: { case_sensitive: false }
validates :image, content_type: %i[jpeg jpg png webp], size: { less_than_or_equal_to: 3.megabytes }

before_save :sanitize_fields

scope :filter_by_name, ->(name) { where("name ILIKE ?", "%#{name}%") }

private

def sanitize_fields
self.description = sanitize(description, scrubber: HtmlScrubbers::WysiwygScrubber.new)
end
end
11 changes: 2 additions & 9 deletions app/models/product.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

class Product < ApplicationRecord
include Filterable
include Sanitizable
include Sluggable

# Set the attribute from which the slug would be generated
Expand All @@ -17,6 +16,8 @@ class Product < ApplicationRecord
has_many :stocks, dependent: :destroy
has_many :order_items, dependent: :restrict_with_exception

has_rich_text :description

broadcasts_refreshes_to :category
broadcasts_refreshes

Expand All @@ -29,16 +30,8 @@ class Product < ApplicationRecord
}
validates :images, content_type: %i[jpeg jpg png webp], size: { less_than_or_equal_to: 3.megabytes }

before_save :sanitize_fields

scope :available, -> { joins(:stocks).where("quantity > 0").distinct }
scope :filter_by_name, ->(name) { where("name ILIKE ?", "%#{name}%") }
scope :filter_by_min, ->(min) { where(price: min..) }
scope :filter_by_max, ->(max) { where(price: ..max) }

private

def sanitize_fields
self.description = sanitize(description, scrubber: HtmlScrubbers::WysiwygScrubber.new)
end
end
13 changes: 13 additions & 0 deletions app/views/active_storage/blobs/_blob.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<figure class="attachment attachment--<%= blob.representable? ? "preview" : "file" %> attachment--<%= blob.filename.extension %>">
<% if blob.representable? %>
<%= image_tag blob.representation(resize_to_limit: local_assigns[:in_gallery] ? [ 800, 600 ] : [ 1024, 768 ]) %>
<% end %>
<figcaption class="attachment__caption">
<% if caption = blob.try(:caption) %>
<%= caption %>
<% else %>
<span class="attachment__name"><%= blob.filename %></span>
<span class="attachment__size"><%= number_to_human_size blob.byte_size %></span>
<% end %>
</figcaption>
</figure>
5 changes: 3 additions & 2 deletions app/views/admin/categories/_category.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ section id="#{dom_id category}" class="section-container"
p
strong class="strong-label" Name:
span class="text-gray-900 dark:text-white" =< category.name
p
div
strong class="strong-label" Description:
span class="text-gray-900 dark:text-white" =< category.description
span class="text-gray-900 dark:text-white"
= category.description
div
=> link_to edit_admin_category_path(category), class: "btn-dark border border-gray-300 dark:border-gray-700 me-2 mb-2" do
i class="fa-solid fa-pen w-3.5 h-3.5 me-2"
Expand Down
2 changes: 1 addition & 1 deletion app/views/admin/categories/_form.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ section class="section-container"
class: "form-input"
.my-5
= form.label :description, class: "form-label"
= form.text_area :description,
= form.rich_text_area :description, placeholder: "Your description here",
class: "form-input"
.my-5
= form.label :image, class: "form-label"
Expand Down
2 changes: 1 addition & 1 deletion app/views/admin/categories/_table.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ div class="relative overflow-x-auto shadow-md sm:rounded-lg"
= image_tag("https://via.placeholder.com/50")
th scope="row" class="underline px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white"
= link_to category.name, edit_admin_category_path(category), data: { turbo_frame: :_top }
td class="px-6 py-4 whitespace-nowrap"
td class="px-6 py-4 line-clamp-1"
= category.description
td class="px-6 py-4"
= status_badge(category.active)
Expand Down
2 changes: 1 addition & 1 deletion app/views/admin/products/_form.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ section class="section-container"
class: "form-input"
div class="sm:col-span-2"
= form.label :description, class: "form-label"
= form.text_area :description, rows: 8, placeholder: "Your description here",
= form.rich_text_area :description, placeholder: "Your description here",
class: "form-input"
= form.submit class: "btn-primary"
div
Expand Down
5 changes: 3 additions & 2 deletions app/views/admin/products/_product.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ section id="#{dom_id product}" class="section-container"
p
strong class="strong-label" Name:
span class="text-gray-900 dark:text-white" =< product.name
p
div
strong class="strong-label" Description:
span class="text-gray-900 dark:text-white" =< product.description
span class="text-gray-900 dark:text-white"
= product.description
p
strong class="strong-label" Price:
span class="text-gray-900 dark:text-white" =< number_to_currency(product.price, unit: "$")
Expand Down
3 changes: 3 additions & 0 deletions app/views/layouts/action_text/contents/_content.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div class="trix-content">
<%= yield -%>
</div>
2 changes: 1 addition & 1 deletion app/views/site/categories/_category.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ div id="#{dom_id category}" class="w-72 bg-white shadow-md rounded-xl duration-5
div class="px-4 py-3 w-72"
h5 class="mb-2 text-lg font-bold tracking-tight text-gray-900 block capitalize"
= category.name
p class="mb-3 font-normal text-gray-700 truncate block"
div class="mb-3 font-normal text-gray-700 line-clamp"
= category.description
div class=("inline-flex items-center px-3 py-2 text-sm font-medium text-center text-white bg-blue-700 rounded-lg" \
" hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300")
Expand Down
2 changes: 1 addition & 1 deletion app/views/site/home/_categories.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ section class="card-wrapper"
div class="px-4 py-3 w-72"
h5 class="mb-2 text-lg font-bold tracking-tight text-gray-900 block capitalize"
= category.name
p class="mb-3 font-normal text-gray-700 truncate block"
div class="mb-3 font-normal text-gray-700 line-clamp"
= category.description
div class=("inline-flex items-center px-3 py-2 text-sm font-medium text-center text-white bg-blue-700 rounded-lg" \
" hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300")
Expand Down
2 changes: 1 addition & 1 deletion app/views/site/products/show.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ div class="flex flex-wrap justify-center gap-10 py-10"
= @product.name
p class="text-2xl mt-4"
= number_to_currency(@product.price, unit: "$")
p class="text-md py-4"
div class="text-md py-4"
= @product.description
div class="my-4"
p class="text-lg uppercase" Size
Expand Down
Loading

0 comments on commit f0c156f

Please sign in to comment.