2022-09-27 17:59:05 +08:00
|
|
|
import { FC } from 'react';
|
2022-11-09 10:22:52 +08:00
|
|
|
import { ListGroup } from 'react-bootstrap';
|
2022-09-27 17:59:05 +08:00
|
|
|
import { NavLink, useParams, useSearchParams } from 'react-router-dom';
|
|
|
|
import { useTranslation } from 'react-i18next';
|
|
|
|
|
2022-12-02 18:27:42 +08:00
|
|
|
import { pathFactory } from '@/router/pathFactory';
|
2022-11-02 17:14:47 +08:00
|
|
|
import type * as Type from '@/common/interface';
|
2022-09-29 14:56:09 +08:00
|
|
|
import {
|
|
|
|
Icon,
|
|
|
|
Tag,
|
|
|
|
Pagination,
|
|
|
|
FormatTime,
|
|
|
|
Empty,
|
|
|
|
BaseUserCard,
|
2022-10-09 18:20:19 +08:00
|
|
|
QueryGroup,
|
2022-11-02 17:14:47 +08:00
|
|
|
} from '@/components';
|
2022-10-31 11:39:33 +08:00
|
|
|
import { useQuestionList } from '@/services';
|
|
|
|
|
2022-09-27 17:59:05 +08:00
|
|
|
const QuestionOrderKeys: Type.QuestionOrderBy[] = [
|
|
|
|
'newest',
|
|
|
|
'active',
|
|
|
|
'frequent',
|
|
|
|
'score',
|
|
|
|
'unanswered',
|
|
|
|
];
|
|
|
|
|
|
|
|
interface Props {
|
|
|
|
source: 'questions' | 'tag';
|
|
|
|
}
|
|
|
|
|
|
|
|
const QuestionLastUpdate = ({ q }) => {
|
|
|
|
const { t } = useTranslation('translation', { keyPrefix: 'question' });
|
|
|
|
if (q.update_time > q.edit_time) {
|
|
|
|
// question answered
|
|
|
|
return (
|
2022-10-14 17:30:16 +08:00
|
|
|
<div className="d-flex">
|
2022-09-29 14:56:09 +08:00
|
|
|
<BaseUserCard
|
|
|
|
data={q.last_answered_user_info}
|
|
|
|
showAvatar={false}
|
|
|
|
className="me-1"
|
|
|
|
/>
|
2022-09-27 17:59:05 +08:00
|
|
|
•
|
|
|
|
<FormatTime
|
|
|
|
time={q.update_time}
|
2022-10-31 14:52:56 +08:00
|
|
|
className="text-secondary ms-1"
|
2022-09-27 17:59:05 +08:00
|
|
|
preFix={t('answered')}
|
|
|
|
/>
|
2022-10-14 17:30:16 +08:00
|
|
|
</div>
|
2022-09-27 17:59:05 +08:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (q.edit_time > q.update_time) {
|
|
|
|
// question modified
|
|
|
|
return (
|
2022-10-14 17:30:16 +08:00
|
|
|
<div className="d-flex">
|
2022-09-29 14:56:09 +08:00
|
|
|
<BaseUserCard
|
|
|
|
data={q.update_user_info}
|
|
|
|
showAvatar={false}
|
|
|
|
className="me-1"
|
|
|
|
/>
|
2022-09-27 17:59:05 +08:00
|
|
|
•
|
|
|
|
<FormatTime
|
|
|
|
time={q.edit_time}
|
2022-10-31 14:52:56 +08:00
|
|
|
className="text-secondary ms-1"
|
2022-09-27 17:59:05 +08:00
|
|
|
preFix={t('modified')}
|
|
|
|
/>
|
2022-10-14 17:30:16 +08:00
|
|
|
</div>
|
2022-09-27 17:59:05 +08:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
// default: asked
|
|
|
|
return (
|
2022-10-14 17:30:16 +08:00
|
|
|
<div className="d-flex">
|
2022-09-29 14:56:09 +08:00
|
|
|
<BaseUserCard data={q.user_info} showAvatar={false} className="me-1" />
|
2022-09-27 17:59:05 +08:00
|
|
|
•
|
|
|
|
<FormatTime
|
|
|
|
time={q.create_time}
|
|
|
|
preFix={t('asked')}
|
2022-10-31 14:52:56 +08:00
|
|
|
className="text-secondary ms-1"
|
2022-09-27 17:59:05 +08:00
|
|
|
/>
|
2022-10-14 17:30:16 +08:00
|
|
|
</div>
|
2022-09-27 17:59:05 +08:00
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
const QuestionList: FC<Props> = ({ source }) => {
|
|
|
|
const { t } = useTranslation('translation', { keyPrefix: 'question' });
|
|
|
|
const { tagName = '' } = useParams();
|
2022-10-09 18:20:19 +08:00
|
|
|
const [urlSearchParams] = useSearchParams();
|
2022-09-27 17:59:05 +08:00
|
|
|
const curOrder = urlSearchParams.get('order') || QuestionOrderKeys[0];
|
|
|
|
const curPage = Number(urlSearchParams.get('page')) || 1;
|
|
|
|
const pageSize = 20;
|
|
|
|
const reqParams: Type.QueryQuestionsReq = {
|
|
|
|
page_size: pageSize,
|
|
|
|
page: curPage,
|
|
|
|
order: curOrder as Type.QuestionOrderBy,
|
2022-10-27 10:50:10 +08:00
|
|
|
tag: tagName,
|
2022-09-27 17:59:05 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
if (source === 'questions') {
|
2022-10-27 10:50:10 +08:00
|
|
|
delete reqParams.tag;
|
2022-09-27 17:59:05 +08:00
|
|
|
}
|
|
|
|
const { data: listData, isLoading } = useQuestionList(reqParams);
|
|
|
|
const count = listData?.count || 0;
|
|
|
|
|
|
|
|
return (
|
|
|
|
<div>
|
2022-11-09 10:22:52 +08:00
|
|
|
<div className="mb-3 d-flex flex-wrap justify-content-between">
|
|
|
|
<h5 className="fs-5 text-nowrap mb-3 mb-md-0">
|
|
|
|
{source === 'questions'
|
|
|
|
? t('all_questions')
|
|
|
|
: t('x_questions', { count })}
|
|
|
|
</h5>
|
|
|
|
<QueryGroup
|
|
|
|
data={QuestionOrderKeys}
|
|
|
|
currentSort={curOrder}
|
|
|
|
pathname={source === 'questions' ? '/questions' : ''}
|
|
|
|
i18nKeyPrefix="question"
|
|
|
|
/>
|
|
|
|
</div>
|
2022-09-27 17:59:05 +08:00
|
|
|
<ListGroup variant="flush" className="border-top border-bottom-0">
|
|
|
|
{listData?.list?.map((li) => {
|
|
|
|
return (
|
2022-12-16 18:58:30 +08:00
|
|
|
<ListGroup.Item
|
|
|
|
key={li.id}
|
|
|
|
className="border-bottom bg-transparent py-3 px-0">
|
2022-09-27 17:59:05 +08:00
|
|
|
<h5 className="text-wrap text-break">
|
2022-12-02 18:27:42 +08:00
|
|
|
<NavLink
|
2022-12-16 17:39:48 +08:00
|
|
|
to={pathFactory.questionLanding(li.id, li.url_title)}
|
2022-12-02 18:27:42 +08:00
|
|
|
className="link-dark">
|
2022-09-27 17:59:05 +08:00
|
|
|
{li.title}
|
2022-09-30 10:00:47 +08:00
|
|
|
{li.status === 2 ? ` [${t('closed')}]` : ''}
|
2022-09-27 17:59:05 +08:00
|
|
|
</NavLink>
|
|
|
|
</h5>
|
2022-12-13 16:22:42 +08:00
|
|
|
<div className="d-flex flex-column flex-md-row align-items-md-center fs-14 mb-2 text-secondary">
|
2022-09-27 17:59:05 +08:00
|
|
|
<QuestionLastUpdate q={li} />
|
2022-10-14 17:30:16 +08:00
|
|
|
<div className="ms-0 ms-md-3 mt-2 mt-md-0">
|
|
|
|
<span>
|
|
|
|
<Icon name="hand-thumbs-up-fill" />
|
2022-10-31 14:52:56 +08:00
|
|
|
<em className="fst-normal ms-1">{li.vote_count}</em>
|
2022-10-14 17:30:16 +08:00
|
|
|
</span>
|
|
|
|
<span
|
|
|
|
className={`ms-3 ${
|
|
|
|
li.accepted_answer_id >= 1 ? 'text-success' : ''
|
|
|
|
}`}>
|
|
|
|
<Icon
|
|
|
|
name={
|
|
|
|
li.accepted_answer_id >= 1
|
|
|
|
? 'check-circle-fill'
|
|
|
|
: 'chat-square-text-fill'
|
|
|
|
}
|
|
|
|
/>
|
2022-10-31 14:52:56 +08:00
|
|
|
<em className="fst-normal ms-1">{li.answer_count}</em>
|
2022-10-14 17:30:16 +08:00
|
|
|
</span>
|
|
|
|
<span className="summary-stat ms-3">
|
|
|
|
<Icon name="eye-fill" />
|
2022-10-31 14:52:56 +08:00
|
|
|
<em className="fst-normal ms-1">{li.view_count}</em>
|
2022-10-14 17:30:16 +08:00
|
|
|
</span>
|
|
|
|
</div>
|
2022-09-27 17:59:05 +08:00
|
|
|
</div>
|
2022-12-08 11:25:56 +08:00
|
|
|
<div className="question-tags m-n1">
|
2022-09-27 17:59:05 +08:00
|
|
|
{Array.isArray(li.tags)
|
|
|
|
? li.tags.map((tag) => {
|
|
|
|
return (
|
2022-11-14 17:43:28 +08:00
|
|
|
<Tag key={tag.slug_name} className="m-1" data={tag} />
|
2022-09-27 17:59:05 +08:00
|
|
|
);
|
|
|
|
})
|
|
|
|
: null}
|
|
|
|
</div>
|
|
|
|
</ListGroup.Item>
|
|
|
|
);
|
|
|
|
})}
|
|
|
|
</ListGroup>
|
|
|
|
{count <= 0 && !isLoading && <Empty />}
|
|
|
|
<div className="mt-4 mb-2 d-flex justify-content-center">
|
|
|
|
<Pagination
|
|
|
|
currentPage={curPage}
|
|
|
|
totalSize={count}
|
|
|
|
pageSize={pageSize}
|
2022-09-28 15:52:42 +08:00
|
|
|
pathname="/questions"
|
2022-09-27 17:59:05 +08:00
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
export default QuestionList;
|