From c3b4e359972a14fcdb7716ff8102f36ddadffbfe Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 18 Apr 2026 15:25:52 +0800 Subject: [PATCH] Match LibTV account and member panels --- .../canvas/LiblibVideoCanvasReplica.tsx | 580 ++++++++++++++---- 1 file changed, 471 insertions(+), 109 deletions(-) diff --git a/components/canvas/LiblibVideoCanvasReplica.tsx b/components/canvas/LiblibVideoCanvasReplica.tsx index fc371b40c..2d90c61e4 100644 --- a/components/canvas/LiblibVideoCanvasReplica.tsx +++ b/components/canvas/LiblibVideoCanvasReplica.tsx @@ -5,7 +5,6 @@ import { ChevronDown, Clock3, Copy, - Crown, FileText, GitBranch, Headphones, @@ -73,6 +72,7 @@ type ComposerMenu = | "settings" | "count" | null; +type MemberStoreTab = "vip" | "model" | "credits"; type CapturedTool = { type?: string; @@ -248,6 +248,90 @@ const AUDIO_REFERENCE_IMAGE_URL = "https://liblibai-online.liblib.cloud/web/ea95cb51f3d94addbb92dc003cd33b49/1342d344-2d95-41a1-a2aa-4d20869a318c.png"; const PUBLISH_MODAL_BG_URL = "https://libtv-res.liblib.art/upload-images/4e7115e6ee6947b78d73e0203a85fc56/771d92a21c6dce69a97513d21ee3253fe0eedec9.png"; +const MEMBER_CARD_THEMES: Record = { + "lib-nano": { + bg: "https://liblibai-online.liblib.cloud/web/4e7115e6ee6947b78d73e0203a85fc56/3b7bcfd5-d1d3-4545-8089-53c04bad6ede.svg", + icon: "https://liblibai-online.liblib.cloud/web/4e7115e6ee6947b78d73e0203a85fc56/8d5f4fb5-8132-4049-b902-7eca7db0de1d.svg", + tone: "#2A2038", + }, + "seedance-2": { + bg: "https://liblibai-online.liblib.cloud/web/4e7115e6ee6947b78d73e0203a85fc56/a520a76c-8101-4be3-8c3b-30a37b2320d9.svg", + icon: "https://liblibai-online.liblib.cloud/web/4e7115e6ee6947b78d73e0203a85fc56/9207509b-a5d5-47af-944b-1894b469735f.svg", + tone: "#222A3E", + }, + "seedance-2-1080p": { + bg: "https://liblibai-online.liblib.cloud/web/4e7115e6ee6947b78d73e0203a85fc56/a32e399e-8353-4cdf-a44e-e7e08cca8c7f.svg", + icon: "https://liblibai-online.liblib.cloud/web/4e7115e6ee6947b78d73e0203a85fc56/9207509b-a5d5-47af-944b-1894b469735f.svg", + tone: "#222222", + }, +}; +const MEMBER_MODEL_CARDS = [ + { + title: "Seedance 2.0", + label: "1080P 专享", + power: "45,000", + price: "2,999", + corner: "首购加赠45000", + desc: "大师版及以上会员可购买", + group: "seedance-2-1080p", + }, + { + title: "Seedance 2.0", + label: "1080P 专享", + power: "60,000", + price: "3,999", + corner: "首购加赠60000", + desc: "大师版及以上会员可购买", + group: "seedance-2-1080p", + }, + { + title: "Lib Nano Pro", + label: "模型积分卡", + power: "20,000", + price: "1,999", + corner: "多生成571张图片", + desc: "尊享版可购买", + group: "lib-nano", + }, + { + title: "Lib Nano 2", + label: "模型积分卡", + power: "45,000", + price: "2,999", + corner: "多生成1500张图片", + desc: "尊享版可购买", + group: "lib-nano", + }, + { + title: "Seedance 2.0", + label: "视频模型卡", + power: "7,500", + price: "599", + corner: "多生成341秒视频", + desc: "大师版及以上会员可购买", + group: "seedance-2", + }, + { + title: "Seedance 2.0", + label: "视频模型卡", + power: "15,000", + price: "999", + corner: "多生成682秒视频", + desc: "大师版及以上会员可购买", + group: "seedance-2", + }, +]; +const VIP_PLAN_CARDS = [ + { title: "基础版VIP", power: "每月 8,000 点积分", price: "39", benefits: ["登录每日赠送20积分", "云端存储空间20GB", "会员专属模型"] }, + { title: "大师版VIP", power: "每月 18,000 点积分", price: "89", benefits: ["无限并发任务", "会员专享无限次加速", "Seedance 2.0 活动权益"] }, + { title: "尊享版VIP", power: "每月 34,000 点积分", price: "169", benefits: ["云端存储空间500GB", "智能分镜(Kling3.0)", "去除品牌水印"] }, +]; +const CREDIT_PACKS = [ + { points: "1,000", price: "6", tag: "限时 6 折" }, + { points: "5,000", price: "30", tag: "首充推荐" }, + { points: "10,000", price: "60", tag: "最高赠送" }, + { points: "30,000", price: "180", tag: "创作囤货" }, +]; const STORY_SCRIPT_PROMPT = "根据我上传的剧本生成一个完整的故事脚本"; const AUDIO_TO_VIDEO_PROMPT = "根据上传的音频生成对应场景画面,镜头语言、节奏、音乐匹配情绪变化,电影级质感。"; @@ -946,6 +1030,12 @@ export function LiblibVideoCanvasReplica({ canvasId, isLoading = false }: Liblib toast.success("分享链接已复制"); }, [canvasId]); + const toggleTopPanel = useCallback((panel: Exclude) => { + setCanvasCommand(null); + setNodeContextMenu(null); + setActivePanel((current) => (current === panel ? null : panel)); + }, []); + const isBusy = isLoading || isProjectLoading; return ( @@ -1055,14 +1145,14 @@ export function LiblibVideoCanvasReplica({ canvasId, isLoading = false }: Liblib draftTitle={draftTitle} isSaving={isSaving} isTitleEditing={isTitleEditing} - onAccount={() => setActivePanel("account")} - onBell={() => setActivePanel("notifications")} + onAccount={() => toggleTopPanel("account")} + onBell={() => toggleTopPanel("notifications")} onCommitTitle={commitTitle} onDraftTitleChange={setDraftTitle} - onMember={() => setActivePanel("member")} + onMember={() => toggleTopPanel("member")} onSave={saveCanvas} - onShare={() => setActivePanel("share")} - onSkills={() => setActivePanel("skills")} + onShare={() => toggleTopPanel("share")} + onSkills={() => toggleTopPanel("skills")} onStartTitleEdit={() => setIsTitleEditing(true)} projectTitle={projectTitle} routerBack={() => router.push("/")} @@ -1189,21 +1279,15 @@ export function LiblibVideoCanvasReplica({ canvasId, isLoading = false }: Liblib ) : null} {activePanel === "member" ? ( - setActivePanel(null)} title="会员中心"> - - + setActivePanel(null)} /> ) : null} {activePanel === "notifications" ? ( - setActivePanel(null)} title="通知"> - - + setActivePanel(null)} /> ) : null} {activePanel === "account" ? ( - setActivePanel(null)} title="账号"> - - + setActivePanel(null)} /> ) : null} {isBusy ? ( @@ -3021,141 +3105,419 @@ function SharePopover({ onPublish: () => void; }) { return ( -
+
- +
+
+ 发布与分享 + + +
); } -function MemberCenterPanel() { +function MemberStoreModal({ onClose }: { onClose: () => void }) { + const [activeTab, setActiveTab] = useState("model"); + return ( -
-
-
限时 39 折
-
会员特惠39折
-
会员超市、模型权益、生成额度与积分套餐待接入。
+
+ + ))} +
+
+ 免费用户登录每日赠送20积分,每日赠2次5折视频;云端存储空间3GB。 +
+
+ +
+
+
+
+ {activeTab === "model" ? "模型积分卡" : activeTab === "vip" ? "会员特惠" : "积分充值"} +
+
+ {activeTab === "model" ? "模型超市内积分有效期为6个月,支付后不退不换。" : activeTab === "vip" ? "购买后立即生效,积分按月自动发放。" : "积分有效期2年,支付后不退不换。"} +
+
+ +
+ +
+ {activeTab === "model" ? : null} + {activeTab === "vip" ? : null} + {activeTab === "credits" ? : null} +
+
+
+
+ ); +} + +function ModelCardGrid() { + return ( +
+
+
+
限时闪购 买一赠一
+
会员专属模型超市,顶级模型囤货必选
+
- {[ - ["100", "可用积分"], - ["67", "模型能力"], - ["25", "工作流预设"], - ].map(([value, label]) => ( -
-
{value}
-
{label}
-
+ {MEMBER_MODEL_CARDS.map((card) => ( + ))}
); } -function NotificationsPanel() { +function MemberModelCard({ card }: { card: (typeof MEMBER_MODEL_CARDS)[number] }) { + const theme = MEMBER_CARD_THEMES[card.group] || MEMBER_CARD_THEMES["seedance-2"]; + return ( -
- {["全部", "生成任务", "系统通知", "会员活动"].map((item, index) => ( - - ))} - {[ - ["生成任务", "任务状态、进度轮询和失败原因接口待接入。"], - ["系统通知", "审核、账户和平台消息接口待接入。"], - ["会员活动", "会员超市与活动消息接口待接入。"], - ].map(([title, description]) => ( -
-
{title}
-
{description}
+ + ); +} + +function VipPlanGrid() { + return ( +
+ {VIP_PLAN_CARDS.map((plan, index) => ( +
+
+ {plan.title} + {index === 1 ? 推荐 : null} +
+
{plan.power}
+
+ ¥ + {plan.price} + /月起 +
+ +
+ {plan.benefits.map((benefit) => ( +
+ + {benefit} +
+ ))} +
))}
); } -function AccountPanel() { +function CreditPackGrid() { return ( -
-
- avatar -
-
微信用户82a0d8
-
账号中心、团队空间和额度设置待接入。
-
+
+ {CREDIT_PACKS.map((pack) => ( -
-
- {[ - ["100", "当前积分"], - ["个人空间", "当前空间"], - ].map(([value, label]) => ( -
-
{value}
-
{label}
+ ))} +
+ ); +} + +function NotificationsPopover({ onClose }: { onClose: () => void }) { + return ( +
+ +
+
+
+ {["全部", "生成任务", "系统通知", "会员活动"].map((item, index) => ( + + ))} +
+ {[ + ["生成任务", "任务状态、进度轮询和失败原因接口待接入。"], + ["系统通知", "审核、账户和平台消息接口待接入。"], + ["会员活动", "限时 39 折,会员超市模型积分卡活动待接入。"], + ].map(([title, description]) => ( + + ))} +
); } +function AccountPopover({ onClose }: { onClose: () => void }) { + return ( +
+ +
+
+ +
+ +
+
+ + 个人空间 +
+ +
+ +
+ + + +
+ +
+ } label="个人中心" onClick={() => toast.info("个人中心入口待接入。")} /> + } label="创建团队" onClick={() => toast.info("创建团队接口待接入。")} /> + } label="订阅与开发票" onClick={() => toast.info("订阅与开发票入口待接入。")} /> + } label="账号设置" onClick={() => toast.info("账号设置入口待接入。")} /> + } label="退出登录" onClick={() => toast.info("退出登录接口待接入。")} /> +
+
+ + + ); +} + +function AccountMetricCard({ + accent = false, + className, + label, + suffix, + value, +}: { + accent?: boolean; + className?: string; + label: string; + suffix: string; + value: string; +}) { + return ( + + ); +} + +function AccountMenuButton({ + icon, + label, + onClick, +}: { + icon: React.ReactNode; + label: string; + onClick: () => void; +}) { + return ( + + ); +} + +function LogoutGlyph() { + return ( + + ); +} + function SupportPanel() { return (