]> git.localhorst.tv Git - alttp.git/blobdiff - resources/js/components/pages/Technique.js
basic content editing
[alttp.git] / resources / js / components / pages / Technique.js
index c4be0666614eb932d5c22e5ae8ccbf0ffd3dc23b..32acd284f56fcd5f4250432ed7c4368e4ced245c 100644 (file)
@@ -1,8 +1,10 @@
 import axios from 'axios';
+import PropTypes from 'prop-types';
 import React, { useEffect, useState } from 'react';
 import { Helmet } from 'react-helmet';
 import { withTranslation } from 'react-i18next';
 import { useParams } from 'react-router-dom';
+import toastr from 'toastr';
 
 import CanonicalLinks from '../common/CanonicalLinks';
 import ErrorBoundary from '../common/ErrorBoundary';
@@ -10,22 +12,52 @@ import ErrorMessage from '../common/ErrorMessage';
 import Loading from '../common/Loading';
 import NotFound from '../pages/NotFound';
 import Detail from '../techniques/Detail';
+import Dialog from '../techniques/Dialog';
+import {
+       mayEditContent,
+} from '../../helpers/permissions';
 import { getLanguages, getMatchedLocale, getTranslation } from '../../helpers/Technique';
+import { useUser } from '../../helpers/UserContext';
 import i18n from '../../i18n';
 
-const Technique = () => {
+const Technique = ({ type }) => {
        const params = useParams();
        const { name } = params;
+       const user = useUser();
 
        const [error, setError] = useState(null);
        const [loading, setLoading] = useState(true);
        const [technique, setTechnique] = useState(null);
 
+       const [editContent, setEditContent] = useState(null);
+       const [showContentDialog, setShowContentDialog] = useState(false);
+
+       const actions = React.useMemo(() => ({
+               editContent: mayEditContent(user) ? content => {
+                       setEditContent(content);
+                       setShowContentDialog(true);
+               } : null,
+       }), [user]);
+
+       const saveContent = React.useCallback(async values => {
+               try {
+                       const response = await axios.put(`/api/content/${values.id}`, {
+                               parent_id: technique.id,
+                               ...values,
+                       });
+                       toastr.success(i18n.t('content.saveSuccess'));
+                       setTechnique(response.data);
+                       setShowContentDialog(false);
+               } catch (e) {
+                       toastr.error(i18n.t('content.saveError'));
+               }
+       }, [technique && technique.id]);
+
        useEffect(() => {
                const ctrl = new AbortController();
                setLoading(true);
                axios
-                       .get(`/api/tech/${name}`, { signal: ctrl.signal })
+                       .get(`/api/pages/${type}/${name}`, { signal: ctrl.signal })
                        .then(response => {
                                setError(null);
                                setLoading(false);
@@ -39,7 +71,7 @@ const Technique = () => {
                return () => {
                        ctrl.abort();
                };
-       }, [name]);
+       }, [name, type]);
 
        if (loading) {
                return <Loading />;
@@ -63,8 +95,19 @@ const Technique = () => {
                        lang={getMatchedLocale(technique, i18n.language)}
                        langs={getLanguages(technique)}
                />
-               <Detail technique={technique} />
+               <Detail actions={actions} technique={technique} />
+               <Dialog
+                       content={editContent}
+                       language={i18n.language}
+                       onHide={() => { setShowContentDialog(false); }}
+                       onSubmit={saveContent}
+                       show={showContentDialog}
+               />
        </ErrorBoundary>;
 };
 
+Technique.propTypes = {
+       type: PropTypes.string,
+};
+
 export default withTranslation()(Technique);