seach bar addded in form

This commit is contained in:
2025-05-15 23:08:16 +05:30
parent ffe239783f
commit 7727ad862c
3 changed files with 82 additions and 64 deletions

View File

@@ -76,6 +76,7 @@
"tailwindcss": "^3.4.17",
"tailwindcss-animate": "^1.0.7",
"tw-animate-css": "^1.2.5",
"use-debounce": "^10.0.4",
"vaul": "^1.1.2",
"wouter": "^3.7.0",
"ws": "^8.18.0",

View File

@@ -1,4 +1,4 @@
import { useEffect } from "react";
import { useEffect, useMemo, useRef, useState } from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { format } from "date-fns";
@@ -31,7 +31,7 @@ import { CalendarIcon, Clock } from "lucide-react";
import { cn } from "@/lib/utils";
import { useQuery } from "@tanstack/react-query";
import { useAuth } from "@/hooks/use-auth";
import { useDebounce } from "use-debounce";
import {
AppointmentUncheckedCreateInputObjectSchema,
PatientUncheckedCreateInputObjectSchema,
@@ -83,6 +83,15 @@ export function AppointmentForm({
isLoading = false,
}: AppointmentFormProps) {
const { user } = useAuth();
const inputRef = useRef<HTMLInputElement>(null);
useEffect(() => {
const timeout = setTimeout(() => {
inputRef.current?.focus();
}, 50); // small delay ensures content is mounted
return () => clearTimeout(timeout);
}, []);
const { data: staffMembersRaw = [] as Staff[], isLoading: isLoadingStaff } =
useQuery<Staff[]>({
@@ -163,6 +172,24 @@ export function AppointmentForm({
defaultValues,
});
const [searchTerm, setSearchTerm] = useState("");
const [debouncedSearchTerm] = useDebounce(searchTerm, 200); // 1 seconds
const [filteredPatients, setFilteredPatients] = useState(patients);
useEffect(() => {
if (!debouncedSearchTerm.trim()) {
setFilteredPatients(patients);
} else {
const term = debouncedSearchTerm.toLowerCase();
setFilteredPatients(
patients.filter((p) =>
`${p.firstName} ${p.lastName} ${p.phone} ${p.dob}`.toLowerCase().includes(term)
)
);
}
}, [debouncedSearchTerm, patients]);
// Force form field values to update and clean up storage
useEffect(() => {
if (parsedStoredData) {
@@ -277,14 +304,45 @@ export function AppointmentForm({
</SelectTrigger>
</FormControl>
<SelectContent>
{patients.map((patient) => (
<SelectItem
key={patient.id}
value={patient.id.toString()}
>
{patient.firstName} {patient.lastName}
</SelectItem>
))}
<div className="p-2" onKeyDown={(e) => e.stopPropagation()}>
<Input
ref={inputRef}
placeholder="Search patients..."
className="w-full"
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
onKeyDown={(e) => {
const navKeys = ['ArrowDown', 'ArrowUp', 'Enter'];
if (!navKeys.includes(e.key)) {
e.stopPropagation(); // Only stop keys that affect select state
}
}}
/>
</div>
<div className="max-h-60 overflow-y-auto scrollbar-thin scrollbar-thumb-muted-foreground/30">
{filteredPatients.length > 0 ? (
filteredPatients.map((patient) => (
<SelectItem
key={patient.id}
value={patient.id.toString()}
><div className="flex flex-col">
<span className="font-medium">
{patient.firstName} {patient.lastName}
</span>
<span className="text-xs text-muted-foreground">
DOB: {new Date(patient.dateOfBirth).toLocaleDateString()} {patient.phone}
</span>
</div>
</SelectItem>
))
) : (
<div className="p-2 text-muted-foreground text-sm">
No patients found
</div>
)}
</div>
</SelectContent>
</Select>
<FormMessage />