Settings Navigation Repositioned

This commit is contained in:
2026-03-06 22:02:23 -04:00
parent af75ea54a6
commit 8ce1c36bb9
10 changed files with 321 additions and 195 deletions

View File

@@ -19,12 +19,19 @@ module CommunityLanding
.select("users.*, COUNT(posts.id) AS post_count")
end
# Public groups
# Public groups — optionally filtered by selected names
data[:groups] = if s.groups_enabled
Group
selected = s.groups_selected.presence
scope = Group
.where(visibility_level: Group.visibility_levels[:public])
.where(automatic: false)
.limit(s.groups_count)
if selected
names = selected.split("|").map(&:strip).reject(&:empty?)
scope = scope.where(name: names) if names.any?
end
scope.limit(s.groups_count)
end
# Trending topics

View File

@@ -4,7 +4,7 @@ module CommunityLanding
module Icons
SUN_SVG = '<svg class="cl-icon-sun" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/><line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/></svg>'
MOON_SVG = '<svg class="cl-icon-moon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>'
QUOTE_SVG = '<svg class="cl-about__quote-mark" viewBox="0 0 24 24" fill="currentColor" width="32" height="32"><path d="M6 7h3l2 4v6H5v-6h3zm8 0h3l2 4v6h-6v-6h3z"/></svg>'
QUOTE_SVG = '<svg class="cl-about__quote-mark" viewBox="0 0 24 24" fill="currentColor" width="32" height="32"><path d="M6 17h3l2-4V7H5v6h3zm8 0h3l2-4V7h-6v6h3z"/></svg>'
STAT_MEMBERS_SVG = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>'
STAT_TOPICS_SVG = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/></svg>'

View File

@@ -58,9 +58,6 @@ module CommunityLanding
html << @styles.color_overrides
html << @styles.section_backgrounds
custom_css = @s.custom_css.presence rescue nil
html << "<style>\n/* Custom CSS */\n#{custom_css}\n</style>\n" if custom_css
html << "</head>\n"
html
end
@@ -169,21 +166,22 @@ module CommunityLanding
stats_title = @s.stats_title.presence || "Premium Stats"
border = @s.stats_border_style rescue "none"
min_h = @s.stats_min_height rescue 0
icon_shape = @s.stat_icon_shape rescue "circle"
html = +""
html << "<section class=\"cl-stats cl-anim\" id=\"cl-stats-row\"#{section_style(border, min_h)}><div class=\"cl-container\">\n"
html << "<h2 class=\"cl-section-title\">#{e(stats_title)}</h2>\n"
html << "<div class=\"cl-stats__grid\">\n"
html << stat_card(Icons::STAT_MEMBERS_SVG, stats[:members], @s.stat_members_label)
html << stat_card(Icons::STAT_TOPICS_SVG, stats[:topics], @s.stat_topics_label)
html << stat_card(Icons::STAT_POSTS_SVG, stats[:posts], @s.stat_posts_label)
html << stat_card(Icons::STAT_LIKES_SVG, stats[:likes], @s.stat_likes_label)
html << stat_card(Icons::STAT_CHATS_SVG, stats[:chats], @s.stat_chats_label)
html << stat_card(Icons::STAT_MEMBERS_SVG, stats[:members], @s.stat_members_label, icon_shape)
html << stat_card(Icons::STAT_TOPICS_SVG, stats[:topics], @s.stat_topics_label, icon_shape)
html << stat_card(Icons::STAT_POSTS_SVG, stats[:posts], @s.stat_posts_label, icon_shape)
html << stat_card(Icons::STAT_LIKES_SVG, stats[:likes], @s.stat_likes_label, icon_shape)
html << stat_card(Icons::STAT_CHATS_SVG, stats[:chats], @s.stat_chats_label, icon_shape)
html << "</div>\n</div></section>\n"
html
end
# ── 4. ABOUT ──
# ── 4. ABOUT — split layout: image left on gradient, text right ──
def render_about
return "" unless @s.about_enabled
@@ -193,21 +191,34 @@ module CommunityLanding
about_role = @s.about_role.presence || @s.title
about_heading_on = @s.about_heading_enabled rescue true
about_heading = @s.about_heading.presence || "About Community"
about_bg_img = @s.about_background_image_url.presence
border = @s.about_border_style rescue "none"
min_h = @s.about_min_height rescue 0
html = +""
html << "<section class=\"cl-about cl-anim\" id=\"cl-about\"#{section_style(border, min_h)}><div class=\"cl-container\">\n"
html << "<div class=\"cl-about__card\">\n"
# Left side — image on gradient background
html << "<div class=\"cl-about__left\">\n"
if about_image
html << "<img src=\"#{about_image}\" alt=\"#{e(@s.about_title)}\" class=\"cl-about__image\">\n"
end
html << "</div>\n"
# Right side — text content
html << "<div class=\"cl-about__right\">\n"
html << "<h2 class=\"cl-about__heading\">#{e(about_heading)}</h2>\n" if about_heading_on
html << Icons::QUOTE_SVG
html << "<div class=\"cl-about__body\">#{about_body}</div>\n" if about_body.present?
html << "<div class=\"cl-about__meta\">\n"
html << "<img src=\"#{about_image}\" alt=\"\" class=\"cl-about__avatar\">\n" if about_image
html << "<div class=\"cl-about__meta-text\">\n"
html << "<span class=\"cl-about__author\">#{e(@s.about_title)}</span>\n"
html << "<span class=\"cl-about__role\">#{e(about_role)}</span>\n"
html << "</div></div>\n</div>\n</div></section>\n"
html << "</div></div>\n"
html << "</div>\n"
html << "</div>\n</div></section>\n"
html
end
@@ -223,7 +234,7 @@ module CommunityLanding
html = +""
html << "<section class=\"cl-topics cl-anim\" id=\"cl-topics\"#{section_style(border, min_h)}><div class=\"cl-container\">\n"
html << "<h2 class=\"cl-section-title\">#{e(@s.topics_title)}</h2>\n"
html << "<div class=\"cl-topics__scroll\">\n"
html << "<div class=\"cl-topics__grid\">\n"
topics.each do |topic|
topic_likes = topic.like_count rescue 0
@@ -288,21 +299,26 @@ module CommunityLanding
html << "<div class=\"cl-spaces__grid\">\n"
groups.each do |group|
display_name = group.name.tr("_-", " ").gsub(/\b\w/, &:upcase)
display_name = group.full_name.presence || group.name.tr("_-", " ").gsub(/\b\w/, &:upcase)
hue = group.name.bytes.sum % 360
sat = 50 + (group.name.bytes.first.to_i % 20)
light = 40 + (group.name.bytes.last.to_i % 15)
sat = 55 + (group.name.bytes.first.to_i % 15)
light = 45 + (group.name.bytes.last.to_i % 12)
icon_color = "hsl(#{hue}, #{sat}%, #{light}%)"
html << "<a href=\"#{login_url}\" class=\"cl-space-card\">\n"
html << "<div class=\"cl-space-card__icon\" style=\"background: hsl(#{hue}, #{sat}%, #{light}%)\">"
html << "<div class=\"cl-space-card__header\" style=\"--space-color: #{icon_color}\">\n"
html << "<div class=\"cl-space-card__icon\">"
if group.flair_url.present?
html << "<img src=\"#{group.flair_url}\" alt=\"\">"
else
html << "<span class=\"cl-space-card__letter\">#{group.name[0].upcase}</span>"
end
html << "</div>\n"
html << "</div>\n"
html << "<div class=\"cl-space-card__body\">\n"
html << "<span class=\"cl-space-card__name\">#{e(display_name)}</span>\n"
html << "<span class=\"cl-space-card__sub\">#{group.user_count} members</span>\n"
html << "</div>\n"
html << "</a>\n"
end
@@ -397,12 +413,11 @@ module CommunityLanding
# ── Shared helpers ──
def stat_card(icon_svg, count, label)
def stat_card(icon_svg, count, label, icon_shape = "circle")
shape_class = icon_shape == "rounded" ? "cl-stat-icon--rounded" : "cl-stat-icon--circle"
"<div class=\"cl-stat-card\">\n" \
"<div class=\"cl-stat-card__top\">\n" \
"<span class=\"cl-stat-card__icon\">#{icon_svg}</span>\n" \
"<div class=\"cl-stat-card__icon-wrap #{shape_class}\">#{icon_svg}</div>\n" \
"<span class=\"cl-stat-card__label\">#{e(label)}</span>\n" \
"</div>\n" \
"<span class=\"cl-stat-card__value\" data-count=\"#{count}\">0</span>\n" \
"</div>\n"
end

