feat(inbox): 素材持久化 CRUD — 数据库表 + API + 前端接入
- 新增 materials 表(id/projectId/description/associatedDate/status/createdAt/updatedAt) - 新增 4 个后端 API 路由(list/create/get/delete)+ 13 个测试 - 新增 use-materials hooks(TanStack Query) - 收集箱页面重构为三层架构(InboxPage + MaterialSidebar + MaterialDetailPanel) - MaterialCard: Popconfirm 删除确认 + 粗粒度时间格式 - MaterialContent: 展示状态标签 + createdAt - 更新开发文档 backend.md / frontend.md
This commit is contained in:
44
src/web/features/inbox/components/MaterialSidebar.tsx
Normal file
44
src/web/features/inbox/components/MaterialSidebar.tsx
Normal file
@@ -0,0 +1,44 @@
|
||||
import { Result } from "antd";
|
||||
|
||||
import { useDeleteMaterial, useMaterialList } from "../../../shared/hooks/use-materials";
|
||||
import { MaterialList } from "./MaterialList";
|
||||
|
||||
interface MaterialSidebarProps {
|
||||
onAddClick: () => void;
|
||||
onDelete: (id: string) => void;
|
||||
onSelect: (id: string) => void;
|
||||
projectId: string;
|
||||
selectedId: null | string;
|
||||
}
|
||||
|
||||
export function MaterialSidebar({ onAddClick, onDelete, onSelect, projectId, selectedId }: MaterialSidebarProps) {
|
||||
const { data, error, isLoading, refetch } = useMaterialList(projectId);
|
||||
const deleteMutation = useDeleteMaterial(projectId);
|
||||
|
||||
const handleDelete = (id: string) => {
|
||||
void deleteMutation.mutate({ materialId: id, projectId }, { onSuccess: () => onDelete(id) });
|
||||
};
|
||||
|
||||
if (error) {
|
||||
return (
|
||||
<div className="app-inbox-sidebar">
|
||||
<Result
|
||||
extra={<button onClick={() => void refetch()}>重试</button>}
|
||||
status="error"
|
||||
subTitle="加载素材列表失败"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<MaterialList
|
||||
loading={isLoading}
|
||||
materials={data?.items ?? []}
|
||||
onAddClick={onAddClick}
|
||||
onDelete={handleDelete}
|
||||
onSelect={onSelect}
|
||||
selectedId={selectedId}
|
||||
/>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user