Files
marmarislocal/components/LiveSearchInput.tsx
T

111 lines
3.5 KiB
TypeScript

'use client'
import { useState, useEffect, useRef } from 'react'
import { useRouter } from 'next/navigation'
import { Search } from 'lucide-react'
import { searchListingsAction } from '@/app/actions'
import { useLocale } from 'next-intl'
interface Suggestion {
id: string
nameTr: string
nameEn: string
nameRu: string
slug: string
categorySlug: string
}
export default function LiveSearchInput({
placeholder = "İsim veya adres...",
defaultValue = "",
className = ""
}: {
placeholder?: string
defaultValue?: string
className?: string
}) {
const [query, setQuery] = useState(defaultValue)
const [suggestions, setSuggestions] = useState<Suggestion[]>([])
const [isOpen, setIsOpen] = useState(false)
const wrapperRef = useRef<HTMLDivElement>(null)
const router = useRouter()
const locale = useLocale()
useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
if (wrapperRef.current && !wrapperRef.current.contains(event.target as Node)) {
setIsOpen(false)
}
}
document.addEventListener('mousedown', handleClickOutside)
return () => document.removeEventListener('mousedown', handleClickOutside)
}, [])
useEffect(() => {
if (query.length < 2) {
setSuggestions([])
setIsOpen(false)
return
}
const timer = setTimeout(async () => {
const results = await searchListingsAction(query)
setSuggestions(results)
setIsOpen(true)
}, 300)
return () => clearTimeout(timer)
}, [query])
const getLocalizedName = (s: Suggestion) => {
return locale === 'ru' ? s.nameRu : locale === 'en' ? s.nameEn : s.nameTr
}
return (
<div className="relative w-full" ref={wrapperRef}>
<div className="flex items-center flex-1 w-full">
<Search className="w-5 h-5 text-shutter shrink-0 absolute left-3" />
<input
type="text"
name="search"
autoComplete="off"
placeholder={placeholder}
value={query}
onChange={(e) => setQuery(e.target.value)}
onFocus={() => {
if (suggestions.length > 0) setIsOpen(true)
}}
className={className ? className : "w-full bg-transparent border-0 focus:ring-0 text-sm py-3 pl-10 pr-3 text-ink placeholder:text-ink/40 outline-none h-full rounded-xl"}
/>
</div>
{isOpen && suggestions.length > 0 && (
<div className="absolute top-full left-0 right-0 mt-2 bg-paper border border-pine/10 rounded-xl shadow-xl overflow-hidden z-50">
<ul className="py-1">
{suggestions.map((s) => (
<li key={s.id}>
<button
type="button"
onClick={() => {
setQuery(getLocalizedName(s))
setIsOpen(false)
router.push(`/${locale}/${s.categorySlug}/${s.slug}`)
}}
className="w-full text-left px-4 py-2.5 hover:bg-stone/50 transition-colors flex items-center justify-between group"
>
<span className="font-heading font-bold text-pine lowercase text-sm group-hover:text-turquoise transition-colors">
{getLocalizedName(s)}
</span>
<span className="text-[10px] font-mono text-shutter uppercase tracking-wider">
{s.categorySlug}
</span>
</button>
</li>
))}
</ul>
</div>
)}
</div>
)
}