| import { useState, useRef, useEffect } from "react" |
| import { useNavigate } from "react-router-dom" |
| import { motion, AnimatePresence } from "framer-motion" |
| import { SearchIcon, X, TrendingUp, Clock, Star } from "lucide-react" |
| import "./Search.css" |
|
|
| export default function Search() { |
| const [keyword, setKeyword] = useState("") |
| const [isFocused, setIsFocused] = useState(false) |
| const [showSuggestions, setShowSuggestions] = useState(false) |
| const [suggestions, setSuggestions] = useState([]) |
| const [recentSearches, setRecentSearches] = useState(["iPhone 14", "Samsung Galaxy", "MacBook Pro", "AirPods"]) |
| const [trendingSearches] = useState(["Gaming Laptop", "Wireless Headphones", "Smart Watch", "4K Monitor"]) |
|
|
| const navigate = useNavigate() |
| const searchRef = useRef(null) |
| const inputRef = useRef(null) |
|
|
| useEffect(() => { |
| const handleClickOutside = (event) => { |
| if (searchRef.current && !searchRef.current.contains(event.target)) { |
| setShowSuggestions(false) |
| setIsFocused(false) |
| } |
| } |
|
|
| document.addEventListener("mousedown", handleClickOutside) |
| return () => document.removeEventListener("mousedown", handleClickOutside) |
| }, []) |
|
|
| const searchHandler = (e) => { |
| e.preventDefault() |
| if (keyword.trim()) { |
| |
| const updatedRecent = [keyword, ...recentSearches.filter((item) => item !== keyword)].slice(0, 4) |
| setRecentSearches(updatedRecent) |
|
|
| navigate(`/productlist?keyword=${keyword}`) |
| setShowSuggestions(false) |
| setIsFocused(false) |
| inputRef.current?.blur() |
| } |
| } |
|
|
| const handleInputChange = (e) => { |
| const value = e.target.value |
| setKeyword(value) |
|
|
| if (value.length > 0) { |
| const mockSuggestions = [`${value} pro`, `${value} max`, `${value} mini`, `best ${value}`, `${value} 2025`].slice( |
| 0, |
| 3, |
| ) |
| setSuggestions(mockSuggestions) |
| } else { |
| setSuggestions([]) |
| } |
| } |
|
|
| const handleSuggestionClick = (suggestion) => { |
| setKeyword(suggestion) |
| navigate(`/productlist?keyword=${suggestion}`) |
| setShowSuggestions(false) |
| setIsFocused(false) |
| } |
|
|
| const clearSearch = () => { |
| setKeyword("") |
| inputRef.current?.focus() |
| } |
|
|
| return ( |
| <div className="Premium-search-container" ref={searchRef}> |
| <motion.form |
| className="Premium-search-form" |
| onSubmit={searchHandler} |
| animate={{ scale: isFocused ? 1.02 : 1 }} |
| transition={{ duration: 0.2 }} |
| > |
| <div className={`search-input-wrapper ${isFocused ? "focused" : ""}`}> |
| <SearchIcon size={20} className="search-icon" /> |
| |
| <input |
| ref={inputRef} |
| type="text" |
| value={keyword} |
| onChange={handleInputChange} |
| onFocus={() => { |
| setIsFocused(true) |
| setShowSuggestions(true) |
| }} |
| className="Premium-search-input" |
| placeholder="Search for products..." |
| autoComplete="off" |
| /> |
| |
| <AnimatePresence> |
| {keyword && ( |
| <motion.button |
| type="button" |
| className="clear-search-btn" |
| onClick={clearSearch} |
| initial={{ opacity: 0, scale: 0 }} |
| animate={{ opacity: 1, scale: 1 }} |
| exit={{ opacity: 0, scale: 0 }} |
| whileHover={{ scale: 1.1 }} |
| whileTap={{ scale: 0.9 }} |
| > |
| <X size={16} /> |
| </motion.button> |
| )} |
| </AnimatePresence> |
| |
| <div className="search-glow-effect"></div> |
| <div className="search-border-animation"></div> |
| </div> |
| |
| <motion.button |
| className="Premium-search-btn" |
| type="submit" |
| whileHover={{ scale: 1.05 }} |
| whileTap={{ scale: 0.95 }} |
| > |
| <span>Search</span> |
| <div className="btn-shine"></div> |
| </motion.button> |
| </motion.form> |
| |
| {} |
| <AnimatePresence> |
| {showSuggestions && isFocused && ( |
| <motion.div |
| className="search-suggestions-dropdown" |
| initial={{ opacity: 0, y: -10, scale: 0.95 }} |
| animate={{ opacity: 1, y: 0, scale: 1 }} |
| exit={{ opacity: 0, y: -10, scale: 0.95 }} |
| transition={{ duration: 0.2 }} |
| > |
| {} |
| {suggestions.length > 0 && ( |
| <div className="suggestion-section"> |
| <div className="suggestion-header"> |
| <SearchIcon size={16} /> |
| <span>Suggestions</span> |
| </div> |
| {suggestions.map((suggestion, index) => ( |
| <motion.div |
| key={suggestion} |
| className="suggestion-item" |
| onClick={() => handleSuggestionClick(suggestion)} |
| initial={{ opacity: 0, x: -20 }} |
| animate={{ opacity: 1, x: 0 }} |
| transition={{ delay: index * 0.05 }} |
| whileHover={{ x: 5, backgroundColor: "rgba(255, 255, 255, 0.1)" }} |
| > |
| <SearchIcon size={14} /> |
| <span>{suggestion}</span> |
| </motion.div> |
| ))} |
| </div> |
| )} |
| |
| {} |
| {recentSearches.length > 0 && keyword.length === 0 && ( |
| <div className="suggestion-section"> |
| <div className="suggestion-header"> |
| <Clock size={16} /> |
| <span>Recent Searches</span> |
| </div> |
| {recentSearches.map((search, index) => ( |
| <motion.div |
| key={search} |
| className="suggestion-item recent" |
| onClick={() => handleSuggestionClick(search)} |
| initial={{ opacity: 0, x: -20 }} |
| animate={{ opacity: 1, x: 0 }} |
| transition={{ delay: index * 0.05 }} |
| whileHover={{ x: 5, backgroundColor: "rgba(255, 255, 255, 0.1)" }} |
| > |
| <Clock size={14} /> |
| <span>{search}</span> |
| </motion.div> |
| ))} |
| </div> |
| )} |
| |
| {} |
| {keyword.length === 0 && ( |
| <div className="suggestion-section"> |
| <div className="suggestion-header trending"> |
| <TrendingUp size={16} /> |
| <span>Trending Now</span> |
| <div className="trending-glow"></div> |
| </div> |
| {trendingSearches.map((trend, index) => ( |
| <motion.div |
| key={trend} |
| className="suggestion-item trending" |
| onClick={() => handleSuggestionClick(trend)} |
| initial={{ opacity: 0, x: -20 }} |
| animate={{ opacity: 1, x: 0 }} |
| transition={{ delay: index * 0.05 }} |
| whileHover={{ x: 5, backgroundColor: "rgba(255, 107, 107, 0.1)" }} |
| > |
| <TrendingUp size={14} /> |
| <span>{trend}</span> |
| <Star size={12} className="trending-star" /> |
| </motion.div> |
| ))} |
| </div> |
| )} |
| |
| {} |
| <div className="suggestion-section quick-actions"> |
| <div className="quick-action-grid"> |
| <motion.div |
| className="quick-action-item" |
| whileHover={{ scale: 1.05 }} |
| onClick={() => navigate("/productlist")} |
| > |
| <div className="quick-action-icon">📱</div> |
| <span>Electronics</span> |
| </motion.div> |
| <motion.div |
| className="quick-action-item" |
| whileHover={{ scale: 1.05 }} |
| onClick={() => navigate("/productlist")} |
| > |
| <div className="quick-action-icon">👕</div> |
| <span>Fashion</span> |
| </motion.div> |
| <motion.div |
| className="quick-action-item" |
| whileHover={{ scale: 1.05 }} |
| onClick={() => navigate("/productlist")} |
| > |
| <div className="quick-action-icon">🏠</div> |
| <span>Home</span> |
| </motion.div> |
| <motion.div |
| className="quick-action-item" |
| whileHover={{ scale: 1.05 }} |
| onClick={() => navigate("/productlist")} |
| > |
| <div className="quick-action-icon">🎮</div> |
| <span>Gaming</span> |
| </motion.div> |
| </div> |
| </div> |
| </motion.div> |
| )} |
| </AnimatePresence> |
| </div> |
| ) |
| } |