UNPKG

charity-base-search

Version:

React component for CharityBase search input

225 lines (196 loc) 6.96 kB
'use strict'; exports.__esModule = true; exports.TextField = exports.Input = exports.HelperText = undefined; var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _propTypes = require('prop-types'); var _propTypes2 = _interopRequireDefault(_propTypes); var _lodash = require('lodash.debounce'); var _lodash2 = _interopRequireDefault(_lodash); var _filterSuggest = require('filter-suggest'); var _filterSuggest2 = _interopRequireDefault(_filterSuggest); var _search = require('./search.svg'); var _search2 = _interopRequireDefault(_search); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var DEBOUNCE_TIME = 100; var applyDebounced = (0, _lodash2.default)(function (f, x) { return f(x); }, DEBOUNCE_TIME); var QUERY = '\n query CBS_SEARCH_FILTERS(\n $search: String!\n $filterType: [String]\n ) {\n CHC {\n getFilters(\n search: $search\n filterType: $filterType\n ) {\n id\n value\n label\n filterType\n score\n }\n }\n }\n'; var getData = function getData(apiUrl, apiKey, variables) { return fetch(apiUrl + '?query=' + QUERY + '&variables=' + JSON.stringify(variables), { headers: { Authorization: 'Apikey ' + apiKey } }).then(function (x) { return x.json(); }); }; var getSearchItem = function getSearchItem(inputValue) { return { id: 'search-' + inputValue, value: inputValue, label: inputValue, filterType: 'search' }; }; var errorMessage = function errorMessage(_ref) { var error = _ref.error, empty = _ref.empty, loading = _ref.loading, searchTerm = _ref.searchTerm; if (error) { return 'Oops something went wrong, please try again'; } if (empty && searchTerm.length > 1 && !loading) { return 'Sorry we can\'t find anything matching \'' + searchTerm + '\''; } return null; }; var CharityBaseSearch = function CharityBaseSearch(_ref2) { var apiKey = _ref2.apiKey, apiUrl = _ref2.apiUrl, className = _ref2.className, filterTypes = _ref2.filterTypes, hideAcknowledgement = _ref2.hideAcknowledgement, label = _ref2.label, mapItem = _ref2.mapItem, menuClassName = _ref2.menuClassName, onBlur = _ref2.onBlur, onFocus = _ref2.onFocus, _onSelect = _ref2.onSelect, outlined = _ref2.outlined, style = _ref2.style, textFieldClassName = _ref2.textFieldClassName; var _useState = (0, _react.useState)(''), inputValue = _useState[0], setInputValue = _useState[1]; var _useState2 = (0, _react.useState)(''), debouncedInputValue = _useState2[0], setDebouncedInputValue = _useState2[1]; var _useState3 = (0, _react.useState)(null), data = _useState3[0], setData = _useState3[1]; var _useState4 = (0, _react.useState)(null), error = _useState4[0], setError = _useState4[1]; var _useState5 = (0, _react.useState)(false), loading = _useState5[0], setLoading = _useState5[1]; var onInputValueChange = function onInputValueChange(x) { var value = x || ''; setInputValue(value); applyDebounced(setDebouncedInputValue, value.trim()); }; (0, _react.useEffect)(function () { var ignore = false; if (debouncedInputValue) { var variables = { search: debouncedInputValue, filterType: filterTypes }; setLoading(true); getData(apiUrl, apiKey, variables).then(function (_ref3) { var data = _ref3.data, errors = _ref3.errors; if (ignore) return; if (errors) { // setData(null) return setError(errors[0].message); // graphql error } setError(null); setData(data); }).catch(function (error) { if (ignore) return; // setData(null) setError(error && error.message || 'Unknown error'); // probably network error }).then(function () { if (ignore) return; setLoading(false); }); } else { setError(null); setData(null); } return function () { ignore = true; }; }, [apiUrl, apiKey, debouncedInputValue, JSON.stringify(filterTypes)]); var syncItems = [getSearchItem(inputValue)].reduce(function (agg, x) { return filterTypes && filterTypes.indexOf(x.filterType) === -1 ? agg : [].concat(agg, [x]); }, []); var filterItems = data && data.CHC ? [].concat(syncItems, data.CHC.getFilters) : []; return _react2.default.createElement( 'div', { className: className, style: style }, hideAcknowledgement ? null : _react2.default.createElement( 'a', { className: 'cbs-acknowledgement', href: 'https://charitybase.uk', target: '_blank', rel: 'noopener noreferrer' }, 'Powered by CharityBase' ), _react2.default.createElement(_filterSuggest2.default, { errorMessage: errorMessage({ error: error, loading: loading, empty: filterItems.length === 0, searchTerm: debouncedInputValue }), inputValue: inputValue, items: filterItems.map(mapItem), label: label, leadingIcon: _react2.default.createElement('img', { width: 24, height: 24, src: _search2.default }), loading: loading, menuClassName: menuClassName, onBlur: onBlur, onFocus: onFocus, onInputValueChange: onInputValueChange, onSelect: function onSelect(item) { onInputValueChange(''); _onSelect(item); }, outlined: outlined, textFieldClassName: textFieldClassName }) ); }; CharityBaseSearch.propTypes = process.env.NODE_ENV !== "production" ? { apiKey: _propTypes2.default.string.isRequired, apiUrl: _propTypes2.default.string, className: _propTypes2.default.string, filterTypes: _propTypes2.default.array, hideAcknowledgement: _propTypes2.default.bool, label: _propTypes2.default.string, mapItem: _propTypes2.default.func, menuClassName: _propTypes2.default.string, onBlur: _propTypes2.default.func, onFocus: _propTypes2.default.func, onSelect: _propTypes2.default.func.isRequired, outlined: _propTypes2.default.bool, style: _propTypes2.default.object, textFieldClassName: _propTypes2.default.string } : {}; CharityBaseSearch.defaultProps = { apiUrl: 'https://charitybase.uk/api/graphql', label: 'Search charities', mapItem: function mapItem(_ref4) { var id = _ref4.id, filterType = _ref4.filterType, value = _ref4.value, label = _ref4.label; return { // __typename ? id: id, filterType: filterType, value: value, label: label, icon: null, primary: label, secondary: 'Filter by ' + filterType }; } }; exports.default = CharityBaseSearch; exports.HelperText = _filterSuggest.HelperText; exports.Input = _filterSuggest.Input; exports.TextField = _filterSuggest.TextField;