+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);