fix(sase): search form not submitting — React form action → onSubmit
Both the VIN list and the user list used the React 19 server-action-
style <form action={fn}> pattern with a client function. In production
that didn't actually navigate — form submitted with no URL change, the
table stayed unfiltered.
Switch to plain onSubmit + controlled input (useState for the query
text). Clears now also resets the input value, not just the URL.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { useRouter, useSearchParams, usePathname } from "next/navigation";
|
||||
import { useTransition } from "react";
|
||||
import { useState, useTransition } from "react";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
@@ -29,6 +29,7 @@ export function UsersFilterBar({
|
||||
const pathname = usePathname();
|
||||
const sp = useSearchParams();
|
||||
const [pending, startTransition] = useTransition();
|
||||
const [query, setQuery] = useState(initial.q ?? "");
|
||||
|
||||
const current: UsersSearchParams = {
|
||||
q: sp.get("q") ?? undefined,
|
||||
@@ -47,6 +48,12 @@ export function UsersFilterBar({
|
||||
startTransition(() => router.push(href));
|
||||
}
|
||||
|
||||
function submitSearch(e: React.FormEvent<HTMLFormElement>) {
|
||||
e.preventDefault();
|
||||
const q = query.trim();
|
||||
nav({ q: q || undefined });
|
||||
}
|
||||
|
||||
function isPlanActive(id: string) {
|
||||
const v = current.plan;
|
||||
if (!v) return false;
|
||||
@@ -65,16 +72,11 @@ export function UsersFilterBar({
|
||||
|
||||
return (
|
||||
<div className="space-y-3 rounded-md border p-3">
|
||||
<form
|
||||
action={(fd) => {
|
||||
const q = String(fd.get("q") ?? "").trim();
|
||||
nav({ q: q || undefined });
|
||||
}}
|
||||
className="flex items-center gap-2"
|
||||
>
|
||||
<form onSubmit={submitSearch} className="flex items-center gap-2">
|
||||
<Input
|
||||
name="q"
|
||||
defaultValue={initial.q ?? ""}
|
||||
value={query}
|
||||
onChange={(e) => setQuery(e.target.value)}
|
||||
placeholder="Email, isim veya user ID ile ara…"
|
||||
className="max-w-md"
|
||||
/>
|
||||
@@ -86,7 +88,10 @@ export function UsersFilterBar({
|
||||
type="button"
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => router.push(pathname)}
|
||||
onClick={() => {
|
||||
setQuery("");
|
||||
router.push(pathname);
|
||||
}}
|
||||
>
|
||||
Temizle
|
||||
</Button>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { useRouter, useSearchParams, usePathname } from "next/navigation";
|
||||
import { useTransition } from "react";
|
||||
import { useState, useTransition } from "react";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
@@ -23,6 +23,7 @@ export function VinsFilterBar({ initial }: { initial: VinsSearchParams }) {
|
||||
const pathname = usePathname();
|
||||
const sp = useSearchParams();
|
||||
const [pending, startTransition] = useTransition();
|
||||
const [query, setQuery] = useState(initial.q ?? "");
|
||||
|
||||
const current: VinsSearchParams = {
|
||||
q: sp.get("q") ?? undefined,
|
||||
@@ -38,6 +39,12 @@ export function VinsFilterBar({ initial }: { initial: VinsSearchParams }) {
|
||||
startTransition(() => router.push(href));
|
||||
}
|
||||
|
||||
function submitSearch(e: React.FormEvent<HTMLFormElement>) {
|
||||
e.preventDefault();
|
||||
const q = query.trim();
|
||||
nav({ q: q || undefined });
|
||||
}
|
||||
|
||||
function isProviderActive(p: string) {
|
||||
const v = current.provider;
|
||||
if (!v) return false;
|
||||
@@ -46,28 +53,30 @@ export function VinsFilterBar({ initial }: { initial: VinsSearchParams }) {
|
||||
|
||||
return (
|
||||
<div className="space-y-3 rounded-md border p-3">
|
||||
<form
|
||||
action={(fd) => {
|
||||
const q = String(fd.get("q") ?? "").trim();
|
||||
nav({ q: q || undefined });
|
||||
}}
|
||||
className="flex items-center gap-2"
|
||||
>
|
||||
<form onSubmit={submitSearch} className="flex items-center gap-2">
|
||||
<Input
|
||||
name="q"
|
||||
defaultValue={initial.q ?? ""}
|
||||
value={query}
|
||||
onChange={(e) => setQuery(e.target.value)}
|
||||
placeholder="VIN veya email ile ara…"
|
||||
className="max-w-md"
|
||||
/>
|
||||
<Button type="submit" disabled={pending} size="sm">
|
||||
Ara
|
||||
</Button>
|
||||
{Object.values(current).some((v) => v !== undefined && v !== "") && (
|
||||
{(current.q ||
|
||||
current.provider ||
|
||||
current.success ||
|
||||
current.from ||
|
||||
current.to) && (
|
||||
<Button
|
||||
type="button"
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => router.push(pathname)}
|
||||
onClick={() => {
|
||||
setQuery("");
|
||||
router.push(pathname);
|
||||
}}
|
||||
>
|
||||
Temizle
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user