From f9c4046d35290bcda43778ecfbb1fd4a0128c2cd Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 21 Jun 2026 00:02:55 -0400 Subject: [PATCH] x --- apps/admin/src/pages/SystemSettingsPage.tsx | 97 +++++++++++++++++++ .../migration.sql | 6 ++ apps/backend/prisma/schema.prisma | 2 + apps/backend/src/routes/settings.ts | 2 + apps/website/src/app/[lang]/layout.tsx | 40 +++++++- packages/types/index.ts | 2 + 6 files changed, 148 insertions(+), 1 deletion(-) create mode 100644 apps/backend/prisma/migrations/20260622000000_add_theme_settings/migration.sql diff --git a/apps/admin/src/pages/SystemSettingsPage.tsx b/apps/admin/src/pages/SystemSettingsPage.tsx index 6cc7672..63c1418 100644 --- a/apps/admin/src/pages/SystemSettingsPage.tsx +++ b/apps/admin/src/pages/SystemSettingsPage.tsx @@ -2,6 +2,27 @@ import { useState, useEffect } from 'react' import { API_BASE, type StoreSettings } from '@homaroma/types' import { Save, Loader2, Landmark, Truck } from 'lucide-react' +const defaultThemeTokens = { + brandPrimary: '#FF6B6B', + brandPrimaryHover: '#FF4500', + brandAccent: '#FFF200', + brandWarm: '#FFA07A', + brandCool: '#E0FFFF', + brandSuccess: '#98FB98', + brandSoft: '#D8BFD8', + surfacePage: '#FFF0F5', + surfaceNavRest: '#F9F8F5', + surfaceCard: '#FFFFFF', + textMain: '#333333', + mutedText: '#666666', + linePrimary: '#00B900', + linePrimaryHover: '#009900', + fontBody: 'system-ui, sans-serif', + fontDisplay: 'system-ui, sans-serif', + shadowCard: '0 10px 25px rgba(0,0,0,0.05)', + shadowCardHover: '0 20px 40px rgba(0,0,0,0.1)', +} + export default function SystemSettingsPage() { const [loading, setLoading] = useState(true) const [saving, setSaving] = useState(false) @@ -9,6 +30,7 @@ export default function SystemSettingsPage() { // Form State const [brandName, setBrandName] = useState('') const [logoUrl, setLogoUrl] = useState('') + const [themePreset, setThemePreset] = useState('default') const [shippingFee, setShippingFee] = useState('') const [bankName, setBankName] = useState('') const [bankAccountName, setBankAccountName] = useState('') @@ -26,6 +48,7 @@ export default function SystemSettingsPage() { const [footerSupportHeading, setFooterSupportHeading] = useState('') const [footerCopyrightText, setFooterCopyrightText] = useState('') + const [themeTokens, setThemeTokens] = useState>(defaultThemeTokens) useEffect(() => { fetch(`${API_BASE}/settings`) @@ -33,6 +56,7 @@ export default function SystemSettingsPage() { .then((data: StoreSettings) => { setBrandName(data.brandName || 'HomAroma') setLogoUrl(data.logoUrl || '') + setThemePreset(data.themePreset || 'default') setShippingFee(data.shippingFee.toString()) setBankName(data.bankName || '') setBankAccountName(data.bankAccountName || '') @@ -48,6 +72,10 @@ export default function SystemSettingsPage() { setNewsletterButtonText(data.newsletterButtonText || '') setFooterSupportHeading(data.footerSupportHeading || '') setFooterCopyrightText(data.footerCopyrightText || '') + setThemeTokens({ + ...defaultThemeTokens, + ...(data.themeTokens && typeof data.themeTokens === 'object' ? data.themeTokens : {}), + }) }) .catch(console.error) .finally(() => setLoading(false)) @@ -64,6 +92,8 @@ export default function SystemSettingsPage() { body: JSON.stringify({ brandName, logoUrl, + themePreset, + themeTokens, shippingFee: parseFloat(shippingFee) || 0, bankName, bankAccountName, @@ -244,6 +274,20 @@ export default function SystemSettingsPage() { )} +
+ + +

Theme preset helps websites choose a starting palette before custom tokens are applied.

+
+