feat: support delete single search record

This commit is contained in:
shinya
2025-06-30 20:31:49 +08:00
parent 770cf1c02b
commit 3fe579bcba
2 changed files with 59 additions and 12 deletions

View File

@@ -1,13 +1,14 @@
/* eslint-disable react-hooks/exhaustive-deps */
'use client';
import { Search } from 'lucide-react';
import { Search, X } from 'lucide-react';
import { useRouter, useSearchParams } from 'next/navigation';
import { Suspense, useEffect, useMemo, useRef, useState } from 'react';
import {
addSearchHistory,
clearSearchHistory,
deleteSearchHistory,
getSearchHistory,
} from '@/lib/db.client';
import { SearchResult } from '@/lib/types';
@@ -224,17 +225,32 @@ function SearchPageClient() {
)}
</h2>
<div className='flex flex-wrap gap-2'>
{searchHistory.map((item, index) => (
<button
key={index}
onClick={() => {
setSearchQuery(item);
router.push(`/search?q=${encodeURIComponent(item)}`);
}}
className='px-4 py-2 bg-gray-500/10 hover:bg-gray-300 rounded-full text-sm text-gray-700 transition-colors duration-200 dark:bg-gray-700/50 dark:hover:bg-gray-600 dark:text-gray-300'
>
{item}
</button>
{searchHistory.map((item) => (
<div key={item} className='relative group'>
<button
onClick={() => {
setSearchQuery(item);
router.push(`/search?q=${encodeURIComponent(item)}`);
}}
className='px-4 py-2 bg-gray-500/10 hover:bg-gray-300 rounded-full text-sm text-gray-700 transition-colors duration-200 dark:bg-gray-700/50 dark:hover:bg-gray-600 dark:text-gray-300'
>
{item}
</button>
{/* 删除按钮 */}
<button
aria-label='删除搜索历史'
onClick={async (e) => {
e.stopPropagation();
e.preventDefault();
await deleteSearchHistory(item);
const history = await getSearchHistory();
setSearchHistory(history);
}}
className='absolute -top-1 -right-1 w-4 h-4 opacity-0 group-hover:opacity-100 bg-gray-400 hover:bg-red-500 text-white rounded-full flex items-center justify-center text-[10px] transition-colors'
>
<X className='w-3 h-3' />
</button>
</div>
))}
</div>
</section>

View File

@@ -265,6 +265,37 @@ export async function clearSearchHistory(): Promise<void> {
localStorage.removeItem(SEARCH_HISTORY_KEY);
}
/**
* 删除单条搜索历史
*/
export async function deleteSearchHistory(keyword: string): Promise<void> {
const trimmed = keyword.trim();
if (!trimmed) return;
// 数据库模式
if (STORAGE_TYPE === 'database') {
try {
await fetch(`/api/searchhistory?keyword=${encodeURIComponent(trimmed)}`, {
method: 'DELETE',
});
} catch (err) {
console.error('删除搜索历史失败:', err);
}
return;
}
// localStorage 模式
if (typeof window === 'undefined') return;
try {
const history = await getSearchHistory();
const newHistory = history.filter((k) => k !== trimmed);
localStorage.setItem(SEARCH_HISTORY_KEY, JSON.stringify(newHistory));
} catch (err) {
console.error('删除搜索历史失败:', err);
}
}
// ---------------- 收藏相关 API ----------------
// 收藏数据结构