import { RefObject, useEffect, useState } from "react"; import { useIntl } from "react-intl"; import { DEFAULT_INITIAL_SEARCH_DATA } from "@saleor/config"; import { ChangeEvent, FormChange } from "@saleor/hooks/useForm"; import useModalDialogOpen from "@saleor/hooks/useModalDialogOpen"; import useNavigator from "@saleor/hooks/useNavigator"; import { maybe } from "@saleor/misc"; import { useOrderDraftCreateMutation } from "@saleor/orders/mutations"; import { orderUrl } from "@saleor/orders/urls"; import useCustomerSearch from "@saleor/searches/useCustomerSearch"; import getModeActions from "./modes"; import { getGqlOrderId, isQueryValidOrderNumber } from "./modes/orders"; import useCheckIfOrderExists from "./queries/useCheckIfOrderExists"; import { QuickSearchAction, QuickSearchMode } from "./types"; type UseQuickSearch = [ string, QuickSearchMode, FormChange, QuickSearchAction[] ]; function useQuickSearch( open: boolean, input: RefObject ): UseQuickSearch { const [query, setQuery] = useState(""); const [mode, setMode] = useState("default"); const intl = useIntl(); const navigate = useNavigator(); const [{ data: orderData }, getOrderData] = useCheckIfOrderExists(); const { result: customers, search: searchCustomers } = useCustomerSearch({ variables: { ...DEFAULT_INITIAL_SEARCH_DATA, first: 5 } }); const [createOrder] = useOrderDraftCreateMutation({ onCompleted: result => { if (result.draftOrderCreate.errors.length === 0) { navigate(orderUrl(result.draftOrderCreate.order.id)); } } }); useModalDialogOpen(open, { onClose: () => { setMode("default"); setQuery(""); } }); const handleBack = (event: KeyboardEvent) => { // `any` type because of poorly typed `KeyboardEvent.EventTarget` which // has no `value` key. Which it would have if `KeyboardEvent` and // `EventTarget` would be generic types accepting HTMLDOM element types. if ((event.target as any).value === "" && event.keyCode === 8) { setMode("default"); } }; useEffect(() => { setQuery(""); if (mode !== "default" && input.current) { input.current.addEventListener("keyup", handleBack); return () => { if (input.current) { input.current.removeEventListener("keyup", handleBack); } }; } }, [mode, open]); const change = (event: ChangeEvent) => { const value = event.target.value; if (mode === "default") { switch (value) { case "> ": setMode("commands"); break; case "@ ": setMode("customers"); break; case "# ": setMode("orders"); break; default: setQuery(value); } } else { if (mode === "orders" && isQueryValidOrderNumber(value)) { getOrderData(getGqlOrderId(value)); } setQuery(value); } if ((["customers", "default"] as QuickSearchMode[]).includes(mode)) { searchCustomers(value); } }; return [ query, mode, change, getModeActions( mode, query, intl, { customers: maybe( () => customers.data.search.edges.map(edge => edge.node), [] ), order: maybe(() => orderData.order) }, { createOrder, navigate } ) ]; } export default useQuickSearch;