Files
gen2d/frontend/src/components/AssetGallery.tsx
T

101 lines
2.7 KiB
TypeScript
Raw Normal View History

import { useEffect, useState } from 'react'
import { getRecentAssets } from '../api/generate'
import type { RecentAssetItem } from '../api/types'
const ASSET_TYPE_LABELS: Record<string, string> = {
sprite: '精灵',
background: '背景',
ui: 'UI',
animation: '动画',
}
export default function AssetGallery() {
const [assets, setAssets] = useState<RecentAssetItem[]>([])
const [loading, setLoading] = useState(true)
useEffect(() => {
getRecentAssets()
.then(setAssets)
.catch(() => {})
.finally(() => setLoading(false))
}, [])
if (loading) return null
if (assets.length === 0) return null
return (
<section style={{ marginBottom: 32 }}>
<h2 style={{ fontSize: 18, marginBottom: 16 }}>最近生成</h2>
<div
style={{
display: 'grid',
gridTemplateColumns: 'repeat(auto-fill, minmax(180px, 1fr))',
gap: 12,
}}
>
{assets.map((item, i) => (
<div
key={`${item.taskId}-${i}`}
className="card"
style={{ padding: 8, cursor: 'pointer' }}
onClick={() => {
// navigate to result page — need projectId for URL
// For now just open the image
}}
>
<div
style={{
width: '100%',
aspectRatio: '1',
overflow: 'hidden',
borderRadius: 'var(--radius)',
background: 'var(--bg-input)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}
>
<img
src={item.url}
alt={item.prompt}
loading="lazy"
style={{
maxWidth: '100%',
maxHeight: '100%',
objectFit: 'contain',
}}
/>
</div>
<div style={{ marginTop: 6 }}>
<span
style={{
fontSize: 11,
padding: '1px 6px',
borderRadius: 999,
background: 'var(--accent-dim)',
color: 'var(--accent)',
}}
>
{ASSET_TYPE_LABELS[item.assetType] || item.assetType}
</span>
</div>
<p
style={{
fontSize: 12,
color: 'var(--text-secondary)',
marginTop: 4,
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
}}
>
{item.prompt}
</p>
</div>
))}
</div>
</section>
)
}