diff --git a/i18n/en_US.yaml b/i18n/en_US.yaml index b4121379..039e2e5e 100644 --- a/i18n/en_US.yaml +++ b/i18n/en_US.yaml @@ -525,6 +525,7 @@ ui: tip_answer: >- Use comments to reply to other users or notify them of changes. If you are adding new information, edit your post instead of commenting. + tip_vote: It adds something useful to the post edit_answer: title: Edit Answer default_reason: Edit answer @@ -784,6 +785,11 @@ ui: answered: answered closed_in: Closed in show_exist: Show existing question. + useful: Useful + question_useful: It is useful and clear + question_un_useful: It is unclear or not useful + answer_useful: It is useful + answer_un_useful: It is not useful answers: title: Answers score: Score @@ -801,10 +807,19 @@ ui: edit link to refine and improve your existing answer, instead.

empty: Answer cannot be empty. characters: content must be at least 6 characters in length. + tips: + header_1: Thanks for your answer + li1_1: Please be sure to answer the question. Provide details and share your research. + li1_2: Back up any statements you make with references or personal experience. + header_2: But avoid ... + li2_1: Asking for help, seeking clarification, or responding to other answers. + reopen: + confirm_btn: Reopen title: Reopen this post content: Are you sure you want to reopen? success: This post has been reopened + delete: title: Delete this post question: >- diff --git a/ui/src/components/Actions/index.tsx b/ui/src/components/Actions/index.tsx index 8ba6a1d4..518708ec 100644 --- a/ui/src/components/Actions/index.tsx +++ b/ui/src/components/Actions/index.tsx @@ -1,5 +1,5 @@ import { memo, FC, useState, useEffect } from 'react'; -import { Button, ButtonGroup } from 'react-bootstrap'; +import { Button, ButtonGroup, Tooltip, OverlayTrigger } from 'react-bootstrap'; import { useTranslation } from 'react-i18next'; import classNames from 'classnames'; @@ -12,6 +12,7 @@ import { bookmark, postVote } from '@/services'; interface Props { className?: string; + source: 'question' | 'answer'; data: { id: string; votesCount: number; @@ -24,7 +25,7 @@ interface Props { }; } -const Index: FC = ({ className, data }) => { +const Index: FC = ({ className, data, source }) => { const [votes, setVotes] = useState(0); const [like, setLike] = useState(false); const [hate, setHated] = useState(false); @@ -101,21 +102,40 @@ const Index: FC = ({ className, data }) => { return (
- + + {source === 'question' + ? t('question_detail.question_useful') + : t('question_detail.answer_useful')} + + }> + + - + + {source === 'question' + ? t('question_detail.question_un_useful') + : t('question_detail.answer_un_useful')} + + }> + + {!data?.hideCollect && ( + {t('tip_vote')}}> + + - )} - - {isAuthor && data.accepted === 1 && ( - )}
diff --git a/ui/src/pages/Questions/Detail/components/Question/index.tsx b/ui/src/pages/Questions/Detail/components/Question/index.tsx index 9eeb66e1..254d2779 100644 --- a/ui/src/pages/Questions/Detail/components/Question/index.tsx +++ b/ui/src/pages/Questions/Detail/components/Question/index.tsx @@ -114,6 +114,7 @@ const Index: FC = ({ data, initPage, hasAnswer, isLogged }) => { void; } @@ -39,6 +40,7 @@ const Index: FC = ({ visible = false, data, callback }) => { const [focusType, setFocusType] = useState(''); const [editorFocusState, setEditorFocusState] = useState(false); const [hasDraft, setHasDraft] = useState(false); + const [showTips, setShowTips] = useState(data.loggedUserRank < 100); usePromptWithUnload({ when: Boolean(formData.content.value), @@ -212,29 +214,58 @@ const Index: FC = ({ visible = false, data, callback }) => { )} {showEditor && ( - { - setFormData({ - content: { - value: val, - isInvalid: false, - errorMsg: '', - }, - }); - }} - onFocus={() => { - setFocusType('answer'); - }} - onBlur={() => { - setFocusType(''); - }} - /> + <> + { + setFormData({ + content: { + value: val, + isInvalid: false, + errorMsg: '', + }, + }); + }} + onFocus={() => { + setFocusType('answer'); + }} + onBlur={() => { + setFocusType(''); + }} + /> + + setShowTips(false)} + dismissible + className="mt-3"> +

{t('tips.header_1')}

+
    +
  • + }} + /> +
  • +
  • {t('tips.li1_2')}
  • +
+

+ }} + /> +

