]> git.localhorst.tv Git - alttp.git/blob - resources/js/components/pages/Techniques.js
add helmet
[alttp.git] / resources / js / components / pages / Techniques.js
1 import axios from 'axios';
2 import PropTypes from 'prop-types';
3 import React from 'react';
4 import { Helmet } from 'react-helmet';
5 import { withTranslation } from 'react-i18next';
6
7 import NotFound from './NotFound';
8 import ErrorBoundary from '../common/ErrorBoundary';
9 import ErrorMessage from '../common/ErrorMessage';
10 import Loading from '../common/Loading';
11 import Overview from '../techniques/Overview';
12 import { compareTranslation } from '../../helpers/Technique';
13 import i18n from '../../i18n';
14
15 const Techniques = ({ namespace, type }) => {
16         const [error, setError] = React.useState(null);
17         const [filter, setFilter] = React.useState({});
18         const [loading, setLoading] = React.useState(true);
19         const [techniques, setTechniques] = React.useState([]);
20
21         React.useEffect(() => {
22                 const savedFilter = localStorage.getItem(`content.filter.${type}`);
23                 if (savedFilter) {
24                         setFilter(JSON.parse(savedFilter));
25                 } else {
26                         setFilter(filter => filter ? {} : filter);
27                 }
28         }, [type]);
29
30         const updateFilter = React.useCallback(newFilter => {
31                 localStorage.setItem(`content.filter.${type}`, JSON.stringify(newFilter));
32                 setFilter(newFilter);
33         }, [type]);
34
35         React.useEffect(() => {
36                 const ctrl = new AbortController();
37                 if (!techniques.length) {
38                         setLoading(true);
39                 }
40                 axios
41                         .get(`/api/content`, {
42                                 params: {
43                                         type,
44                                         ...filter,
45                                 },
46                                 signal: ctrl.signal
47                         })
48                         .then(response => {
49                                 setError(null);
50                                 setLoading(false);
51                                 setTechniques(response.data.sort(compareTranslation('title', i18n.language)));
52                         })
53                         .catch(error => {
54                                 if (!axios.isCancel(error)) {
55                                         setError(error);
56                                         setLoading(false);
57                                         setTechniques([]);
58                                 }
59                         });
60                 return () => {
61                         ctrl.abort();
62                 };
63         }, [filter, namespace, type]);
64
65         React.useEffect(() => {
66                 setTechniques(t => [...t].sort(compareTranslation('title', i18n.language)));
67         }, [namespace, i18n.language]);
68
69         if (loading) {
70                 return <Loading />;
71         }
72
73         if (error) {
74                 return <ErrorMessage error={error} />;
75         }
76
77         if (!techniques || !techniques.length) {
78                 return <NotFound />;
79         }
80
81         return <ErrorBoundary>
82                 <Helmet>
83                         <title>{i18n.t(`${namespace}.heading`)}</title>
84                         <meta name="description" content={i18n.t(`${namespace}.description`)} />
85                 </Helmet>
86                 <Overview
87                         filter={filter}
88                         namespace={namespace}
89                         setFilter={updateFilter}
90                         techniques={techniques}
91                         type={type}
92                 />
93         </ErrorBoundary>;
94 };
95
96 Techniques.propTypes = {
97         namespace: PropTypes.string,
98         type: PropTypes.string,
99 };
100
101 export default withTranslation()(Techniques);