1- import { Select , Divider , Space , Dropdown , Button , Menu , Checkbox } from 'antd' ;
2- import { SortAscendingOutlined , SortDescendingOutlined , TagOutlined , FilterOutlined , DownOutlined } from '@ant-design/icons' ;
1+ import { Select , Divider , Space , Dropdown , Button , Menu , Checkbox , Input } from 'antd' ;
2+ import { SortAscendingOutlined , SortDescendingOutlined , TagOutlined , FilterOutlined , DownOutlined , SearchOutlined } from '@ant-design/icons' ;
33import { useTranslation } from 'react-i18next' ;
4+ import { useState , ChangeEvent } from 'react' ;
45import StarRating from '../StarRating' ;
56
7+ // 定义平台枚举值
8+ const PLATFORM_TYPES = [ 'Web' , 'Android' , 'iOS' ] ;
9+
610interface ChallengeControlsProps {
711 /**
812 * 所有可用的标签
@@ -85,6 +89,9 @@ const ChallengeControls: React.FC<ChallengeControlsProps> = ({
8589} ) => {
8690 const { t } = useTranslation ( ) ;
8791
92+ // 在组件的开头部分添加状态
93+ const [ tagSearchText , setTagSearchText ] = useState ( '' ) ;
94+
8895 // 排序功能菜单
8996 const sortMenu = (
9097 < Menu
@@ -130,7 +137,8 @@ const ChallengeControls: React.FC<ChallengeControlsProps> = ({
130137 onClick = { ( { key } ) => onPlatformChange ( key ) }
131138 >
132139 < Menu . Item key = "all" > { t ( 'challenges.filters.allPlatforms' ) } </ Menu . Item >
133- { allPlatforms . map ( platform => (
140+ { /* 使用固定的平台枚举列表,而不是从挑战中提取的 */ }
141+ { PLATFORM_TYPES . map ( platform => (
134142 < Menu . Item key = { platform } > { platform } </ Menu . Item >
135143 ) ) }
136144 </ Menu >
@@ -142,17 +150,55 @@ const ChallengeControls: React.FC<ChallengeControlsProps> = ({
142150 padding : '12px' ,
143151 maxHeight : '400px' ,
144152 overflowY : 'auto' ,
145- minWidth : '200px ' ,
153+ minWidth : '300px ' ,
146154 backgroundColor : '#fff' ,
147155 boxShadow : '0 2px 8px rgba(0, 0, 0, 0.15)' ,
148156 borderRadius : '4px' ,
149157 border : '1px solid #f0f0f0'
150158 } } >
151- < Checkbox . Group
152- options = { allTags . map ( tag => ( { label : tag , value : tag } ) ) }
153- value = { selectedTags }
154- onChange = { tags => onTagsChange ( tags as string [ ] ) }
159+ { /* 添加标签搜索框 */ }
160+ < Input
161+ prefix = { < SearchOutlined /> }
162+ placeholder = { t ( 'challenges.filters.searchTags' ) }
163+ style = { { marginBottom : '12px' } }
164+ onChange = { ( e : ChangeEvent < HTMLInputElement > ) => {
165+ setTagSearchText ( e . target . value ) ;
166+ } }
167+ allowClear
155168 />
169+
170+ { /* 标签列表,使用Grid布局优化显示 */ }
171+ < div >
172+ < Checkbox . Group
173+ value = { selectedTags }
174+ onChange = { tags => onTagsChange ( tags as string [ ] ) }
175+ style = { {
176+ display : 'flex' ,
177+ flexWrap : 'wrap' ,
178+ width : '100%'
179+ } }
180+ >
181+ { allTags
182+ . filter ( tag => tag . toLowerCase ( ) . includes ( tagSearchText . toLowerCase ( ) ) )
183+ . map ( tag => (
184+ < Checkbox
185+ key = { tag }
186+ value = { tag }
187+ style = { {
188+ marginRight : '12px' ,
189+ marginBottom : '6px' ,
190+ width : 'auto' ,
191+ display : 'inline-flex' ,
192+ alignItems : 'center' ,
193+ fontSize : '13px'
194+ } }
195+ >
196+ { tag }
197+ </ Checkbox >
198+ ) )
199+ }
200+ </ Checkbox . Group >
201+ </ div >
156202 </ div >
157203 ) ;
158204
0 commit comments