X-Git-Url: https://git.localhorst.tv/?a=blobdiff_plain;ds=sidebyside;f=resources%2Fjs%2Fcomponents%2Fcommon%2FUserSelect.js;fp=resources%2Fjs%2Fcomponents%2Fcommon%2FUserSelect.js;h=be473b66e5fafe8d61d13251daa54f723752d05c;hb=c5b15dc5518c627daa4f02f653ff900e4fe13db7;hp=0000000000000000000000000000000000000000;hpb=75951b15b6f61268c223906b60babf414c01cc2d;p=alttp.git diff --git a/resources/js/components/common/UserSelect.js b/resources/js/components/common/UserSelect.js new file mode 100644 index 0000000..be473b6 --- /dev/null +++ b/resources/js/components/common/UserSelect.js @@ -0,0 +1,118 @@ +import axios from 'axios'; +import PropTypes from 'prop-types'; +import React, { useCallback, useEffect, useRef, useState } from 'react'; +import { Button, Form, ListGroup } from 'react-bootstrap'; + +import Icon from '../common/Icon'; +import UserBox from '../users/Box'; +import debounce from '../../helpers/debounce'; + +const UserSelect = ({ name, onChange, value }) => { + const [resolved, setResolved] = useState(null); + const [results, setResults] = useState([]); + const [search, setSearch] = useState(''); + const [showResults, setShowResults] = useState(false); + + const ref = useRef(null); + + useEffect(() => { + const handleEventOutside = e => { + if (ref.current && !ref.current.contains(e.target)) { + setShowResults(false); + } + }; + document.addEventListener('click', handleEventOutside, true); + document.addEventListener('focus', handleEventOutside, true); + return () => { + document.removeEventListener('click', handleEventOutside, true); + document.removeEventListener('focus', handleEventOutside, true); + }; + }, []); + + let ctrl = null; + const fetch = useCallback(debounce(async phrase => { + if (ctrl) { + ctrl.abort(); + } + ctrl = new AbortController(); + if (!phrase || phrase.length < 3) { + setResults([]); + return; + } + try { + const response = await axios.get(`/api/users`, { + params: { + phrase, + }, + signal: ctrl.signal, + }); + ctrl = null; + setResults(response.data); + } catch (e) { + ctrl = null; + console.error(e); + } + }, 300), []); + + useEffect(() => { + fetch(search); + }, [search]); + + useEffect(() => { + if (value) { + axios + .get(`/api/users/${value}`) + .then(response => { + setResolved(response.data); + }); + } else { + setResolved(null); + } + }, [value]); + + if (value) { + return
+ {resolved ? : value} + +
; + } + return
+ setSearch(e.target.value)} + onFocus={() => setShowResults(true)} + type="search" + value={search} + /> +
+ + {results.map(result => + onChange({ + target: { name, value: result.id }, + })} + > + + + )} + +
+
; +}; + +UserSelect.propTypes = { + name: PropTypes.string, + onChange: PropTypes.func, + value: PropTypes.string, +}; + +export default UserSelect;