View File

@@ -22,7 +22,15 @@ module CommunityLanding
app_g1 = hex(@s.app_cta_gradient_start) || accent
app_g2 = hex(@s.app_cta_gradient_mid) || accent_hover
app_g3 = hex(@s.app_cta_gradient_end) || accent_hover
stat_icon_bg = hex(@s.stat_icon_bg_color.presence) rescue nil
stat_counter = hex(@s.stat_counter_color.presence) rescue nil
space_card_bg = hex(@s.groups_card_bg_color.presence) rescue nil
accent_rgb = hex_to_rgb(accent)
stat_icon_rgb = hex_to_rgb(stat_icon)
stat_icon_bg_val = stat_icon_bg || "rgba(#{stat_icon_rgb}, 0.1)"
stat_counter_val = stat_counter || "var(--cl-text-strong)"
space_card_bg_val = space_card_bg || "var(--cl-card)"
about_bg_extra = about_bg_img ? ", url('#{about_bg_img}') center/cover no-repeat" : ""
@@ -38,6 +46,9 @@ module CommunityLanding
--cl-border-hover: rgba(#{accent_rgb}, 0.25);
--cl-orb-1: rgba(#{accent_rgb}, 0.12);
--cl-stat-icon-color: #{stat_icon};
--cl-stat-icon-bg: #{stat_icon_bg_val};
--cl-stat-counter-color: #{stat_counter_val};
--cl-space-card-bg: #{space_card_bg_val};
--cl-about-gradient: linear-gradient(135deg, #{about_g1}, #{about_g2}, #{about_g3})#{about_bg_extra};
--cl-app-gradient: linear-gradient(135deg, #{app_g1}, #{app_g2}, #{app_g3});
}
@@ -52,6 +63,9 @@ module CommunityLanding
--cl-border-hover: rgba(#{accent_rgb}, 0.3);
--cl-orb-1: rgba(#{accent_rgb}, 0.08);
--cl-stat-icon-color: #{stat_icon};
--cl-stat-icon-bg: #{stat_icon_bg_val};
--cl-stat-counter-color: #{stat_counter_val};
--cl-space-card-bg: #{space_card_bg_val};
--cl-about-gradient: linear-gradient(135deg, #{about_g1}, #{about_g2}, #{about_g3})#{about_bg_extra};
--cl-app-gradient: linear-gradient(135deg, #{app_g1}, #{app_g2}, #{app_g3});
}