feat: 添加搜索清空按钮并移除 AI 搜索提示
- 在搜索输入框有内容时显示清空按钮(X 图标) - 点击清空按钮可清除输入内容并重置搜索状态 - 移除 AI 模式下的提示文字以简化界面 - 清理相关的 aiHint/traditionalHint props 及传递链 Co-Authored-By: Claude (glm-4.7) <noreply@anthropic.com>
This commit is contained in:
@@ -39,8 +39,6 @@ export default async function HomePage({ params }: HomePageProps) {
|
|||||||
toggleToAI={tCommon('toggleToAI')}
|
toggleToAI={tCommon('toggleToAI')}
|
||||||
toggleToTraditional={tCommon('toggleToTraditional')}
|
toggleToTraditional={tCommon('toggleToTraditional')}
|
||||||
searching={tCommon('searching')}
|
searching={tCommon('searching')}
|
||||||
aiHint={tCommon('aiHint')}
|
|
||||||
traditionalHint={tCommon('traditionalHint')}
|
|
||||||
/>
|
/>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@@ -22,8 +22,6 @@ interface ProjectsPageClientProps {
|
|||||||
toggleToAI: string
|
toggleToAI: string
|
||||||
toggleToTraditional: string
|
toggleToTraditional: string
|
||||||
searching: string
|
searching: string
|
||||||
aiHint: string
|
|
||||||
traditionalHint: string
|
|
||||||
translations: {
|
translations: {
|
||||||
viewDetails: string
|
viewDetails: string
|
||||||
submitProjectTitle: string
|
submitProjectTitle: string
|
||||||
@@ -42,8 +40,6 @@ export function ProjectsPageClient({
|
|||||||
toggleToAI,
|
toggleToAI,
|
||||||
toggleToTraditional,
|
toggleToTraditional,
|
||||||
searching,
|
searching,
|
||||||
aiHint,
|
|
||||||
traditionalHint,
|
|
||||||
translations,
|
translations,
|
||||||
}: ProjectsPageClientProps) {
|
}: ProjectsPageClientProps) {
|
||||||
const searchParams = useSearchParams()
|
const searchParams = useSearchParams()
|
||||||
@@ -143,8 +139,6 @@ export function ProjectsPageClient({
|
|||||||
toggleToAI={toggleToAI}
|
toggleToAI={toggleToAI}
|
||||||
toggleToTraditional={toggleToTraditional}
|
toggleToTraditional={toggleToTraditional}
|
||||||
searching={searching}
|
searching={searching}
|
||||||
aiHint={aiHint}
|
|
||||||
traditionalHint={traditionalHint}
|
|
||||||
onSearch={handleAISearch}
|
onSearch={handleAISearch}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -52,8 +52,6 @@ export default async function ProjectsPage({
|
|||||||
toggleToAI={tCommon('toggleToAI')}
|
toggleToAI={tCommon('toggleToAI')}
|
||||||
toggleToTraditional={tCommon('toggleToTraditional')}
|
toggleToTraditional={tCommon('toggleToTraditional')}
|
||||||
searching={tCommon('searching')}
|
searching={tCommon('searching')}
|
||||||
aiHint={tCommon('aiHint')}
|
|
||||||
traditionalHint={tCommon('traditionalHint')}
|
|
||||||
translations={translations}
|
translations={translations}
|
||||||
>
|
>
|
||||||
{/* Tag Cloud - rendered inside client component for non-AI mode */}
|
{/* Tag Cloud - rendered inside client component for non-AI mode */}
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useState } from 'react'
|
import { useState, useEffect } from 'react'
|
||||||
import { Sparkles } from 'lucide-react'
|
import { useRouter, useSearchParams } from 'next/navigation'
|
||||||
|
import { Sparkles, X } from 'lucide-react'
|
||||||
|
|
||||||
interface AISearchBarProps {
|
interface AISearchBarProps {
|
||||||
locale: string
|
locale: string
|
||||||
@@ -12,8 +13,6 @@ interface AISearchBarProps {
|
|||||||
toggleToAI: string
|
toggleToAI: string
|
||||||
toggleToTraditional: string
|
toggleToTraditional: string
|
||||||
searching: string
|
searching: string
|
||||||
aiHint: string
|
|
||||||
traditionalHint: string
|
|
||||||
onSearch: (query: string, isAI: boolean) => void
|
onSearch: (query: string, isAI: boolean) => void
|
||||||
loading?: boolean
|
loading?: boolean
|
||||||
}
|
}
|
||||||
@@ -27,14 +26,22 @@ export function AISearchBar({
|
|||||||
toggleToAI,
|
toggleToAI,
|
||||||
toggleToTraditional,
|
toggleToTraditional,
|
||||||
searching,
|
searching,
|
||||||
aiHint,
|
|
||||||
traditionalHint,
|
|
||||||
onSearch,
|
onSearch,
|
||||||
loading = false,
|
loading = false,
|
||||||
}: AISearchBarProps) {
|
}: AISearchBarProps) {
|
||||||
|
const router = useRouter()
|
||||||
|
const searchParams = useSearchParams()
|
||||||
const [query, setQuery] = useState('')
|
const [query, setQuery] = useState('')
|
||||||
const [aiMode, setAiMode] = useState(false)
|
const [aiMode, setAiMode] = useState(false)
|
||||||
|
|
||||||
|
// 从 URL 参数初始化 query
|
||||||
|
useEffect(() => {
|
||||||
|
const searchParam = searchParams.get('search')
|
||||||
|
if (searchParam) {
|
||||||
|
setQuery(searchParam)
|
||||||
|
}
|
||||||
|
}, [searchParams])
|
||||||
|
|
||||||
const handleSubmit = (e: React.FormEvent) => {
|
const handleSubmit = (e: React.FormEvent) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
if (query.trim()) {
|
if (query.trim()) {
|
||||||
@@ -46,6 +53,11 @@ export function AISearchBar({
|
|||||||
setAiMode(!aiMode)
|
setAiMode(!aiMode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleClear = () => {
|
||||||
|
setQuery('')
|
||||||
|
router.push(`/${locale}/projects`)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={handleSubmit} className="max-w-2xl mx-auto">
|
<form onSubmit={handleSubmit} className="max-w-2xl mx-auto">
|
||||||
<div className="relative group">
|
<div className="relative group">
|
||||||
@@ -69,6 +81,18 @@ export function AISearchBar({
|
|||||||
|
|
||||||
{/* Buttons Container */}
|
{/* Buttons Container */}
|
||||||
<div className="absolute inset-y-2 right-2 flex items-center gap-2">
|
<div className="absolute inset-y-2 right-2 flex items-center gap-2">
|
||||||
|
{/* Clear button - only show when there's a query */}
|
||||||
|
{query && (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={handleClear}
|
||||||
|
className="px-3 py-2 bg-white dark:bg-surface-dark text-gray-600 dark:text-gray-400 border-2 border-gray-300 dark:border-gray-600 hover:bg-gray-100 dark:hover:bg-white/10 transition-colors shadow-neo-sm active:shadow-none active:translate-x-[2px] active:translate-y-[2px]"
|
||||||
|
title="清空搜索"
|
||||||
|
>
|
||||||
|
<X className="w-4 h-4" />
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* AI Mode Toggle */}
|
{/* AI Mode Toggle */}
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -96,13 +120,6 @@ export function AISearchBar({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* AI Mode Hint */}
|
|
||||||
{aiMode && (
|
|
||||||
<div className="mt-3 text-sm text-gray-600 dark:text-gray-400 font-display">
|
|
||||||
💡 {aiHint}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</form>
|
</form>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,8 +11,6 @@ interface HomeSearchBarProps {
|
|||||||
toggleToAI: string
|
toggleToAI: string
|
||||||
toggleToTraditional: string
|
toggleToTraditional: string
|
||||||
searching: string
|
searching: string
|
||||||
aiHint: string
|
|
||||||
traditionalHint: string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function HomeSearchBar({
|
export function HomeSearchBar({
|
||||||
@@ -24,8 +22,6 @@ export function HomeSearchBar({
|
|||||||
toggleToAI,
|
toggleToAI,
|
||||||
toggleToTraditional,
|
toggleToTraditional,
|
||||||
searching,
|
searching,
|
||||||
aiHint,
|
|
||||||
traditionalHint,
|
|
||||||
}: HomeSearchBarProps) {
|
}: HomeSearchBarProps) {
|
||||||
const handleSearch = (query: string, isAI: boolean) => {
|
const handleSearch = (query: string, isAI: boolean) => {
|
||||||
const params = new URLSearchParams()
|
const params = new URLSearchParams()
|
||||||
@@ -44,8 +40,6 @@ export function HomeSearchBar({
|
|||||||
toggleToAI={toggleToAI}
|
toggleToAI={toggleToAI}
|
||||||
toggleToTraditional={toggleToTraditional}
|
toggleToTraditional={toggleToTraditional}
|
||||||
searching={searching}
|
searching={searching}
|
||||||
aiHint={aiHint}
|
|
||||||
traditionalHint={traditionalHint}
|
|
||||||
onSearch={handleSearch}
|
onSearch={handleSearch}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user