From 1ee25e3dab75f02c30d038e0383bc462105a3a39 Mon Sep 17 00:00:00 2001 From: v0 Date: Wed, 14 Jan 2026 08:03:05 +0000 Subject: [PATCH] fix: prevent controlled component errors Ensure all input values have default values and use empty string as fallback. #VERCEL_SKIP Co-authored-by: null <4804959+fnvtk@users.noreply.github.com> --- app/admin/site/page.tsx | 113 +++++++++++++++++++++++----------------- 1 file changed, 65 insertions(+), 48 deletions(-) diff --git a/app/admin/site/page.tsx b/app/admin/site/page.tsx index d1d7180..39258d7 100644 --- a/app/admin/site/page.tsx +++ b/app/admin/site/page.tsx @@ -9,43 +9,49 @@ import { Switch } from "@/components/ui/switch" import { useStore } from "@/lib/store" import { Save, Globe, Menu, FileText, Palette } from "lucide-react" +const defaultSiteConfig = { + siteName: "卡若日记", + siteTitle: "一场SOUL的创业实验场", + siteDescription: "来自Soul派对房的真实商业故事", + logo: "/logo.png", + favicon: "/favicon.ico", + primaryColor: "#00CED1", +} + +const defaultMenuConfig = { + home: { enabled: true, label: "首页" }, + chapters: { enabled: true, label: "目录" }, + match: { enabled: true, label: "匹配" }, + my: { enabled: true, label: "我的" }, +} + +const defaultPageConfig = { + homeTitle: "一场SOUL的创业实验场", + homeSubtitle: "来自Soul派对房的真实商业故事", + chaptersTitle: "我要看", + matchTitle: "语音匹配", + myTitle: "我的", + aboutTitle: "关于作者", +} + export default function SiteConfigPage() { const { settings, updateSettings } = useStore() const [localSettings, setLocalSettings] = useState({ - siteConfig: settings.siteConfig || { - siteName: "卡若日记", - siteTitle: "一场SOUL的创业实验场", - siteDescription: "来自Soul派对房的真实商业故事", - logo: "/logo.png", - favicon: "/favicon.ico", - primaryColor: "#00CED1", - }, - menuConfig: settings.menuConfig || { - home: { enabled: true, label: "首页" }, - chapters: { enabled: true, label: "目录" }, - match: { enabled: true, label: "匹配" }, - my: { enabled: true, label: "我的" }, - }, - pageConfig: settings.pageConfig || { - homeTitle: "一场SOUL的创业实验场", - homeSubtitle: "来自Soul派对房的真实商业故事", - chaptersTitle: "我要看", - matchTitle: "语音匹配", - myTitle: "我的", - aboutTitle: "关于作者", - }, + siteConfig: { ...defaultSiteConfig }, + menuConfig: { ...defaultMenuConfig }, + pageConfig: { ...defaultPageConfig }, }) const [saved, setSaved] = useState(false) + const [mounted, setMounted] = useState(false) useEffect(() => { - if (settings.siteConfig) { - setLocalSettings({ - siteConfig: settings.siteConfig, - menuConfig: settings.menuConfig, - pageConfig: settings.pageConfig, - }) - } - }, [settings]) + setMounted(true) + setLocalSettings({ + siteConfig: { ...defaultSiteConfig, ...settings.siteConfig }, + menuConfig: { ...defaultMenuConfig, ...settings.menuConfig }, + pageConfig: { ...defaultPageConfig, ...settings.pageConfig }, + }) + }, [settings.siteConfig, settings.menuConfig, settings.pageConfig]) const handleSave = () => { updateSettings(localSettings) @@ -53,6 +59,17 @@ export default function SiteConfigPage() { setTimeout(() => setSaved(false), 2000) } + if (!mounted) { + return ( +
+
+
+
+
+
+ ) + } + return (
@@ -88,7 +105,7 @@ export default function SiteConfigPage() { setLocalSettings((prev) => ({ ...prev, @@ -104,7 +121,7 @@ export default function SiteConfigPage() { setLocalSettings((prev) => ({ ...prev, @@ -121,7 +138,7 @@ export default function SiteConfigPage() { setLocalSettings((prev) => ({ ...prev, @@ -138,7 +155,7 @@ export default function SiteConfigPage() { setLocalSettings((prev) => ({ ...prev, @@ -154,7 +171,7 @@ export default function SiteConfigPage() { setLocalSettings((prev) => ({ ...prev, @@ -187,7 +204,7 @@ export default function SiteConfigPage() { id="primary-color" type="color" className="w-16 h-10 bg-[#0a1628] border-gray-700 cursor-pointer" - value={localSettings.siteConfig.primaryColor} + value={localSettings.siteConfig.primaryColor || "#00CED1"} onChange={(e) => setLocalSettings((prev) => ({ ...prev, @@ -197,7 +214,7 @@ export default function SiteConfigPage() { /> setLocalSettings((prev) => ({ ...prev, @@ -209,7 +226,7 @@ export default function SiteConfigPage() {
预览
@@ -231,7 +248,7 @@ export default function SiteConfigPage() {
setLocalSettings((prev) => ({ ...prev, @@ -245,7 +262,7 @@ export default function SiteConfigPage() { {key} setLocalSettings((prev) => ({ ...prev, @@ -257,8 +274,8 @@ export default function SiteConfigPage() { } />
- - {config.enabled ? "显示" : "隐藏"} + + {config?.enabled ? "显示" : "隐藏"}
))} @@ -280,7 +297,7 @@ export default function SiteConfigPage() { setLocalSettings((prev) => ({ ...prev, @@ -293,7 +310,7 @@ export default function SiteConfigPage() { setLocalSettings((prev) => ({ ...prev, @@ -308,7 +325,7 @@ export default function SiteConfigPage() { setLocalSettings((prev) => ({ ...prev, @@ -321,7 +338,7 @@ export default function SiteConfigPage() { setLocalSettings((prev) => ({ ...prev, @@ -336,7 +353,7 @@ export default function SiteConfigPage() { setLocalSettings((prev) => ({ ...prev, @@ -349,7 +366,7 @@ export default function SiteConfigPage() { setLocalSettings((prev) => ({ ...prev,