diff --git a/src/app/article/index.js b/src/app/article/index.js index caea26492..89b09a6bc 100644 --- a/src/app/article/index.js +++ b/src/app/article/index.js @@ -13,31 +13,49 @@ import TopHead from '../../containers/top-head'; import { useDispatch, useSelector } from 'react-redux'; import shallowequal from 'shallowequal'; import articleActions from '../../store-redux/article/actions'; -import Reviews from '../reviews'; +import commentsActions from '../../store-redux/comments/actions'; +import CommentContainer from '../../containers/comment'; function Article() { const store = useStore(); + const dispatch = useDispatch(); + // Параметры из пути /articles/:id + const params = useParams(); + useInit(() => { //store.actions.article.load(params.id); dispatch(articleActions.load(params.id)); + dispatch(commentsActions.load(params.id)); }, [params.id]); + const select = useSelector( state => ({ article: state.article.data, waiting: state.article.waiting, + comments: state.comments.data, + waitingComments: state.comments.waiting }), shallowequal, - ); + ); // Нужно указать функцию для сравнения свойства объекта, так как хуком вернули объект const { t } = useTranslate(); - + const callbacks = { // Добавление в корзину addToBasket: useCallback(_id => store.actions.basket.addToBasket(_id), [store]), }; + const handleReply = commentId => { + dispatch(commentsActions.setReplyTo(commentId)); + }; + //const tree = listToTree(select.comments.items) + // const commentsArray = treeToList(listToTree(select.comments.items)) ; + console.log('select.comments.items=',select.comments.items) + //const commentsArray = select.comments.items.map(comment => ( + // + //)) return ( @@ -47,9 +65,12 @@ function Article() { - +

Комментарии ({select.comments.count})

+
{select.comments.items && select.comments.items.map(comment => ())}
+
); } -export default memo(Article); \ No newline at end of file + +export default memo(Article); diff --git a/src/app/index.js b/src/app/index.js index 6fe9ae3fb..c54c2afc5 100644 --- a/src/app/index.js +++ b/src/app/index.js @@ -1,5 +1,6 @@ - +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'; @@ -9,6 +10,7 @@ import Login from './login'; import Profile from './profile'; import Protected from '../containers/protected'; import { useSelector as useSelectorRedux } from 'react-redux'; + /** * Приложение * @returns {React.ReactElement} @@ -18,7 +20,9 @@ function App() { useInit(async () => { await store.actions.session.remind(); }); + const activeModal = useSelectorRedux(state => state.modals.name); + return ( <> @@ -34,8 +38,10 @@ function App() { } /> + {activeModal === 'basket' && } ); } -export default App; \ No newline at end of file + +export default App; diff --git a/src/app/login/index.js b/src/app/login/index.js index 8ccf151a8..9cecc31a4 100644 --- a/src/app/login/index.js +++ b/src/app/login/index.js @@ -18,22 +18,27 @@ function Login() { const location = useLocation(); const navigate = useNavigate(); const store = useStore(); + useInit(() => { store.actions.session.resetErrors(); }); + const select = useSelector(state => ({ waiting: state.session.waiting, errors: state.session.errors, })); + const [data, setData] = useState({ login: '', password: '', }); + const callbacks = { // Колбэк на ввод в элементах формы onChange: useCallback((value, name) => { setData(prevData => ({ ...prevData, [name]: value })); }, []), + // Отправка данных формы для авторизации onSubmit: useCallback( e => { @@ -47,9 +52,7 @@ function Login() { navigate(back); }); }, - - [data, location.state, navigate, store.actions.session] - // [data, location.state], + [data, location.state], ), }; @@ -83,4 +86,5 @@ function Login() { ); } -export default memo(Login); \ No newline at end of file + +export default memo(Login); diff --git a/src/app/reviews/index.js b/src/app/reviews/index.js deleted file mode 100644 index 2587ad16b..000000000 --- a/src/app/reviews/index.js +++ /dev/null @@ -1,74 +0,0 @@ -import { memo } from 'react'; -import React, { useRef, useEffect } from 'react'; -import { useParams } from 'react-router-dom'; -import { Link, useLocation } from 'react-router-dom'; -import useInit from '../../hooks/use-init'; -import { useSelector as useReduxSelector } from 'react-redux'; -import { useDispatch } from 'react-redux'; -import useSelector from '../../hooks/use-selector'; -import reviewsActions from '../../store-redux/reviews/actions'; -import listToTree from '../../utils/list-to-tree'; -import CommentsForm from '../../containers/comments-form'; -import CommentContainer from '../../containers/comment'; -import NoComments from '../../components/no-comments'; -import Spinner from '../../components/spinner'; - -function Reviews() { - const location = useLocation(); - const dispatch = useDispatch(); - const { id: articleId } = useParams(); - const select = useSelector(state => ({ - exists: state.session.exists, - })); - - useInit(() => { - dispatch(reviewsActions.load(articleId)); - }, []); - - const { reviews, waiting, replyTo } = useReduxSelector(state => ({ - reviews: state.reviews.data || [], - waiting: state.reviews.waiting, - replyTo: state.reviews.replyTo, - })); - - const commentsArray = reviews || []; - const commentsTree = listToTree(commentsArray, '_id'); - - const handleReply = commentId => { - dispatch(reviewsActions.setReplyTo(commentId)); - }; - - if (waiting) { - return ; - } - - if (commentsArray.length === 0) { - return ; - } - - const totalComments=commentsArray.length - - return ( -
- {totalComments &&

Комментарии ({totalComments})

} - {commentsTree.map(comment => ( - - ))} - -
{!replyTo && select.exists && }
- {!replyTo && !select.exists && ( -

- - Войдите - - , чтобы иметь возможность комментировать -

- )} -
- ); -} -export default memo(Reviews); \ No newline at end of file diff --git a/src/components/comment-view/index.js b/src/components/comment-view/index.js index 5ebfd06fc..b23b905b1 100644 --- a/src/components/comment-view/index.js +++ b/src/components/comment-view/index.js @@ -30,7 +30,7 @@ const CommentView = ({ : 'comment-author'; return ( -
+
{comment.author?.profile?.name || 'Аноним'}{' '} diff --git a/src/components/comment-view/style.css b/src/components/comment-view/style.css index f1d5b9969..e6e233f8b 100644 --- a/src/components/comment-view/style.css +++ b/src/components/comment-view/style.css @@ -1,4 +1,3 @@ - .comment-author--current { color: #666666; } diff --git a/src/components/comment/index.js b/src/components/comment/index.js deleted file mode 100644 index beb4f31ff..000000000 --- a/src/components/comment/index.js +++ /dev/null @@ -1,85 +0,0 @@ -import { memo } from 'react'; -import PropTypes from 'prop-types'; -import { cn as bem } from '@bem-react/classname'; -import CommentList from '../comment_list'; -import CommentForm from '../comment_form'; -import { toCommentDate } from '../../utils/date'; -//import CommentNoAuth from '../comment-no-auth'; -import './style.css'; - -function Comment({comment, openCommentId, onCancel, onAdd, onOpen, isAuth, t = text => text }) { - const { author, text, dateCreate, isDeleted, children, _id } = comment; - const cn = bem('Comment'); - //const onAddAnswer = (text, onSuccess) => onAdd({parent: {_id, _type: 'comment'}, text}, onSuccess) - console.log('author.profile.name=',author.profile.name ) - console.log('_id, openCommentId =',_id, openCommentId) - return ( -
-
-
{author.profile.name}
-
{toCommentDate(dateCreate)}
-
-

{ isDeleted ? t('comments.deleted-comment') : text}

- - {isAuth && openCommentId === _id && ( - - )} - - {!!children?.length && ( - - )} -
- ); -} -// {!isAuth && openCommentId === _id && ( -// -// )} -Comment.propTypes = { - comment: PropTypes.shape({ - children: PropTypes.array, - _id: PropTypes.string.isRequired, - parent: PropTypes.shape({ - _id: PropTypes.string, - _type: PropTypes.oneOf(['article', 'comment']), - }), - text: PropTypes.string.isRequired, - dateCreate: PropTypes.string.isRequired, - isDeleted: PropTypes.bool, - author: PropTypes.shape({ - profile: PropTypes.shape({ - name: PropTypes.string.isRequired, - }).isRequired, - }).isRequired, - }), - onCancel: PropTypes.func, - onAdd: PropTypes.func, - onOpen: PropTypes.func, - isAuth: PropTypes.bool, - t: PropTypes.func, -}; - -export default memo(Comment); \ No newline at end of file diff --git a/src/components/comment/style.css b/src/components/comment/style.css deleted file mode 100644 index c15b49da2..000000000 --- a/src/components/comment/style.css +++ /dev/null @@ -1,33 +0,0 @@ -.Comment-user-date { - display: flex; - gap: 10px; - font-size: 12px; - } - - .Comment-user { - font-weight: bold; - } - - .Comment-date { - color: #666666; - } - - .Comment-text { - font-size: 14px; - margin: 10px 0; - padding-right: 20px; - } - - .Comment-answer-btn { - color: #0087e9; - border: none; - background-color: transparent; - cursor: pointer; - margin-bottom: 26px; - padding: 0; - font-size: 12px; - } - - .Comment-answer-btn:hover { - text-decoration: underline; - } \ No newline at end of file diff --git a/src/components/comment_footer/index.js b/src/components/comment_footer/index.js deleted file mode 100644 index 270c29e1c..000000000 --- a/src/components/comment_footer/index.js +++ /dev/null @@ -1,22 +0,0 @@ -import { memo } from 'react'; -import PropTypes from 'prop-types'; -import { cn as bem } from '@bem-react/classname'; -import { Link } from 'react-router-dom'; -//import './style.css'; - -function CommentFooter(props) { - const { t = text => text } = props; - const cn = bem('CommentFooter'); - return ( -
- {t("comment.login" )} - {t("comment.footer" )} -
- ); -} - -CommentFooter.propTypes = { - t: PropTypes.func, -}; - -export default memo(CommentFooter); \ No newline at end of file diff --git a/src/components/comment_form/index.js b/src/components/comment_form/index.js deleted file mode 100644 index aeaed9cf5..000000000 --- a/src/components/comment_form/index.js +++ /dev/null @@ -1,49 +0,0 @@ -import { memo, useRef } from 'react'; -import PropTypes from 'prop-types'; -import { cn as bem } from '@bem-react/classname'; -import './style.css'; - -function CommentForm({author, parentId, 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() - } - // { - // "text": "Первый ответ на коммент!", - // "parent": {"_id": "670429839c74519426f378bd", "_type": "comment"} - // } - onAdd({"text": value, "parent": {parentId, "_type": 'comment'}},author , onSuccess) - - } - - return ( -
-

{title}

-