Add vendor search

Signed-off-by: gearnode <bryan@frimin.fr>
This commit is contained in:
gearnode
2025-02-12 08:48:57 -08:00
parent 725d24dc0f
commit 2c7449ef0f
3 changed files with 64 additions and 3 deletions

View File

@@ -20,6 +20,7 @@
"@radix-ui/react-tooltip": "^1.1.8",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"fuse.js": "^7.1.0",
"lucide-react": "^0.475.0",
"posthog-js": "^1.215.1",
"react": "^18.3.1",

View File

@@ -1,4 +1,4 @@
import { Suspense, useEffect } from "react";
import { Suspense, useEffect, useState } from "react";
import {
graphql,
PreloadedQuery,
@@ -10,6 +10,7 @@ import { Badge } from "@/components/ui/badge";
import { CircleUser, Globe, Shield, Store } from "lucide-react";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import Fuse from "fuse.js";
import type { VendorListQuery as VendorListQueryType } from "./__generated__/VendorListQuery.graphql";
const VendorListQuery = graphql`
@@ -32,13 +33,30 @@ const VendorListQuery = graphql`
}
`;
// TODO: Remove this once we have a real list of vendors
const vendorsList = [
{ id: '1', name: 'Amazon Web Services', createdAt: new Date().toISOString() },
{ id: '2', name: 'Google Cloud Platform', createdAt: new Date().toISOString() },
{ id: '3', name: 'Microsoft Azure', createdAt: new Date().toISOString() },
{ id: '4', name: 'Salesforce', createdAt: new Date().toISOString() },
{ id: '5', name: 'Slack', createdAt: new Date().toISOString() },
];
function VendorListContent({
queryRef,
}: {
queryRef: PreloadedQuery<VendorListQueryType>;
}) {
const data = usePreloadedQuery(VendorListQuery, queryRef);
const vendors = data.node.vendors?.edges.map(edge => edge?.node) ?? [];
const vendors = data.node?.vendors?.edges?.map(edge => edge?.node) ?? [];
const [searchTerm, setSearchTerm] = useState("");
const [filteredVendors, setFilteredVendors] = useState<Array<typeof vendors[0]>>([]);
const fuse = new Fuse(vendorsList, {
keys: ['name'],
threshold: 0.3,
});
return (
<div className="p-6 space-y-6">
@@ -61,12 +79,44 @@ function VendorListContent({
</div>
</div>
<div className="flex items-center gap-4">
<div className="flex gap-3">
<div className="flex flex-col gap-3 relative">
<Input
type="text"
placeholder="Type vendor's name"
className="w-64"
value={searchTerm}
onChange={(e) => {
const value = e.target.value;
setSearchTerm(value);
if (value.trim() === "") {
setFilteredVendors([]);
} else {
const results = fuse.search(value).map(result => result.item);
setFilteredVendors(results);
}
}}
/>
{searchTerm.trim() !== "" && filteredVendors.length > 0 && (
<div className="absolute top-full mt-1 w-64 max-h-48 overflow-y-auto rounded-md border bg-white shadow-lg z-10">
{filteredVendors.map((vendor) => (
<div
key={vendor?.id}
className="px-3 py-2 hover:bg-gray-100 cursor-pointer"
onClick={() => {
// Handle vendor selection
console.log('Selected vendor:', vendor);
setSearchTerm("");
setFilteredVendors([]);
}}
>
<div className="flex items-center gap-2">
<Store className="h-4 w-4" />
<span>{vendor?.name}</span>
</div>
</div>
))}
</div>
)}
<Button variant="secondary">
Search
<span className="ml-2">→</span>

10
package-lock.json generated
View File

@@ -28,6 +28,7 @@
"@radix-ui/react-tooltip": "^1.1.8",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"fuse.js": "^7.1.0",
"lucide-react": "^0.475.0",
"posthog-js": "^1.215.1",
"react": "^18.3.1",
@@ -3966,6 +3967,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/fuse.js": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-7.1.0.tgz",
"integrity": "sha512-trLf4SzuuUxfusZADLINj+dE8clK1frKdmqiJNb1Es75fmI5oY6X2mxLVUciLLjxqw/xr72Dhy+lER6dGd02FQ==",
"license": "Apache-2.0",
"engines": {
"node": ">=10"
}
},
"node_modules/gensync": {
"version": "1.0.0-beta.2",
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",