diff --git a/src/api/index.js b/src/api/index.js index a5f073295..c38e3b6cf 100644 --- a/src/api/index.js +++ b/src/api/index.js @@ -20,10 +20,11 @@ class APIService { * @returns {Promise<{}>} */ async request({ url, method = 'GET', headers = {}, ...options }) { + const lang = this.services?.i18n?.getLang(); if (!url.match(/^(http|\/\/)/)) url = this.config.baseUrl + url; const res = await fetch(url, { method, - headers: { ...this.defaultHeaders, ...headers }, + headers: { ...this.defaultHeaders, ...headers, 'Accept-Language': lang || 'ru' }, ...options, }); return { data: await res.json(), status: res.status, headers: res.headers }; diff --git a/src/app/article/index.js b/src/app/article/index.js index 56859bc76..329d5709d 100644 --- a/src/app/article/index.js +++ b/src/app/article/index.js @@ -10,36 +10,52 @@ import Spinner from '../../components/spinner'; import ArticleCard from '../../components/article-card'; import LocaleSelect from '../../containers/locale-select'; import TopHead from '../../containers/top-head'; -import { useDispatch, useSelector } from 'react-redux'; +import { useDispatch, useSelector as useSelectorRedux } from 'react-redux'; import shallowequal from 'shallowequal'; import articleActions from '../../store-redux/article/actions'; +import commentsActions from '../../store-redux/comments/actions'; +import CommentsSection from '../../components/comments-section'; +import useSelector from '../../hooks/use-selector'; function Article() { const store = useStore(); const dispatch = useDispatch(); - // Параметры из пути /articles/:id const params = useParams(); + const { t, lang } = useTranslate(); + useInit(() => { - //store.actions.article.load(params.id); dispatch(articleActions.load(params.id)); - }, [params.id]); + }, [params.id, lang]); + + useInit(() => { + dispatch(commentsActions.load(params.id)); + }, [params.id]); // комментам язык не нужен - const select = useSelector( + const select = useSelectorRedux( state => ({ article: state.article.data, waiting: state.article.waiting, + comments: state.comments.items, + commentsCount: state.comments.count, + commentsWaiting: state.comments.waiting, }), shallowequal, ); // Нужно указать функцию для сравнения свойства объекта, так как хуком вернули объект - const { t } = useTranslate(); + const {userId, userName, u} = useSelector( + state => ({ + userName: state.session.user?.profile?.name, + userId: state.session.user?._id, + }), + ); + const callbacks = { - // Добавление в корзину addToBasket: useCallback(_id => store.actions.basket.addToBasket(_id), [store]), + addComment: useCallback((data, onSuccess) => dispatch(commentsActions.add(data, userName, onSuccess)), [userName]), }; return ( @@ -52,6 +68,16 @@ function Article() { + + + ); } diff --git a/src/app/basket/index.js b/src/app/basket/index.js index 52a7badfd..a140280be 100644 --- a/src/app/basket/index.js +++ b/src/app/basket/index.js @@ -1,8 +1,7 @@ import { memo, useCallback } from 'react'; -import { useDispatch, useStore as useStoreRedux } from 'react-redux'; +import { useDispatch} from 'react-redux'; import useStore from '../../hooks/use-store'; import useSelector from '../../hooks/use-selector'; -import useInit from '../../hooks/use-init'; import useTranslate from '../../hooks/use-translate'; import ItemBasket from '../../components/item-basket'; import List from '../../components/list'; diff --git a/src/app/index.js b/src/app/index.js index c54c2afc5..8cfbf3f1a 100644 --- a/src/app/index.js +++ b/src/app/index.js @@ -1,6 +1,4 @@ -import { useCallback, useContext, useEffect, useState } from 'react'; import { Routes, Route } from 'react-router-dom'; -import useSelector from '../hooks/use-selector'; import useStore from '../hooks/use-store'; import useInit from '../hooks/use-init'; import Main from './main'; @@ -10,6 +8,7 @@ import Login from './login'; import Profile from './profile'; import Protected from '../containers/protected'; import { useSelector as useSelectorRedux } from 'react-redux'; +import useTranslate from '../hooks/use-translate'; /** * Приложение @@ -17,6 +16,7 @@ import { useSelector as useSelectorRedux } from 'react-redux'; */ function App() { const store = useStore(); + useInit(async () => { await store.actions.session.remind(); }); diff --git a/src/app/main/index.js b/src/app/main/index.js index 21a36457a..f055c27de 100644 --- a/src/app/main/index.js +++ b/src/app/main/index.js @@ -12,17 +12,16 @@ import TopHead from '../../containers/top-head'; function Main() { const store = useStore(); + const {lang, t} = useTranslate(); useInit( async () => { await Promise.all([store.actions.catalog.initParams(), store.actions.categories.load()]); }, - [], + [lang], true, ); - const { t } = useTranslate(); - return ( diff --git a/src/app/profile/index.js b/src/app/profile/index.js index 9c6149159..73ee751cf 100644 --- a/src/app/profile/index.js +++ b/src/app/profile/index.js @@ -1,5 +1,4 @@ -import { memo, useCallback, useMemo } from 'react'; -import { useParams } from 'react-router-dom'; +import { memo } from 'react'; import useStore from '../../hooks/use-store'; import useSelector from '../../hooks/use-selector'; import useTranslate from '../../hooks/use-translate'; @@ -8,25 +7,23 @@ import PageLayout from '../../components/page-layout'; import Head from '../../components/head'; import Navigation from '../../containers/navigation'; import Spinner from '../../components/spinner'; -import ArticleCard from '../../components/article-card'; import LocaleSelect from '../../containers/locale-select'; import TopHead from '../../containers/top-head'; import ProfileCard from '../../components/profile-card'; function Profile() { const store = useStore(); + const { t, lang } = useTranslate(); useInit(() => { store.actions.profile.load(); - }, []); + }, [lang]); const select = useSelector(state => ({ profile: state.profile.data, waiting: state.profile.waiting, })); - const { t } = useTranslate(); - return ( diff --git a/src/components/comment-form/index.js b/src/components/comment-form/index.js new file mode 100644 index 000000000..20be1d725 --- /dev/null +++ b/src/components/comment-form/index.js @@ -0,0 +1,44 @@ +import { memo, useRef } from 'react'; +import PropTypes from 'prop-types'; +import { cn as bem } from '@bem-react/classname'; +import './style.css'; + +function CommentForm({ onAdd, onCancel, title, cancelButtonText, t}) { + const cn = bem('CommentForm'); + const ref = useRef(null) + + const onSend = (e) => { + e.preventDefault(); + const value = ref.current?.value; + if (!value.trim()) { + console.error('Нельзя оставлять пустые комментарии'); + return; + } + const onSuccess = () => { + ref.current.value = ''; + onCancel() + } + onAdd(value, onSuccess); + } + + return ( +
+

{title}

+