Console Logging Enabled

Checking for where the video upload is failing
This commit is contained in:
2026-03-08 20:06:45 -04:00
parent 435ad5e00f
commit 2473c5990d
7 changed files with 100 additions and 39 deletions

View File

@@ -44,7 +44,7 @@ const DESCRIPTIONS = {
title_font_name: "Separate Google Font for titles and headings. Leave blank to use the body font.", title_font_name: "Separate Google Font for titles and headings. Leave blank to use the body font.",
// ── Icons ── // ── Icons ──
fontawesome_enabled: "Load FontAwesome 6 Free icons from CDN for use on buttons.", icon_library: "Icon library for buttons and titles. 'fontawesome' = FA 6 Free, 'google' = Material Symbols Outlined.",
// ── Navbar ── // ── Navbar ──
navbar_signin_label: "Sign-in link text. Use 'icon | Label' for FA icon before or 'Label | icon' for after (e.g. 'right-to-bracket | Sign In').", navbar_signin_label: "Sign-in link text. Use 'icon | Label' for FA icon before or 'Label | icon' for after (e.g. 'right-to-bracket | Sign In').",
@@ -248,6 +248,8 @@ const DESCRIPTIONS = {
footer_links: 'Footer links as JSON array: [{\"label\":\"Terms\",\"url\":\"/tos\"}].', footer_links: 'Footer links as JSON array: [{\"label\":\"Terms\",\"url\":\"/tos\"}].',
footer_bg_dark: "Footer background for dark mode. Leave blank for default.", footer_bg_dark: "Footer background for dark mode. Leave blank for default.",
footer_bg_light: "Footer background for light mode.", footer_bg_light: "Footer background for light mode.",
footer_text_color_dark: "Footer text color for dark mode. Applies to site name, links, copyright, and description.",
footer_text_color_light: "Footer text color for light mode.",
footer_border_style: "Border style at the top of the footer bar.", footer_border_style: "Border style at the top of the footer bar.",
}; };
@@ -264,7 +266,7 @@ const TABS = [
"orb_color", "orb_opacity", "orb_color", "orb_opacity",
"scroll_animation", "staggered_reveal_enabled", "dynamic_background_enabled", "scroll_animation", "staggered_reveal_enabled", "dynamic_background_enabled",
"mouse_parallax_enabled", "scroll_progress_enabled", "mouse_parallax_enabled", "scroll_progress_enabled",
"google_font_name", "title_font_name", "fontawesome_enabled" "google_font_name", "title_font_name", "icon_library"
]) ])
}, },
{ {
@@ -391,7 +393,9 @@ const TABS = [
label: "Footer", label: "Footer",
settings: new Set([ settings: new Set([
"footer_description", "footer_text", "footer_links", "footer_description", "footer_text", "footer_links",
"footer_bg_dark", "footer_bg_light", "footer_border_style" "footer_bg_dark", "footer_bg_light",
"footer_text_color_dark", "footer_text_color_light",
"footer_border_style"
]) ])
} }
]; ];
@@ -958,23 +962,38 @@ function getCsrfToken() {
} }
async function uploadFile(file) { async function uploadFile(file) {
console.log("[CL Upload] Starting upload:", {
name: file.name,
type: file.type,
size: `${(file.size / 1024 / 1024).toFixed(2)} MB`,
});
const formData = new FormData(); const formData = new FormData();
formData.append("file", file); formData.append("file", file);
formData.append("upload_type", "site_setting"); formData.append("upload_type", "site_setting");
formData.append("for_site_setting", "true"); formData.append("for_site_setting", "true");
formData.append("synchronous_uploads", "true"); formData.append("synchronous_uploads", "true");
const csrfToken = getCsrfToken();
console.log("[CL Upload] CSRF token present:", !!csrfToken);
const response = await fetch("/uploads.json", { const response = await fetch("/uploads.json", {
method: "POST", method: "POST",
headers: { "X-CSRF-Token": getCsrfToken() }, headers: { "X-CSRF-Token": csrfToken },
body: formData, body: formData,
}); });
console.log("[CL Upload] Response status:", response.status, response.statusText);
if (!response.ok) { if (!response.ok) {
const text = await response.text(); const text = await response.text();
console.error("[CL Upload] Error response body:", text);
throw new Error(`Upload failed (${response.status}): ${text}`); throw new Error(`Upload failed (${response.status}): ${text}`);
} }
return response.json();
const data = await response.json();
console.log("[CL Upload] Success:", { id: data.id, url: data.url, short_url: data.short_url });
return data;
} }
async function pinUpload(uploadId, settingName) { async function pinUpload(uploadId, settingName) {

View File

@@ -179,7 +179,7 @@ html.dark-scheme .cl-admin-tabs .cl-admin-tab:hover {
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting^="footer_"], .admin-detail:not(.cl-tabs-active) .row.setting[data-setting^="footer_"],
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting^="google_"], .admin-detail:not(.cl-tabs-active) .row.setting[data-setting^="google_"],
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting^="title_font"], .admin-detail:not(.cl-tabs-active) .row.setting[data-setting^="title_font"],
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting="fontawesome_enabled"] { .admin-detail:not(.cl-tabs-active) .row.setting[data-setting="icon_library"] {
margin-bottom: 20px; margin-bottom: 20px;
} }
@@ -191,7 +191,7 @@ html.dark-scheme .cl-admin-tabs .cl-admin-tab:hover {
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting="accent_color"], .admin-detail:not(.cl-tabs-active) .row.setting[data-setting="accent_color"],
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting="scroll_animation"], .admin-detail:not(.cl-tabs-active) .row.setting[data-setting="scroll_animation"],
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting="google_font_name"], .admin-detail:not(.cl-tabs-active) .row.setting[data-setting="google_font_name"],
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting="fontawesome_enabled"], .admin-detail:not(.cl-tabs-active) .row.setting[data-setting="icon_library"],
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting="social_twitter_url"], .admin-detail:not(.cl-tabs-active) .row.setting[data-setting="social_twitter_url"],
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting="navbar_signin_label"], .admin-detail:not(.cl-tabs-active) .row.setting[data-setting="navbar_signin_label"],
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting="hero_title"], .admin-detail:not(.cl-tabs-active) .row.setting[data-setting="hero_title"],
@@ -216,7 +216,7 @@ html.dark-scheme .admin-detail:not(.cl-tabs-active) .row.setting[data-setting="l
html.dark-scheme .admin-detail:not(.cl-tabs-active) .row.setting[data-setting="accent_color"], html.dark-scheme .admin-detail:not(.cl-tabs-active) .row.setting[data-setting="accent_color"],
html.dark-scheme .admin-detail:not(.cl-tabs-active) .row.setting[data-setting="scroll_animation"], html.dark-scheme .admin-detail:not(.cl-tabs-active) .row.setting[data-setting="scroll_animation"],
html.dark-scheme .admin-detail:not(.cl-tabs-active) .row.setting[data-setting="google_font_name"], html.dark-scheme .admin-detail:not(.cl-tabs-active) .row.setting[data-setting="google_font_name"],
html.dark-scheme .admin-detail:not(.cl-tabs-active) .row.setting[data-setting="fontawesome_enabled"], html.dark-scheme .admin-detail:not(.cl-tabs-active) .row.setting[data-setting="icon_library"],
html.dark-scheme .admin-detail:not(.cl-tabs-active) .row.setting[data-setting="social_twitter_url"], html.dark-scheme .admin-detail:not(.cl-tabs-active) .row.setting[data-setting="social_twitter_url"],
html.dark-scheme .admin-detail:not(.cl-tabs-active) .row.setting[data-setting="navbar_signin_label"], html.dark-scheme .admin-detail:not(.cl-tabs-active) .row.setting[data-setting="navbar_signin_label"],
html.dark-scheme .admin-detail:not(.cl-tabs-active) .row.setting[data-setting="hero_title"], html.dark-scheme .admin-detail:not(.cl-tabs-active) .row.setting[data-setting="hero_title"],

View File

@@ -51,7 +51,7 @@
--cl-border-hover: rgba(196, 146, 46, 0.25); --cl-border-hover: rgba(196, 146, 46, 0.25);
--cl-hero-bg: #faf9f6; --cl-hero-bg: #faf9f6;
--cl-hero-text: #1a1a2e; --cl-hero-text: #1a1a2e;
--cl-footer-bg: #f5f4ef; --cl-footer-bg: #ffffff;
--cl-shadow: rgba(0, 0, 0, 0.04); --cl-shadow: rgba(0, 0, 0, 0.04);
--cl-glass: rgba(255, 255, 255, 0.7); --cl-glass: rgba(255, 255, 255, 0.7);
--cl-glass-border: rgba(0, 0, 0, 0.04); --cl-glass-border: rgba(0, 0, 0, 0.04);
@@ -81,7 +81,7 @@
--cl-border-hover: rgba(212, 162, 78, 0.3); --cl-border-hover: rgba(212, 162, 78, 0.3);
--cl-hero-bg: #faf6f0; --cl-hero-bg: #faf6f0;
--cl-hero-text: #1a1a2e; --cl-hero-text: #1a1a2e;
--cl-footer-bg: #f5f0e8; --cl-footer-bg: #ffffff;
--cl-shadow: rgba(0, 0, 0, 0.06); --cl-shadow: rgba(0, 0, 0, 0.06);
--cl-glass: rgba(255, 255, 255, 0.6); --cl-glass: rgba(255, 255, 255, 0.6);
--cl-glass-border: rgba(0, 0, 0, 0.05); --cl-glass-border: rgba(0, 0, 0, 0.05);
@@ -390,6 +390,18 @@ html, .cl-body {
margin: 0 0.35em; margin: 0 0.35em;
} }
/* Google Material Symbols icon spacing inside buttons */
.cl-btn .material-symbols-outlined {
margin: 0 0.35em;
font-size: 1.1em;
vertical-align: middle;
}
.cl-participation-stat__icon.material-symbols-outlined {
font-size: 0.85em;
vertical-align: middle;
}
/* ═══════════════════════════════════════════════════════════════════ /* ═══════════════════════════════════════════════════════════════════
1. NAVBAR — logo left, theme toggle + auth right 1. NAVBAR — logo left, theme toggle + auth right
═══════════════════════════════════════════════════════════════════ */ ═══════════════════════════════════════════════════════════════════ */
@@ -1514,8 +1526,9 @@ html, .cl-body {
border-radius: 6px; border-radius: 6px;
font-size: 0.65rem; font-size: 0.65rem;
font-weight: 800; font-weight: 800;
color: #fff; color: var(--cl-text-strong);
background: var(--cat-color); background: var(--cl-secondary-btn-bg, var(--cl-accent-subtle));
border: 1px solid var(--cl-accent);
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.06em; letter-spacing: 0.06em;
white-space: nowrap; white-space: nowrap;
@@ -2034,7 +2047,7 @@ html, .cl-body {
} }
.cl-footer-desc__text { .cl-footer-desc__text {
color: var(--cl-muted); color: var(--cl-footer-text, var(--cl-muted));
font-size: 0.88rem; font-size: 0.88rem;
line-height: 1.7; line-height: 1.7;
} }
@@ -2077,7 +2090,7 @@ html, .cl-body {
.cl-footer__site-name { .cl-footer__site-name {
font-size: 0.95rem; font-size: 0.95rem;
font-weight: 700; font-weight: 700;
color: var(--cl-text-strong); color: var(--cl-footer-text, var(--cl-text-strong));
} }
.cl-footer__links { .cl-footer__links {
@@ -2088,7 +2101,7 @@ html, .cl-body {
} }
.cl-footer__link { .cl-footer__link {
color: var(--cl-muted); color: var(--cl-footer-text, var(--cl-muted));
text-decoration: none; text-decoration: none;
font-size: 0.82rem; font-size: 0.82rem;
transition: color 0.2s; transition: color 0.2s;
@@ -2106,11 +2119,11 @@ html, .cl-body {
.cl-footer__copy { .cl-footer__copy {
font-size: 0.75rem; font-size: 0.75rem;
color: var(--cl-muted); color: var(--cl-footer-text, var(--cl-muted));
} }
.cl-footer__text { .cl-footer__text {
color: var(--cl-muted); color: var(--cl-footer-text, var(--cl-muted));
font-size: 0.82rem; font-size: 0.82rem;
padding: 1rem 0 0; padding: 1rem 0 0;
} }

View File

@@ -38,7 +38,7 @@ en:
title_font_name: "Separate Google Font for section titles and headings. Leave blank to use the body font. Must match exact Google Fonts name." title_font_name: "Separate Google Font for section titles and headings. Leave blank to use the body font. Must match exact Google Fonts name."
# ── Icons ── # ── Icons ──
fontawesome_enabled: "━━ ICONS ━━ — Enable FontAwesome 6 Free icons. Loads the icon library from CDN for use on buttons." icon_library: "━━ ICONS ━━ — Icon library for buttons and section titles. 'fontawesome' loads FontAwesome 6 Free; 'google' loads Google Material Symbols Outlined. Use the pipe syntax in labels: \"icon_name | Label\"."
# ── 1. Navbar ── # ── 1. Navbar ──
navbar_signin_label: "━━ ROW 1: NAVBAR ━━ — Fixed navigation bar at the top with logo, theme toggle, sign-in link, and join button. This setting controls the sign-in link text." navbar_signin_label: "━━ ROW 1: NAVBAR ━━ — Fixed navigation bar at the top with logo, theme toggle, sign-in link, and join button. This setting controls the sign-in link text."
@@ -230,4 +230,6 @@ en:
footer_links: 'Footer navigation links as a JSON array. Format: [{"label":"Terms","url":"/tos"},{"label":"Privacy","url":"/privacy"}].' footer_links: 'Footer navigation links as a JSON array. Format: [{"label":"Terms","url":"/tos"},{"label":"Privacy","url":"/privacy"}].'
footer_bg_dark: "Section background color override. Dark (left) and light (right) color pickers. Leave blank for default." footer_bg_dark: "Section background color override. Dark (left) and light (right) color pickers. Leave blank for default."
footer_bg_light: "Light mode background for the footer." footer_bg_light: "Light mode background for the footer."
footer_text_color_dark: "Footer text color for dark mode. Applies to site name, links, copyright, and description. Leave blank for default."
footer_text_color_light: "Footer text color for light mode."
footer_border_style: "Border style at the top of the footer bar." footer_border_style: "Border style at the top of the footer bar."

View File

@@ -123,11 +123,15 @@ plugins:
type: string type: string
# ══════════════════════════════════════════ # ══════════════════════════════════════════
# Icons (FontAwesome) # Icons
# ══════════════════════════════════════════ # ══════════════════════════════════════════
fontawesome_enabled: icon_library:
default: false default: "none"
type: bool type: enum
choices:
- none
- fontawesome
- google
# ══════════════════════════════════════════ # ══════════════════════════════════════════
# 1. Navbar # 1. Navbar
@@ -809,7 +813,13 @@ plugins:
default: "" default: ""
type: color type: color
footer_bg_light: footer_bg_light:
default: "#ffffff" default: ""
type: color
footer_text_color_dark:
default: ""
type: color
footer_text_color_light:
default: ""
type: color type: color
footer_border_style: footer_border_style:
default: "solid" default: "solid"

View File

@@ -77,8 +77,12 @@ module CommunityLanding
html << "<link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">\n" html << "<link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">\n"
html << "<link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n" html << "<link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n"
html << "<link href=\"https://fonts.googleapis.com/css2?#{font_params}&display=swap\" rel=\"stylesheet\">\n" html << "<link href=\"https://fonts.googleapis.com/css2?#{font_params}&display=swap\" rel=\"stylesheet\">\n"
if (@s.fontawesome_enabled rescue false) icon_lib = (@s.icon_library rescue "none").to_s
case icon_lib
when "fontawesome"
html << "<link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css\" crossorigin=\"anonymous\">\n" html << "<link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css\" crossorigin=\"anonymous\">\n"
when "google"
html << "<link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&display=swap\">\n"
end end
html << "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, viewport-fit=cover\">\n" html << "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, viewport-fit=cover\">\n"
html << "<meta name=\"color-scheme\" content=\"dark light\">\n" html << "<meta name=\"color-scheme\" content=\"dark light\">\n"
@@ -504,7 +508,7 @@ module CommunityLanding
html << "<a href=\"#{login_url}\" class=\"cl-topic-card\">\n" html << "<a href=\"#{login_url}\" class=\"cl-topic-card\">\n"
if topic.category if topic.category
html << "<span class=\"cl-topic-card__cat\" style=\"--cat-color: ##{topic.category.color}\">#{e(topic.category.name)}</span>\n" html << "<span class=\"cl-topic-card__cat\">#{e(topic.category.name)}</span>\n"
end end
html << "<span class=\"cl-topic-card__title\">#{e(topic.title)}</span>\n" html << "<span class=\"cl-topic-card__title\">#{e(topic.title)}</span>\n"
html << "<div class=\"cl-topic-card__meta\">" html << "<div class=\"cl-topic-card__meta\">"
@@ -845,17 +849,31 @@ module CommunityLanding
size > 0 ? " style=\"font-size: #{size}px\"" : "" size > 0 ? " style=\"font-size: #{size}px\"" : ""
end end
# Render an icon element based on the chosen icon library
def icon_tag(name, extra_class = nil)
lib = (@s.icon_library rescue "none").to_s
cls = extra_class ? " #{extra_class}" : ""
case lib
when "fontawesome"
"<i class=\"fa-solid fa-#{e(name)}#{cls}\"></i>"
when "google"
"<span class=\"material-symbols-outlined#{cls}\">#{e(name)}</span>"
else
nil
end
end
def participation_stat(count, raw_label, default_svg) def participation_stat(count, raw_label, default_svg)
fa_enabled = (@s.fontawesome_enabled rescue false) lib = (@s.icon_library rescue "none").to_s
# Parse "icon | Label" format — if present, use FA icon instead of default SVG # Parse "icon | Label" format — if present, use library icon instead of default SVG
if fa_enabled && raw_label.include?("|") if lib != "none" && raw_label.include?("|")
parts = raw_label.split("|", 2).map(&:strip) parts = raw_label.split("|", 2).map(&:strip)
left, right = parts left, right = parts
if left.match?(/\A[\w-]+\z/) && left.length < 30 if left.match?(/\A[\w-]+\z/) && left.length < 30
icon_html = "<i class=\"fa-solid fa-#{e(left)} cl-participation-stat__icon\"></i>" icon_html = icon_tag(left, "cl-participation-stat__icon")
label = right label = right
elsif right.match?(/\A[\w-]+\z/) && right.length < 30 elsif right.match?(/\A[\w-]+\z/) && right.length < 30
icon_html = "<i class=\"fa-solid fa-#{e(right)} cl-participation-stat__icon\"></i>" icon_html = icon_tag(right, "cl-participation-stat__icon")
label = left label = left
else else
icon_html = default_svg icon_html = default_svg
@@ -872,20 +890,15 @@ module CommunityLanding
end end
def button_with_icon(raw_label) def button_with_icon(raw_label)
fa_enabled = (@s.fontawesome_enabled rescue false) lib = (@s.icon_library rescue "none").to_s
return e(raw_label) unless fa_enabled && raw_label.include?("|") return e(raw_label) unless lib != "none" && raw_label.include?("|")
parts = raw_label.split("|", 2).map(&:strip) parts = raw_label.split("|", 2).map(&:strip)
# Try to detect which side is the icon name (no spaces, short) vs label text
left, right = parts left, right = parts
if left.match?(/\A[\w-]+\z/) && left.length < 30 if left.match?(/\A[\w-]+\z/) && left.length < 30
# "iconname | Label" — icon before "#{icon_tag(left)} #{e(right)}"
icon_html = "<i class=\"fa-solid fa-#{e(left)}\"></i>"
"#{icon_html} #{e(right)}"
elsif right.match?(/\A[\w-]+\z/) && right.length < 30 elsif right.match?(/\A[\w-]+\z/) && right.length < 30
# "Label | iconname" — icon after "#{e(left)} #{icon_tag(right)}"
icon_html = "<i class=\"fa-solid fa-#{e(right)}\"></i>"
"#{e(left)} #{icon_html}"
else else
e(raw_label) e(raw_label)
end end

View File

@@ -65,6 +65,8 @@ module CommunityLanding
cta_headline_light = safe_hex(:app_cta_headline_color_light) cta_headline_light = safe_hex(:app_cta_headline_color_light)
cta_subtext_dark = safe_hex(:app_cta_subtext_color_dark) cta_subtext_dark = safe_hex(:app_cta_subtext_color_dark)
cta_subtext_light = safe_hex(:app_cta_subtext_color_light) cta_subtext_light = safe_hex(:app_cta_subtext_color_light)
footer_text_dark = safe_hex(:footer_text_color_dark)
footer_text_light = safe_hex(:footer_text_color_light)
orb_color = safe_hex(:orb_color) orb_color = safe_hex(:orb_color)
orb_opacity = [[@s.orb_opacity.to_i, 0].max, 100].min rescue 50 orb_opacity = [[@s.orb_opacity.to_i, 0].max, 100].min rescue 50
@@ -101,6 +103,7 @@ module CommunityLanding
dark_extras << "\n --cl-video-btn-bg: #{video_btn_bg};" dark_extras << "\n --cl-video-btn-bg: #{video_btn_bg};"
dark_extras << "\n --cl-video-btn-glow: rgba(#{video_btn_rgb}, 0.35);" dark_extras << "\n --cl-video-btn-glow: rgba(#{video_btn_rgb}, 0.35);"
end end
dark_extras << "\n --cl-footer-text: #{footer_text_dark};" if footer_text_dark
light_extras = +"" light_extras = +""
light_extras << "\n --cl-navbar-signin-color: #{navbar_signin_light || navbar_signin_dark};" if navbar_signin_light || navbar_signin_dark light_extras << "\n --cl-navbar-signin-color: #{navbar_signin_light || navbar_signin_dark};" if navbar_signin_light || navbar_signin_dark
@@ -113,6 +116,7 @@ module CommunityLanding
light_extras << "\n --cl-video-btn-bg: #{video_btn_bg};" light_extras << "\n --cl-video-btn-bg: #{video_btn_bg};"
light_extras << "\n --cl-video-btn-glow: rgba(#{video_btn_rgb}, 0.25);" light_extras << "\n --cl-video-btn-glow: rgba(#{video_btn_rgb}, 0.25);"
end end
light_extras << "\n --cl-footer-text: #{footer_text_light || footer_text_dark};" if footer_text_light || footer_text_dark
"<style> "<style>
:root, [data-theme=\"dark\"] { :root, [data-theme=\"dark\"] {