Spaces:
Sleeping
Sleeping
File size: 3,814 Bytes
4fc8eae e85fa50 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
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; |