Spaces:
Sleeping
Sleeping
| import React, { useState } from 'react'; | |
| // eslint-disable-next-line | |
| import { PromptGroup } from '../../types'; | |
| import PromptGroupCard from './PromptGroupCard'; | |
| import { useApp } from '../../contexts/AppContext'; | |
| import CategorySelector from '../Category/CategorySelector'; | |
| import Input from '../common/Input'; | |
| const PromptGroupList: React.FC = () => { | |
| // eslint-disable-next-line | |
| const { promptGroups, categories } = useApp(); | |
| const [searchTerm, setSearchTerm] = useState(''); | |
| const [selectedCategory, setSelectedCategory] = useState<string>(''); | |
| // 搜索和过滤提示词组 | |
| const filteredPromptGroups = promptGroups.filter((group) => { | |
| const matchesSearch = | |
| group.name.toLowerCase().includes(searchTerm.toLowerCase()) || | |
| (group.description?.toLowerCase() || '').includes(searchTerm.toLowerCase()); | |
| // 处理 category 可能是对象或字符串的情况 | |
| const groupCategoryId = typeof group.category === 'object' | |
| ? group.category._id | |
| : group.category; | |
| const matchesCategory = | |
| selectedCategory === '' || groupCategoryId === selectedCategory; | |
| return matchesSearch && matchesCategory; | |
| }); | |
| const handleSearch = (e: React.ChangeEvent<HTMLInputElement>) => { | |
| setSearchTerm(e.target.value); | |
| }; | |
| const handleCategoryChange = (categoryId: string) => { | |
| setSelectedCategory(categoryId); | |
| }; | |
| const resetFilters = () => { | |
| setSearchTerm(''); | |
| setSelectedCategory(''); | |
| }; | |
| return ( | |
| <div> | |
| <div className="mb-4 flex flex-col sm:flex-row gap-3"> | |
| <Input | |
| placeholder="搜索提示词组..." | |
| value={searchTerm} | |
| onChange={handleSearch} | |
| className="flex-1" | |
| style={{ paddingLeft: "40px" }} /* Add explicit inline padding */ | |
| icon={ | |
| <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"> | |
| <circle cx="11" cy="11" r="8"></circle> | |
| <line x1="21" y1="21" x2="16.65" y2="16.65"></line> | |
| </svg> | |
| } | |
| /> | |
| <div className="flex gap-2"> | |
| <CategorySelector | |
| selectedCategory={selectedCategory} | |
| onChange={handleCategoryChange} | |
| /> | |
| {(searchTerm || selectedCategory) && ( | |
| <button | |
| className="ios-navbar-button" | |
| onClick={resetFilters} | |
| > | |
| 清除筛选 | |
| </button> | |
| )} | |
| </div> | |
| </div> | |
| {filteredPromptGroups.length === 0 ? ( | |
| <div className="ios-empty-state"> | |
| <div className="ios-empty-state-icon"> | |
| <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"> | |
| <circle cx="11" cy="11" r="8"></circle> | |
| <line x1="21" y1="21" x2="16.65" y2="16.65"></line> | |
| </svg> | |
| </div> | |
| <h3 className="ios-empty-state-title">未找到提示词组</h3> | |
| <p className="ios-empty-state-text"> | |
| {searchTerm || selectedCategory | |
| ? '请尝试调整筛选条件' | |
| : '点击底部的"新建"按钮创建您的第一个提示词组'} | |
| </p> | |
| </div> | |
| ) : ( | |
| <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4"> | |
| {filteredPromptGroups.map((group) => ( | |
| <PromptGroupCard | |
| key={group._id} | |
| promptGroup={group} | |
| /> | |
| ))} | |
| </div> | |
| )} | |
| </div> | |
| ); | |
| }; | |
| export default PromptGroupList; |