@@ -20,6 +20,7 @@
|
|||||||
"@radix-ui/react-tooltip": "^1.1.8",
|
"@radix-ui/react-tooltip": "^1.1.8",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
|
"fuse.js": "^7.1.0",
|
||||||
"lucide-react": "^0.475.0",
|
"lucide-react": "^0.475.0",
|
||||||
"posthog-js": "^1.215.1",
|
"posthog-js": "^1.215.1",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Suspense, useEffect } from "react";
|
import { Suspense, useEffect, useState } from "react";
|
||||||
import {
|
import {
|
||||||
graphql,
|
graphql,
|
||||||
PreloadedQuery,
|
PreloadedQuery,
|
||||||
@@ -10,6 +10,7 @@ import { Badge } from "@/components/ui/badge";
|
|||||||
import { CircleUser, Globe, Shield, Store } from "lucide-react";
|
import { CircleUser, Globe, Shield, Store } from "lucide-react";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
|
import Fuse from "fuse.js";
|
||||||
import type { VendorListQuery as VendorListQueryType } from "./__generated__/VendorListQuery.graphql";
|
import type { VendorListQuery as VendorListQueryType } from "./__generated__/VendorListQuery.graphql";
|
||||||
|
|
||||||
const 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({
|
function VendorListContent({
|
||||||
queryRef,
|
queryRef,
|
||||||
}: {
|
}: {
|
||||||
queryRef: PreloadedQuery<VendorListQueryType>;
|
queryRef: PreloadedQuery<VendorListQueryType>;
|
||||||
}) {
|
}) {
|
||||||
const data = usePreloadedQuery(VendorListQuery, queryRef);
|
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 (
|
return (
|
||||||
<div className="p-6 space-y-6">
|
<div className="p-6 space-y-6">
|
||||||
@@ -61,12 +79,44 @@ function VendorListContent({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-4">
|
<div className="flex items-center gap-4">
|
||||||
<div className="flex gap-3">
|
<div className="flex flex-col gap-3 relative">
|
||||||
<Input
|
<Input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Type vendor's name"
|
placeholder="Type vendor's name"
|
||||||
className="w-64"
|
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">
|
<Button variant="secondary">
|
||||||
Search
|
Search
|
||||||
<span className="ml-2">→</span>
|
<span className="ml-2">→</span>
|
||||||
|
|||||||
10
package-lock.json
generated
10
package-lock.json
generated
@@ -28,6 +28,7 @@
|
|||||||
"@radix-ui/react-tooltip": "^1.1.8",
|
"@radix-ui/react-tooltip": "^1.1.8",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
|
"fuse.js": "^7.1.0",
|
||||||
"lucide-react": "^0.475.0",
|
"lucide-react": "^0.475.0",
|
||||||
"posthog-js": "^1.215.1",
|
"posthog-js": "^1.215.1",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
@@ -3966,6 +3967,15 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"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": {
|
"node_modules/gensync": {
|
||||||
"version": "1.0.0-beta.2",
|
"version": "1.0.0-beta.2",
|
||||||
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
|
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
|
||||||
|
|||||||
Reference in New Issue
Block a user