rwadurian/frontend/mobile-upgrade/src/app/page.tsx

177 lines
5.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'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>
)
}