Files
rednote-tool-studio/components/Studio.tsx
T
hexin-codex-bot e961e3091b
Verify and deploy production / verify-and-deploy (push) Successful in 2m29s
ui: mirror rednote creator platform layout
2026-10-05 13:50:21 +08:00

77 lines
4.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
import { useState } from "react";
type IconName = "home" | "note" | "code" | "chart" | "flag" | "bulb" | "school" | "book" | "draft" | "plus" | "chevron" | "upload";
const paths: Record<IconName, React.ReactNode> = {
home: <><path d="m4 10 8-6 8 6v8a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2Z"/><path d="M9 14h6"/></>,
note: <><rect x="5" y="3" width="14" height="18" rx="3"/><path d="M9 8h6M9 12h5"/></>,
code: <><rect x="3" y="4" width="18" height="16" rx="3"/><path d="m9 9-3 3 3 3m6-6 3 3-3 3m-2-7-2 8"/></>,
chart: <><rect x="3" y="4" width="18" height="16" rx="3"/><path d="m7 15 3-3 3 2 4-5"/></>,
flag: <><path d="M6 21V5m0 1c4-3 7 3 12 0v9c-5 3-8-3-12 0"/></>,
bulb: <><path d="M9 18h6m-5 3h4"/><path d="M8.2 15.5a7 7 0 1 1 7.6 0c-.8.5-.8 1.5-.8 2.5H9c0-1 0-2-.8-2.5Z"/></>,
school: <><path d="m3 9 9-5 9 5-9 5Z"/><path d="M7 12v5c3 2 7 2 10 0v-5m4-3v6"/></>,
book: <><path d="M6 3h11a2 2 0 0 1 2 2v16H7a3 3 0 0 1-3-3V5a2 2 0 0 1 2-2Z"/><path d="M7 15h12M9 7h6"/></>,
draft: <><path d="M5 5h14v15H5z"/><path d="M9 3h6v4H9zM8 11h8m-8 4h6"/></>,
plus: <><rect x="3" y="5" width="18" height="14" rx="3"/><path d="M12 9v6m-3-3h6"/></>,
chevron: <path d="m8 10 4 4 4-4"/>,
upload: <><path d="M7 18a5 5 0 0 1-.5-10A7 7 0 0 1 20 10.5 4 4 0 0 1 19 18"/><path d="m9 12 3-3 3 3m-3-3v10"/></>,
};
function Icon({ name, size = 19, strokeWidth = 1.55 }: { name: IconName; size?: number; strokeWidth?: number }) {
return <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">{paths[name]}</svg>;
}
const navItems: Array<{ icon: IconName; label: string; expandable?: boolean }> = [
{ icon: "home", label: "首页" },
{ icon: "note", label: "笔记管理" },
{ icon: "code", label: "Builder hub", expandable: true },
{ icon: "chart", label: "数据看板", expandable: true },
{ icon: "flag", label: "活动中心" },
{ icon: "bulb", label: "笔记灵感" },
{ icon: "school", label: "创作学院" },
{ icon: "book", label: "创作百科" },
];
const tabs = ["上传视频", "上传图文", "写长文", "发播客"];
export default function Studio() {
const [activeTab, setActiveTab] = useState("上传视频");
return <main className="creator-shell">
<header className="creator-header">
<div className="creator-brand"><span className="xiaohongshu-logo">小红书</span><strong>创作服务平台</strong></div>
<button className="creator-account"><span className="account-photo">创</span><span>内容工作室</span><Icon name="chevron" size={14} /></button>
</header>
<aside className="creator-sidebar">
<button className="publish-button"><Icon name="plus" size={19} strokeWidth={1.8} /><span>发布笔记</span><Icon name="chevron" size={18} strokeWidth={2} /></button>
<nav className="creator-nav">
{navItems.map((item) => <button className="creator-nav-item" key={item.label}><Icon name={item.icon} /><span>{item.label}</span>{item.expandable && <Icon name="chevron" size={17} />}</button>)}
</nav>
</aside>
<section className="creator-main">
<div className="creator-toolbar">
<div className="creator-tabs">{tabs.map((tab) => <button key={tab} className={activeTab === tab ? "active" : ""} onClick={() => setActiveTab(tab)}>{tab}</button>)}</div>
<button className="draft-button"><Icon name="draft" size={18} /><span>草稿箱(0)</span></button>
</div>
<div className="upload-panel">
<div className="upload-center">
<div className="cloud-upload"><Icon name="upload" size={104} strokeWidth={1.15} /></div>
<p>{activeTab === "上传视频" ? "拖拽视频到此或点击上传" : activeTab === "上传图文" ? "拖拽图片到此或点击上传" : activeTab === "写长文" ? "点击开始创作长文" : "拖拽音频到此或点击上传"}</p>
<button className="upload-action">{activeTab === "上传视频" ? "上传视频" : activeTab === "上传图文" ? "上传图文" : activeTab === "写长文" ? "开始写作" : "上传音频"}</button>
</div>
</div>
<div className="upload-guides">
<div><strong>{activeTab === "上传视频" ? "视频大小" : "文件大小"}</strong><p>{activeTab === "上传视频" ? <>支持时长4小时以内,<br />最大20GB的视频文件</> : <>单个文件不超过20GB,<br />支持批量选择上传</>}</p></div>
<div><strong>{activeTab === "上传视频" ? "视频格式" : "支持格式"}</strong><p>{activeTab === "上传视频" ? <>支持常用视频格式,<br />推荐使用mp4、mov</> : <>支持平台常用格式,<br />上传后可继续编辑</>}</p></div>
<div><strong>{activeTab === "上传视频" ? "视频分辨率" : "内容质量"}</strong><p>{activeTab === "上传视频" ? <>超过1080P的视频用网页端上传画质更清晰</> : <>建议上传清晰、完整的原创内容</>}</p></div>
</div>
</section>
</main>;
}