+
    +
  • {t('tips.li2_1')}
  • +
+
+ )} diff --git a/ui/src/pages/Questions/Detail/index.tsx b/ui/src/pages/Questions/Detail/index.tsx index a6b3cc2d..7397c527 100644 --- a/ui/src/pages/Questions/Detail/index.tsx +++ b/ui/src/pages/Questions/Detail/index.tsx @@ -56,7 +56,9 @@ const Index = () => { const userInfo = loggedUserInfoStore((state) => state.user); const isAuthor = userInfo?.username === question?.user_info?.username; const isAdmin = userInfo?.role_id === 2; + const isModerator = userInfo?.role_id === 3; const isLogged = Boolean(userInfo?.access_token); + const loggedUserRank = userInfo?.rank; const { state: locationState } = useLocation(); useEffect(() => { @@ -221,7 +223,7 @@ const Index = () => { data={item} questionTitle={question?.title || ''} slugTitle={question?.url_title} - isAuthor={isAuthor} + canAccept={isAuthor || isAdmin || isModerator} callback={initPage} isLogged={isLogged} /> @@ -247,6 +249,7 @@ const Index = () => { data={{ qid, answered: question?.answered, + loggedUserRank, }} callback={writeAnswerCallback} /> diff --git a/ui/src/pages/Questions/EditAnswer/index.tsx b/ui/src/pages/Questions/EditAnswer/index.tsx index 680547f0..5c8e9798 100644 --- a/ui/src/pages/Questions/EditAnswer/index.tsx +++ b/ui/src/pages/Questions/EditAnswer/index.tsx @@ -1,4 +1,4 @@ -import React, { useState, useRef, useEffect } from 'react'; +import React, { useState, useRef, useEffect, useLayoutEffect } from 'react'; import { Container, Row, Col, Form, Button, Card } from 'react-bootstrap'; import { useParams, useNavigate } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; @@ -23,18 +23,7 @@ interface FormDataItem { content: Type.FormValue; description: Type.FormValue; } -const initFormData = { - content: { - value: '', - isInvalid: false, - errorMsg: '', - }, - description: { - value: '', - isInvalid: false, - errorMsg: '', - }, -}; + const Index = () => { const { aid = '', qid = '' } = useParams(); const [focusType, setForceType] = useState(''); @@ -42,12 +31,36 @@ const Index = () => { const { t } = useTranslation('translation', { keyPrefix: 'edit_answer' }); const navigate = useNavigate(); + const initFormData = { + content: { + value: '', + isInvalid: false, + errorMsg: '', + }, + description: { + value: '', + isInvalid: false, + errorMsg: '', + }, + }; + const { data } = useQueryAnswerInfo(aid); const [formData, setFormData] = useState(initFormData); const [immData, setImmData] = useState(initFormData); const [contentChanged, setContentChanged] = useState(false); - initFormData.content.value = data?.info.content || ''; + useLayoutEffect(() => { + if (data?.info?.content) { + setFormData({ + ...formData, + content: { + value: data.info.content, + isInvalid: false, + errorMsg: '', + }, + }); + } + }, [data?.info?.content]); const { data: revisions = [] } = useQueryRevisions(aid); @@ -147,9 +160,11 @@ const Index = () => { const handleSelectedRevision = (e) => { const index = e.target.value; const revision = revisions[index]; - formData.content.value = revision.content.content; - setImmData({ ...formData }); - setFormData({ ...formData }); + if (revision?.content) { + formData.content.value = revision.content.content; + setImmData({ ...formData }); + setFormData({ ...formData }); + } }; const backPage = () => { @@ -192,7 +207,7 @@ const Index = () => {
{t('form.fields.revision.label')} - + {revisions.map(({ create_at, reason, user_info }, index) => { const date = dayjs(create_at * 1000) .tz()