From 36b42c92e25a24c7db3b757de854bd6b2dc3e05e Mon Sep 17 00:00:00 2001 From: Nikita <39565703+nicitaacom@users.noreply.github.com> Date: Mon, 6 Nov 2023 20:01:13 +0100 Subject: [PATCH] search logic done --- app/(site)/page.tsx | 8 ++-- app/(site)/search/page.tsx | 39 +++++++++++++++++++ .../Navbar/components/NavbarSearch.tsx | 36 +++++++++++------ app/components/ui/Inputs/SearchInput.tsx | 37 ++++++++++++++++++ app/interfaces/types_db.ts | 2 +- 5 files changed, 105 insertions(+), 17 deletions(-) create mode 100644 app/(site)/search/page.tsx create mode 100644 app/components/ui/Inputs/SearchInput.tsx diff --git a/app/(site)/page.tsx b/app/(site)/page.tsx index ae3b500d..1248158e 100644 --- a/app/(site)/page.tsx +++ b/app/(site)/page.tsx @@ -3,11 +3,11 @@ import { Products } from "./components" import PaginationControls from "@/components/PaginationControls" import { ProductsPerPage } from "@/components/ProductsPerPage" -export default async function Home({ - searchParams, -}: { +interface SearchProps { searchParams: { [key: string]: string | string[] | undefined } -}) { +} + +export default async function Home({ searchParams }: SearchProps) { //Fetching all data from DB const products_response = await supabaseServer().from("products").select("*").order("price", { ascending: true }) if (products_response.error) throw products_response.error diff --git a/app/(site)/search/page.tsx b/app/(site)/search/page.tsx new file mode 100644 index 00000000..5f8544c0 --- /dev/null +++ b/app/(site)/search/page.tsx @@ -0,0 +1,39 @@ +import { Metadata } from "next" + +import supabaseServer from "@/libs/supabaseServer" + +import { Products } from "../components" + +interface SearchPageProps { + searchParams: { query: string } +} + +export function generateMetadata({ searchParams: { query } }: SearchPageProps): Metadata { + return { + title: `Search ${query} - Flowmazon`, + } +} + +export default async function SearchPage({ searchParams: { query } }: SearchPageProps) { + //https://github.com/nicitaacom/19_spotify-clone/blob/development/actions/getSongsByTitle.ts + //https://supabase.com/docs/reference/javascript/or + const products_response = await supabaseServer() + .from("products") + .select("*") + .or(`title.ilike.%${query}%,sub_title.ilike.%${query}%`) + .order("price", { ascending: true }) + if (products_response.error) throw products_response.error + const products = products_response.data + + if (products.length === 0) { + return
No products found
+ } + + return ( +
+
+ +
+
+ ) +} diff --git a/app/components/Navbar/components/NavbarSearch.tsx b/app/components/Navbar/components/NavbarSearch.tsx index c7e72035..f24a4631 100644 --- a/app/components/Navbar/components/NavbarSearch.tsx +++ b/app/components/Navbar/components/NavbarSearch.tsx @@ -1,19 +1,31 @@ -"use client" +import { BiSearchAlt } from "react-icons/bi" -import { Input } from "@/components/ui/Inputs" -import { useState } from "react" +import { redirect } from "next/navigation" +import { SearchInput } from "@/components/ui/Inputs/SearchInput" -import { BiSearchAlt } from "react-icons/bi" +async function searchProducts(formData: FormData) { + "use server" + + const searchQuery = formData.get("searchQuery")?.toString() + + if (searchQuery === "") { + redirect("/") + } + + if (searchQuery) { + redirect("/search?query=" + searchQuery) + } +} export function NavbarSearch() { - const [search, setSearch] = useState("") return ( - } - className="hidden tablet:flex w-[40vw] max-w-[600px]" - value={search} - onChange={e => setSearch(e.target.value)} - placeholder="Search..." - /> +
+ } + name="searchQuery" + placeholder="Search..." + /> + ) } diff --git a/app/components/ui/Inputs/SearchInput.tsx b/app/components/ui/Inputs/SearchInput.tsx new file mode 100644 index 00000000..e905fe85 --- /dev/null +++ b/app/components/ui/Inputs/SearchInput.tsx @@ -0,0 +1,37 @@ +import { type ChangeEvent } from "react" +import { twMerge } from "tailwind-merge" + +interface InputProps extends React.HTMLAttributes { + type?: string + className?: string + startIcon?: React.ReactElement + pattern?: string + name?: string + required?: boolean +} + +export function SearchInput({ + type = "text", + className = "", + startIcon, + pattern, + required = false, + name, + ...props +}: InputProps) { + return ( +
+
{startIcon}
+ +
+ ) +} diff --git a/app/interfaces/types_db.ts b/app/interfaces/types_db.ts index 84dc7c22..0c556be4 100644 --- a/app/interfaces/types_db.ts +++ b/app/interfaces/types_db.ts @@ -28,7 +28,7 @@ export interface Database { price: number price_id: string sub_title: string - title?: string + title: string } Update: { id?: string