feat: 收集箱右侧区域布局优化——上下两段式,操作栏固定底部始终显示
This commit is contained in:
@@ -1,22 +1,14 @@
|
||||
import { Card, Descriptions, Tag, Typography } from "antd";
|
||||
|
||||
import type { Material, MaterialStatus, MaterialType } from "../types";
|
||||
import type { Material, MaterialType } from "../types";
|
||||
|
||||
import { formatRelativeTime } from "../../../shared/utils/time";
|
||||
import { STATUS_MAP } from "./constants";
|
||||
|
||||
interface MaterialContentProps {
|
||||
material: Material;
|
||||
}
|
||||
|
||||
const STATUS_MAP: Record<MaterialStatus, { color: string; label: string }> = {
|
||||
approved: { color: "green", label: "已通过" },
|
||||
discarded: { color: "red", label: "已放弃" },
|
||||
failed: { color: "magenta", label: "失败" },
|
||||
pending: { color: "gold", label: "待处理" },
|
||||
processing: { color: "blue", label: "处理中" },
|
||||
review: { color: "orange", label: "待审核" },
|
||||
};
|
||||
|
||||
const MATERIAL_TYPE_LABELS: Record<MaterialType, string> = {
|
||||
general: "通用",
|
||||
meeting: "会议",
|
||||
@@ -27,7 +19,7 @@ export function MaterialContent({ material }: MaterialContentProps) {
|
||||
const typeLabel = MATERIAL_TYPE_LABELS[material.materialType] ?? material.materialType;
|
||||
|
||||
return (
|
||||
<div className="app-inbox-content">
|
||||
<>
|
||||
<Typography.Title level={4}>素材详情</Typography.Title>
|
||||
<Card>
|
||||
<Typography.Paragraph>{material.description}</Typography.Paragraph>
|
||||
@@ -52,6 +44,6 @@ export function MaterialContent({ material }: MaterialContentProps) {
|
||||
<Descriptions.Item label="创建时间">{formatRelativeTime(material.createdAt)}</Descriptions.Item>
|
||||
</Descriptions>
|
||||
</Card>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import { CheckOutlined, CloseOutlined, RedoOutlined } from "@ant-design/icons";
|
||||
import { App as AntApp, Button, Empty, Result, Space, Spin } from "antd";
|
||||
|
||||
import type { Material } from "../types";
|
||||
import { App as AntApp, Button, Empty, Result, Space, Spin, Tag } from "antd";
|
||||
|
||||
import { useMaterial } from "../../../shared/hooks/use-materials";
|
||||
import { STATUS_MAP } from "./constants";
|
||||
import { MaterialContent } from "./MaterialContent";
|
||||
|
||||
interface MaterialDetailPanelProps {
|
||||
@@ -23,8 +22,10 @@ export function MaterialDetailPanel({
|
||||
}: MaterialDetailPanelProps) {
|
||||
if (!materialId) {
|
||||
return (
|
||||
<div className="app-inbox-content">
|
||||
<Empty description="请在左侧选择素材" />
|
||||
<div className="app-inbox-panel">
|
||||
<div className="app-inbox-content">
|
||||
<Empty description="请在左侧选择素材" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -46,24 +47,30 @@ function MaterialDetailPanelInner({ materialId, onApprove, onDiscard, onRetry, p
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="app-inbox-content">
|
||||
<Spin />
|
||||
<div className="app-inbox-panel">
|
||||
<div className="app-inbox-content">
|
||||
<Spin />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return (
|
||||
<div className="app-inbox-content">
|
||||
<Result subTitle="加载素材详情失败" />
|
||||
<div className="app-inbox-panel">
|
||||
<div className="app-inbox-content">
|
||||
<Result subTitle="加载素材详情失败" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (!data || !materialId) {
|
||||
return (
|
||||
<div className="app-inbox-content">
|
||||
<Empty description="请在左侧选择素材" />
|
||||
<div className="app-inbox-panel">
|
||||
<div className="app-inbox-content">
|
||||
<Empty description="请在左侧选择素材" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -97,44 +104,32 @@ function MaterialDetailPanelInner({ materialId, onApprove, onDiscard, onRetry, p
|
||||
}
|
||||
};
|
||||
|
||||
const statusInfo = STATUS_MAP[data.status] ?? { color: "default", label: data.status };
|
||||
|
||||
return (
|
||||
<div className="app-inbox-content">
|
||||
<MaterialContent material={data} />
|
||||
<ActionButtons material={data} onApprove={handleApprove} onDiscard={handleDiscard} onRetry={handleRetry} />
|
||||
<div className="app-inbox-panel">
|
||||
<div className="app-inbox-content">
|
||||
<MaterialContent material={data} />
|
||||
</div>
|
||||
<div className="app-inbox-action-bar">
|
||||
<Tag color={statusInfo.color}>{statusInfo.label}</Tag>
|
||||
{data.status === "review" ? (
|
||||
<Space>
|
||||
<Button icon={<CheckOutlined />} onClick={() => void handleApprove()} type="primary">
|
||||
通过
|
||||
</Button>
|
||||
<Button danger icon={<CloseOutlined />} onClick={() => void handleDiscard()}>
|
||||
放弃
|
||||
</Button>
|
||||
</Space>
|
||||
) : data.status === "failed" ? (
|
||||
<Space>
|
||||
<Button icon={<RedoOutlined />} onClick={() => void handleRetry()}>
|
||||
重试
|
||||
</Button>
|
||||
</Space>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
interface ActionButtonsProps {
|
||||
material: Material;
|
||||
onApprove: () => Promise<void>;
|
||||
onDiscard: () => Promise<void>;
|
||||
onRetry: () => Promise<void>;
|
||||
}
|
||||
|
||||
function ActionButtons({ material, onApprove, onDiscard, onRetry }: ActionButtonsProps) {
|
||||
if (material.status === "review") {
|
||||
return (
|
||||
<Space style={{ marginTop: 16 }}>
|
||||
<Button icon={<CheckOutlined />} onClick={() => void onApprove()} type="primary">
|
||||
通过
|
||||
</Button>
|
||||
<Button danger icon={<CloseOutlined />} onClick={() => void onDiscard()}>
|
||||
放弃
|
||||
</Button>
|
||||
</Space>
|
||||
);
|
||||
}
|
||||
|
||||
if (material.status === "failed") {
|
||||
return (
|
||||
<Space style={{ marginTop: 16 }}>
|
||||
<Button icon={<RedoOutlined />} onClick={() => void onRetry()}>
|
||||
重试
|
||||
</Button>
|
||||
</Space>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
10
src/web/features/inbox/components/constants.ts
Normal file
10
src/web/features/inbox/components/constants.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import type { MaterialStatus } from "../types";
|
||||
|
||||
export const STATUS_MAP: Record<MaterialStatus, { color: string; label: string }> = {
|
||||
approved: { color: "green", label: "已通过" },
|
||||
discarded: { color: "red", label: "已放弃" },
|
||||
failed: { color: "magenta", label: "失败" },
|
||||
pending: { color: "gold", label: "待处理" },
|
||||
processing: { color: "blue", label: "处理中" },
|
||||
review: { color: "orange", label: "待审核" },
|
||||
};
|
||||
Reference in New Issue
Block a user