diff --git a/web/src/app/home/bots/botConfig.module.css b/web/src/app/home/bots/botConfig.module.css index ae201324..80fa5f2c 100644 --- a/web/src/app/home/bots/botConfig.module.css +++ b/web/src/app/home/bots/botConfig.module.css @@ -13,7 +13,7 @@ align-self: flex-start; justify-self: flex-start; width: calc(100% - 60px); - margin: auto; + margin: auto; display: grid; grid-template-rows: repeat(auto-fill, minmax(220px, 1fr)); grid-template-columns: repeat(auto-fill, minmax(360px, 1fr)); diff --git a/web/src/app/home/bots/page.tsx b/web/src/app/home/bots/page.tsx index fdd32f59..c2760b01 100644 --- a/web/src/app/home/bots/page.tsx +++ b/web/src/app/home/bots/page.tsx @@ -1,162 +1,168 @@ -"use client" +"use client"; -import {useEffect, useState} from "react"; +import { useEffect, useState } from "react"; import styles from "./botConfig.module.css"; import EmptyAndCreateComponent from "@/app/home/components/empty-and-create-component/EmptyAndCreateComponent"; -import {useRouter} from "next/navigation"; -import {BotCardVO} from "@/app/home/bots/components/bot-card/BotCardVO"; -import {Modal, notification, Spin} from "antd"; +import { useRouter } from "next/navigation"; +import { BotCardVO } from "@/app/home/bots/components/bot-card/BotCardVO"; +import { Modal, notification, Spin } from "antd"; import BotForm from "@/app/home/bots/components/bot-form/BotForm"; import BotCard from "@/app/home/bots/components/bot-card/BotCard"; -import CreateCardComponent from "@/app/infra/basic-component/create-card-component/CreateCardComponent" -import {httpClient} from "@/app/infra/http/HttpClient"; +import CreateCardComponent from "@/app/infra/basic-component/create-card-component/CreateCardComponent"; +import { httpClient } from "@/app/infra/http/HttpClient"; import { Bot } from "@/app/infra/api/api-types"; export default function BotConfigPage() { - const router = useRouter(); - const [pageShowRule, setPageShowRule] = useState(BotConfigPageShowRule.NO_BOT) - const [modalOpen, setModalOpen] = useState(false); - const [botList, setBotList] = useState([]) - const [isEditForm, setIsEditForm] = useState(false) - const [nowSelectedBotCard, setNowSelectedBotCard] = useState() - const [isLoading, setIsLoading] = useState(false) + const router = useRouter(); + const [pageShowRule, setPageShowRule] = useState( + BotConfigPageShowRule.NO_BOT + ); + const [modalOpen, setModalOpen] = useState(false); + const [botList, setBotList] = useState([]); + const [isEditForm, setIsEditForm] = useState(false); + const [nowSelectedBotCard, setNowSelectedBotCard] = useState(); + const [isLoading, setIsLoading] = useState(false); + useEffect(() => { + // TODO:补齐加载转圈逻辑 + setIsLoading(true); + checkHasLLM().then((hasLLM) => { + if (hasLLM) { + getBotList(); + } else { + setPageShowRule(BotConfigPageShowRule.NO_LLM); + setIsLoading(false); + } + }); + }, []); - useEffect(() => { - // TODO:补齐加载转圈逻辑 - setIsLoading(true) - checkHasLLM().then((hasLLM) => { - if (hasLLM) { - getBotList() - } else { - setPageShowRule(BotConfigPageShowRule.NO_LLM) - setIsLoading(false) - } - }) - }, []) + async function checkHasLLM(): Promise { + // NOT IMPL + return true; + } - async function checkHasLLM(): Promise { - // NOT IMPL - return true - } + function getBotList() { + httpClient + .getBots() + .then((resp) => { + const botList: BotCardVO[] = resp.bots.map((bot: Bot) => { + return new BotCardVO({ + adapter: bot.adapter, + description: bot.description, + id: bot.uuid || "", + name: bot.name, + updateTime: bot.updated_at || "", + pipelineName: bot.use_pipeline_name || "" + }); + }); + if (botList.length === 0) { + setPageShowRule(BotConfigPageShowRule.NO_BOT); + } else { + setPageShowRule(BotConfigPageShowRule.HAVE_BOT); + } + setBotList(botList); + }) + .catch((err) => { + console.error("get bot list error", err); + // TODO HACK: need refactor to hook mode Notification, but it's not working under render + notification.error({ + message: "获取机器人列表失败", + description: err.message, + placement: "bottomRight" + }); + }) + .finally(() => { + setIsLoading(false); + }); + } - function getBotList() { - httpClient.getBots().then((resp) => { - const botList: BotCardVO[] = resp.bots.map((bot: Bot) => { - return new BotCardVO({ - adapter: bot.adapter, - description: bot.description, - id: bot.uuid || "", - name: bot.name, - updateTime: bot.updated_at || "", - pipelineName: bot.use_pipeline_name || "", - }) - }) - if (botList.length === 0) { - setPageShowRule(BotConfigPageShowRule.NO_BOT) - } else { - setPageShowRule(BotConfigPageShowRule.HAVE_BOT) - } - setBotList(botList) - }).catch((err) => { - console.error("get bot list error", err) - // TODO HACK: need refactor to hook mode Notification, but it's not working under render - notification.error({ - message: "获取机器人列表失败", - description: err.message, - placement: "bottomRight", - }) - }).finally(() => { - setIsLoading(false) - }) - } + function handleCreateBotClick() { + setIsEditForm(false); + setNowSelectedCard(undefined); + setModalOpen(true); + } - function handleCreateBotClick() { - setIsEditForm(false) - setNowSelectedCard(undefined) - setModalOpen(true); - } + function setNowSelectedCard(cardVO: BotCardVO | undefined) { + setNowSelectedBotCard(cardVO); + } - function setNowSelectedCard(cardVO: BotCardVO | undefined) { - setNowSelectedBotCard(cardVO) - } + function selectBot(cardVO: BotCardVO) { + setIsEditForm(true); + setNowSelectedCard(cardVO); + console.log("set now vo", cardVO); + setModalOpen(true); + } - function selectBot(cardVO: BotCardVO) { - setIsEditForm(true) - setNowSelectedCard(cardVO) - console.log("set now vo", cardVO) - setModalOpen(true) - } + return ( +
+ + setModalOpen(false)} + onCancel={() => setModalOpen(false)} + width={700} + footer={null} + destroyOnClose={true} + > + { + getBotList(); + setModalOpen(false); + }} + onFormCancel={() => setModalOpen(false)} + /> + + {pageShowRule === BotConfigPageShowRule.NO_LLM && ( + { + router.push("/home/models"); + }} + /> + )} - return ( - -
- setModalOpen(false)} - onCancel={() => setModalOpen(false)} - width={700} - footer={null} - destroyOnClose={true} - > - { - getBotList() - setModalOpen(false) - }} - onFormCancel={() => setModalOpen(false)} - /> - - {pageShowRule === BotConfigPageShowRule.NO_LLM && - { - router.push("/home/models"); - }} - /> - } - - {pageShowRule === BotConfigPageShowRule.NO_BOT && - - } - - {pageShowRule === BotConfigPageShowRule.HAVE_BOT && -
- {botList.map(cardVO => { - return ( -
{selectBot(cardVO)}} - > - -
) - })} - -
- } + {pageShowRule === BotConfigPageShowRule.NO_BOT && ( + + )} + + {/* 注意:其余的返回内容需要保持在Spin组件外部 */} + {pageShowRule === BotConfigPageShowRule.HAVE_BOT && ( +
+ {botList.map((cardVO) => { + return ( +
{ + selectBot(cardVO); + }} + > + +
+ ); + })} +
- - ) + )} +
+ ); } enum BotConfigPageShowRule { - NO_LLM, - NO_BOT, - HAVE_BOT, -} \ No newline at end of file + NO_LLM, + NO_BOT, + HAVE_BOT +} diff --git a/web/src/app/home/components/home-sidebar/HomeSidebar.tsx b/web/src/app/home/components/home-sidebar/HomeSidebar.tsx index 12813b29..7a950e91 100644 --- a/web/src/app/home/components/home-sidebar/HomeSidebar.tsx +++ b/web/src/app/home/components/home-sidebar/HomeSidebar.tsx @@ -67,34 +67,42 @@ export default function HomeSidebar({ } } - return ( -
- {/* LangBot、ICON区域 */} -
- {/* icon */} -
L
-
Langbot
-
- {/* 菜单列表,后期可升级成配置驱动 */} -
- {sidebarConfigList.map((config) => { - return ( -
{ - console.log("click:", config.id); - handleChildClick(config); - }} - > - + + return ( +
+ {/* LangBot、ICON区域 */} +
+ {/* icon */} +
+ L +
+
+ Langbot +
- ); - })} -
-
- ); -} + {/* 菜单列表,后期可升级成配置驱动 */} +
+ { + sidebarConfigList.map(config => { + return ( +
{ + console.log('click:', config.id) + handleChildClick(config) + }} + > + +
+ ) + }) + } + +
+
+ ); +} \ No newline at end of file diff --git a/web/src/app/home/layout.module.css b/web/src/app/home/layout.module.css index bcbdc800..8bc33e35 100644 --- a/web/src/app/home/layout.module.css +++ b/web/src/app/home/layout.module.css @@ -1,3 +1,4 @@ +/* 主布局容器 */ .homeLayoutContainer { width: 100vw; height: 100vh; @@ -5,14 +6,12 @@ flex-direction: row; } +/* 主内容区域 */ .main { + background-color: #f5f5f7; + padding: 0; + overflow: auto; width: 100%; height: 100%; - background-color: #FAFBFB; -} - -.mainContent { - width: calc(100% - 40px); - height: calc(100% - 110px); - margin: 20px; + padding: 20px; } \ No newline at end of file diff --git a/web/src/app/home/layout.tsx b/web/src/app/home/layout.tsx index 7985dae6..c765aef0 100644 --- a/web/src/app/home/layout.tsx +++ b/web/src/app/home/layout.tsx @@ -1,30 +1,48 @@ -"use client"; +"use client" -import "@ant-design/v5-patch-for-react-19"; -import styles from "./layout.module.css"; +import '@ant-design/v5-patch-for-react-19'; +import styles from "./layout.module.css" import HomeSidebar from "@/app/home/components/home-sidebar/HomeSidebar"; import HomeTitleBar from "@/app/home/components/home-titlebar/HomeTitleBar"; import React, { useState } from "react"; import { SidebarChildVO } from "@/app/home/components/home-sidebar/HomeSidebarChild"; +import { useRouter } from 'next/navigation'; +import { Layout } from 'antd'; + +const { Sider, Content } = Layout; export default function HomeLayout({ children }: Readonly<{ children: React.ReactNode; }>) { - const [title, setTitle] = useState(""); - const onSelectedChange = (child: SidebarChildVO) => { - setTitle(child.name); - }; + const router = useRouter(); + const [title, setTitle] = useState("") + const onSelectedChangeAction = (child: SidebarChildVO) => { + setTitle(child.name) + } return ( -
- -
+ + {/* homeLayoutContainer 是整个容器的入口,使用 flex 的左右布局 */} + + + + {/* HomeSidebar 为侧边栏 */} + + + + {/* right 为内容显示区域,right使用 flex 上下布局,right 使用 flex 布局吃掉剩余部分 */} + - {/* 主页面 */} -
{children}
-
-
- ); + + + {/* mainContent 为主页面 */} + {children} + + + + ) } diff --git a/web/src/app/home/plugins/page.tsx b/web/src/app/home/plugins/page.tsx index e28db69d..10151b39 100644 --- a/web/src/app/home/plugins/page.tsx +++ b/web/src/app/home/plugins/page.tsx @@ -1,6 +1,6 @@ "use client" import { Radio } from 'antd'; -import {useState} from "react"; +import { useState } from "react"; import PluginInstalledComponent from "@/app/home/plugins/plugin-installed/PluginInstalledComponent"; import PluginMarketComponent from "@/app/home/plugins/plugin-market/PluginMarketComponent"; import styles from './plugins.module.css' @@ -14,33 +14,24 @@ export default function PluginConfigPage() { const [nowPageType, setNowPageType] = useState(PageType.INSTALLED) return ( -
-
- { - // 这里静态类型检测有问题 - setNowPageType(e.target.value) - }} - /> -
-
- { - nowPageType === PageType.INSTALLED && - } - { - nowPageType === PageType.MARKET && - } -
+
+ { + setNowPageType(e.target.value as PageType) + }} + /> + {nowPageType === PageType.INSTALLED ? : }
); } diff --git a/web/src/app/home/plugins/plugin-installed/PluginInstalledComponent.tsx b/web/src/app/home/plugins/plugin-installed/PluginInstalledComponent.tsx index 1b5cea43..b6e149ae 100644 --- a/web/src/app/home/plugins/plugin-installed/PluginInstalledComponent.tsx +++ b/web/src/app/home/plugins/plugin-installed/PluginInstalledComponent.tsx @@ -1,8 +1,8 @@ "use client"; +import { useState, useEffect } from "react"; import CreateCardComponent from "@/app/infra/basic-component/create-card-component/CreateCardComponent"; import { PluginCardVO } from "@/app/home/plugins/plugin-installed/PluginCardVO"; -import { useEffect, useState } from "react"; import PluginCardComponent from "@/app/home/plugins/plugin-installed/plugin-card/PluginCardComponent"; import styles from "@/app/home/plugins/plugins.module.css"; import { Modal, Input } from "antd"; @@ -66,16 +66,12 @@ export default function PluginInstalledComponent() { fontSize: "30px", marginRight: "20px" }} - type="setting" /> - 从 GitHub 安装插件
} - centered open={modalOpen} - onOk={() => handleModalConfirm()} + onOk={handleModalConfirm} onCancel={() => setModalOpen(false)} - width={500} destroyOnClose={true} >
@@ -95,7 +91,6 @@ export default function PluginInstalledComponent() { ); })} { diff --git a/web/src/app/home/plugins/plugin-installed/plugin-card/PluginCardComponent.tsx b/web/src/app/home/plugins/plugin-installed/plugin-card/PluginCardComponent.tsx index fcae4000..8999534f 100644 --- a/web/src/app/home/plugins/plugin-installed/plugin-card/PluginCardComponent.tsx +++ b/web/src/app/home/plugins/plugin-installed/plugin-card/PluginCardComponent.tsx @@ -46,19 +46,22 @@ export default function PluginCardComponent({
{/* footer */}
-
-
- - 1 +
+
+
+ + 1 +
+ +
+
+
-
- -
); diff --git a/web/src/app/home/plugins/plugin-installed/plugin-card/pluginCard.module.css b/web/src/app/home/plugins/plugin-installed/plugin-card/pluginCard.module.css index 81ad489a..1d09d462 100644 --- a/web/src/app/home/plugins/plugin-installed/plugin-card/pluginCard.module.css +++ b/web/src/app/home/plugins/plugin-installed/plugin-card/pluginCard.module.css @@ -1,5 +1,6 @@ .cardContainer { - width: 360px; + width: 100%; + /* 修改为 100% 以撑满整个网格单元 */ height: 140px; box-sizing: border-box; background-color: #FFF; @@ -40,12 +41,29 @@ .cardFooter { width: 90%; height: 30px; + position: relative; +} + +.footerContainer { + width: 100%; + height: 100%; display: flex; flex-direction: row; align-items: center; justify-content: space-between; } +.linkAndToolContainer { + display: flex; + flex-direction: row; + align-items: center; + gap: 10px; +} + +.switchContainer { + display: flex; + justify-content: flex-end; +} .fontGray { color: #6C6C6C; @@ -73,4 +91,4 @@ align-self: center; justify-content: space-between; } -} +} \ No newline at end of file diff --git a/web/src/app/home/plugins/plugin-market/PluginMarketComponent.tsx b/web/src/app/home/plugins/plugin-market/PluginMarketComponent.tsx index d01aeb6e..9e84c0ff 100644 --- a/web/src/app/home/plugins/plugin-market/PluginMarketComponent.tsx +++ b/web/src/app/home/plugins/plugin-market/PluginMarketComponent.tsx @@ -8,80 +8,100 @@ import { Input, Pagination } from "antd"; import { spaceClient } from "@/app/infra/http/HttpClient"; export default function PluginMarketComponent() { - const [marketPluginList, setMarketPluginList] = useState< - PluginMarketCardVO[] - >([]); - const [totalCount, setTotalCount] = useState(0); - const [nowPage, setNowPage] = useState(1); - const [searchKeyword, setSearchKeyword] = useState(""); + const [marketPluginList, setMarketPluginList] = useState< + PluginMarketCardVO[] + >([]); + const [totalCount, setTotalCount] = useState(0); + const [nowPage, setNowPage] = useState(1); + const [searchKeyword, setSearchKeyword] = useState(""); + const [loading, setLoading] = useState(false); + const pageSize = 10; - useEffect(() => { - initData(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + useEffect(() => { + initData(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); - function initData() { - getPluginList(); - } + function initData() { + getPluginList(); + } - function onInputSearchKeyword(keyword: string) { - // 这里记得加防抖,暂时没加 - setSearchKeyword(keyword); - setNowPage(1); - getPluginList(1, keyword); - } + function onInputSearchKeyword(keyword: string) { + // 这里记得加防抖,暂时没加 + setSearchKeyword(keyword); + setNowPage(1); + getPluginList(1, keyword); + } - function getPluginList( - page: number = nowPage, - keyword: string = searchKeyword - ) { - spaceClient.getMarketPlugins(page, 10, keyword).then((res) => { - setMarketPluginList( - res.plugins.map( - (marketPlugin) => - new PluginMarketCardVO({ - author: marketPlugin.author, - description: marketPlugin.description, - githubURL: marketPlugin.repository, - name: marketPlugin.name, - pluginId: String(marketPlugin.ID), - starCount: marketPlugin.stars - }) - ) - ); - setTotalCount(res.total); - console.log("market plugins:", res); - }); - } + function getPluginList( + page: number = nowPage, + keyword: string = searchKeyword + ) { + setLoading(true); + spaceClient.getMarketPlugins(page, pageSize, keyword).then((res) => { + setMarketPluginList( + res.plugins.map( + (marketPlugin) => + new PluginMarketCardVO({ + author: marketPlugin.author, + description: marketPlugin.description, + githubURL: marketPlugin.repository, + name: marketPlugin.name, + pluginId: String(marketPlugin.ID), + starCount: marketPlugin.stars, + version: "version" in marketPlugin ? String(marketPlugin.version) : "1.0.0", // Default version if not provided + }) + ) + ); + setTotalCount(res.total); + setLoading(false); + console.log("market plugins:", res); + }).catch(error => { + console.error("获取插件列表失败:", error); + setLoading(false); + }); + } - return ( -
- onInputSearchKeyword(e.target.value)} - /> -
- {marketPluginList.map((vo, index) => { - return ( -
- + function handlePageChange(page: number) { + setNowPage(page); + getPluginList(page); + } + + return ( +
+ onInputSearchKeyword(e.target.value)} + /> +
+ {loading ? ( +
加载中...
+ ) : marketPluginList.length === 0 ? ( +
没有找到匹配的插件
+ ) : ( + marketPluginList.map((vo, index) => ( +
+ +
+ )) + )}
- ); - })} -
- { - setNowPage(pageNumber); - getPluginList(pageNumber); - }} - /> -
- ); + {totalCount > 0 && ( +
+ +
+ )} +
+ ) } diff --git a/web/src/app/home/plugins/plugin-market/plugin-market-card/PluginMarketCardComponent.tsx b/web/src/app/home/plugins/plugin-market/plugin-market-card/PluginMarketCardComponent.tsx index 5d96c57f..dcc1dfd0 100644 --- a/web/src/app/home/plugins/plugin-market/plugin-market-card/PluginMarketCardComponent.tsx +++ b/web/src/app/home/plugins/plugin-market/plugin-market-card/PluginMarketCardComponent.tsx @@ -1,56 +1,49 @@ -import styles from "./pluginMarketCard.module.css" -import {GithubOutlined, StarOutlined} from '@ant-design/icons'; -import {PluginMarketCardVO} from "@/app/home/plugins/plugin-market/plugin-market-card/PluginMarketCardVO"; -import {Button} from "antd"; +import styles from "./pluginMarketCard.module.css"; +import { GithubOutlined, StarOutlined } from "@ant-design/icons"; +import { PluginMarketCardVO } from "@/app/home/plugins/plugin-market/plugin-market-card/PluginMarketCardVO"; +import { Button } from "antd"; export default function PluginMarketCardComponent({ - cardVO + cardVO }: { - cardVO: PluginMarketCardVO + cardVO: PluginMarketCardVO; }) { + function handleInstallClick(pluginId: string) { + console.log("Install plugin: ", pluginId); + } - - function handleInstallClick (pluginId: string) { - console.log("Install plugin: ", pluginId) - } - - return ( -
- {/* header */} -
- {/* left author */} -
{cardVO.author}
- {/* right icon */} - -
- {/* content */} -
-
{cardVO.name}
-
{cardVO.description}
-
- {/* footer */} -
-
-
- - {cardVO.starCount} -
-
- -
+ return ( +
+ {/* header */} +
+ {/* left author */} +
{cardVO.author}
+ {/* right icon */} + +
+ {/* content */} +
+
{cardVO.name}
+
{cardVO.description}
+
+ {/* footer */} +
+
+
+ + {cardVO.starCount} +
- ); + +
+
+ ); } diff --git a/web/src/app/home/plugins/plugin-market/plugin-market-card/PluginMarketCardVO.ts b/web/src/app/home/plugins/plugin-market/plugin-market-card/PluginMarketCardVO.ts index 6af3f199..9d508066 100644 --- a/web/src/app/home/plugins/plugin-market/plugin-market-card/PluginMarketCardVO.ts +++ b/web/src/app/home/plugins/plugin-market/plugin-market-card/PluginMarketCardVO.ts @@ -5,6 +5,7 @@ export interface IPluginMarketCardVO { description: string, starCount: number, githubURL: string, + version: string, } export class PluginMarketCardVO implements IPluginMarketCardVO { @@ -14,6 +15,7 @@ export class PluginMarketCardVO implements IPluginMarketCardVO { author: string; githubURL: string; starCount: number; + version: string; constructor(prop: IPluginMarketCardVO) { this.description = prop.description @@ -22,5 +24,6 @@ export class PluginMarketCardVO implements IPluginMarketCardVO { this.githubURL = prop.githubURL this.starCount = prop.starCount this.pluginId = prop.pluginId + this.version = prop.version } } diff --git a/web/src/app/home/plugins/plugin-market/plugin-market-card/pluginMarketCard.module.css b/web/src/app/home/plugins/plugin-market/plugin-market-card/pluginMarketCard.module.css index f611f335..97a5e224 100644 --- a/web/src/app/home/plugins/plugin-market/plugin-market-card/pluginMarketCard.module.css +++ b/web/src/app/home/plugins/plugin-market/plugin-market-card/pluginMarketCard.module.css @@ -1,6 +1,4 @@ .cardContainer { - width: 360px; - height: 140px; box-sizing: border-box; background-color: #FFF; border-radius: 9px; @@ -73,5 +71,6 @@ color: #6062E7; align-self: center; justify-content: space-between; + align-items: center; } -} +} \ No newline at end of file diff --git a/web/src/app/home/plugins/plugins.module.css b/web/src/app/home/plugins/plugins.module.css index 1393c15b..24688273 100644 --- a/web/src/app/home/plugins/plugins.module.css +++ b/web/src/app/home/plugins/plugins.module.css @@ -1,8 +1,8 @@ .pageContainer { width: 100%; - height: calc(100% - 30px); } + .marketComponentBody { width: 100%; height: calc(100% - 60px); @@ -11,17 +11,13 @@ .pluginListContainer { align-self: flex-start; justify-self: flex-start; - width: calc(100% - 60px); - height: 100%; - max-height: 100%; - margin: auto; + margin: auto; display: grid; grid-template-rows: repeat(auto-fill, minmax(160px, 1fr)); grid-template-columns: repeat(auto-fill, minmax(360px, 1fr)); gap: 15px; - justify-items: center; + /* justify-items: center; */ align-items: center; - overflow-y: scroll; } .modalTitle { @@ -35,4 +31,4 @@ display: flex; flex-direction: column; justify-content: space-around; -} +} \ No newline at end of file diff --git a/web/src/app/infra/basic-component/create-card-component/CreateCardComponent.tsx b/web/src/app/infra/basic-component/create-card-component/CreateCardComponent.tsx index 3e33d712..f1a280fc 100644 --- a/web/src/app/infra/basic-component/create-card-component/CreateCardComponent.tsx +++ b/web/src/app/infra/basic-component/create-card-component/CreateCardComponent.tsx @@ -1,12 +1,10 @@ import styles from "./createCartComponent.module.css"; export default function CreateCardComponent({ - width, height, plusSize, onClick, }: { - width: number; height: number; plusSize: number; onClick: () => void @@ -15,7 +13,7 @@ export default function CreateCardComponent({
{ return this.post(`/api/v1/market/plugins`, { page, @@ -366,7 +364,7 @@ class HttpClient { query, sort_by: "stars", sort_order: "DESC" - }) + }); } public installPluginFromGithub( source: string @@ -415,4 +413,4 @@ class HttpClient { export const httpClient = new HttpClient("https://version-4.langbot.dev"); // 临时写法,未来两种Client都继承自HttpClient父类,不允许共享方法 -export const spaceClient = new HttpClient("https://space.langbot.app") +export const spaceClient = new HttpClient("https://space.langbot.app"); diff --git a/web/src/app/not-found.tsx b/web/src/app/not-found.tsx index 0d5f0770..7882f911 100644 --- a/web/src/app/not-found.tsx +++ b/web/src/app/not-found.tsx @@ -10,66 +10,69 @@ export default function NotFound() { const router = useRouter(); return ( - -
-
- {/* Ant Design 图标,可以换成 Langbot 的 Logo */} -
- -
+ + + +
+
+ {/* Ant Design 图标,可以换成 Langbot 的 Logo */} +
+ +
-
- - 404 - - - 页面不存在 - - - 您要查找的页面似乎不存在。请检查您输入的 URL 是否正确,或者返回首页。 - -
+
+ + 404 + + + 页面不存在 + + + 您要查找的页面似乎不存在。请检查您输入的 URL 是否正确,或者返回首页。 + +
-
- - - - -
+
+ + + + +
-
- - 需要帮助吗?您可以联系 support@qq.com - +
+ + 需要帮助吗?您可以联系 support@qq.com + +
+
-
-
- + + ); }