]> git.localhorst.tv Git - alttp.git/blob - resources/js/components/common/DiscordChannelSelect.js
round category select
[alttp.git] / resources / js / components / common / DiscordChannelSelect.js
1 import axios from 'axios';
2 import PropTypes from 'prop-types';
3 import React, { useCallback, useEffect, useState } from 'react';
4 import { Form } from 'react-bootstrap';
5 import { withTranslation } from 'react-i18next';
6
7 import debounce from '../../helpers/debounce';
8 import i18n from '../../i18n';
9
10 const DiscordChannelSelect = ({
11         guild,
12         isInvalid,
13         name,
14         onBlur,
15         onChange,
16         types,
17         value,
18 }) => {
19         const [results, setResults] = useState([]);
20
21         let ctrl = null;
22         const fetch = useCallback(debounce(async (guild, types) => {
23                 if (ctrl) {
24                         ctrl.abort();
25                 }
26                 ctrl = new AbortController();
27                 try {
28                         const response = await axios.get(`/api/discord-guilds/${guild}/channels`, {
29                                 params: {
30                                         types,
31                                 },
32                                 signal: ctrl.signal,
33                         });
34                         ctrl = null;
35                         setResults(response.data);
36                 } catch (e) {
37                         ctrl = null;
38                         console.error(e);
39                 }
40                 return () => {
41                         if (ctrl) ctrl.abort();
42                 };
43         }, 300), []);
44
45         useEffect(() => {
46                 fetch(guild, types);
47         }, [guild, ...types]);
48
49         return <Form.Select
50                 isInvalid={isInvalid}
51                 name={name}
52                 onBlur={onBlur}
53                 onChange={onChange}
54                 type="search"
55                 value={value}
56         >
57                 <option value="">{i18n.t('tournaments.discordNoCategory')}</option>
58                 {results && results.length ? results.map(result =>
59                         <option key={result.id} value={result.channel_id}>{result.name}</option>
60                 ) : null}
61         </Form.Select>;
62 };
63
64 DiscordChannelSelect.propTypes = {
65         guild: PropTypes.string,
66         isInvalid: PropTypes.bool,
67         name: PropTypes.string,
68         onBlur: PropTypes.func,
69         onChange: PropTypes.func,
70         types: PropTypes.arrayOf(PropTypes.number),
71         value: PropTypes.string,
72 };
73
74 export default withTranslation()(DiscordChannelSelect);