import Spinner from '@components/admin/Spinner.js'; import { InputGroup, InputGroupAddon, InputGroupInput } from '@components/common/ui/InputGroup.js'; import { Search } from 'lucide-react'; import React, { useRef, useState } from 'react'; import { useQuery } from 'urql'; import { NoResult } from './search/NoResult.js'; import { Results } from './search/Results.js'; const useClickOutside = (ref, callback) => { const handleClick = (e) => { if (ref.current && !ref.current.contains(e.target)) { callback(); } }; React.useEffect(() => { document.addEventListener('click', handleClick); return () => { document.removeEventListener('click', handleClick); }; }); }; const SearchQuery = ` query Query ($filters: [FilterInput]) { customers(filters: $filters) { items { customerId uuid fullName email url: editUrl } } products(filters: $filters) { items { productId uuid sku name url: editUrl } } orders(filters: $filters) { items { orderId uuid orderNumber url: editUrl } } } `; interface SearchBoxProps { resourceLinks: { url: string; name: string; }[]; } export default function SearchBox({ resourceLinks }: SearchBoxProps) { const [keyword, setKeyword] = React.useState(''); const [showResult, setShowResult] = useState(false); const [loading, setLoading] = useState(false); const InputRef = useRef(null); const clickRef = React.useRef(null); const onClickOutside = () => { if (InputRef.current !== document.activeElement) { setShowResult(false); } }; useClickOutside(clickRef, onClickOutside); const [result, reexecuteQuery] = useQuery({ query: SearchQuery, variables: { filters: keyword ? [{ key: 'keyword', operation: 'eq', value: keyword }] : [] }, pause: true }); const { data, fetching } = result; React.useEffect(() => { setLoading(true); if (keyword) { setShowResult(true); } else { setShowResult(false); } const timer = setTimeout(() => { if (keyword) { reexecuteQuery({ requestPolicy: 'network-only' }); setLoading(false); } }, 1500); return () => clearTimeout(timer); }, [keyword]); return (
setKeyword(e.target.value)} /> {showResult && (
{(loading || fetching) && (
)} {!keyword && (
Search for products, order and other resources
)} {data?.products.items.length === 0 && data?.customers.items.length === 0 && data?.orders.items.length === 0 && keyword && !loading && ( )} {data && !loading && !fetching && (data?.products.items.length > 0 || data?.customers.items.length > 0 || data?.orders.items.length > 0) && ( )}
)}
); } export const layout = { areaId: 'header', sortOrder: 20 };