Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
ethanniser committed Oct 18, 2024
2 parents b40d7e3 + f39010e commit d6d873f
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 50 deletions.
83 changes: 33 additions & 50 deletions src/components/search-dropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,49 +1,30 @@
"use client";

import { useState } from "react";
import { useEffect, useState } from "react";
import { Input } from "@/components/ui/input";
import { ScrollArea } from "@/components/ui/scroll-area";
import { Search, X } from "lucide-react";
import Image from "next/image";
import { cn } from "@/lib/utils";
import { Product } from "../db/schema";
import { searchProducts } from "../lib/actions";
import Link from "next/link";

type Item = {
id: string;
name: string;
icon: string;
};

const items: Item[] = [
{ id: "1", name: "aluminum", icon: "/placeholder.svg?height=40&width=40" },
{
id: "2",
name: "aluminum extrusions",
icon: "/placeholder.svg?height=40&width=40",
},
{
id: "3",
name: "aluminum tubing",
icon: "/placeholder.svg?height=40&width=40",
},
{
id: "4",
name: "allen wrenches",
icon: "/placeholder.svg?height=40&width=40",
},
{
id: "5",
name: "all thread rods",
icon: "/placeholder.svg?height=40&width=40",
},
];
type SearchResult = Product & { href: string };

export function SearchDropdownComponent() {
const [searchTerm, setSearchTerm] = useState("");
const [filteredItems, setFilteredItems] = useState<SearchResult[]>([]);
const [isOpen, setIsOpen] = useState(false);

const filteredItems = items.filter((item) =>
item.name.toLowerCase().includes(searchTerm.toLowerCase()),
);
useEffect(() => {
const search = async () => {
const results = await searchProducts(searchTerm);
setFilteredItems(results);
};

search();
}, [searchTerm]);

return (
<div className="font-sans">
Expand Down Expand Up @@ -77,23 +58,25 @@ export function SearchDropdownComponent() {
<div className="absolute z-10 mt-1 w-full rounded-md border border-gray-200 bg-white shadow-lg">
<ScrollArea className="h-[300px]">
{filteredItems.map((item) => (
<div
key={item.id}
className="flex cursor-pointer items-center p-2 hover:bg-gray-100"
onClick={() => {
setSearchTerm(item.name);
setIsOpen(false);
}}
>
<Image
src={item.icon}
alt=""
className="h-10 w-10 pr-2"
height={40}
width={40}
/>
<span className="text-sm">{item.name}</span>
</div>
<Link href={item.href}>
<div
key={item.slug}
className="flex cursor-pointer items-center p-2 hover:bg-gray-100"
onClick={() => {
setSearchTerm(item.name);
setIsOpen(false);
}}
>
<Image
src={item.icon}

Check failure on line 71 in src/components/search-dropdown.tsx

View workflow job for this annotation

GitHub Actions / typecheck

Property 'icon' does not exist on type 'SearchResult'.
alt=""
className="h-10 w-10 pr-2"
height={40}
width={40}
/>
<span className="text-sm">{item.name}</span>
</div>
</Link>
))}
</ScrollArea>
</div>
Expand Down
38 changes: 38 additions & 0 deletions src/lib/actions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
"use server";
import { sql } from "drizzle-orm";
import { db } from "../db";
import {
categories,
products,
subcategories,
subcollection,
} from "../db/schema";
import { getCart, updateCart } from "./cart";

export async function addToCart(prevState: unknown, formData: FormData) {
Expand Down Expand Up @@ -35,3 +43,33 @@ export async function addToCart(prevState: unknown, formData: FormData) {

return "Item added to cart";
}

export async function searchProducts(searchTerm: string) {
const results = await db
.select()
.from(products)
.where(
sql`to_tsvector('english', ${products.name}) @@ plainto_tsquery('english', ${searchTerm})`,
)
.limit(5)
.innerJoin(
subcategories,
sql`${products.subcategory_slug} = ${subcategories.slug}`,
)
.innerJoin(
subcollection,
sql`${subcategories.subcollection_id} = ${subcollection.id}`,
)
.innerJoin(
categories,
sql`${subcollection.category_slug} = ${categories.slug}`,
);

return results.map((item) => {
const href = `/products/${item.categories.slug}/${item.subcategories.slug}/${item.products.slug}`;
return {
...item.products,
href,
};
});
}

0 comments on commit d6d873f

Please sign in to comment.