Merge pull request #302 from answerdev/feat/1.0.8/ui

Feat/1.0.8/UI
This commit is contained in:
dashuai 2023-04-04 17:50:32 +08:00 committed by GitHub
commit 90eb6c92a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 54 additions and 42 deletions

View File

@ -56,10 +56,13 @@ export interface QuestionParams {
title: string;
url_title?: string;
content: string;
html?: string;
tags: Tag[];
}
export interface QuestionWithAnswer extends QuestionParams {
answer_content: string;
}
export interface ListResult<T = any> {
count: number;
list: T[];

View File

@ -17,8 +17,8 @@ import {
} from '@/components';
const QuestionOrderKeys: Type.QuestionOrderBy[] = [
'newest',
'active',
'newest',
'frequent',
'score',
'unanswered',

View File

@ -16,9 +16,10 @@ import {
questionDetail,
modifyQuestion,
useQueryRevisions,
postAnswer,
// postAnswer,
useQueryQuestionByTitle,
getTagsBySlugName,
saveQuestionWidthAnaser,
} from '@/services';
import { handleFormError, SaveDraft, storageExpires } from '@/utils';
import { pathFactory } from '@/router/pathFactory';
@ -29,7 +30,7 @@ interface FormDataItem {
title: Type.FormValue<string>;
tags: Type.FormValue<Type.Tag[]>;
content: Type.FormValue<string>;
answer: Type.FormValue<string>;
answer_content: Type.FormValue<string>;
edit_summary: Type.FormValue<string>;
}
@ -52,7 +53,7 @@ const Ask = () => {
isInvalid: false,
errorMsg: '',
},
answer: {
answer_content: {
value: '',
isInvalid: false,
errorMsg: '',
@ -92,7 +93,7 @@ const Ask = () => {
return;
}
getTagsBySlugName(queryTags).then((tags) => {
// eslint-disable-next-line @typescript-eslint/no-use-before-define
// eslint-disable-next-line
handleTagsChange(tags);
});
};
@ -116,8 +117,8 @@ const Ask = () => {
formData.title.value = draft.title;
formData.content.value = draft.content;
formData.tags.value = draft.tags;
formData.answer.value = draft.answer;
setCheckState(Boolean(draft.answer));
formData.answer_content.value = draft.answer_content;
setCheckState(Boolean(draft.answer_content));
setHasDraft(true);
setFormData({ ...formData });
} else {
@ -131,7 +132,7 @@ const Ask = () => {
}, [qid]);
useEffect(() => {
const { title, tags, content, answer } = formData;
const { title, tags, content, answer_content } = formData;
const { title: editTitle, tags: editTags, content: editContent } = immData;
// edited
@ -151,14 +152,19 @@ const Ask = () => {
return;
}
// write
if (title.value || tags.value.length > 0 || content.value || answer.value) {
if (
title.value ||
tags.value.length > 0 ||
content.value ||
answer_content.value
) {
// save draft
saveDraft.save({
params: {
title: title.value,
tags: tags.value,
content: content.value,
answer: answer.value,
answer_content: answer_content.value,
},
callback: () => setHasDraft(true),
});
@ -215,7 +221,7 @@ const Ask = () => {
const handleAnswerChange = (value: string) =>
setFormData({
...formData,
answer: { ...formData.answer, value, errorMsg: '' },
answer_content: { ...formData.answer_content, value, errorMsg: '' },
});
const handleSummaryChange = (evt: React.ChangeEvent<HTMLInputElement>) =>
@ -263,31 +269,30 @@ const Ask = () => {
}
});
} else {
const res = await saveQuestion(params).catch((err) => {
if (err.isError) {
const data = handleFormError(err, formData);
setFormData({ ...data });
}
});
let res;
if (checked) {
res = await saveQuestionWidthAnaser({
...params,
answer_content: formData.answer_content.value,
}).catch((err) => {
if (err.isError) {
const data = handleFormError(err, formData);
setFormData({ ...data });
}
});
} else {
res = await saveQuestion(params).catch((err) => {
if (err.isError) {
const data = handleFormError(err, formData);
setFormData({ ...data });
}
});
}
const id = res?.id;
const id = res?.id || res?.question?.id;
if (id) {
if (checked) {
postAnswer({
question_id: id,
content: formData.answer.value,
})
.then(() => {
navigate(pathFactory.questionLanding(id, params.url_title));
})
.catch((err) => {
if (err.isError) {
const data = handleFormError(err, formData, [
{ from: 'content', to: 'answer' },
]);
setFormData({ ...data });
}
});
navigate(pathFactory.questionLanding(id, res?.question?.url_title));
} else {
navigate(pathFactory.questionLanding(id));
}
@ -448,7 +453,7 @@ const Ask = () => {
<Form.Group controlId="answer" className="mt-4">
<Form.Label>{t('form.fields.answer.label')}</Form.Label>
<Editor
value={formData.answer.value}
value={formData.answer_content.value}
onChange={handleAnswerChange}
ref={editorRef2}
className={classNames(
@ -464,11 +469,11 @@ const Ask = () => {
/>
<Form.Control
type="text"
isInvalid={formData.answer.isInvalid}
isInvalid={formData.answer_content.isInvalid}
hidden
/>
<Form.Control.Feedback type="invalid">
{formData.answer.errorMsg}
{formData.answer_content.errorMsg}
</Form.Control.Feedback>
</Form.Group>
)}

View File

@ -14,7 +14,7 @@ const Questions: FC = () => {
const { user: loggedUser } = loggedUserInfoStore((_) => _);
const [urlSearchParams] = useSearchParams();
const curPage = Number(urlSearchParams.get('page')) || 1;
const curOrder = urlSearchParams.get('order') || 'newest';
const curOrder = urlSearchParams.get('order') || 'active';
const reqParams: Type.QueryQuestionsReq = {
page_size: 20,
page: curPage,

View File

@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next';
import { QueryGroup } from '@/components';
const sortBtns = ['relevance', 'newest', 'active', 'score'];
const sortBtns = ['active', 'relevance', 'newest', 'score'];
interface Props {
count: number;

View File

@ -21,7 +21,7 @@ const Index = () => {
const [searchParams] = useSearchParams();
const page = searchParams.get('page') || 1;
const q = searchParams.get('q') || '';
const order = searchParams.get('order') || 'relevance';
const order = searchParams.get('order') || 'active';
const { data, isLoading } = useSearch({
q,

View File

@ -28,7 +28,7 @@ const Questions: FC = () => {
const routeParams = useParams();
const curTagName = routeParams.tagName || '';
const [urlSearchParams] = useSearchParams();
const curOrder = urlSearchParams.get('order') || 'newest';
const curOrder = urlSearchParams.get('order') || 'active';
const curPage = Number(urlSearchParams.get('page')) || 1;
const reqParams: Type.QueryQuestionsReq = {
page_size: 20,

View File

@ -274,3 +274,7 @@ export const markdownToHtml = (content: string) => {
const apiUrl = '/answer/api/v1/post/render';
return request.post(apiUrl, { content });
};
export const saveQuestionWidthAnaser = (params: Type.QuestionWithAnswer) => {
return request.post('/answer/api/v1/question/answer', params);
};

View File

@ -11,7 +11,7 @@ export type QuestionDraft = {
title: string;
content: string;
tags: any[];
answer: string;
answer_content: string;
};
callback?: () => void;
};