Files

56 lines
1.9 KiB
TypeScript

'use client'
import { useRouter, usePathname, useSearchParams } from 'next/navigation'
import { useTransition, useRef } from 'react'
export default function LiveFilterForm({ children }: { children: React.ReactNode }) {
const router = useRouter()
const pathname = usePathname()
const searchParams = useSearchParams()
const [isPending, startTransition] = useTransition()
const debounceTimer = useRef<NodeJS.Timeout | null>(null)
function updateRoute(form: HTMLFormElement) {
const formData = new FormData(form)
const params = new URLSearchParams(searchParams.toString())
const search = formData.get('search') as string
const neighborhood = formData.get('neighborhood') as string
const price = formData.get('price') as string
const approved = formData.get('approved') as string
if (search) params.set('search', search)
else params.delete('search')
if (neighborhood) params.set('neighborhood', neighborhood)
else params.delete('neighborhood')
if (price) params.set('price', price)
else params.delete('price')
if (approved) params.set('approved', 'true')
else params.delete('approved')
startTransition(() => {
router.push(`${pathname}?${params.toString()}`, { scroll: false })
})
}
function onChange(e: React.FormEvent<HTMLFormElement>) {
const form = e.currentTarget
if (debounceTimer.current) clearTimeout(debounceTimer.current)
debounceTimer.current = setTimeout(() => {
updateRoute(form)
}, 300)
}
return (
<form onChange={onChange} onSubmit={(e) => { e.preventDefault(); updateRoute(e.currentTarget); }} className="grid grid-cols-1 sm:grid-cols-4 gap-4 items-end relative">
{children}
{isPending && (
<div className="absolute inset-0 bg-stone/20 backdrop-blur-[1px] flex items-center justify-center z-10 rounded-xl transition-all" />
)}
</form>
)
}