import React, { useState, useEffect } from 'react'; import { Model, ModelStatus, Gender, ModelViewMode, ModelSortBy, SortOrder } from '../types/model'; import { modelService } from '../services/modelService'; import ModelCard from './ModelCard'; import ModelForm from './ModelForm'; import ModelSearch from './ModelSearch'; import { PlusIcon, Squares2X2Icon, ListBulletIcon, FunnelIcon, MagnifyingGlassIcon, SparklesIcon, HeartIcon } from '@heroicons/react/24/outline'; interface ModelListProps { onModelSelect?: (model: Model) => void; } const ModelList: React.FC = ({ onModelSelect }) => { const [models, setModels] = useState([]); const [filteredModels, setFilteredModels] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [showCreateModal, setShowCreateModal] = useState(false); const [editingModel, setEditingModel] = useState(null); const [viewMode, setViewMode] = useState(ModelViewMode.Grid); const [sortBy, setSortBy] = useState(ModelSortBy.CreatedAt); const [sortOrder, setSortOrder] = useState(SortOrder.Desc); const [searchQuery, setSearchQuery] = useState(''); const [statusFilter, setStatusFilter] = useState('all'); const [genderFilter, setGenderFilter] = useState('all'); const [favorites, setFavorites] = useState>(new Set()); const [showFilters, setShowFilters] = useState(true); useEffect(() => { loadModels(); }, []); useEffect(() => { filterAndSortModels(); }, [models, searchQuery, statusFilter, genderFilter, sortBy, sortOrder]); const loadModels = async () => { try { setLoading(true); setError(null); console.log('开始加载模特列表...'); const modelList = await modelService.getAllModels(); console.log('模特列表加载成功:', modelList); setModels(modelList); } catch (err) { console.error('加载模特列表失败:', err); setError(err instanceof Error ? err.message : '加载模特列表失败'); } finally { setLoading(false); } }; const filterAndSortModels = () => { let filtered = [...models]; // 搜索过滤 if (searchQuery.trim()) { const query = searchQuery.toLowerCase(); filtered = filtered.filter(model => model.name.toLowerCase().includes(query) || (model.stage_name && model.stage_name.toLowerCase().includes(query)) || model.tags.some(tag => tag.toLowerCase().includes(query)) ); } // 状态过滤 if (statusFilter !== 'all') { filtered = filtered.filter(model => model.status === statusFilter); } // 性别过滤 if (genderFilter !== 'all') { filtered = filtered.filter(model => model.gender === genderFilter); } // 排序 filtered.sort((a, b) => { let aValue: any, bValue: any; switch (sortBy) { case ModelSortBy.Name: aValue = a.name.toLowerCase(); bValue = b.name.toLowerCase(); break; case ModelSortBy.CreatedAt: aValue = new Date(a.created_at); bValue = new Date(b.created_at); break; case ModelSortBy.UpdatedAt: aValue = new Date(a.updated_at); bValue = new Date(b.updated_at); break; case ModelSortBy.Rating: aValue = a.rating || 0; bValue = b.rating || 0; break; case ModelSortBy.Age: aValue = a.age || 0; bValue = b.age || 0; break; case ModelSortBy.Height: aValue = a.height || 0; bValue = b.height || 0; break; default: return 0; } if (aValue < bValue) return sortOrder === SortOrder.Asc ? -1 : 1; if (aValue > bValue) return sortOrder === SortOrder.Asc ? 1 : -1; return 0; }); setFilteredModels(filtered); }; const handleCreateModel = async (modelData: any) => { try { await modelService.createModel(modelData); setShowCreateModal(false); await loadModels(); } catch (err) { console.error('创建模特失败:', err); } }; const handleUpdateModel = async (modelData: any) => { if (!editingModel) return; try { await modelService.updateModel(editingModel.id, modelData); setEditingModel(null); await loadModels(); } catch (err) { console.error('更新模特失败:', err); } }; const handleDeleteModel = async (modelId: string) => { if (!confirm('确定要删除这个模特吗?')) return; try { await modelService.deleteModel(modelId); await loadModels(); } catch (err) { console.error('删除模特失败:', err); } }; const handleFavorite = (modelId: string) => { setFavorites(prev => { const newFavorites = new Set(prev); if (newFavorites.has(modelId)) { newFavorites.delete(modelId); } else { newFavorites.add(modelId); } // 保存到本地存储 localStorage.setItem('model-favorites', JSON.stringify([...newFavorites])); return newFavorites; }); }; // 从本地存储加载收藏 useEffect(() => { const savedFavorites = localStorage.getItem('model-favorites'); if (savedFavorites) { try { const favoriteIds = JSON.parse(savedFavorites); setFavorites(new Set(favoriteIds)); } catch (error) { console.error('加载收藏列表失败:', error); } } }, []); if (loading) { return (
{/* 头部骨架 */}
{/* 搜索栏骨架 */}
{/* 模特卡片骨架 */}
{[...Array(8)].map((_, i) => (
))}
); } if (error) { return (

加载失败

{error}

); } return ( <>
{/* 美观的头部工具栏 */}

模特管理

共 {filteredModels.length} 个模特 {favorites.size > 0 && ( <> {favorites.size} 个收藏 )}

{/* 过滤器切换 */} {/* 视图模式切换 */}
{/* 创建模特按钮 */}
{/* 搜索和过滤 */}
{/* 模特列表 - 优化滚动 */}
{filteredModels.length === 0 ? (

{models.length === 0 ? '还没有模特' : '没有找到匹配的模特'}

{models.length === 0 ? '开始添加您的第一个模特,建立您的模特库' : '尝试调整搜索条件或筛选器' }

{models.length === 0 && ( )}
) : (
{filteredModels.map((model, index) => (
setEditingModel(model)} onDelete={() => handleDeleteModel(model.id)} onSelect={() => onModelSelect?.(model)} onFavorite={handleFavorite} isFavorite={favorites.has(model.id)} />
))}
)}
{/* 创建模特模态框 */} {showCreateModal && ( setShowCreateModal(false)} /> )} {/* 编辑模特模态框 */} {editingModel && ( setEditingModel(null)} isEdit={true} /> )} ); }; export default ModelList;