feat: Updated the design of the category page (#8165)

Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
Co-authored-by: Pranav Raj S <pranav@chatwoot.com>
This commit is contained in:
Sivin Varghese
2023-11-09 07:33:16 +05:30
committed by GitHub
parent 268e26625b
commit 950f085e80
8 changed files with 77 additions and 44 deletions

View File

@@ -41,4 +41,8 @@ module PortalHelper
def generate_article_link(portal_slug, article_slug, theme)
"/hc/#{portal_slug}/articles/#{article_slug}#{theme.present? && theme != 'system' ? "?theme=#{theme}" : ''}"
end
def render_category_content(content)
ChatwootMarkdownRenderer.new(content).render_markdown_to_plain_text
end
end

View File

@@ -11,7 +11,7 @@
<% portal.articles.published.where(category_id: nil).order(position: :asc).take(5).each do |article| %>
<a
class="text-slate-800 dark:text-slate-100 hover:underline leading-8"
href="/hc/<%= portal.slug %>/articles/<%= article.slug %><%= @theme.present? ? '?theme='+@theme : '' %>"
href="<%= generate_article_link(portal.slug, article.slug, @theme) %>"
>
<div class="flex justify-between content-center my-1 -mx-1 p-1 rounded-lg hover:bg-slate-25 dark:hover:bg-slate-800">
<%= article.title %>

View File

@@ -2,7 +2,7 @@
<section class="lg:container w-full py-6 px-4 flex flex-col h-full">
<div class="flex justify-between items-center w-full">
<h3 class="text-xl text-slate-900 dark:text-white font-semibold leading-relaxed hover:underline">
<a href="/hc/<%= portal.slug %>/<%= category.locale %>/categories/<%= category.slug %><%= @theme.present? ? '?theme='+@theme : '' %>">
<a href="/hc/<%= portal.slug %>/<%= category.locale %>/categories/<%= category.slug %><%= @theme.present? && @theme != 'system' ? '?theme='+@theme : '' %>">
<%= category.name %>
</a>
</h3>
@@ -20,7 +20,7 @@
<div class="flex justify-between content-center h-8 my-1">
<a
class="text-slate-800 dark:text-slate-50 hover:underline leading-8"
href="/hc/<%= portal.slug %>/articles/<%= article.slug %><%= @theme.present? ? '?theme='+@theme : '' %>"
href="/hc/<%= portal.slug %>/articles/<%= article.slug %><%= @theme.present? && @theme != 'system' ? '?theme='+@theme : '' %>"
>
<%= article.title %>
</a>
@@ -45,7 +45,7 @@
</div>
<div>
<a
href="/hc/<%= portal.slug %>/<%= category.locale %>/categories/<%= category.slug %><%= @theme.present? ? '?theme='+@theme : '' %>"
href="/hc/<%= portal.slug %>/<%= category.locale %>/categories/<%= category.slug %><%= @theme.present? && @theme != 'system' ? '?theme='+@theme : '' %>"
class="flex flex-row items-center text-base font-medium text-woot-600 dark:text-woot-500 hover:text-slate-900 dark:hover:text-white hover:underline mt-4"
>
<%= I18n.t('public_portal.common.view_all_articles') %>

View File

@@ -1,17 +1,26 @@
<div class="px-8 max-w-6xl w-full mx-auto">
<a
class="text-slate-700 dark:text-slate-100 text-sm hover:underline leading-8 font-semibold"
href="/hc/<%= portal.slug %>/<%= category.locale %><%= @theme.present? ? '?theme='+@theme : '' %>"
>
<%= I18n.t('public_portal.common.home') %>
</a>
<span class="text-xs text-slate-600 dark:text-slate-200 px-1">/</span>
<div class="flex justify-start items-center w-full">
<h1 class="text-3xl font-semibold leading-snug md:tracking-normal text-slate-900 dark:text-white">
<%= category.name %>
</h1>
<div class="text-slate-500 px-8 mt-2">
<%= render 'public/api/v1/portals/article_count', article_count: category.articles.published.size %>
<div class="flex flex-col px-8 max-w-5xl w-full mx-auto gap-6 <%= @is_plain_layout_enabled && 'py-4' %>">
<div class="flex items-center flex-row">
<a
class="text-slate-500 dark:text-slate-200 text-sm gap-1 <%= @is_plain_layout_enabled && 'hover:underline' %> hover:cursor-pointer leading-8 font-semibold"
href="/hc/<%= portal.slug %>/<%= category.locale %><%= @theme.present? && @theme != 'system' ? '?theme='+@theme : '' %>"
>
<%= I18n.t('public_portal.common.home') %>
</a>
<span class="w-4 h-4 [&>svg]:w-3 [&>svg]:h-3 flex items-center justify-center text-xs text-slate-500 dark:text-slate-300"><%= render partial: 'icons/chevron-right' %></span>
<span class="text-sm text-slate-800 dark:text-slate-100 font-semibold"><%= category.name %></span>
</div>
<div class="flex justify-start flex-col items-start w-full gap-2">
<div class="flex flex-col gap-2">
<% if category.icon.present? %>
<span class="text-4xl"><%= category.icon %></span>
<% end %>
<h1 class="text-3xl font-semibold leading-[52.5px] text-slate-900 dark:text-white">
<%= category.name %>
</h1>
<% if category.description.present? %>
<span class="font-medium text-slate-800 dark:text-slate-75 text-base leading-5"><%= category.description %></span>
<% end %>
</div>
<span class="flex items-center text-base text-slate-600 dark:text-slate-400 font-medium"><%= render 'public/api/v1/portals/article_count', article_count: category.articles.published.size %></span>
</div>
</div>

View File

@@ -6,48 +6,36 @@
<% end %>
<% if !@is_plain_layout_enabled %>
<div class="bg-woot-50 dark:bg-woot-900" style="<%= generate_portal_bg(@portal.color, @theme) %>">
<div class="pt-16 pb-20" style="<%= generate_gradient_to_bottom(@theme) %>">
<div id="portal-bg" class="bg-woot-50 dark:bg-woot-900" style="<%= generate_portal_bg(@portal.color, @theme) %>">
<div id="portal-bg-gradient" class="pt-8 pb-8 md:pt-14 md:pb-6" style="<%= generate_gradient_to_bottom(@theme) %>">
<%= render 'public/api/v1/portals/categories/category-hero', category: @category, portal: @portal %>
</div>
</div>
<% else %>
<%= render 'public/api/v1/portals/categories/category-hero', category: @category, portal: @portal %>
<% end %>
<section class="max-w-6xl w-full mx-auto py-6 px-8 flex flex-col items-center justify-center flex-grow">
<div class="py-4 w-full mt-2 flex-grow">
<section class="max-w-5xl w-full mx-auto px-8 py-6 flex flex-col items-center justify-center flex-grow">
<div class="w-full flex flex-col gap-6 flex-grow">
<% if @category.articles.published.size == 0 %>
<div class="h-full flex items-center justify-center bg-slate-50 dark:bg-slate-800 rounded-xl py-6">
<p class="text-sm text-slate-500"><%= I18n.t('public_portal.common.no_articles') %></p>
</div>
<% else %>
<% @category.articles.published.order(:position).each do |article| %>
<div class="<%= !@is_plain_layout_enabled ? 'group border border-solid border-slate-100 dark:border-slate-800 hover:border-woot-600 dark:hover:border-woot-600 rounded-lg' : '' %>">
<a
class="text-slate-800 dark:text-slate-50 flex justify-between content-center mb-4 py-2"
href="/hc/<%= @portal.slug %>/articles/<%= article.slug %><%= @theme.present? ? '?theme='+@theme : '' %>"
class="<%= !@is_plain_layout_enabled ? 'p-4' : 'px-0 py-1' %> text-slate-800 dark:text-slate-50 flex justify-between content-center hover:cursor-pointer"
href="/hc/<%= @portal.slug %>/articles/<%= article.slug %><%= @theme.present? && @theme != 'system' ? '?theme='+@theme : '' %>"
>
<div>
<p class="mb-2 hover:underline font-semibold"><%= article.title %></p>
<p class="text-sm">
<%= I18n.t('public_portal.common.last_updated_on', last_updated_on: article.updated_at.strftime("%b %d, %Y")) %>
</p>
<div class="flex flex-col gap-5">
<div class="flex flex-col gap-1">
<h3 class="text-lg text-slate-900 dark:text-slate-50 font-semibold <%= @is_plain_layout_enabled ? 'hover:underline' : 'group-hover:text-woot-600 dark:group-hover:text-woot-600' %>"><%= article.title %></h3>
<p class="text-base font-normal text-slate-500 dark:text-slate-200 line-clamp-1 break-all"><%= render_category_content(article.content) %></p>
</div>
<span class="text-sm text-slate-600 dark:text-slate-400 font-medium flex items-center"><%= I18n.t('public_portal.common.last_updated_on', last_updated_on: article.updated_at.strftime("%b %d, %Y")) %></span>
</div>
<span>
<svg
class="w-4 h-4 fill-current text-slate-700 dark:text-slate-200"
width="24"
height="24"
fill="none"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M8.47 4.22a.75.75 0 0 0 0 1.06L15.19 12l-6.72 6.72a.75.75 0 1 0 1.06 1.06l7.25-7.25a.75.75 0 0 0 0-1.06L9.53 4.22a.75.75 0 0 0-1.06 0Z"
/>
</svg>
</span>
</a>
</div>
<% end %>
<% end %>
</div>

View File

@@ -18,6 +18,10 @@ class ChatwootMarkdownRenderer
render_as_html_safe(html)
end
def render_markdown_to_plain_text
CommonMarker.render_doc(@content, :DEFAULT).to_plaintext
end
private
def render_as_html_safe(html)

View File

@@ -119,4 +119,19 @@ describe PortalHelper do
end
end
end
describe '#render_category_content' do
let(:markdown_content) { 'This is a *test* markdown content' }
let(:plain_text_content) { 'This is a test markdown content' }
let(:renderer) { instance_double(ChatwootMarkdownRenderer) }
before do
allow(ChatwootMarkdownRenderer).to receive(:new).with(markdown_content).and_return(renderer)
allow(renderer).to receive(:render_markdown_to_plain_text).and_return(plain_text_content)
end
it 'converts markdown to plain text' do
expect(helper.render_category_content(markdown_content)).to eq(plain_text_content)
end
end
end

View File

@@ -2,6 +2,7 @@ require 'rails_helper'
RSpec.describe ChatwootMarkdownRenderer do
let(:markdown_content) { 'This is a *test* content with ^markdown^' }
let(:plain_text_content) { 'This is a test content with markdown' }
let(:doc) { instance_double(CommonMarker::Node) }
let(:renderer) { described_class.new(markdown_content) }
let(:markdown_renderer) { instance_double(CustomMarkdownRenderer) }
@@ -44,4 +45,16 @@ RSpec.describe ChatwootMarkdownRenderer do
expect(rendered_message).to be_html_safe
end
end
describe '#render_markdown_to_plain_text' do
let(:rendered_content) { renderer.render_markdown_to_plain_text }
before do
allow(doc).to receive(:to_plaintext).and_return(plain_text_content)
end
it 'renders the markdown content to plain text' do
expect(rendered_content).to eq(plain_text_content)
end
end
end