refactor(platform): 用户工作台 - 重构画布、任务与资源页面的浏览体验
This commit is contained in:
1 parent
66c68ccd51
commit
5c27879f86
14 files changed
+956
-462
No files matched your search
@@ -162,8 +162,8 @@ export default function SkillsPage() {
|
||||
|
||||
return (
|
||||
<>
|
||||
<WorkspacePage>
|
||||
<PageHeader icon="skills" title="技能库" meta={<span className="text-xs text-foreground/45">{total} 个技能</span>} actions={<Button type="primary" icon={<Plus className="size-4" />} onClick={() => void openEditor()}>创建技能</Button>} />
|
||||
<WorkspacePage className="library-page skills-library-page" grid>
|
||||
<PageHeader icon="skills" title="技能库" description="把常用的提示词、角色设定和创作方法收进自己的工具架。" meta={<span className="text-xs text-foreground/45">{total} 个技能</span>} actions={null} />
|
||||
|
||||
<div className="mt-1 flex flex-col border-b border-border/75 xl:flex-row xl:items-end xl:justify-between">
|
||||
<nav className="thin-scrollbar -mb-px flex min-w-0 overflow-x-auto" aria-label="技能库范围" role="tablist">
|
||||
@@ -186,7 +186,7 @@ export default function SkillsPage() {
|
||||
})}
|
||||
</nav>
|
||||
|
||||
<div className="flex min-w-0 flex-wrap items-center gap-2 py-2.5 xl:flex-nowrap xl:justify-end">
|
||||
<div className="library-toolbar-controls flex min-w-0 flex-wrap items-center gap-2 py-2.5 xl:flex-nowrap xl:justify-end">
|
||||
<Input className="w-full sm:!w-72" prefix={<Search className="size-4 text-foreground/38" />} value={search} allowClear placeholder="搜索技能或作者" onChange={(event) => { setSearch(event.target.value); setPage(1); }} />
|
||||
<Select className="w-[136px]" value={tag} options={[{ value: "all", label: "全部分类" }, ...categories]} onChange={(value) => { setTag(value); setPage(1); }} />
|
||||
<Select className="w-[124px]" value={sort} options={sortOptions} onChange={(value) => { setSort(value); setPage(1); }} />
|
||||
@@ -206,7 +206,8 @@ export default function SkillsPage() {
|
||||
<h2 id={`skill-category-${group.value}`} className="text-sm font-medium text-foreground/62">{group.label}</h2>
|
||||
<span className="text-[var(--fs-label)] text-foreground/32">{group.skills.length} 个</span>
|
||||
</div>
|
||||
<div className="grid grid-cols-1 gap-3 md:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4">
|
||||
<div className="library-grid skill-library-grid">
|
||||
{groupedSkills[0] === group ? <button type="button" className="library-create-card" onClick={() => void openEditor()}><span className="library-create-cover"><Plus className="size-8" /></span><span className="library-create-title">创建技能</span><span className="library-create-meta">把一套方法变成可复用能力</span></button> : null}
|
||||
{group.skills.map((skill) => <SkillCard key={skill.skill_id} skill={skill} loading={mutatingID === skill.skill_id} onOpen={() => void openSkill(skill)} onAdd={() => void toggleAdded(skill)} onLike={() => void toggleLiked(skill)} onEdit={() => void openEditor(skill)} onDelete={() => confirmDelete(skill)} />)}
|
||||
</div>
|
||||
</section>
|
||||
@@ -238,7 +239,7 @@ export default function SkillsPage() {
|
||||
|
||||
function SkillCard({ skill, loading, onOpen, onAdd, onLike, onEdit, onDelete }: { skill: Skill; loading: boolean; onOpen: () => void; onAdd: () => void; onLike: () => void; onEdit: () => void; onDelete: () => void }) {
|
||||
return (
|
||||
<article className="flex h-[178px] min-w-0 flex-col rounded-md border border-border/55 bg-[color:var(--workspace-surface-strong)] p-4 transition-[border-color,box-shadow,background-color] duration-200 hover:border-border hover:bg-[color:var(--workspace-surface)] hover:shadow-sm">
|
||||
<article className="library-card skill-library-card group">
|
||||
<div className="flex min-h-8 items-start gap-3">
|
||||
<button type="button" className="min-w-0 flex-1 rounded-sm text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring" onClick={onOpen}>
|
||||
<h3 className="line-clamp-1 text-[var(--fs-body-lg)] font-semibold leading-6">{skill.skill_name}</h3>
|
||||
|
||||
@@ -6,7 +6,7 @@ import type { Skill, SkillCategory } from "@/services/api/skills";
|
||||
|
||||
export function SkillDetailDrawer({ skill, loading, mutating, categories, onClose, onAdd, onLike, onEdit }: { skill: Skill | null; loading: boolean; mutating: boolean; categories: SkillCategory[]; onClose: () => void; onAdd: (skill: Skill) => void; onLike: (skill: Skill) => void; onEdit: (skill: Skill) => void }) {
|
||||
return (
|
||||
<Drawer open={Boolean(skill)} size={760} destroyOnHidden title={skill?.skill_name || "技能详情"} onClose={onClose} extra={skill?.is_owner ? <Button icon={<Pencil className="size-4" />} onClick={() => onEdit(skill)}>编辑</Button> : undefined}>
|
||||
<Drawer className="library-drawer" open={Boolean(skill)} size={760} destroyOnHidden title={skill?.skill_name || "技能详情"} onClose={onClose} extra={skill?.is_owner ? <Button icon={<Pencil className="size-4" />} onClick={() => onEdit(skill)}>编辑</Button> : undefined}>
|
||||
{skill ? (
|
||||
<div className="space-y-6">
|
||||
<header>
|
||||
|
||||
@@ -61,7 +61,7 @@ export function SkillEditorDrawer({ open, skill, onClose, onSaved }: { open: boo
|
||||
};
|
||||
|
||||
return (
|
||||
<Drawer open={open} size={720} destroyOnHidden maskClosable={!dirty} title={skill ? "编辑技能" : "创建技能"} onClose={requestClose} extra={<Button type="primary" loading={saving} icon={<Save className="size-4" />} onClick={() => form.submit()}>保存技能</Button>}>
|
||||
<Drawer className="library-drawer" open={open} size={720} destroyOnHidden maskClosable={!dirty} title={skill ? "编辑技能" : "创建技能"} onClose={requestClose} extra={<Button type="primary" loading={saving} icon={<Save className="size-4" />} onClick={() => form.submit()}>保存技能</Button>}>
|
||||
<Form form={form} layout="vertical" requiredMark="optional" onFinish={submit} onValuesChange={() => setDirty(true)}>
|
||||
<div className="grid gap-x-4 sm:grid-cols-2">
|
||||
<Form.Item name="skill_name" label="技能名称" rules={[{ required: true, message: "请填写技能名称" }, { max: 80, message: "最多 80 个字符" }]}>
|
||||
|
||||
Reference in new issue
Block a user