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';
7 import NotFound from './NotFound';
8 import CanonicalLinks from '../components/common/CanonicalLinks';
9 import ErrorBoundary from '../components/common/ErrorBoundary';
10 import ErrorMessage from '../components/common/ErrorMessage';
11 import Loading from '../components/common/Loading';
12 import Overview from '../components/techniques/Overview';
13 import { compareTranslation } from '../helpers/Technique';
14 import i18n from '../i18n';
16 const Techniques = ({ namespace, type }) => {
17 const [error, setError] = React.useState(null);
18 const [filter, setFilter] = React.useState({});
19 const [loading, setLoading] = React.useState(true);
20 const [techniques, setTechniques] = React.useState([]);
22 React.useEffect(() => {
23 const savedFilter = localStorage.getItem(`content.filter.${type}`);
25 setFilter(JSON.parse(savedFilter));
27 setFilter(filter => filter ? {} : filter);
31 const updateFilter = React.useCallback(newFilter => {
32 localStorage.setItem(`content.filter.${type}`, JSON.stringify(newFilter));
36 React.useEffect(() => {
37 const ctrl = new AbortController();
38 if (!techniques.length) {
42 .get(`/api/pages/${type}`, {
49 setTechniques(response.data.sort(compareTranslation('title', i18n.language)));
52 if (!axios.isCancel(error)) {
61 }, [filter, namespace, type]);
63 React.useEffect(() => {
64 setTechniques(t => [...t].sort(compareTranslation('title', i18n.language)));
65 }, [namespace, i18n.language]);
72 return <ErrorMessage error={error} />;
75 if (!techniques || !techniques.length) {
79 return <ErrorBoundary>
81 <title>{i18n.t(`${namespace}.heading`)}</title>
82 <meta name="description" content={i18n.t(`${namespace}.description`)} />
84 <CanonicalLinks base="/tech" />
88 setFilter={updateFilter}
89 techniques={techniques}
95 Techniques.propTypes = {
96 namespace: PropTypes.string,
97 type: PropTypes.string,
100 export default withTranslation()(Techniques);