]> git.localhorst.tv Git - alttp.git/blob - resources/js/components/episodes/Filter.js
06dcf13f65501839f08090b58754c69d35fafa1f
[alttp.git] / resources / js / components / episodes / Filter.js
1 import axios from 'axios';
2 import moment from 'moment';
3 import PropTypes from 'prop-types';
4 import React from 'react';
5 import { Button } from 'react-bootstrap';
6
7 const Filter = ({ filter, setFilter }) => {
8         const [events, setEvents] = React.useState([]);
9
10         React.useEffect(() => {
11                 const controller = new AbortController();
12                 axios.get(`/api/events`, {
13                         signal: controller.signal,
14                         params: {
15                                 after: moment().startOf('day').subtract(7, 'days').toISOString(),
16                                 before: moment().startOf('day').add(8, 'days').toISOString(),
17                         },
18                 }).then(response => {
19                         const newEvents = (response.data || []).sort(
20                                 (a, b) => (a.short || a.title).localeCompare(b.short || b.title)
21                         );
22                         setEvents(newEvents);
23                 }).catch(e => {
24                         if (!axios.isCancel(e)) {
25                                 console.error(e);
26                         }
27                 });
28                 return () => {
29                         controller.abort();
30                 };
31         }, []);
32
33         const toggleEvent = React.useCallback(event => {
34                 const eventFilter = filter.event || [];
35                 if (eventFilter.includes(event.id)) {
36                         setFilter({
37                                 ...filter,
38                                 event: eventFilter.filter(id => id !== event.id && events.find(e => e.id === id)),
39                         });
40                 } else {
41                         setFilter({
42                                 ...filter,
43                                 event: [...eventFilter, event.id],
44                         });
45                 }
46         }, [events, filter, setFilter]);
47
48         const isEventSelected = React.useCallback(event => {
49                 const eventFilter = filter.event || [];
50                 return eventFilter.includes(event.id);
51         }, [filter]);
52
53         if (!events || !events.length) return null;
54
55         return <div className="episode-filter button-bar text-end">
56                 {events.map(event =>
57                         <Button
58                                 active={isEventSelected(event)}
59                                 key={event.id}
60                                 onClick={() => toggleEvent(event)}
61                                 title={event.short ? event.title : null}
62                                 variant="outline-secondary"
63                         >
64                                 {event.short || event.title}
65                         </Button>
66                 )}
67         </div>;
68 };
69
70 Filter.propTypes = {
71         filter: PropTypes.shape(),
72         setFilter: PropTypes.func,
73 };
74
75 export default Filter;