+
+
-
- {placeholderLabel}
+
+
+ {isChinese ? "更多服务即将上线" : "More services coming soon"}
+
+
+ {isChinese
+ ? "预留卡片位置,持续扩充入口。"
+ : "Reserved slots for new service entries."}
+
-
- {placeholderDescription}
-
-
+
{isChinese ? "敬请期待" : "Stay tuned"}
);
-};
-
-const ServiceGrid = ({
- view,
- services,
- isChinese,
-}: {
- view: "classic" | "material";
- services: ServiceCardData[];
- isChinese: boolean;
-}) => {
- return (
-
- {services.map((service) => (
-
- ))}
- {Array.from({ length: placeholderCount }).map((_, index) => (
-
- ))}
-
- );
-};
-
-const ClawdbotLogo = (props: any) => (
-

-);
+}
export default function ServicesPage() {
- const { view, isHydrated } = useViewStore();
const { language } = useLanguage();
const isChinese = language === "zh";
@@ -299,71 +211,83 @@ export default function ServicesPage() {
external: true,
},
{
- key: "moltbot",
+ key: "xworkmate",
name: "XWorkmate",
description: isChinese
? "在线版 XWorkmate 工作区,底层由 OpenClaw gateway 驱动。"
: "Online XWorkmate workspace powered by the OpenClaw gateway.",
href: "/xworkmate",
- icon: ClawdbotLogo,
+ icon: Command,
},
];
- if (!isHydrated) {
- return null;
- }
-
- if (view === "material") {
- return (
-
-
-
- Service Overview
-
-
- Real-time metrics and system health for your current production
- environment.
-
-
-
-
- );
- }
-
return (
-
-
-
-
-
-
-
- {isChinese ? "更多服务" : "More services"}
-
-
- {isChinese ? "扩展服务与工具箱" : "Extended Services & Toolbox"}
-
-
- {isChinese
- ? "汇聚开发辅助、运维监控与核心制品,构建无缝衔接的云原生工作台。"
- : "A unified hub for development aids, operations monitoring, and core artifacts."}
-
-
-
+
+
+
+
+ {isChinese ? "页面原则" : "Page rhythm"}
+
+
+ {isChinese
+ ? "保持结构不变,但去掉 classic / material 的风格分裂。"
+ : "Keep the structure, remove the classic/material visual split."}
+
+
+
+
+
+
+
+
+
+ {isChinese ? "服务目录" : "Service directory"}
+
+
+ {isChinese
+ ? "每个入口都使用同一种卡片语法:白底、细边框、轻阴影、明确标题。"
+ : "Every entry now follows the same card grammar: pale surface, fine border, light shadow, and clear hierarchy."}
+
+
+
+ {services.length} {isChinese ? "个入口" : "entries"}
+
+
+
+
+ {services.map((service) => (
+
+ ))}
+ {Array.from({ length: placeholderCount }).map((_, index) => (
+
+ ))}
+
+
+
);
}
diff --git a/src/app/xworkmate/admin/page.tsx b/src/app/xworkmate/admin/page.tsx
index dff0a3a..192ee5a 100644
--- a/src/app/xworkmate/admin/page.tsx
+++ b/src/app/xworkmate/admin/page.tsx
@@ -1,6 +1,6 @@
import { headers } from "next/headers";
import { redirect } from "next/navigation";
-
+export const dynamic = "force-dynamic";
import { XWorkmateProfileEditor } from "@/components/xworkmate/XWorkmateProfileEditor";
import {
buildSharedXWorkmateUrl,
diff --git a/src/app/xworkmate/integrations/page.tsx b/src/app/xworkmate/integrations/page.tsx
index ba03674..a043365 100644
--- a/src/app/xworkmate/integrations/page.tsx
+++ b/src/app/xworkmate/integrations/page.tsx
@@ -1,6 +1,6 @@
import { headers } from "next/headers";
import { redirect } from "next/navigation";
-
+export const dynamic = "force-dynamic";
import { XWorkmateProfileEditor } from "@/components/xworkmate/XWorkmateProfileEditor";
import {
buildSharedXWorkmateUrl,
diff --git a/src/app/xworkmate/layout.tsx b/src/app/xworkmate/layout.tsx
new file mode 100644
index 0000000..9a6b1c8
--- /dev/null
+++ b/src/app/xworkmate/layout.tsx
@@ -0,0 +1,9 @@
+export const dynamic = "force-dynamic";
+
+export default function XWorkmateLayout({
+ children,
+}: {
+ children: React.ReactNode;
+}) {
+ return children;
+}
diff --git a/src/app/xworkmate/page.tsx b/src/app/xworkmate/page.tsx
index 60fbe89..5615354 100644
--- a/src/app/xworkmate/page.tsx
+++ b/src/app/xworkmate/page.tsx
@@ -2,6 +2,8 @@ import { Suspense } from "react";
import { headers } from "next/headers";
import { redirect } from "next/navigation";
+export const dynamic = "force-dynamic";
+
import { XWorkmateLoading } from "@/app/xworkmate/XWorkmateLoading";
import { XWorkmateWorkspacePage } from "@/components/xworkmate/XWorkmateWorkspacePage";
import {
diff --git a/src/components/doc/DocArticle.tsx b/src/components/doc/DocArticle.tsx
index fc0af0d..fb7e9b1 100644
--- a/src/components/doc/DocArticle.tsx
+++ b/src/components/doc/DocArticle.tsx
@@ -1,17 +1,17 @@
-import { marked } from 'marked'
+import { marked } from "marked";
interface DocArticleProps {
- content: string
+ content: string;
}
export default async function DocArticle({ content }: DocArticleProps) {
// Convert markdown to HTML
- const htmlContent = await marked(content)
+ const htmlContent = await marked(content);
return (
- )
+ );
}
diff --git a/src/components/doc/DocMetaPanel.tsx b/src/components/doc/DocMetaPanel.tsx
index bec7fb4..41407a4 100644
--- a/src/components/doc/DocMetaPanel.tsx
+++ b/src/components/doc/DocMetaPanel.tsx
@@ -1,29 +1,40 @@
-import ClientTime from '@/app/components/ClientTime'
+import ClientTime from "@/app/components/ClientTime";
interface DocMetaPanelProps {
- description?: string
- updatedAt?: string
- tags?: string[]
+ description?: string;
+ updatedAt?: string;
+ tags?: string[];
}
-export default function DocMetaPanel({ description, updatedAt, tags }: DocMetaPanelProps) {
+export default function DocMetaPanel({
+ description,
+ updatedAt,
+ tags,
+}: DocMetaPanelProps) {
return (
-
- {description &&
{description}
}
- {tags && tags.length > 0 && (
+
+ {description ? (
+
{description}
+ ) : null}
+
+ {tags && tags.length > 0 ? (
{tags.map((tag) => (
-
+
{tag}
))}
- )}
- {updatedAt && (
-
+ ) : null}
+
+ {updatedAt ? (
+
Updated
- )}
+ ) : null}
- )
+ );
}
diff --git a/src/components/public/PublicPageShell.tsx b/src/components/public/PublicPageShell.tsx
new file mode 100644
index 0000000..b4b360a
--- /dev/null
+++ b/src/components/public/PublicPageShell.tsx
@@ -0,0 +1,82 @@
+import Footer from "@/components/Footer";
+import UnifiedNavigation from "@/components/UnifiedNavigation";
+import { cn } from "@/lib/utils";
+
+type PublicPageShellProps = {
+ children: React.ReactNode;
+ mainClassName?: string;
+ containerClassName?: string;
+};
+
+type PublicPageIntroProps = {
+ eyebrow?: string;
+ title: string;
+ subtitle?: string;
+ titleClassName?: string;
+ className?: string;
+};
+
+export function PublicPageShell({
+ children,
+ mainClassName,
+ containerClassName,
+}: PublicPageShellProps) {
+ return (
+
+
+
+
+
+
+ {children}
+
+
+
+
+
+ );
+}
+
+export function PublicPageIntro({
+ eyebrow,
+ title,
+ subtitle,
+ titleClassName,
+ className,
+}: PublicPageIntroProps) {
+ return (
+
+ {eyebrow ? (
+
+ {eyebrow}
+
+ ) : null}
+
+ {title}
+
+ {subtitle ? (
+
+ {subtitle}
+
+ ) : null}
+
+ );
+}
diff --git a/src/components/xworkmate/XWorkmateWorkspacePage.tsx b/src/components/xworkmate/XWorkmateWorkspacePage.tsx
index 6e53fcf..2da26c6 100644
--- a/src/components/xworkmate/XWorkmateWorkspacePage.tsx
+++ b/src/components/xworkmate/XWorkmateWorkspacePage.tsx
@@ -12,12 +12,15 @@ import {
Grip,
KeyRound,
ListTodo,
+ Paperclip,
Puzzle,
RefreshCw,
+ Send,
Settings2,
Shield,
Sparkles,
UserCircle2,
+ Zap,
} from "lucide-react";
import { useRouter } from "next/navigation";
@@ -73,7 +76,7 @@ type DetailCardProps = {
meta: string;
};
-function pickCopy(isChinese: boolean, zh: string, en: string): string {
+function pickCopy
(isChinese: boolean, zh: T, en: T): T {
return isChinese ? zh : en;
}
@@ -506,6 +509,7 @@ function AssistantHome({
secondaryActionLabel,
connectionHint,
actionDisabled,
+ isSharedProfile,
}: {
isChinese: boolean;
tabs: SectionTab[];
@@ -518,122 +522,122 @@ function AssistantHome({
secondaryActionLabel: string;
connectionHint?: string;
actionDisabled?: boolean;
+ isSharedProfile?: boolean;
}) {
- return (
- <>
-
-
-
-
-
-
-
-
-
- {pickCopy(isChinese, "默认任务", "Default Task")}
-
-
- {pickCopy(
- isChinese,
- "连接 Gateway 后,当前对话会自动作为默认任务开始执行。",
- "After connecting the gateway, the current conversation starts as the default task.",
- )}
-
-
- {tabs.map((tab, index) => (
-
- ))}
-
-
-
- {connected
- ? `${pickCopy(isChinese, "在线", "Online")} · ${endpointLabel}`
- : pickCopy(isChinese, "离线 · 未连接目标", "Offline · No target")}
-
-
-
+ const suggestions = pickCopy(
+ isChinese,
+ [
+ "幻灯片",
+ "视频生成",
+ "深度研究",
+ "文档处理",
+ "数据分析",
+ "可视化",
+ "金融服务",
+ "产品管理",
+ "设计",
+ "邮件编辑",
+ ],
+ [
+ "Slides",
+ "Video Gen",
+ "Deep Research",
+ "Docs Processing",
+ "Data Analysis",
+ "Visualization",
+ "Finance",
+ "Product Management",
+ "Design",
+ "Email Edit",
+ ]
+ );
-
-
-
-
- {pickCopy(isChinese, "先连接 Gateway", "Connect Gateway First")}
-
-
- {pickCopy(
- isChinese,
- "连接后可直接对话、创建任务,并在当前会话查看结果。",
- "Connect first to start chatting, create tasks, and view results in the current conversation.",
- )}
-
- {connectionHint ? (
-
- {connectionHint}
-
- ) : null}
-
+ return (
+
+
+ {!isSharedProfile && (
+
+
+
+
+ {pickCopy(isChinese, "未连接 Gateway", "Gateway Disconnected")}
+
+
+ {connectionHint || pickCopy(isChinese, "请连接 Gateway 以获取完整能力。", "Please connect Gateway for full capabilities.")}
+
+
-
-
+ )}
-