style: format code with prettier agian
Local Build and Deploy / deploy (push) Failing after 49s

This commit is contained in:
openhands committed 2026-07-13 21:41:52 +02:00
1 parent e6d7f2280b
commit 8efd032cc6
71 files changed
+6796 -3751

No files matched your search

+20 -3
View File
@@ -74,13 +74,30 @@ export function ColorField({
name={name}
value={val}
onChange={(e) => setVal(e.target.value)}
style={{ width: 42, height: 36, padding: 0, border: "none", background: "none", cursor: "pointer", flexShrink: 0 }}
style={{
width: 42,
height: 36,
padding: 0,
border: "none",
background: "none",
cursor: "pointer",
flexShrink: 0,
}}
/>
<div style={{ display: "flex", flexDirection: "column", minWidth: 0, flex: 1 }}>
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", gap: "0.5rem" }}>
<div
style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", gap: "0.5rem" }}
>
<span style={{ fontSize: "0.82rem", fontWeight: 600, lineHeight: 1.2 }}>{field.label}</span>
{ratio != null ? (
<span style={{ fontSize: "0.7rem", fontWeight: 700, color: ok ? "#22c55e" : "#ef4444", whiteSpace: "nowrap" }}>
<span
style={{
fontSize: "0.7rem",
fontWeight: 700,
color: ok ? "#22c55e" : "#ef4444",
whiteSpace: "nowrap",
}}
>
{ratio.toFixed(1)}:1 {ok ? "✓" : "⚠"}
</span>
) : null}
+171 -41
View File
@@ -1,5 +1,11 @@
import { getTranslations } from "next-intl/server";
import { applyCustomTheme, applyPreset, deleteCustomTheme, saveCustomTheme, saveTheme } from "@/actions/admin-theme";
import {
applyCustomTheme,
applyPreset,
deleteCustomTheme,
saveCustomTheme,
saveTheme,
} from "@/actions/admin-theme";
import { siteSettings } from "@/lib/services/site-settings";
import { FONTS, PRESETS } from "@/lib/theme-presets";
import { listCustomThemes } from "@/lib/theme-custom-store";
@@ -10,15 +16,58 @@ export const dynamic = "force-dynamic";
export const metadata = { title: "Theme" };
const COLOR_FIELDS: { key: string; label: string; def: string; desc: string; bgKey?: string }[] = [
{ key: "color_background", label: "Page background", def: "#f8fafc", desc: "Main page background behind all content" },
{ key: "color_surface", label: "Card / surface", def: "#ffffff", desc: "Cards, panels, and elevated surfaces" },
{ key: "color_dropdown", label: "Dropdown menu", def: "#ffffff", desc: "Dropdown menus and input backgrounds" },
{
key: "color_background",
label: "Page background",
def: "#f8fafc",
desc: "Main page background behind all content",
},
{
key: "color_surface",
label: "Card / surface",
def: "#ffffff",
desc: "Cards, panels, and elevated surfaces",
},
{
key: "color_dropdown",
label: "Dropdown menu",
def: "#ffffff",
desc: "Dropdown menus and input backgrounds",
},
{ key: "color_navbar", label: "Navbar bar", def: "#ffffff", desc: "Top navigation bar background" },
{ key: "color_navbar_text", label: "Navbar text", def: "#1e293b", desc: "Text color in the navigation bar", bgKey: "color_navbar" },
{ key: "color_text", label: "Body text", def: "#0f172a", desc: "Main body text — must contrast with background/surface", bgKey: "color_surface" },
{ key: "color_text_muted", label: "Muted text", def: "#64748b", desc: "Secondary text, labels, hints — lighter than body text", bgKey: "color_surface" },
{ key: "color_primary", label: "Primary accent", def: "#f59e0b", desc: "Main brand color, highlights, active elements" },
{ key: "color_accent", label: "Secondary accent", def: "#10b981", desc: "Secondary brand color, success-oriented highlights" },
{
key: "color_navbar_text",
label: "Navbar text",
def: "#1e293b",
desc: "Text color in the navigation bar",
bgKey: "color_navbar",
},
{
key: "color_text",
label: "Body text",
def: "#0f172a",
desc: "Main body text — must contrast with background/surface",
bgKey: "color_surface",
},
{
key: "color_text_muted",
label: "Muted text",
def: "#64748b",
desc: "Secondary text, labels, hints — lighter than body text",
bgKey: "color_surface",
},
{
key: "color_primary",
label: "Primary accent",
def: "#f59e0b",
desc: "Main brand color, highlights, active elements",
},
{
key: "color_accent",
label: "Secondary accent",
def: "#10b981",
desc: "Secondary brand color, success-oriented highlights",
},
{ key: "border_color", label: "Border (golden)", def: "#eeb425", desc: "Borders, dividers, outlines" },
{ key: "color_success", label: "Success", def: "#16a34a", desc: "Positive status (green)" },
{ key: "color_warning", label: "Warning", def: "#eab308", desc: "Warning status (yellow)" },
@@ -27,21 +76,81 @@ const COLOR_FIELDS: { key: string; label: string; def: string; desc: string; bgK
];
const BUTTON_FIELDS: { key: string; label: string; def: string; desc: string; bgKey?: string }[] = [
{ key: "button_primary_color", label: "Primary button", def: "#f59e0b", desc: "Main call-to-action button background" },
{ key: "button_text_color", label: "Button text", def: "#1e293b", desc: "Text on primary buttons — must contrast with button color", bgKey: "button_primary_color" },
{ key: "button_secondary_color", label: "Secondary button", def: "#22c55e", desc: "Secondary action button background" },
{ key: "button_secondary_text_color", label: "Secondary text", def: "#ffffff", desc: "Text on secondary buttons", bgKey: "button_secondary_color" },
{ key: "button_danger_color", label: "Danger button", def: "#ef4444", desc: "Destructive action button (delete, ban)" },
{ key: "button_danger_text_color", label: "Danger text", def: "#ffffff", desc: "Text on danger buttons", bgKey: "button_danger_color" },
{ key: "button_outline_color", label: "Outline border", def: "#eeb425", desc: "Outline button border color" },
{ key: "button_outline_text_color", label: "Outline text", def: "#1a1a2e", desc: "Text on outline buttons", bgKey: "color_surface" },
{
key: "button_primary_color",
label: "Primary button",
def: "#f59e0b",
desc: "Main call-to-action button background",
},
{
key: "button_text_color",
label: "Button text",
def: "#1e293b",
desc: "Text on primary buttons — must contrast with button color",
bgKey: "button_primary_color",
},
{
key: "button_secondary_color",
label: "Secondary button",
def: "#22c55e",
desc: "Secondary action button background",
},
{
key: "button_secondary_text_color",
label: "Secondary text",
def: "#ffffff",
desc: "Text on secondary buttons",
bgKey: "button_secondary_color",
},
{
key: "button_danger_color",
label: "Danger button",
def: "#ef4444",
desc: "Destructive action button (delete, ban)",
},
{
key: "button_danger_text_color",
label: "Danger text",
def: "#ffffff",
desc: "Text on danger buttons",
bgKey: "button_danger_color",
},
{
key: "button_outline_color",
label: "Outline border",
def: "#eeb425",
desc: "Outline button border color",
},
{
key: "button_outline_text_color",
label: "Outline text",
def: "#1a1a2e",
desc: "Text on outline buttons",
bgKey: "color_surface",
},
{ key: "link_color", label: "Link", def: "#eeb425", desc: "Hyperlink text color", bgKey: "color_surface" },
{ key: "link_hover_color", label: "Link hover", def: "#cf9d15", desc: "Hyperlink text on hover", bgKey: "color_surface" },
{
key: "link_hover_color",
label: "Link hover",
def: "#cf9d15",
desc: "Hyperlink text on hover",
bgKey: "color_surface",
},
];
const GRADIENT_FIELDS: { key: string; label: string; def: string; desc: string }[] = [
{ key: "gradient_from", label: "Gradient start", def: "#f59e0b", desc: "Left/top color of card header and hero gradients" },
{ key: "gradient_to", label: "Gradient end", def: "#10b981", desc: "Right/bottom color of card header and hero gradients" },
{
key: "gradient_from",
label: "Gradient start",
def: "#f59e0b",
desc: "Left/top color of card header and hero gradients",
},
{
key: "gradient_to",
label: "Gradient end",
def: "#10b981",
desc: "Right/bottom color of card header and hero gradients",
},
];
const HEADINGS: { key: string; label: string; def: string }[] = [
@@ -52,9 +161,26 @@ const HEADINGS: { key: string; label: string; def: string }[] = [
const ADMIN_FIELDS: { key: string; label: string; def: string; desc: string; bgKey?: string }[] = [
{ key: "admin_canvas", label: "Page background", def: "#0f172a", desc: "Main admin page background" },
{ key: "admin_surface", label: "Card / panel", def: "#1e293b", desc: "Admin cards, tables, and panel backgrounds" },
{ key: "admin_text", label: "Body text", def: "#f1f5f9", desc: "Main admin text — must contrast with canvas/surface", bgKey: "admin_canvas" },
{ key: "admin_text_muted", label: "Muted text", def: "#94a3b8", desc: "Secondary labels, hints, descriptions", bgKey: "admin_canvas" },
{
key: "admin_surface",
label: "Card / panel",
def: "#1e293b",
desc: "Admin cards, tables, and panel backgrounds",
},
{
key: "admin_text",
label: "Body text",
def: "#f1f5f9",
desc: "Main admin text — must contrast with canvas/surface",
bgKey: "admin_canvas",
},
{
key: "admin_text_muted",
label: "Muted text",
def: "#94a3b8",
desc: "Secondary labels, hints, descriptions",
bgKey: "admin_canvas",
},
{ key: "admin_border", label: "Border", def: "#334155", desc: "Table borders, dividers, input outlines" },
{ key: "admin_sidebar_bg", label: "Sidebar", def: "#0f172a", desc: "Left navigation sidebar background" },
];
@@ -73,11 +199,7 @@ interface ThemeField {
bgKey?: string;
}
function colorFields(
fields: ThemeField[],
current: Record<string, string>,
suffix = "",
) {
function colorFields(fields: ThemeField[], current: Record<string, string>, suffix = "") {
return (
<div
style={{
@@ -108,7 +230,14 @@ function colorFields(
export default async function AdminTheme({
searchParams,
}: {
searchParams: Promise<{ saved?: string; preset?: string; savedTheme?: string; theme?: string; renamed?: string; deletedTheme?: string }>;
searchParams: Promise<{
saved?: string;
preset?: string;
savedTheme?: string;
theme?: string;
renamed?: string;
deletedTheme?: string;
}>;
}) {
const t = await getTranslations("pages.admin.theme");
@@ -170,9 +299,7 @@ export default async function AdminTheme({
<div className="mb-4 p-3 rounded-lg theme-status-success text-xs">Theme saved as preset.</div>
) : null}
{sp.theme ? (
<div className="mb-4 p-3 rounded-lg theme-status-success text-xs">
Applied theme “{sp.theme}”.
</div>
<div className="mb-4 p-3 rounded-lg theme-status-success text-xs">Applied theme “{sp.theme}”.</div>
) : null}
{sp.renamed ? (
<div className="mb-4 p-3 rounded-lg theme-status-success text-xs">Theme renamed.</div>
@@ -213,8 +340,8 @@ export default async function AdminTheme({
<section className="mt-6">
<h2 className="admin-section-title">Your saved themes</h2>
<p className="text-xs text-[var(--admin-text-muted)] mb-3">
Save the current configuration as a named preset, then load it anytime. Perfect for keeping multiple brand
themes ready to switch.
Save the current configuration as a named preset, then load it anytime. Perfect for keeping multiple
brand themes ready to switch.
</p>
<form action={saveCustomTheme} className="flex flex-wrap items-center gap-2 mb-4">
<input
@@ -277,14 +404,15 @@ export default async function AdminTheme({
<form action={saveTheme}>
<h2 className="mt-6 text-lg font-extrabold">☀ Light mode</h2>
<p className="text-xs text-[var(--admin-text-muted)] mb-3 mt-1">
These colors are used when visitors view your site in light mode (default). Make sure body text contrasts well
with both the page background and card surface.
These colors are used when visitors view your site in light mode (default). Make sure body text
contrasts well with both the page background and card surface.
</p>
<section className="mt-6">
<h2 className="admin-section-title">Page &amp; text colors</h2>
<p className="text-xs text-[var(--admin-text-muted)] mb-2">
Backgrounds, surfaces, and text colors. Text colors must contrast with their backgrounds for readability.
Backgrounds, surfaces, and text colors. Text colors must contrast with their backgrounds for
readability.
</p>
<div className="admin-card">{colorFields(COLOR_FIELDS, current)}</div>
</section>
@@ -292,7 +420,8 @@ export default async function AdminTheme({
<section className="mt-6">
<h2 className="admin-section-title">Buttons &amp; links</h2>
<p className="text-xs text-[var(--admin-text-muted)] mb-2">
Button backgrounds, text on buttons, and link colors. Button text must contrast with its button background.
Button backgrounds, text on buttons, and link colors. Button text must contrast with its button
background.
</p>
<div className="admin-card">{colorFields(BUTTON_FIELDS, current)}</div>
</section>
@@ -307,8 +436,8 @@ export default async function AdminTheme({
<h2 className="mt-8 text-lg font-extrabold">🛠 Admin panel (HK)</h2>
<p className="text-xs text-[var(--admin-text-muted)] mb-3 mt-1">
Override colors for the Housekeeping admin panel. These apply across both light and dark modes. Leave empty to
use auto-derived defaults.
Override colors for the Housekeeping admin panel. These apply across both light and dark modes.
Leave empty to use auto-derived defaults.
</p>
<section className="mt-4">
<div className="admin-card">{colorFields(ADMIN_FIELDS, current)}</div>
@@ -316,7 +445,8 @@ export default async function AdminTheme({
<h2 className="mt-8 text-lg font-extrabold">🌙 Dark mode</h2>
<p className="text-xs text-[var(--admin-text-muted)] mb-3 mt-1">
These colors are used when visitors switch to dark mode. Dark backgrounds need lighter text for good contrast.
These colors are used when visitors switch to dark mode. Dark backgrounds need lighter text for good
contrast.
</p>
<section className="mt-4">
<h3 className="admin-section-title">Page &amp; text colors</h3>