]> git.localhorst.tv Git - alttp.git/blobdiff - resources/js/components/common/DiscordChannelSelect.js
round category select
[alttp.git] / resources / js / components / common / DiscordChannelSelect.js
diff --git a/resources/js/components/common/DiscordChannelSelect.js b/resources/js/components/common/DiscordChannelSelect.js
new file mode 100644 (file)
index 0000000..400ab9f
--- /dev/null
@@ -0,0 +1,74 @@
+import axios from 'axios';
+import PropTypes from 'prop-types';
+import React, { useCallback, useEffect, useState } from 'react';
+import { Form } from 'react-bootstrap';
+import { withTranslation } from 'react-i18next';
+
+import debounce from '../../helpers/debounce';
+import i18n from '../../i18n';
+
+const DiscordChannelSelect = ({
+       guild,
+       isInvalid,
+       name,
+       onBlur,
+       onChange,
+       types,
+       value,
+}) => {
+       const [results, setResults] = useState([]);
+
+       let ctrl = null;
+       const fetch = useCallback(debounce(async (guild, types) => {
+               if (ctrl) {
+                       ctrl.abort();
+               }
+               ctrl = new AbortController();
+               try {
+                       const response = await axios.get(`/api/discord-guilds/${guild}/channels`, {
+                               params: {
+                                       types,
+                               },
+                               signal: ctrl.signal,
+                       });
+                       ctrl = null;
+                       setResults(response.data);
+               } catch (e) {
+                       ctrl = null;
+                       console.error(e);
+               }
+               return () => {
+                       if (ctrl) ctrl.abort();
+               };
+       }, 300), []);
+
+       useEffect(() => {
+               fetch(guild, types);
+       }, [guild, ...types]);
+
+       return <Form.Select
+               isInvalid={isInvalid}
+               name={name}
+               onBlur={onBlur}
+               onChange={onChange}
+               type="search"
+               value={value}
+       >
+               <option value="">{i18n.t('tournaments.discordNoCategory')}</option>
+               {results && results.length ? results.map(result =>
+                       <option key={result.id} value={result.channel_id}>{result.name}</option>
+               ) : null}
+       </Form.Select>;
+};
+
+DiscordChannelSelect.propTypes = {
+       guild: PropTypes.string,
+       isInvalid: PropTypes.bool,
+       name: PropTypes.string,
+       onBlur: PropTypes.func,
+       onChange: PropTypes.func,
+       types: PropTypes.arrayOf(PropTypes.number),
+       value: PropTypes.string,
+};
+
+export default withTranslation()(DiscordChannelSelect);