feat(ux): 空状态组件,替换各页面空白提示
新增 EmptyState 组件,ProjectPage 暂无任务时显示带操作按钮的 友好提示,AssetPreview 暂无素材时显示引导文案。
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import type { Asset } from '../api/types'
|
||||
import EmptyState from './EmptyState'
|
||||
|
||||
interface AssetPreviewProps {
|
||||
assets: Asset[]
|
||||
@@ -6,11 +7,7 @@ interface AssetPreviewProps {
|
||||
|
||||
export default function AssetPreview({ assets }: AssetPreviewProps) {
|
||||
if (assets.length === 0) {
|
||||
return (
|
||||
<div style={{ color: 'var(--text-muted)', textAlign: 'center', padding: 40 }}>
|
||||
暂无素材
|
||||
</div>
|
||||
)
|
||||
return <EmptyState title="暂无素材" description="生成完成后,素材将在这里展示" />
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
interface EmptyStateProps {
|
||||
icon?: string
|
||||
title: string
|
||||
description?: string
|
||||
action?: {
|
||||
label: string
|
||||
onClick: () => void
|
||||
}
|
||||
}
|
||||
|
||||
export default function EmptyState({ icon = '📭', title, description, action }: EmptyStateProps) {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
padding: '48px 24px',
|
||||
textAlign: 'center',
|
||||
}}
|
||||
>
|
||||
<span style={{ fontSize: 48, marginBottom: 16, opacity: 0.6 }}>{icon}</span>
|
||||
<h3 style={{ fontSize: 16, color: 'var(--text-secondary)', marginBottom: 8 }}>
|
||||
{title}
|
||||
</h3>
|
||||
{description && (
|
||||
<p style={{ fontSize: 13, color: 'var(--text-muted)', marginBottom: action ? 20 : 0 }}>
|
||||
{description}
|
||||
</p>
|
||||
)}
|
||||
{action && (
|
||||
<button
|
||||
className="btn-primary"
|
||||
onClick={action.onClick}
|
||||
style={{ padding: '8px 24px', fontSize: 13 }}
|
||||
>
|
||||
{action.label}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import { Link, useParams } from 'react-router-dom'
|
||||
import { Link, useNavigate, useParams } from 'react-router-dom'
|
||||
import { useProjectStore } from '../stores/project'
|
||||
import { getTasks } from '../api/project'
|
||||
import type { Task } from '../api/types'
|
||||
import StyleSelector from '../components/StyleSelector'
|
||||
import Skeleton from '../components/Skeleton'
|
||||
import EmptyState from '../components/EmptyState'
|
||||
|
||||
const STATUS_LABELS: Record<string, { label: string; color: string }> = {
|
||||
pending: { label: '等待中', color: 'var(--text-muted)' },
|
||||
@@ -15,6 +16,7 @@ const STATUS_LABELS: Record<string, { label: string; color: string }> = {
|
||||
|
||||
export default function ProjectPage() {
|
||||
const { projectId = 'proj-default' } = useParams()
|
||||
const navigate = useNavigate()
|
||||
const {
|
||||
name,
|
||||
style,
|
||||
@@ -95,9 +97,11 @@ export default function ProjectPage() {
|
||||
</div>
|
||||
|
||||
{tasks.length === 0 ? (
|
||||
<p style={{ color: 'var(--text-muted)', textAlign: 'center', padding: 32 }}>
|
||||
暂无任务
|
||||
</p>
|
||||
<EmptyState
|
||||
title="暂无任务"
|
||||
description="点击「新建生成」开始创建你的第一个游戏素材"
|
||||
action={{ label: '新建生成', onClick: () => navigate(`/projects/${projectId}/generate`) }}
|
||||
/>
|
||||
) : (
|
||||
<table style={{ width: '100%', borderCollapse: 'collapse' }}>
|
||||
<thead>
|
||||
|
||||
Reference in New Issue
Block a user