]> git.localhorst.tv Git - alttp.git/blobdiff - resources/js/components/pages/Techniques.js
more alternate/canonical links
[alttp.git] / resources / js / components / pages / Techniques.js
index 4bc0066baefd69654ac06f4ed678fc24230f89f8..ebeb6e5613e8f9067995bbdbde2b639f93365967 100644 (file)
@@ -1,9 +1,11 @@
 import axios from 'axios';
 import PropTypes from 'prop-types';
 import React from 'react';
+import { Helmet } from 'react-helmet';
 import { withTranslation } from 'react-i18next';
 
 import NotFound from './NotFound';
+import CanonicalLinks from '../common/CanonicalLinks';
 import ErrorBoundary from '../common/ErrorBoundary';
 import ErrorMessage from '../common/ErrorMessage';
 import Loading from '../common/Loading';
@@ -13,17 +15,34 @@ import i18n from '../../i18n';
 
 const Techniques = ({ namespace, type }) => {
        const [error, setError] = React.useState(null);
+       const [filter, setFilter] = React.useState({});
        const [loading, setLoading] = React.useState(true);
        const [techniques, setTechniques] = React.useState([]);
 
+       React.useEffect(() => {
+               const savedFilter = localStorage.getItem(`content.filter.${type}`);
+               if (savedFilter) {
+                       setFilter(JSON.parse(savedFilter));
+               } else {
+                       setFilter(filter => filter ? {} : filter);
+               }
+       }, [type]);
+
+       const updateFilter = React.useCallback(newFilter => {
+               localStorage.setItem(`content.filter.${type}`, JSON.stringify(newFilter));
+               setFilter(newFilter);
+       }, [type]);
+
        React.useEffect(() => {
                const ctrl = new AbortController();
-               setLoading(true);
-               window.document.title = i18n.t(`${namespace}.heading`);
+               if (!techniques.length) {
+                       setLoading(true);
+               }
                axios
                        .get(`/api/content`, {
                                params: {
                                        type,
+                                       ...filter,
                                },
                                signal: ctrl.signal
                        })
@@ -33,17 +52,18 @@ const Techniques = ({ namespace, type }) => {
                                setTechniques(response.data.sort(compareTranslation('title', i18n.language)));
                        })
                        .catch(error => {
-                               setError(error);
-                               setLoading(false);
-                               setTechniques([]);
+                               if (!axios.isCancel(error)) {
+                                       setError(error);
+                                       setLoading(false);
+                                       setTechniques([]);
+                               }
                        });
                return () => {
                        ctrl.abort();
                };
-       }, [namespace, type]);
+       }, [filter, namespace, type]);
 
        React.useEffect(() => {
-               window.document.title = i18n.t(`${namespace}.heading`);
                setTechniques(t => [...t].sort(compareTranslation('title', i18n.language)));
        }, [namespace, i18n.language]);
 
@@ -60,7 +80,18 @@ const Techniques = ({ namespace, type }) => {
        }
 
        return <ErrorBoundary>
-               <Overview namespace={namespace} techniques={techniques} />
+               <Helmet>
+                       <title>{i18n.t(`${namespace}.heading`)}</title>
+                       <meta name="description" content={i18n.t(`${namespace}.description`)} />
+               </Helmet>
+               <CanonicalLinks base="/tech" />
+               <Overview
+                       filter={filter}
+                       namespace={namespace}
+                       setFilter={updateFilter}
+                       techniques={techniques}
+                       type={type}
+               />
        </ErrorBoundary>;
 };