mkcart / frontend /src /components /Search.jsx
Kumar
updated
c2efbe6
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>
)
}