diff --git a/app/(chat)/page.tsx b/app/(chat)/page.tsx
deleted file mode 100644
index 3dc7a5e22..000000000
--- a/app/(chat)/page.tsx
+++ /dev/null
@@ -1,51 +0,0 @@
-import { Suspense } from "react";
-import { LovartHome } from "@/components/home/lovart-home";
-import { auth } from "../(auth)/auth";
-import { getSiteSettings, getSystemSetting } from "@/lib/db/queries";
-
-export default function Page() {
- return (
- }>
-
-
- );
-}
-
-async function NewChatPage() {
- const [session, siteSettings, surpriseCategoriesSetting] =
- await Promise.all([
- auth(),
- getSiteSettings(),
- getSystemSetting({ key: "home_surprise_categories" }).catch(() => undefined),
- ]);
-
- const surpriseCategories = Array.isArray(surpriseCategoriesSetting?.value)
- ? surpriseCategoriesSetting?.value
- .map((item: unknown) => String(item || "").trim())
- .filter(Boolean)
- : ["全部", "精选"];
-
- return (
-
- );
-}
diff --git a/app/api/site-settings/route.ts b/app/api/site-settings/route.ts
index cf92b3f2a..befa3d7f1 100644
--- a/app/api/site-settings/route.ts
+++ b/app/api/site-settings/route.ts
@@ -798,6 +798,7 @@ async function getScopedPublicSiteSettings(
}
const { settings, valueByKey } = await readScopedSiteSettings([
+ HOME_SURPRISE_CATEGORIES_KEY,
LOVART_COMPOSER_PREVIEW_TEXTS_KEY,
LOVART_COMPOSER_PREFIX_KEY,
LOVART_PROMPT_TAG_VISIBILITY_KEY,
@@ -813,6 +814,16 @@ async function getScopedPublicSiteSettings(
return createScopedSiteSettingsResponse(scope, {
...createBrandingSettings(typedSettings),
+ lovartPromoText:
+ typedSettings?.lovartPromoText ||
+ "现在升级,立享 Kling 3.0 与 Nano Banana Pro,最高 5 折优惠",
+ lovartPromoActionText: typedSettings?.lovartPromoActionText || "立即升级",
+ lovartHeroTitle: typedSettings?.lovartHeroTitle || "由壹点AI 让设计更简单",
+ lovartHeroSubtitle:
+ typedSettings?.lovartHeroSubtitle || "懂你的设计代理,帮你搞定一切",
+ surpriseCategories: normalizeSurpriseCategories(
+ valueByKey.get(HOME_SURPRISE_CATEGORIES_KEY)
+ ),
canvasDefaultModelId: typedSettings?.canvasDefaultModelId || null,
lovartComposerPrefix: normalizeLovartComposerPrefix(
valueByKey.get(LOVART_COMPOSER_PREFIX_KEY)
diff --git a/app/layout.tsx b/app/layout.tsx
index 272befcfa..02a43736b 100644
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ -7,36 +7,26 @@ import { ImageDeliveryOptimizer } from "@/components/image-delivery-optimizer";
import "./globals.css";
import { SessionProvider } from "next-auth/react";
-import { getSiteSettings } from "@/lib/db/queries";
+const metadataBase = process.env.AUTH_URL
+ ? new URL(process.env.AUTH_URL)
+ : undefined;
-export async function generateMetadata(): Promise {
- const settings = await getSiteSettings();
- const updatedAt =
- "updatedAt" in settings && settings.updatedAt
- ? new Date(settings.updatedAt).getTime()
- : "default";
- const faviconUrl = `/api/favicon?v=${updatedAt}`;
- const metadataBase = process.env.AUTH_URL
- ? new URL(process.env.AUTH_URL)
- : undefined;
-
- return {
- metadataBase,
- title: {
- template: `%s | ${settings.siteName}`,
- default: settings.siteName,
- },
- description: settings.siteName,
- icons: {
- icon: [
- { url: faviconUrl, sizes: "any" },
- { url: faviconUrl, type: "image/x-icon" },
- ],
- apple: faviconUrl,
- shortcut: faviconUrl,
- },
- };
-}
+export const metadata: Metadata = {
+ metadataBase,
+ title: {
+ template: "%s | AI Chatbot",
+ default: "AI Chatbot",
+ },
+ description: "AI Chatbot",
+ icons: {
+ icon: [
+ { url: "/api/favicon", sizes: "any" },
+ { url: "/api/favicon", type: "image/x-icon" },
+ ],
+ apple: "/api/favicon",
+ shortcut: "/api/favicon",
+ },
+};
export const viewport = {
maximumScale: 1, // Disable auto-zoom on mobile Safari
@@ -153,15 +143,11 @@ const CHUNK_ERROR_RECOVERY_SCRIPT = `\
});
})();`;
-export default async function RootLayout({
+export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
- // 获取网站设置中的默认主题
- const settings = await getSiteSettings();
- const defaultTheme = settings.defaultTheme || "system";
-
return (
diff --git a/app/page.tsx b/app/page.tsx
new file mode 100644
index 000000000..dde8f02c2
--- /dev/null
+++ b/app/page.tsx
@@ -0,0 +1,5 @@
+import { LovartHome } from "@/components/home/lovart-home";
+
+export default function Page() {
+ return ;
+}
diff --git a/components/home/lovart-home.tsx b/components/home/lovart-home.tsx
index fc778fef5..45672ae54 100644
--- a/components/home/lovart-home.tsx
+++ b/components/home/lovart-home.tsx
@@ -228,12 +228,12 @@ type AccountCenterResponse = {
};
type LovartHomeProps = {
- user: HomeUser | null;
- isAuthenticated: boolean;
- siteName: string;
+ user?: HomeUser | null;
+ isAuthenticated?: boolean;
+ siteName?: string;
siteLogo?: string | null;
siteLogoDark?: string | null;
- surpriseCategories: string[];
+ surpriseCategories?: string[];
heroPromoText?: string | null;
heroPromoActionText?: string | null;
heroTitleText?: string | null;
@@ -422,27 +422,19 @@ function AccountMenuItem({
}
export function LovartHome({
- user,
- isAuthenticated,
- siteName,
- siteLogo,
- siteLogoDark,
- surpriseCategories,
- heroPromoText,
- heroPromoActionText,
- heroTitleText,
- heroSubtitleText,
-}: LovartHomeProps) {
+ user = null,
+ isAuthenticated = false,
+ siteName: initialSiteName = "AI Chatbot",
+ siteLogo: initialSiteLogo = null,
+ siteLogoDark: initialSiteLogoDark = null,
+ surpriseCategories: initialSurpriseCategories = ["全部", "精选"],
+ heroPromoText: initialHeroPromoText = null,
+ heroPromoActionText: initialHeroPromoActionText = null,
+ heroTitleText: initialHeroTitleText = null,
+ heroSubtitleText: initialHeroSubtitleText = null,
+}: LovartHomeProps = {}) {
const router = useRouter();
const { theme, resolvedTheme, setTheme } = useTheme();
- const displayLogo =
- resolvedTheme === "dark"
- ? siteLogoDark?.trim() || siteLogo?.trim() || ""
- : siteLogo?.trim() || siteLogoDark?.trim() || "";
- const shouldInvertLogo =
- resolvedTheme === "dark" &&
- !siteLogoDark?.trim() &&
- Boolean(siteLogo?.trim());
const sidebarPopupBaseClass =
"rounded-[24px] border border-black/8 bg-white/96 p-2.5 text-[#111827] shadow-[0_24px_64px_rgba(15,23,42,0.12)] backdrop-blur-xl";
const lovartSidebarButtonClass = (active = false) =>
@@ -578,6 +570,14 @@ export function LovartHome({
);
const { data: siteSettingsData } = useSWR<{
+ siteName?: string | null;
+ siteLogo?: string | null;
+ siteLogoDark?: string | null;
+ lovartPromoText?: string | null;
+ lovartPromoActionText?: string | null;
+ lovartHeroTitle?: string | null;
+ lovartHeroSubtitle?: string | null;
+ surpriseCategories?: string[];
canvasDefaultModelId?: string | null;
lovartComposerPrefix?: string | null;
lovartComposerPreviewTexts?: string[];
@@ -603,6 +603,30 @@ export function LovartHome({
lovartHomeSidebarConfig?: unknown;
}>("/api/site-settings?scope=home", fetcher);
+ const siteName = String(
+ siteSettingsData?.siteName || initialSiteName || "AI Chatbot"
+ ).trim();
+ const siteLogo = String(siteSettingsData?.siteLogo || initialSiteLogo || "").trim();
+ const siteLogoDark = String(
+ siteSettingsData?.siteLogoDark || initialSiteLogoDark || ""
+ ).trim();
+ const heroPromoText =
+ siteSettingsData?.lovartPromoText ?? initialHeroPromoText;
+ const heroPromoActionText =
+ siteSettingsData?.lovartPromoActionText ?? initialHeroPromoActionText;
+ const heroTitleText =
+ siteSettingsData?.lovartHeroTitle ?? initialHeroTitleText;
+ const heroSubtitleText =
+ siteSettingsData?.lovartHeroSubtitle ?? initialHeroSubtitleText;
+ const surpriseCategories =
+ siteSettingsData?.surpriseCategories ?? initialSurpriseCategories;
+ const displayLogo =
+ resolvedTheme === "dark"
+ ? siteLogoDark || siteLogo || ""
+ : siteLogo || siteLogoDark || "";
+ const shouldInvertLogo =
+ resolvedTheme === "dark" && !siteLogoDark && Boolean(siteLogo);
+
const { data: tutorialVideosData } = useSWR<{ videos: TutorialVideo[] }>(
isSecondaryDataReady && siteSettingsData?.tutorialEnabled
? "/api/tutorial-videos"