diff --git a/apps/web/src/features/search/components/search-page/SearchPage.tsx b/apps/web/src/features/search/components/search-page/SearchPage.tsx index 1ba12f0f9..885923853 100644 --- a/apps/web/src/features/search/components/search-page/SearchPage.tsx +++ b/apps/web/src/features/search/components/search-page/SearchPage.tsx @@ -41,7 +41,7 @@ export function SearchPage() { {isLoading ? ( ) : !query ? ( - + ) : !hasResults ? ( ) : results ? ( diff --git a/apps/web/src/features/search/components/search-page/SearchPageDiscovery.tsx b/apps/web/src/features/search/components/search-page/SearchPageDiscovery.tsx index 5bc12872e..1d22d98fd 100644 --- a/apps/web/src/features/search/components/search-page/SearchPageDiscovery.tsx +++ b/apps/web/src/features/search/components/search-page/SearchPageDiscovery.tsx @@ -1,8 +1,53 @@ +import { useState } from 'react'; import { Card } from '@/components/ui/card'; -import { Music, User, Sparkles } from 'lucide-react'; +import { Music, User, Sparkles, History } from 'lucide-react'; +import { useSearchHistory } from '../../hooks/useSearchHistory'; + +interface SearchPageDiscoveryProps { + onQuerySelect?: (query: string) => void; +} + +export function SearchPageDiscovery({ onQuerySelect }: SearchPageDiscoveryProps) { + const { getHistory, clearHistory } = useSearchHistory(); + const [refreshKey, setRefreshKey] = useState(0); + const history = getHistory(); + + const handleClear = () => { + clearHistory(); + setRefreshKey((k) => k + 1); + }; -export function SearchPageDiscovery() { return ( +
+ {history.length > 0 && ( +
+
+

+ + Recherches récentes +

+ +
+
+ {history.map((q) => ( + + ))} +
+
+ )}
Trending creators this week

+
); } diff --git a/apps/web/src/features/search/components/search-page/useSearchPage.ts b/apps/web/src/features/search/components/search-page/useSearchPage.ts index 892d045a6..607a2e7fd 100644 --- a/apps/web/src/features/search/components/search-page/useSearchPage.ts +++ b/apps/web/src/features/search/components/search-page/useSearchPage.ts @@ -3,6 +3,7 @@ import { useSearchParams } from 'react-router-dom'; import { searchApi } from '@/services/api/search'; import { SearchResults } from '@/types/search'; import { useDebounce } from '@/hooks/useDebounce'; +import { useSearchHistory } from '../../hooks/useSearchHistory'; export type SearchActiveTab = 'all' | 'track' | 'user' | 'playlist'; @@ -12,6 +13,7 @@ function tabToTypes(tab: SearchActiveTab): string[] { } export function useSearchPage() { + const { addToHistory } = useSearchHistory(); const [searchParams, setSearchParams] = useSearchParams(); const queryParam = searchParams.get('q') ?? ''; const typeParam = searchParams.get('type') ?? 'all'; @@ -48,6 +50,7 @@ export function useSearchPage() { const types = tabToTypes(activeTab); const data = await searchApi.search(debouncedQuery, types); setResults(data); + addToHistory(debouncedQuery); } catch (err) { setError(err instanceof Error ? err : new Error('Search signal interrupted.')); } finally { diff --git a/apps/web/src/features/search/hooks/useSearchHistory.ts b/apps/web/src/features/search/hooks/useSearchHistory.ts new file mode 100644 index 000000000..f63e1328e --- /dev/null +++ b/apps/web/src/features/search/hooks/useSearchHistory.ts @@ -0,0 +1,39 @@ +const STORAGE_KEY = 'veza_search_history'; +const MAX_ITEMS = 10; + +export function useSearchHistory() { + const getHistory = (): string[] => { + try { + const raw = localStorage.getItem(STORAGE_KEY); + if (!raw) return []; + const parsed = JSON.parse(raw) as unknown; + if (!Array.isArray(parsed)) return []; + return parsed.filter((x): x is string => typeof x === 'string').slice(0, MAX_ITEMS); + } catch { + return []; + } + }; + + const addToHistory = (q: string) => { + const trimmed = q.trim(); + if (!trimmed) return; + const current = getHistory(); + const filtered = current.filter((x) => x.toLowerCase() !== trimmed.toLowerCase()); + const updated = [trimmed, ...filtered].slice(0, MAX_ITEMS); + try { + localStorage.setItem(STORAGE_KEY, JSON.stringify(updated)); + } catch { + // ignore quota or other storage errors + } + }; + + const clearHistory = () => { + try { + localStorage.removeItem(STORAGE_KEY); + } catch { + // ignore + } + }; + + return { getHistory, addToHistory, clearHistory }; +}