appdev_with_generative_ai/src/knowledge-drive/components/SearchInput.tsx (102 lines of code) (raw):

"use client"; import { AiOutlineSearch } from "react-icons/ai"; import { Input } from "./ui/input"; import { IoMdOptions } from "react-icons/io"; import * as z from "zod"; import { zodResolver } from "@hookform/resolvers/zod"; import { useForm } from "react-hook-form"; import { Form, FormControl, FormField, FormItem, FormMessage } from "./ui/form"; import SearchDialog from "./SearchDialog"; import { useState } from "react"; import { useRouter, useSearchParams } from "next/navigation"; import { User } from "firebase/auth"; const formSchema = z.object({ query: z .string({ required_error: "検索条件を入力してください" }) .min(3, { message: "3 文字以上、70 文字以下で入力してください", }) .max(50, { message: "3 文字以上、70 文字以下で入力してください", }), }); type SearchInputProps = { csrfToken: string; user: User; }; const SearchInput = ({ csrfToken, user }: SearchInputProps) => { const [searchDialogOpen, setSearchDialogOpen] = useState(false); const [isLLMSearch, setIsLLMSearch] = useState(false); const router = useRouter(); const searchParams = useSearchParams(); const search = searchParams.get("q") || ""; const form = useForm<z.infer<typeof formSchema>>({ resolver: zodResolver(formSchema), defaultValues: { query: search, }, }); function onSubmit(values: z.infer<typeof formSchema>) { const query = form.getValues("query"); if (!query) return; if (isLLMSearch) { setSearchDialogOpen(true); return; } router.replace(`/search?q=${query}`); } const toggleFormType = () => { setIsLLMSearch(!isLLMSearch); }; return ( <div className="grow"> <div className={`grow flex rounded-full items-center border border-transparent h-12 min-w-[500px] max-w-[722px] ${ isLLMSearch ? "bg-[#ebdbff]" : "bg-[#edf2fc]" }`} > <div className={`w-14 h-[46px] my-0 mx-[5px] p-0 rounded-full text-black ${ isLLMSearch ? "bg-[#ebdbff]" : "bg-[#edf2fc]" }`} > <AiOutlineSearch size={40} className="p-2 m-[3px]" /> </div> <Form {...form}> <form onSubmit={form.handleSubmit(onSubmit)}> <FormField control={form.control} name="query" render={({ field }) => ( <FormItem> <FormControl> <Input className={`border-none w-[600px] text-[16px] focus-visible:ring-0 focus-visible:ring-offset-0 ${ isLLMSearch ? "bg-[#ebdbff]" : "bg-[#edf2fc]" }`} placeholder={ isLLMSearch ? "質問文を入力" : "ファイル名/フォルダ名で検索" } maxLength={70} {...field} /> </FormControl> </FormItem> )} /> </form> </Form> <div> <IoMdOptions size={40} className="p-[8px] m-[3px]" /> </div> </div> <SearchDialog open={searchDialogOpen} onOpenChange={setSearchDialogOpen} query={form.getValues("query")} csrfToken={csrfToken} user={user} /> </div> ); }; export default SearchInput;