Spaces:
Sleeping
Sleeping
Download frontend/src/components/SearchHistory.js from vishalharkal/BookMind: direct link, hf CLI and curl.
- Browser
- Download file 3.1 kB
-
https://huggingface.co/spaces/vishalharkal/BookMind/resolve/main/frontend/src/components/SearchHistory.js
- Command line
-
hf download hf://spaces/vishalharkal/BookMind/frontend/src/components/SearchHistory.js
-
curl -L -o SearchHistory.js https://huggingface.co/spaces/vishalharkal/BookMind/resolve/main/frontend/src/components/SearchHistory.js
3.1 kB
| import React, { useEffect, useState } from 'react'; | |
| import { Clock, X } from 'lucide-react'; | |
| const SearchHistory = ({ onSelectBook, onClose }) => { | |
| const [history, setHistory] = useState([]); | |
| useEffect(() => { | |
| const saved = JSON.parse(localStorage.getItem('searchHistory') || '[]'); | |
| setHistory(saved.reverse()); | |
| }, []); | |
| const clearHistory = () => { | |
| localStorage.setItem('searchHistory', '[]'); | |
| setHistory([]); | |
| }; | |
| const removeItem = (book) => { | |
| const updated = history.filter(h => h.title !== book.title); | |
| setHistory(updated); | |
| localStorage.setItem('searchHistory', JSON.stringify(updated.reverse())); | |
| }; | |
| if (history.length === 0) return null; | |
| return ( | |
| <div className="absolute top-full left-0 right-0 mt-2 bg-white border-2 border-border rounded-2xl shadow-2xl z-50 overflow-hidden max-h-96 overflow-y-auto"> | |
| <div className="sticky top-0 bg-gradient-to-r from-[#0369a1] to-[#0891b2] text-white px-4 py-3 flex items-center justify-between"> | |
| <div className="flex items-center gap-2"> | |
| <Clock size={16} /> | |
| <span className="font-semibold">Recent Searches</span> | |
| </div> | |
| <button | |
| onClick={clearHistory} | |
| className="text-xs px-2 py-1 bg-white/20 hover:bg-white/30 rounded transition-all" | |
| > | |
| Clear | |
| </button> | |
| </div> | |
| <div> | |
| {history.map((item, i) => ( | |
| <button | |
| key={i} | |
| onClick={() => { | |
| onSelectBook(item.title); | |
| onClose(); | |
| }} | |
| className="w-full flex items-center gap-3 p-3 hover:bg-bg-hover transition-all border-b border-border/50 last:border-0 group" | |
| > | |
| <img | |
| src={item.image_url} | |
| alt={item.title} | |
| className="w-10 h-14 object-cover rounded shadow-sm group-hover:scale-105 transition-transform" | |
| /> | |
| <div className="flex-1 text-left"> | |
| <div className="font-semibold text-text-primary text-sm line-clamp-1">{item.title}</div> | |
| <div className="text-xs text-text-secondary">{item.author}</div> | |
| </div> | |
| <button | |
| onClick={(e) => { | |
| e.stopPropagation(); | |
| removeItem(item); | |
| }} | |
| className="opacity-0 group-hover:opacity-100 transition-opacity" | |
| > | |
| <X size={16} className="text-text-muted" /> | |
| </button> | |
| </button> | |
| ))} | |
| </div> | |
| </div> | |
| ); | |
| }; | |
| export default SearchHistory; | |