mirror of
https://github.com/lingble/chatwoot.git
synced 2025-11-01 19:48:08 +00:00
feat: Adds dark theme support for public portal [CW-2525] (#7979)
Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
6a73953003
commit
b71a580573
@@ -1,5 +1,6 @@
|
||||
class Public::Api::V1::Portals::BaseController < PublicController
|
||||
before_action :show_plain_layout
|
||||
before_action :set_color_scheme
|
||||
around_action :set_locale
|
||||
after_action :allow_iframe_requests
|
||||
|
||||
@@ -9,6 +10,14 @@ class Public::Api::V1::Portals::BaseController < PublicController
|
||||
@is_plain_layout_enabled = params[:show_plain_layout] == 'true'
|
||||
end
|
||||
|
||||
def set_color_scheme
|
||||
@theme = if %w[dark light].include?(params[:theme])
|
||||
params[:theme]
|
||||
else
|
||||
''
|
||||
end
|
||||
end
|
||||
|
||||
def set_locale(&)
|
||||
switch_locale_with_portal(&) if params[:locale].present?
|
||||
switch_locale_with_article(&) if params[:article_slug].present?
|
||||
|
||||
11
app/helpers/portal_helper.rb
Normal file
11
app/helpers/portal_helper.rb
Normal file
@@ -0,0 +1,11 @@
|
||||
module PortalHelper
|
||||
def generate_portal_bg_color(portal_color, theme)
|
||||
base_color = theme == 'dark' ? 'black' : 'white'
|
||||
"color-mix(in srgb, #{portal_color} 10%, #{base_color})"
|
||||
end
|
||||
|
||||
def generate_portal_bg(portal_color, theme)
|
||||
bg_image = theme == 'dark' ? 'grid_dark.svg' : 'grid.svg'
|
||||
"background: url(/assets/images/hc/#{bg_image}) #{generate_portal_bg_color(portal_color, theme)}"
|
||||
end
|
||||
end
|
||||
@@ -1,16 +1,16 @@
|
||||
<template>
|
||||
<div
|
||||
class="w-full flex items-center rounded-md border-solid border-2 h-16 bg-white px-4 py-2 text-slate-600"
|
||||
class="w-full flex items-center rounded-md border-solid border-2 h-16 bg-white dark:bg-slate-900 px-4 py-2 text-slate-600 dark:text-slate-200"
|
||||
:class="{
|
||||
'shadow border-woot-100': isFocused,
|
||||
'border-slate-50 shadow-sm': !isFocused,
|
||||
'shadow border-woot-100 dark:border-woot-700': isFocused,
|
||||
'border-slate-50 dark:border-slate-800 shadow-sm': !isFocused,
|
||||
}"
|
||||
>
|
||||
<fluent-icon icon="search" />
|
||||
<input
|
||||
:value="value"
|
||||
type="text"
|
||||
class="w-full focus:outline-none text-base h-full bg-white px-2 py-2 text-slate-700 placeholder-slate-500"
|
||||
class="w-full focus:outline-none text-base h-full bg-white dark:bg-slate-900 px-2 py-2 text-slate-700 dark:text-slate-100 placeholder-slate-500"
|
||||
:placeholder="searchPlaceholder"
|
||||
role="search"
|
||||
@input="onChange"
|
||||
|
||||
@@ -1,16 +1,22 @@
|
||||
<template>
|
||||
<div
|
||||
class="shadow-md bg-white mt-2 max-h-72 scroll-py-2 p-4 rounded overflow-y-auto text-sm text-slate-700"
|
||||
class="shadow-md bg-white dark:bg-slate-900 mt-2 max-h-72 scroll-py-2 p-4 rounded overflow-y-auto text-sm text-slate-700 dark:text-slate-100"
|
||||
>
|
||||
<div v-if="isLoading" class="font-medium text-sm text-slate-400">
|
||||
<div
|
||||
v-if="isLoading"
|
||||
class="font-medium text-sm text-slate-400 dark:text-slate-700"
|
||||
>
|
||||
{{ loadingPlaceholder }}
|
||||
</div>
|
||||
<h3 v-if="shouldShowResults" class="font-medium text-sm text-slate-400">
|
||||
<h3
|
||||
v-if="shouldShowResults"
|
||||
class="font-medium text-sm text-slate-400 dark:text-slate-700"
|
||||
>
|
||||
{{ resultsTitle }}
|
||||
</h3>
|
||||
<ul
|
||||
v-if="shouldShowResults"
|
||||
class="bg-white mt-2 max-h-72 scroll-py-2 overflow-y-auto text-sm text-slate-700"
|
||||
class="bg-white dark:bg-slate-900 mt-2 max-h-72 scroll-py-2 overflow-y-auto text-sm text-slate-700 dark:text-slate-100"
|
||||
role="listbox"
|
||||
>
|
||||
<li
|
||||
@@ -18,7 +24,7 @@
|
||||
:id="article.id"
|
||||
:key="article.id"
|
||||
class="group flex cursor-default select-none items-center rounded-md p-2 mb-1"
|
||||
:class="{ 'bg-slate-25': index === selectedIndex }"
|
||||
:class="{ 'bg-slate-25 dark:bg-slate-800': index === selectedIndex }"
|
||||
role="option"
|
||||
tabindex="-1"
|
||||
@mouseover="onHover(index)"
|
||||
@@ -32,7 +38,10 @@
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div v-if="showEmptyResults" class="font-medium text-sm text-slate-400">
|
||||
<div
|
||||
v-if="showEmptyResults"
|
||||
class="font-medium text-sm text-slate-400 dark:text-slate-700"
|
||||
>
|
||||
{{ emptyPlaceholder }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<nav class="max-w-2xl">
|
||||
<h2
|
||||
id="on-this-page-title"
|
||||
class="text-slate-800 font-semibold tracking-wide border-b mb-3 leading-7"
|
||||
class="text-slate-800 dark:text-slate-50 font-semibold tracking-wide border-b mb-3 leading-7"
|
||||
>
|
||||
{{ tocHeader }}
|
||||
</h2>
|
||||
@@ -14,7 +14,7 @@
|
||||
<a
|
||||
:href="`#${element.slug}`"
|
||||
data-turbolinks="false"
|
||||
class="text-base text-slate-800 cursor-pointer"
|
||||
class="text-base text-slate-800 dark:text-slate-50 cursor-pointer"
|
||||
>
|
||||
{{ element.title }}
|
||||
</a>
|
||||
|
||||
@@ -28,8 +28,8 @@ By default, it renders:
|
||||
<% end %>
|
||||
</head>
|
||||
<body>
|
||||
<div class="antialiased">
|
||||
<main class="main-content min-h-screen flex flex-col" role="main">
|
||||
<div class="antialiased <%= @theme %>">
|
||||
<main class="main-content min-h-screen flex flex-col bg-white dark:bg-slate-900" role="main">
|
||||
<% if !@is_plain_layout_enabled %>
|
||||
<%= render "public/api/v1/portals/header", portal: @portal %>
|
||||
<% end %>
|
||||
@@ -40,6 +40,11 @@ By default, it renders:
|
||||
</main>
|
||||
</div>
|
||||
</body>
|
||||
<style>
|
||||
:root {
|
||||
color-scheme: '<%= @theme %>';
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
window.portalConfig = {
|
||||
portalSlug: '<%= @portal.slug %>',
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<section class="bg-white lg:container w-full py-6 px-4 flex flex-col h-full">
|
||||
<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-800 font-medium leading-relaxed hover:underline">
|
||||
<a href="/hc/<%= portal.slug %>/<%= category.locale %>/categories/<%= category.slug %>">
|
||||
<h3 class="text-xl text-slate-800 dark:text-slate-50 font-medium leading-relaxed hover:underline">
|
||||
<a href="/hc/<%= portal.slug %>/<%= category.locale %>/categories/<%= category.slug %><%= @theme.present? ? '?theme='+@theme : '' %>">
|
||||
<%= category.name %>
|
||||
</a>
|
||||
</h3>
|
||||
@@ -11,20 +11,20 @@
|
||||
</div>
|
||||
<div class="py-4 w-full mt-2 flex-grow">
|
||||
<% if category.articles.published.size == 0 %>
|
||||
<div class="h-full flex items-center justify-center bg-slate-50 rounded-xl mb-4">
|
||||
<div class="h-full flex items-center justify-center bg-slate-50 dark:bg-slate-800 rounded-xl mb-4">
|
||||
<p class="text-sm text-slate-500"><%= I18n.t('public_portal.common.no_articles') %></p>
|
||||
</div>
|
||||
<% else %>
|
||||
<% category.articles.published.order(position: :asc).take(5).each do |article| %>
|
||||
<a
|
||||
class="text-slate-800 hover:underline leading-8"
|
||||
href="/hc/<%= portal.slug %>/articles/<%= article.slug %>"
|
||||
class="text-slate-800 dark:text-slate-50 hover:underline leading-8"
|
||||
href="/hc/<%= portal.slug %>/articles/<%= article.slug %><%= @theme.present? ? '?theme='+@theme : '' %>"
|
||||
>
|
||||
<div class="flex justify-between content-center my-1 -mx-1 p-1 rounded-lg hover:bg-slate-25">
|
||||
<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 %>
|
||||
<span class="flex items-center">
|
||||
<svg
|
||||
class="w-4 h-4 fill-current text-slate-700"
|
||||
class="w-4 h-4 fill-current text-slate-700 dark:text-slate-200"
|
||||
width="24"
|
||||
height="24"
|
||||
fill="none"
|
||||
@@ -42,7 +42,7 @@
|
||||
</div>
|
||||
<div>
|
||||
<a
|
||||
href="/hc/<%= portal.slug %>/<%= category.locale %>/categories/<%= category.slug %>"
|
||||
href="/hc/<%= portal.slug %>/<%= category.locale %>/categories/<%= category.slug %><%= @theme.present? ? '?theme='+@theme : '' %>"
|
||||
class="flex flex-row items-center text-base font-medium text-woot-500 hover:underline mt-4"
|
||||
style="color: <%= portal.color %>"
|
||||
>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
<footer class="pt-16 pb-8 flex flex-col items-center justify-center">
|
||||
<div class="mx-auto max-w-2xl">
|
||||
<p class="text-slate-700 py-2 text-center">
|
||||
<p class="text-slate-700 dark:text-slate-100 py-2 text-center">
|
||||
<%= I18n.t('public_portal.footer.made_with') %> <a class="hover:underline" href="https://www.chatwoot.com" target="_blank" rel="noopener noreferrer nofoll/ow">Chatwoot</a> 💙
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
|
||||
<header class="bg-white w-full shadow-sm sticky top-0 z-50">
|
||||
<nav class=" flex bg-white mx-auto max-w-6xl px-8" aria-label="Top">
|
||||
<header class="bg-white dark:bg-slate-900 w-full shadow-sm sticky top-0 z-50">
|
||||
<nav class=" flex mx-auto max-w-6xl px-8" aria-label="Top">
|
||||
<div class="w-full py-5 flex items-center">
|
||||
<a href="/hc/<%= @portal.slug %>/<%= @portal.config['default_locale'] || params[:locale] %>/" class="h-10 text-lg flex items-center text-slate-900 font-semibold">
|
||||
<a href="/hc/<%= @portal.slug %>/<%= @portal.config['default_locale'] || params[:locale] %>/<%= @theme.present? ? '?theme='+@theme : '' %>" class="h-10 text-lg flex items-center text-slate-900 dark:text-white font-semibold">
|
||||
<% if @portal.logo.present? %>
|
||||
<img src="<%= url_for(@portal.logo) %>" class="h-10 w-auto mr-2" />
|
||||
<% end %>
|
||||
<%= @portal.name %>
|
||||
</a>
|
||||
<% if @portal.homepage_link %>
|
||||
<div class="ml-8 border-l-1 border-slate-50 hidden md:block">
|
||||
<div class="ml-8 border-l-1 border-slate-50 dark:border-slate-800 hidden md:block">
|
||||
<div class="flex-grow flex-shrink-0">
|
||||
<a target="_blank" rel="noopener noreferrer nofollow" href="<%= @portal.homepage_link %>" class="flex flex-row items-center text-sm font-medium text-slate-700 hover:text-slate-800 hover:underline"> <%= I18n.t('public_portal.header.go_to_homepage') %>
|
||||
<a target="_blank" rel="noopener noreferrer nofollow" href="<%= @portal.homepage_link %>" class="flex flex-row items-center text-sm font-medium text-slate-700 dark:text-slate-200 hover:text-slate-800 dark:hover:text-slate-300 hover:underline"> <%= I18n.t('public_portal.header.go_to_homepage') %>
|
||||
<span class="ml-2">
|
||||
<svg class="w-4 h-4 fill-current text-slate-600" width="24" height="24" fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M13.267 4.209a.75.75 0 0 0-1.034 1.086l6.251 5.955H3.75a.75.75 0 0 0 0 1.5h14.734l-6.251 5.954a.75.75 0 0 0 1.034 1.087l7.42-7.067a.996.996 0 0 0 .3-.58.758.758 0 0 0-.001-.29.995.995 0 0 0-.3-.578l-7.419-7.067Z" /></svg>
|
||||
<svg class="w-4 h-4 fill-current text-slate-600 dark:text-slate-200" width="24" height="24" fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M13.267 4.209a.75.75 0 0 0-1.034 1.086l6.251 5.955H3.75a.75.75 0 0 0 0 1.5h14.734l-6.251 5.954a.75.75 0 0 0 1.034 1.087l7.42-7.067a.996.996 0 0 0 .3-.58.758.758 0 0 0-.001-.29.995.995 0 0 0-.3-.578l-7.419-7.067Z" /></svg>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
@@ -25,13 +25,13 @@
|
||||
<div class="inline-flex relative w-24">
|
||||
<select
|
||||
data-portal-slug="<%= @portal.slug %>"
|
||||
class="appearance-none w-full bg-white px-3 py-2 pr-8 rounded leading-tight focus:outline-none focus:shadow-outline locale-switcher hover:bg-slate-75 cursor-pointer"
|
||||
class="appearance-none w-full bg-white dark:bg-slate-900 dark:text-slate-100 px-3 py-2 pr-8 rounded leading-tight focus:outline-none focus:shadow-outline locale-switcher hover:bg-slate-75 dark:hover:bg-slate-800 cursor-pointer"
|
||||
>
|
||||
<% @portal.config["allowed_locales"].each do |locale| %>
|
||||
<option <%= locale == params[:locale] ? 'selected': '' %> value="<%= locale %>"><%= locale %></option>
|
||||
<% end %>
|
||||
</select>
|
||||
<div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-gray-700">
|
||||
<div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-slate-700 dark:text-slate-200">
|
||||
<svg class="fill-current h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"/></svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<% if !@is_plain_layout_enabled %>
|
||||
<section class="pt-8 pb-16 md:py-20 w-full bg-woot-50 shadow-inner" style="background: url(/assets/images/hc/grid.svg) color-mix(in srgb, <%= @portal.color %> 10%, white)">
|
||||
<section class="pt-8 pb-16 md:py-20 w-full bg-woot-50 dark:bg-woot-900 shadow-inner" style="<%= generate_portal_bg(@portal.color, @theme) %>">
|
||||
<div class="mx-auto max-w-6xl px-8 flex flex-col items-center sm:items-start">
|
||||
<h1 class="text-2xl md:text-4xl text-slate-900 font-semibold leading-normal">
|
||||
<h1 class="text-2xl md:text-4xl text-slate-900 dark:text-white font-semibold leading-normal">
|
||||
<%= portal.header_text %>
|
||||
</h1>
|
||||
<p class="text-slate-600 text-center text-lg leading-normal pt-4 pb-4"><%= I18n.t('public_portal.hero.sub_title') %></p>
|
||||
<p class="text-slate-600 dark:text-slate-200 text-center text-lg leading-normal pt-4 pb-4"><%= I18n.t('public_portal.hero.sub_title') %></p>
|
||||
<div id="search-wrap"></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<section class="bg-white lg:container w-full py-6 px-4 flex flex-col h-full">
|
||||
<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 font-semibold leading-relaxed hover:underline">
|
||||
<h3 class="text-xl text-slate-900 dark:text-white font-semibold leading-relaxed hover:underline">
|
||||
<%= category %>
|
||||
</h3>
|
||||
<span class="text-slate-500">
|
||||
@@ -10,14 +10,14 @@
|
||||
<div class="py-4 w-full mt-2 flex-grow">
|
||||
<% portal.articles.published.where(category_id: nil).order(position: :asc).take(5).each do |article| %>
|
||||
<a
|
||||
class="text-slate-800 hover:underline leading-8"
|
||||
href="/hc/<%= portal.slug %>/articles/<%= article.slug %>"
|
||||
class="text-slate-800 dark:text-slate-100 hover:underline leading-8"
|
||||
href="/hc/<%= portal.slug %>/articles/<%= article.slug %><%= @theme.present? ? '?theme='+@theme : '' %>"
|
||||
>
|
||||
<div class="flex justify-between content-center my-1 -mx-1 p-1 rounded-lg hover:bg-slate-25">
|
||||
<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 %>
|
||||
<span class="flex items-center">
|
||||
<svg
|
||||
class="w-4 h-4 fill-current text-slate-700"
|
||||
class="w-4 h-4 fill-current text-slate-700 dark:text-slate-200"
|
||||
width="24"
|
||||
height="24"
|
||||
fill="none"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<h1 class="text-3xl font-semibold md:tracking-normal leading-snug md:text-4xl text-slate-900">
|
||||
<h1 class="text-3xl font-semibold md:tracking-normal leading-snug md:text-4xl text-slate-900 dark:text-white">
|
||||
<%= article.title %>
|
||||
</h1>
|
||||
<div class="flex flex-col items-start justify-between w-full md:flex-row md:items-center pt-2">
|
||||
@@ -9,8 +9,8 @@
|
||||
</div>
|
||||
<% end %>
|
||||
<div>
|
||||
<h5 class="text-base font-medium text-slate-900 mb-2"><%= article.author.available_name %></h5>
|
||||
<p class="text-sm font-normal text-slate-700">
|
||||
<h5 class="text-base font-medium text-slate-900 dark:text-white mb-2"><%= article.author.available_name %></h5>
|
||||
<p class="text-sm font-normal text-slate-700 dark:text-slate-100">
|
||||
<%= I18n.t('public_portal.common.last_updated_on', last_updated_on: article.updated_at.strftime("%b %d, %Y")) %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<div class="bg-slate-50">
|
||||
<div class="bg-slate-50 dark:bg-slate-800">
|
||||
<div class="max-w-4xl px-6 py-16 mx-auto space-y-12 w-full">
|
||||
<div class="space-y-4">
|
||||
<div>
|
||||
<a
|
||||
class="text-slate-800 hover:underline leading-8"
|
||||
href="/hc/<%= @portal.slug %>/<%= @category.present? ? @category.slug : '' %>"
|
||||
href="/hc/<%= @portal.slug %>/<%= @category.present? ? @category.slug : '' %><%= @theme.present? ? '?theme='+@theme : '' %>"
|
||||
>
|
||||
<%= @portal.name %> <%= I18n.t('public_portal.common.home') %>
|
||||
</a>
|
||||
@@ -12,14 +12,14 @@
|
||||
<span>/</span>
|
||||
</div>
|
||||
<% @articles.each do |article| %>
|
||||
<h1 class="text-4xl font-semibold md:tracking-normal leading-snug md:text-5xl text-slate-900">
|
||||
<h1 class="text-4xl font-semibold md:tracking-normal leading-snug md:text-5xl text-slate-900 dark:text-white">
|
||||
<%= article.title %></h1>
|
||||
<div class="flex flex-col items-start justify-between w-full md:flex-row md:items-center pt-2">
|
||||
<div class="flex items-center space-x-2">
|
||||
<img src="<%= article.author.avatar_url %>" alt="" class="w-12 h-812 border rounded-full">
|
||||
<div>
|
||||
<h5 class="text-base font-medium text-slate-900 mb-2"><%= article.author.name %></h5>
|
||||
<p class="text-sm font-normal text-slate-700">
|
||||
<h5 class="text-base font-medium text-slate-900 dark:text-white mb-2"><%= article.author.name %></h5>
|
||||
<p class="text-sm font-normal text-slate-700 dark:text-slate-100">
|
||||
<%= article.author.updated_at.strftime("%B %d %Y") %></p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -30,7 +30,7 @@
|
||||
</div>
|
||||
<div class="max-w-4xl flex-grow w-full px-8 py-16 mx-auto space-y-12">
|
||||
<article class="space-y-8">
|
||||
<div class="text-slate-800 font-sans leading-8 text-lg max-w-3xl blog-content">
|
||||
<div class="text-slate-800 dark:text-slate-50 font-sans leading-8 text-lg max-w-3xl blog-content">
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
|
||||
@@ -12,25 +12,25 @@
|
||||
<% end %>
|
||||
|
||||
<% if !@is_plain_layout_enabled %>
|
||||
<div class="bg-woot-50 py-8 shadow-inner" style="background: url(/assets/images/hc/grid.svg) color-mix(in srgb, <%= @portal.color %> 10%, white)">
|
||||
<div class="bg-woot-50 dark:bg-woot-900 py-8 shadow-inner" style="<%= generate_portal_bg(@portal.color, @theme) %>">
|
||||
<div class="max-w-6xl px-8 pt-8 pb-16 mx-auto space-y-4 w-full">
|
||||
<div>
|
||||
<a
|
||||
class="text-slate-700 hover:underline leading-8 text-sm font-semibold"
|
||||
href="/hc/<%= @portal.slug %>/<%= @article.category&.locale %>"
|
||||
class="text-slate-700 dark:text-slate-100 hover:underline leading-8 text-sm font-semibold"
|
||||
href="/hc/<%= @portal.slug %>/<%= @article.category&.locale %><%= @theme.present? ? '?theme='+@theme : '' %>"
|
||||
>
|
||||
Home
|
||||
</a>
|
||||
<span class="text-xs text-slate-600 px-1">/</span>
|
||||
<span class="text-xs text-slate-600 dark:text-slate-200 px-1">/</span>
|
||||
<% if @article.category %>
|
||||
<a
|
||||
class="text-slate-700 hover:underline leading-8 text-sm font-semibold"
|
||||
href="/hc/<%= @portal.slug %>/<%= @article.category.locale %>/categories/<%= @article.category.slug %>"
|
||||
class="text-slate-700 dark:text-slate-100 hover:underline leading-8 text-sm font-semibold"
|
||||
href="/hc/<%= @portal.slug %>/<%= @article.category.locale %>/categories/<%= @article.category.slug %><%= @theme.present? ? '?theme='+@theme : '' %>"
|
||||
>
|
||||
<%= @article.category&.name %>
|
||||
</a>
|
||||
<% else %>
|
||||
<span class="text-slate-700 leading-8 text-sm font-semibold" > Uncategorized </span>
|
||||
<span class="text-slate-700 dark:text-slate-100 leading-8 text-sm font-semibold" > Uncategorized </span>
|
||||
<% end %>
|
||||
</div>
|
||||
<%= render "public/api/v1/portals/articles/article_header", article: @article %>
|
||||
@@ -43,7 +43,7 @@
|
||||
<% end %>
|
||||
|
||||
<div class="flex max-w-6xl w-full px-8 mx-auto">
|
||||
<article id="cw-article-content" class="flex-grow flex-2 mx-auto text-slate-800 text-lg max-w-3xl prose break-words w-full <%= @is_plain_layout_enabled ? 'py-4' : 'py-12' %>">
|
||||
<article id="cw-article-content" class="flex-grow flex-2 mx-auto text-slate-800 dark:text-slate-50 text-lg max-w-3xl prose dark:prose-invert break-words w-full <%= @is_plain_layout_enabled ? 'py-4' : 'py-12' %>">
|
||||
<%= @parsed_content %>
|
||||
</article>
|
||||
<div class="flex-1" id="cw-hc-toc"></div>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
|
||||
<section class="bg-white lg:container w-full py-6 px-4 flex flex-col h-full">
|
||||
<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 font-semibold leading-relaxed hover:underline"">
|
||||
<a href="/hc/<%= portal.slug %>/<%= category.locale %>/categories/<%= category.slug %>">
|
||||
<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 : '' %>">
|
||||
<%= category.name %>
|
||||
</a>
|
||||
</h3>
|
||||
@@ -12,21 +12,21 @@
|
||||
</div>
|
||||
<div class="py-4 w-full mt-2 flex-grow">
|
||||
<% if category.articles.published.size == 0 %>
|
||||
<div class="h-full flex items-center justify-center bg-slate-50 rounded-xl mb-4">
|
||||
<div class="h-full flex items-center justify-center bg-slate-50 dark:bg-slate-800 rounded-xl mb-4">
|
||||
<p class="text-sm text-slate-500"><%= I18n.t('public_portal.common.no_articles') %></p>
|
||||
</div>
|
||||
<% else %>
|
||||
<% category.articles.published.order(position: :asc).take(5).each do |article| %>
|
||||
<div class="flex justify-between content-center h-8 my-1">
|
||||
<a
|
||||
class="text-slate-800 hover:underline leading-8"
|
||||
href="/hc/<%= portal.slug %>/articles/<%= article.slug %>"
|
||||
class="text-slate-800 dark:text-slate-50 hover:underline leading-8"
|
||||
href="/hc/<%= portal.slug %>/articles/<%= article.slug %><%= @theme.present? ? '?theme='+@theme : '' %>"
|
||||
>
|
||||
<%= article.title %>
|
||||
</a>
|
||||
<span class="flex items-center">
|
||||
<svg
|
||||
class="w-4 h-4 fill-current text-slate-700"
|
||||
class="w-4 h-4 fill-current text-slate-700 dark:text-slate-200"
|
||||
width="24"
|
||||
height="24"
|
||||
fill="none"
|
||||
@@ -45,8 +45,8 @@
|
||||
</div>
|
||||
<div>
|
||||
<a
|
||||
href="/hc/<%= portal.slug %>/<%= category.locale %>/categories/<%= category.slug %>"
|
||||
class="flex flex-row items-center text-base font-medium text-woot-600 hover:text-slate-900 hover:underline mt-4"
|
||||
href="/hc/<%= portal.slug %>/<%= category.locale %>/categories/<%= category.slug %><%= @theme.present? ? '?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') %>
|
||||
<span class="ml-2">
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<div class="px-8 max-w-6xl w-full mx-auto">
|
||||
<a
|
||||
class="text-slate-700 text-sm hover:underline leading-8 font-semibold"
|
||||
href="/hc/<%= portal.slug %>/<%= category.locale %>"
|
||||
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 px-1">/</span>
|
||||
<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">
|
||||
<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">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
<section class="bg-slate-50 py-16 flex flex-col items-center justify-center">
|
||||
<section class="bg-slate-50 dark:bg-slate-800 py-16 flex flex-col items-center justify-center">
|
||||
<div class="mx-auto max-w-2xl">
|
||||
<h1 class="text-4xl text-slate-900 font-semibold leading-relaxed text-center"><%= portal.header_text %></h1>
|
||||
<p class="text-slate-700 py-2 text-center"><%= I18n.t('public_portal.hero.sub_title') %></p>
|
||||
<h1 class="text-4xl text-slate-900 dark:text-white font-semibold leading-relaxed text-center"><%= portal.header_text %></h1>
|
||||
<p class="text-slate-700 dark:text-slate-100 py-2 text-center"><%= I18n.t('public_portal.hero.sub_title') %></p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -6,23 +6,23 @@
|
||||
<% end %>
|
||||
|
||||
<% if !@is_plain_layout_enabled %>
|
||||
<div class="bg-woot-50 pt-16 pb-20" style="background: url(/assets/images/hc/grid.svg) color-mix(in srgb, <%= @portal.color %> 10%, white)">
|
||||
<div class="bg-woot-50 dark:bg-woot-900 pt-16 pb-20" style="<%= generate_portal_bg(@portal.color, @theme) %>">
|
||||
<%= render 'public/api/v1/portals/categories/category-hero', category: @category, portal: @portal %>
|
||||
</div>
|
||||
<% else %>
|
||||
<%= render 'public/api/v1/portals/categories/category-hero', category: @category, portal: @portal %>
|
||||
<% end %>
|
||||
<section class="bg-white max-w-6xl w-full mx-auto py-6 px-8 flex flex-col items-center justify-center flex-grow">
|
||||
<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">
|
||||
<% if @category.articles.published.size == 0 %>
|
||||
<div class="h-full flex items-center justify-center bg-slate-50 rounded-xl py-6">
|
||||
<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| %>
|
||||
<a
|
||||
class="text-slate-800 flex justify-between content-center mb-4 py-2"
|
||||
href="/hc/<%= @portal.slug %>/articles/<%= article.slug %>"
|
||||
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 : '' %>"
|
||||
>
|
||||
<div>
|
||||
<p class="mb-2 hover:underline font-semibold"><%= article.title %></p>
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
<span>
|
||||
<svg
|
||||
class="w-4 h-4 fill-current text-slate-700"
|
||||
class="w-4 h-4 fill-current text-slate-700 dark:text-slate-200"
|
||||
width="24"
|
||||
height="24"
|
||||
fill="none"
|
||||
|
||||
4
public/assets/images/hc/grid_dark.svg
Normal file
4
public/assets/images/hc/grid_dark.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="32" height="32" fill="none" stroke="#b0c7d4"
|
||||
stroke-opacity="0.04">
|
||||
<path d="M0 .5H31.5V32" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 173 B |
60
spec/helpers/portal_helper_spec.rb
Normal file
60
spec/helpers/portal_helper_spec.rb
Normal file
@@ -0,0 +1,60 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe PortalHelper do
|
||||
describe '#generate_portal_bg_color' do
|
||||
context 'when theme is dark' do
|
||||
it 'returns the correct color mix with black' do
|
||||
expect(helper.generate_portal_bg_color('#ff0000', 'dark')).to eq(
|
||||
'color-mix(in srgb, #ff0000 10%, black)'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when theme is not dark' do
|
||||
it 'returns the correct color mix with white' do
|
||||
expect(helper.generate_portal_bg_color('#ff0000', 'light')).to eq(
|
||||
'color-mix(in srgb, #ff0000 10%, white)'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when provided with various colors' do
|
||||
it 'adjusts the color mix appropriately' do
|
||||
expect(helper.generate_portal_bg_color('#00ff00', 'dark')).to eq(
|
||||
'color-mix(in srgb, #00ff00 10%, black)'
|
||||
)
|
||||
expect(helper.generate_portal_bg_color('#0000ff', 'light')).to eq(
|
||||
'color-mix(in srgb, #0000ff 10%, white)'
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#generate_portal_bg' do
|
||||
context 'when theme is dark' do
|
||||
it 'returns the correct background with dark grid image and color mix with black' do
|
||||
expected_bg = 'background: url(/assets/images/hc/grid_dark.svg) color-mix(in srgb, #ff0000 10%, black)'
|
||||
expect(helper.generate_portal_bg('#ff0000', 'dark')).to eq(expected_bg)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when theme is not dark' do
|
||||
it 'returns the correct background with light grid image and color mix with white' do
|
||||
expected_bg = 'background: url(/assets/images/hc/grid.svg) color-mix(in srgb, #ff0000 10%, white)'
|
||||
expect(helper.generate_portal_bg('#ff0000', 'light')).to eq(expected_bg)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when provided with various colors' do
|
||||
it 'adjusts the background appropriately for dark theme' do
|
||||
expected_bg = 'background: url(/assets/images/hc/grid_dark.svg) color-mix(in srgb, #00ff00 10%, black)'
|
||||
expect(helper.generate_portal_bg('#00ff00', 'dark')).to eq(expected_bg)
|
||||
end
|
||||
|
||||
it 'adjusts the background appropriately for light theme' do
|
||||
expected_bg = 'background: url(/assets/images/hc/grid.svg) color-mix(in srgb, #0000ff 10%, white)'
|
||||
expect(helper.generate_portal_bg('#0000ff', 'light')).to eq(expected_bg)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user