Files
xiaoxia-saas/apps/web/src/pages/generate/components/GenerateResultPanel.tsx
T

97 lines
2.9 KiB
TypeScript
Executable File

import React from "react"
import { Typography } from "antd"
import { PlayCircleOutlined, CloseCircleOutlined } from "@ant-design/icons"
import type { GeneratedVideo } from "@/api/template-editor"
import { ProgressIndicator } from "./result-panel/ProgressIndicator"
import { ResultVideoCard } from "./result-panel/ResultVideoCard"
const { Text } = Typography
interface GenerateResultPanelProps {
generated: boolean
generating: boolean
progress: number
generateError: string | null
generatedVideos: GeneratedVideo[]
onVideoPreview: (video: GeneratedVideo) => void
onDownload: () => void
onShare: () => void
onGoToLibrary: () => void
}
const GenerateResultPanel: React.FC<GenerateResultPanelProps> = ({
generated,
generating,
progress,
generateError,
generatedVideos,
onVideoPreview,
onDownload,
onShare,
onGoToLibrary,
}) => {
return (
<div className="xx-generate-result">
<div className="xx-result-header">
<h3>生成结果</h3>
{generated && generatedVideos.length > 0 && (
<span className="xx-result-count">{generatedVideos.length} 个视频</span>
)}
</div>
{generating && <ProgressIndicator progress={progress} />}
{generateError && !generating && (
<div className="xx-result-empty">
<CloseCircleOutlined style={{ fontSize: 40, color: "#ff4d4f", marginBottom: 12 }} />
<Text strong style={{ display: "block", marginBottom: 4 }}>
生成失败
</Text>
<Text style={{ fontSize: 12, color: "var(--text-secondary)" }}>
{typeof generateError === "string" ? generateError : "请重试"}
</Text>
</div>
)}
{!generated && !generating && !generateError && (
<div className="xx-result-empty">
<PlayCircleOutlined
style={{ fontSize: 48, color: "var(--text-tertiary)", marginBottom: 12 }}
/>
<Text style={{ color: "var(--text-secondary)", fontSize: 13 }}>
完成配置后点击「确认生成」
</Text>
<Text style={{ color: "var(--text-tertiary)", fontSize: 12, marginTop: 4 }}>
生成的视频将在这里展示
</Text>
</div>
)}
{generated && generatedVideos.length > 0 && (
<div className="xx-video-grid">
{generatedVideos.map((video, idx) => (
<ResultVideoCard
key={video.id || idx}
video={video}
index={idx}
onPreview={onVideoPreview}
onDownload={onDownload}
onShare={onShare}
/>
))}
</div>
)}
{generated && (
<div className="xx-result-footer">
<button className="xx-btn xx-btn-ghost xx-btn-block" onClick={onGoToLibrary}>
前往成片库 →
</button>
</div>
)}
</div>
)
}
export default GenerateResultPanel