import React, { useState, useEffect, useReducer } from 'react'; import { Switch, Route, Link, useParams, useHistory } from 'react-router-dom'; import './light.css'; import { Button, Container, Dropdown, Grid, Header, Icon, Image, Input, Item, Segment, Table } from 'semantic-ui-react'; import { statusColor, isAdmin, isInstructor, BasicTable, staticUrl, requester } from './utils.js'; import { NotFound } from './Misc.js'; import { AdminMemberInfo, AdminMemberPause, AdminMemberForm, AdminMemberCards, AdminMemberTraining, AdminMemberCertifications } from './AdminMembers.js'; import { AdminMemberTransactions } from './AdminTransactions.js'; import { AdminHistory } from './Admin.js'; import { StorageButton } from './Storage.js'; import AbortController from 'abort-controller'; const memberSorts = { recently_vetted: 'Recently Vetted', last_scanned: 'Last Scanned', pinball_score: 'Pinball Score', newest_active: 'Newest', //newest_overall: 'Newest Overall', oldest_active: 'Oldest', //oldest_overall: 'Oldest Overall', recently_inactive: 'Recently Inactive', is_director: 'Directors', is_instructor: 'Instructors', due: 'Due', overdue: 'Overdue', storage: 'Storage', everyone: 'Everyone', }; export function MembersDropdown(props) { const { token, name, onChange, value, initial, autofocus, filterActive } = props; const [response, setResponse] = useState({ results: [] }); const searchDefault = {seq: 0, q: initial || '', sort: 'newest_active'}; const [search, setSearch] = useState(searchDefault); useEffect(() => { requester('/search/', 'POST', token, search) .then(res => { if (!search.seq || res.seq > response.seq) { if (filterActive) { setResponse({...res, results: res.results.filter(x => ['Prepaid', 'Current', 'Due', 'Overdue'].includes(x.member.status))}); } else { setResponse(res); } } }) .catch(err => { console.log(err); }); }, [search]); const options = response.results.map((x, i) => ({ key: x.member.id, value: x.member.id, text: x.member.preferred_name + ' ' + x.member.last_name, image: { avatar: true, src: x.member.photo_small ? staticUrl + '/' + x.member.photo_small : '/nophoto.png' }, })); return ( setSearch({seq: parseInt(e.timeStamp), q: v.searchQuery, sort: 'newest_active'})} searchInput={{ autoFocus: autofocus }} openOnFocus={!autofocus} /> ); }; let responseCache = false; let pageCache = 0; let sortCache = ''; let searchCache = ''; const loadMoreStrings = [ 'Load More', 'Load EVEN More', 'Load WAY More', 'Why did you stop? LOAD MORE!', 'GIVE ME MORE NAMES!!', 'Shower me with names, baby', 'I don\'t care about the poor server, MORE NAMES!', 'Names make me hotter than two rats in a wool sock', 'Holy shit, I can\'t get enough names', 'I don\'t have anything better to do than LOAD NAMES!', 'I need names because I love N̶a̸M̸E̵S̴ it\'s not to late to stop but I can\'t because it feels so good god help me', 'The One who loads the names will liquify the NERVES of the sentient whilst I o̴̭̐b̴̙̾s̷̺͝ē̶̟r̷̦̓v̸͚̐ę̸̈́ ̷̞̒t̸͘ͅh̴͂͜e̵̜̕i̶̾͜r̷̃͜ ̵̹͊Ḷ̷͝Ȍ̸͚Ä̶̘́D̴̰́I̸̧̚N̵͖̎G̷̣͒', 'The Song of Names will will e̶̟̤͋x̷̜̀͘͜t̴̳̀i̸̪͑̇n̷̘̍g̵̥̗̓ṳ̴̑̈́i̷͚̿s̸̨̪̓ḣ̶̡̓ ̷̲͊ṫ̴̫h̸̙͕͗ḛ̸̡̃̈́ ̷̘̫̉̏v̸̧̟͗̕o̴͕̾͜i̷̢͛̿ͅc̴͕̥̈́̂ȅ̵͕s̶̹͋̀ ̶̰́͜͠ǒ̷̰̯f̵̛̥̊ ̸̟̟̒͝m̸̯̀̂o̶̝͛̌͜r̸̞̀ṫ̴̥͗ä̶̢́l̶̯̄͘ ̵̫̈́m̷̦̑̂ą̶͕͝ṋ̴̎͝ from the sphere I can see it can you see it it is beautiful', 'The final suffering of T̷̯̂͝H̴̰̏̉Ḛ̸̀̓ ̷̟̒ͅN̷̠̾Ą̵̟̈́M̶̡̾͝E̸̥̟̐͐S̸̖̍ are lies all is lost the pony he come h̷̲̺͂̾͒̔͝ḙ̶̻͒͠ ̷̙̘͈̬̰̽̽̈́̒͘c̵͎̺̞̰͝ơ̷͚̱̺̰̺͐̏͑͠m̴̖̰̓̈͝ĕ̷̜s̶̛̹̤̦͉̓͝ the í̵̠̞̙̦̱̠̅̊͒̌͊̓͠͠c̴̻̺̙͕̲͚͔̩̥͑ḩ̷̦̰̠̯̳̖̘́̉̾̾͠o̴͈̯̟̣̲͙̦̖̖͍̞̞̻̎͐̊͊̇͋̒͛̅͆̌͂̈̕r̷̡̝̲̜͇͉̣̹̖͕̻̐̑̉̋͋̉͒͋̍́̒͐͐͘ͅ ̵̳̖͕̩̝̮͈̻̣̤͎̟͓̜̄̿̓̈́p̴̰̝͓̣͍̫̞͓̑͌͊͑̓̂̽͑͝e̶̛̪̜̐̋́̆͊͌̋̄́͘r̶̫̬͈͌̔̽m̶̛̱̣͍͌̈́͋̾̈̀͑̽̋̏̊͋͝ę̶̋̀̈̃͠ą̵̡̣̫̮͙͈͚̞̰̠̥͇̣̽̿̉́̔̒͌̓͌̂̌̕͜͠t̷̯͚̭̮̠̐͋͆́͛̿́̏̆̚ě̶̢̨̩̞ş̸̢͍̱̻͕̪̗̻͖͇̱̳̽̈́̚͠ ̴͉̝̖̤͚̖̩̻̪̒ͅà̸̙̥̩̠̝̪̰͋́̊̓͌́͒̕͝ĺ̵̖̖͚̱͎̤̟̲̺͎͑͋̐̈́̓͂͆̅̈́̎̆̋̇l̸̢̧̟͉̞͇̱͉̙͇͊̏͐͠ͅ', ]; export function Members(props) { const [response, setResponse] = useState(responseCache); const [loading, setLoading] = useState(false); const [page, setPage] = useState(pageCache); const [sort, setSort] = useState(sortCache); const [search, setSearch] = useState(searchCache); const [controller, setController] = useState(false); const { token, user } = props; const history = useHistory(); const makeRequest = ({loadPage, q, sort_key}) => { let pageNum = 0; if (loadPage) { pageNum = page + 1; setPage(pageNum); pageCache = pageNum; } else { setResponse(false); setPage(0); pageCache = 0; } if (controller) { controller.abort(); } const ctl = new AbortController(); setController(ctl); const signal = ctl.signal; const data = {page: pageNum}; if (q) data.q = q; if (sort_key) data.sort = sort_key; requester('/search/', 'POST', token, data, signal) .then(res => { const r = loadPage ? {...response, results: [...response.results, ...res.results]} : res; setResponse(r); responseCache = r; setLoading(false); }) .catch(err => { console.log('Aborted.'); }); } const loadMore = () => { setLoading(true); makeRequest({loadPage: true, q: search, sort_key: sort}); }; const doSort = (sort_key) => { setSort(sort_key); sortCache = sort_key; setSearch(''); searchCache = ''; makeRequest({loadPage: false, sort_key: sort_key}); }; const doSearch = (q) => { if (q) { setSearch(q); searchCache = q; setSort(''); sortCache = ''; makeRequest({loadPage: false, q: q}); } else { doSort('recently_vetted'); } }; const handleChange = (event) => { const q = event.target.value; doSearch(q); }; useEffect(() => { if (!responseCache) { doSort('recently_vetted'); } }, []); return (
Member List

Search by name, email, Spacebar username, member ID, or member shelf:

{search.length ? } { !isMe && isSponsoring && } {isInstructor(user) && !isAdmin(user) && } :

Loading...

: }
); };