@@ -10,6 +10,7 @@ interface PromptListProps {
1010 searchTerm : string
1111 allPromptsCount : number
1212 onToggleEnabled ?: ( id : string , enabled : boolean ) => void
13+ onTogglePinned ?: ( id : string , pinned : boolean ) => void
1314 selectedCategoryId ?: string | null
1415}
1516
@@ -20,6 +21,7 @@ const PromptList = ({
2021 searchTerm,
2122 allPromptsCount,
2223 onToggleEnabled,
24+ onTogglePinned,
2325 selectedCategoryId,
2426} : PromptListProps ) => {
2527 const [ categories , setCategories ] = useState < Category [ ] > ( [ ] )
@@ -165,9 +167,21 @@ const PromptList = ({
165167 className = 'bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-600 rounded-xl overflow-hidden shadow-sm hover:shadow-md transition-all duration-200 flex flex-col'
166168 >
167169 { /* Card Header */ }
168- < div className = 'px-5 py-4 border-b border-gray-100 dark:border-gray-700 bg-gradient-to-r from-gray-50 to-white dark:from-gray-800 dark:to-gray-700' >
170+ < div className = { `px-5 py-4 border-b border-gray-100 dark:border-gray-700 ${
171+ prompt . pinned
172+ ? 'bg-gradient-to-r from-amber-50 to-orange-50 dark:from-amber-900/20 dark:to-orange-900/20'
173+ : 'bg-gradient-to-r from-gray-50 to-white dark:from-gray-800 dark:to-gray-700'
174+ } `} >
169175 < div className = 'flex items-center justify-between' >
170- < h3 className = 'text-lg font-semibold text-gray-800 dark:text-gray-200 truncate flex-1' > { prompt . title } </ h3 >
176+ < div className = 'flex items-center flex-1 min-w-0' >
177+ { /* 置顶图标 */ }
178+ { prompt . pinned && (
179+ < svg className = 'w-4 h-4 text-amber-600 dark:text-amber-400 mr-2 flex-shrink-0' fill = 'none' stroke = 'currentColor' viewBox = '0 0 24 24' >
180+ < path strokeLinecap = 'round' strokeLinejoin = 'round' strokeWidth = '2' d = 'M5 15l7-7 7 7' />
181+ </ svg >
182+ ) }
183+ < h3 className = 'text-lg font-semibold text-gray-800 dark:text-gray-200 truncate' > { prompt . title } </ h3 >
184+ </ div >
171185 { /* 分类标识 */ }
172186 { category && (
173187 < div className = 'ml-2 flex items-center' >
@@ -254,6 +268,34 @@ const PromptList = ({
254268
255269 { /* Card Footer / Actions */ }
256270 < div className = 'px-5 py-3 bg-gray-50 dark:bg-gray-700 border-t border-gray-100 dark:border-gray-600 flex justify-end space-x-2' >
271+ { /* 置顶按钮 */ }
272+ { onTogglePinned && (
273+ < button
274+ onClick = { ( ) => onTogglePinned ( prompt . id , ! prompt . pinned ) }
275+ className = { `px-3 py-1.5 text-sm rounded-md border transition-colors duration-200 ${
276+ prompt . pinned
277+ ? 'bg-amber-100 dark:bg-amber-900/50 border-amber-300 dark:border-amber-600 text-amber-700 dark:text-amber-400 hover:bg-amber-200 dark:hover:bg-amber-900/70'
278+ : 'bg-white dark:bg-gray-800 border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-700'
279+ } focus:outline-none focus:ring-2 focus:ring-offset-1 focus:ring-amber-500`}
280+ title = { prompt . pinned ? t ( 'unpinPrompt' ) : t ( 'pinPrompt' ) }
281+ >
282+ < span className = 'flex items-center' >
283+ { prompt . pinned ? (
284+ // 已置顶状态:显示向下箭头,表示可以取消置顶
285+ < svg className = 'w-4 h-4 mr-1.5' fill = 'none' stroke = 'currentColor' viewBox = '0 0 24 24' >
286+ < path strokeLinecap = 'round' strokeLinejoin = 'round' strokeWidth = '2' d = 'M19 9l-7 7-7-7' />
287+ </ svg >
288+ ) : (
289+ // 未置顶状态:显示向上箭头,表示可以置顶
290+ < svg className = 'w-4 h-4 mr-1.5' fill = 'none' stroke = 'currentColor' viewBox = '0 0 24 24' >
291+ < path strokeLinecap = 'round' strokeLinejoin = 'round' strokeWidth = '2' d = 'M5 15l7-7 7 7' />
292+ </ svg >
293+ ) }
294+ { prompt . pinned ? t ( 'unpin' ) : t ( 'pin' ) }
295+ </ span >
296+ </ button >
297+ ) }
298+
257299 < button
258300 onClick = { ( ) => handleCopy ( prompt . content , prompt . id ) }
259301 className = { `px-3 py-1.5 text-sm rounded-md border transition-colors duration-200 ${
0 commit comments