177 lines
5.6 KiB
TypeScript
177 lines
5.6 KiB
TypeScript
'use client'
|
||
|
||
import { useEffect, useState, useCallback } from 'react'
|
||
import { useVersions, useVersionActions } from '@/application'
|
||
import { Platform } from '@/domain'
|
||
import { VersionCard } from '@/presentation/components/version-card'
|
||
import { UploadModal } from '@/presentation/components/upload-modal'
|
||
import { EditModal } from '@/presentation/components/edit-modal'
|
||
import toast from 'react-hot-toast'
|
||
|
||
export default function HomePage() {
|
||
const { versions, isLoading, error, refetch, setFilter } = useVersions()
|
||
const { deleteVersion, toggleVersion } = useVersionActions()
|
||
|
||
const [platformFilter, setPlatformFilter] = useState<Platform | 'all'>('all')
|
||
const [showUploadModal, setShowUploadModal] = useState(false)
|
||
const [editingVersionId, setEditingVersionId] = useState<string | null>(null)
|
||
|
||
useEffect(() => {
|
||
setFilter({ platform: platformFilter === 'all' ? undefined : platformFilter })
|
||
}, [platformFilter, setFilter])
|
||
|
||
const handleRefresh = useCallback(() => {
|
||
refetch()
|
||
}, [refetch])
|
||
|
||
const handleDelete = async (id: string) => {
|
||
if (!confirm('确定要删除这个版本吗?此操作不可恢复。')) {
|
||
return
|
||
}
|
||
try {
|
||
await deleteVersion(id)
|
||
toast.success('版本已删除')
|
||
} catch (err) {
|
||
toast.error('删除失败')
|
||
}
|
||
}
|
||
|
||
const handleToggle = async (id: string, isEnabled: boolean) => {
|
||
try {
|
||
await toggleVersion(id, isEnabled)
|
||
toast.success(isEnabled ? '版本已启用' : '版本已禁用')
|
||
} catch (err) {
|
||
toast.error('操作失败')
|
||
}
|
||
}
|
||
|
||
const handleUploadSuccess = () => {
|
||
setShowUploadModal(false)
|
||
refetch()
|
||
toast.success('版本上传成功')
|
||
}
|
||
|
||
const handleEditSuccess = () => {
|
||
setEditingVersionId(null)
|
||
refetch()
|
||
toast.success('版本更新成功')
|
||
}
|
||
|
||
const filteredVersions = versions
|
||
|
||
return (
|
||
<div className="space-y-6">
|
||
{/* Header */}
|
||
<div className="flex justify-between items-center">
|
||
<div>
|
||
<h2 className="text-2xl font-bold text-gray-900">版本管理</h2>
|
||
<p className="text-gray-600 mt-1">管理移动应用的版本更新</p>
|
||
</div>
|
||
<button
|
||
onClick={() => setShowUploadModal(true)}
|
||
className="btn btn-primary"
|
||
>
|
||
上传新版本
|
||
</button>
|
||
</div>
|
||
|
||
{/* Filters */}
|
||
<div className="card">
|
||
<div className="flex items-center gap-4">
|
||
<label className="label">平台筛选:</label>
|
||
<div className="flex gap-2">
|
||
<button
|
||
onClick={() => setPlatformFilter('all')}
|
||
className={`px-4 py-2 rounded-lg text-sm font-medium transition-colors ${
|
||
platformFilter === 'all'
|
||
? 'bg-blue-600 text-white'
|
||
: 'bg-gray-100 text-gray-700 hover:bg-gray-200'
|
||
}`}
|
||
>
|
||
全部
|
||
</button>
|
||
<button
|
||
onClick={() => setPlatformFilter('android')}
|
||
className={`px-4 py-2 rounded-lg text-sm font-medium transition-colors ${
|
||
platformFilter === 'android'
|
||
? 'bg-green-600 text-white'
|
||
: 'bg-gray-100 text-gray-700 hover:bg-gray-200'
|
||
}`}
|
||
>
|
||
Android
|
||
</button>
|
||
<button
|
||
onClick={() => setPlatformFilter('ios')}
|
||
className={`px-4 py-2 rounded-lg text-sm font-medium transition-colors ${
|
||
platformFilter === 'ios'
|
||
? 'bg-gray-800 text-white'
|
||
: 'bg-gray-100 text-gray-700 hover:bg-gray-200'
|
||
}`}
|
||
>
|
||
iOS
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Error State */}
|
||
{error && (
|
||
<div className="bg-red-50 border border-red-200 rounded-lg p-4 text-red-700">
|
||
加载失败:{error}
|
||
</div>
|
||
)}
|
||
|
||
{/* Loading State */}
|
||
{isLoading && (
|
||
<div className="flex justify-center py-12">
|
||
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div>
|
||
</div>
|
||
)}
|
||
|
||
{/* Version List */}
|
||
{!isLoading && !error && (
|
||
<div className="space-y-4">
|
||
{filteredVersions.length === 0 ? (
|
||
<div className="card text-center py-12">
|
||
<p className="text-gray-500">暂无版本数据</p>
|
||
<button
|
||
onClick={() => setShowUploadModal(true)}
|
||
className="btn btn-primary mt-4"
|
||
>
|
||
上传第一个版本
|
||
</button>
|
||
</div>
|
||
) : (
|
||
filteredVersions.map((version) => (
|
||
<VersionCard
|
||
key={version.id}
|
||
version={version}
|
||
onEdit={() => setEditingVersionId(version.id)}
|
||
onDelete={() => handleDelete(version.id)}
|
||
onToggle={(enabled) => handleToggle(version.id, enabled)}
|
||
/>
|
||
))
|
||
)}
|
||
</div>
|
||
)}
|
||
|
||
{/* Upload Modal */}
|
||
{showUploadModal && (
|
||
<UploadModal
|
||
onClose={() => setShowUploadModal(false)}
|
||
onSuccess={handleUploadSuccess}
|
||
/>
|
||
)}
|
||
|
||
{/* Edit Modal */}
|
||
{editingVersionId && (
|
||
<EditModal
|
||
versionId={editingVersionId}
|
||
onClose={() => setEditingVersionId(null)}
|
||
onSuccess={handleEditSuccess}
|
||
/>
|
||
)}
|
||
</div>
|
||
)
|
||
}
|