mirror of https://gitee.com/answerdev/answer.git
fix: add QueryGroup component
This commit is contained in:
parent
01bfa95962
commit
13a7bffc74
|
@ -0,0 +1,62 @@
|
|||
import { FC, memo } from 'react';
|
||||
import { ButtonGroup, Button } from 'react-bootstrap';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
interface Props {
|
||||
data: string[] | Array<{ name: string; sort: string }>;
|
||||
i18nkeyPrefix: string;
|
||||
currentSort: string;
|
||||
sortKey?: string;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const Index: FC<Props> = ({
|
||||
data,
|
||||
currentSort = '',
|
||||
sortKey = 'order',
|
||||
i18nkeyPrefix = '',
|
||||
className = '',
|
||||
}) => {
|
||||
const [searchParams, setUrlSearchParams] = useSearchParams();
|
||||
|
||||
const { t } = useTranslation('translation', {
|
||||
keyPrefix: i18nkeyPrefix,
|
||||
});
|
||||
|
||||
const handleParams = (order): string => {
|
||||
searchParams.delete('page');
|
||||
searchParams.set(sortKey, order);
|
||||
const searchStr = searchParams.toString();
|
||||
return `?${searchStr}`;
|
||||
};
|
||||
|
||||
const handleClick = (e, type) => {
|
||||
e.preventDefault();
|
||||
const str = handleParams(type);
|
||||
setUrlSearchParams(str);
|
||||
};
|
||||
|
||||
return (
|
||||
<ButtonGroup size="sm">
|
||||
{data.map((btn) => {
|
||||
const key = typeof btn === 'string' ? btn : btn.sort;
|
||||
const name = typeof btn === 'string' ? btn : btn.name;
|
||||
return (
|
||||
<Button
|
||||
as="a"
|
||||
key={key}
|
||||
variant="outline-secondary"
|
||||
active={currentSort === name}
|
||||
className={`text-capitalize ${className}`}
|
||||
href={handleParams(key)}
|
||||
onClick={(evt) => handleClick(evt, key)}>
|
||||
{t(name)}
|
||||
</Button>
|
||||
);
|
||||
})}
|
||||
</ButtonGroup>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(Index);
|
|
@ -1,5 +1,5 @@
|
|||
import { FC } from 'react';
|
||||
import { Row, Col, ButtonGroup, Button, ListGroup } from 'react-bootstrap';
|
||||
import { Row, Col, ListGroup } from 'react-bootstrap';
|
||||
import { NavLink, useParams, useSearchParams } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
|
@ -12,6 +12,7 @@ import {
|
|||
FormatTime,
|
||||
Empty,
|
||||
BaseUserCard,
|
||||
QueryGroup,
|
||||
} from '@answer/components';
|
||||
|
||||
const QuestionOrderKeys: Type.QuestionOrderBy[] = [
|
||||
|
@ -83,7 +84,7 @@ const QuestionLastUpdate = ({ q }) => {
|
|||
const QuestionList: FC<Props> = ({ source }) => {
|
||||
const { t } = useTranslation('translation', { keyPrefix: 'question' });
|
||||
const { tagName = '' } = useParams();
|
||||
const [urlSearchParams, setUrlSearchParams] = useSearchParams();
|
||||
const [urlSearchParams] = useSearchParams();
|
||||
const curOrder = urlSearchParams.get('order') || QuestionOrderKeys[0];
|
||||
const curPage = Number(urlSearchParams.get('page')) || 1;
|
||||
const pageSize = 20;
|
||||
|
@ -99,15 +100,15 @@ const QuestionList: FC<Props> = ({ source }) => {
|
|||
}
|
||||
const { data: listData, isLoading } = useQuestionList(reqParams);
|
||||
const count = listData?.count || 0;
|
||||
const onOrderChange = (evt, order) => {
|
||||
evt.preventDefault();
|
||||
if (order === curOrder) {
|
||||
return;
|
||||
}
|
||||
urlSearchParams.set('page', '1');
|
||||
urlSearchParams.set('order', order);
|
||||
setUrlSearchParams(urlSearchParams);
|
||||
};
|
||||
// const onOrderChange = (evt, order) => {
|
||||
// evt.preventDefault();
|
||||
// if (order === curOrder) {
|
||||
// return;
|
||||
// }
|
||||
// urlSearchParams.set('page', '1');
|
||||
// urlSearchParams.set('order', order);
|
||||
// setUrlSearchParams(urlSearchParams);
|
||||
// };
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
@ -120,21 +121,11 @@ const QuestionList: FC<Props> = ({ source }) => {
|
|||
</h5>
|
||||
</Col>
|
||||
<Col>
|
||||
<ButtonGroup size="sm">
|
||||
{QuestionOrderKeys.map((k) => {
|
||||
return (
|
||||
<Button
|
||||
as="a"
|
||||
key={k}
|
||||
className="text-capitalize"
|
||||
href={`?page=1&order=${k}`}
|
||||
onClick={(evt) => onOrderChange(evt, k)}
|
||||
variant={curOrder === k ? 'secondary' : 'outline-secondary'}>
|
||||
{t(k)}
|
||||
</Button>
|
||||
);
|
||||
})}
|
||||
</ButtonGroup>
|
||||
<QueryGroup
|
||||
data={QuestionOrderKeys}
|
||||
currentSort={curOrder}
|
||||
i18nkeyPrefix="question"
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
<ListGroup variant="flush" className="border-top border-bottom-0">
|
||||
|
|
|
@ -24,6 +24,7 @@ import PageTitle from './PageTitle';
|
|||
import Empty from './Empty';
|
||||
import BaseUserCard from './BaseUserCard';
|
||||
import FollowingTags from './FollowingTags';
|
||||
import QueryGroup from './QueryGroup';
|
||||
|
||||
export {
|
||||
Avatar,
|
||||
|
@ -53,5 +54,6 @@ export {
|
|||
BaseUserCard,
|
||||
FollowingTags,
|
||||
htmlRender,
|
||||
QueryGroup,
|
||||
};
|
||||
export type { EditorRef };
|
||||
|
|
|
@ -1,12 +1,5 @@
|
|||
import { FC } from 'react';
|
||||
import {
|
||||
ButtonGroup,
|
||||
Button,
|
||||
Form,
|
||||
Table,
|
||||
Stack,
|
||||
Badge,
|
||||
} from 'react-bootstrap';
|
||||
import { Button, Form, Table, Stack, Badge } from 'react-bootstrap';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
|
@ -17,6 +10,7 @@ import {
|
|||
Modal,
|
||||
BaseUserCard,
|
||||
Empty,
|
||||
QueryGroup,
|
||||
} from '@answer/components';
|
||||
import { ADMIN_LIST_STATUS } from '@answer/common/constants';
|
||||
import { useEditStatusModal } from '@answer/hooks';
|
||||
|
@ -28,7 +22,7 @@ import '../index.scss';
|
|||
const answerFilterItems: Type.AdminContentsFilterBy[] = ['normal', 'deleted'];
|
||||
|
||||
const Answers: FC = () => {
|
||||
const [urlSearchParams, setUrlSearchParams] = useSearchParams();
|
||||
const [urlSearchParams] = useSearchParams();
|
||||
const curFilter = urlSearchParams.get('status') || answerFilterItems[0];
|
||||
const PAGE_SIZE = 20;
|
||||
const curPage = Number(urlSearchParams.get('page')) || 1;
|
||||
|
@ -44,14 +38,6 @@ const Answers: FC = () => {
|
|||
status: curFilter as Type.AdminContentsFilterBy,
|
||||
});
|
||||
const count = listData?.count || 0;
|
||||
const onFilterChange = (filter) => {
|
||||
if (filter === curFilter) {
|
||||
return;
|
||||
}
|
||||
urlSearchParams.set('page', '1');
|
||||
urlSearchParams.set('status', filter);
|
||||
setUrlSearchParams(urlSearchParams);
|
||||
};
|
||||
|
||||
const handleCallback = (id, type) => {
|
||||
if (type === 'normal') {
|
||||
|
@ -95,20 +81,13 @@ const Answers: FC = () => {
|
|||
<>
|
||||
<h3 className="mb-4">{t('page_title')}</h3>
|
||||
<div className="d-flex justify-content-between align-items-center mb-3">
|
||||
<ButtonGroup size="sm">
|
||||
{answerFilterItems.map((li) => {
|
||||
return (
|
||||
<Button
|
||||
key={li}
|
||||
size="sm"
|
||||
className="text-capitalize"
|
||||
onClick={() => onFilterChange(li)}
|
||||
variant={curFilter === li ? 'secondary' : 'outline-secondary'}>
|
||||
{t(li)}
|
||||
</Button>
|
||||
);
|
||||
})}
|
||||
</ButtonGroup>
|
||||
<QueryGroup
|
||||
data={answerFilterItems}
|
||||
currentSort={curFilter}
|
||||
sortKey="status"
|
||||
i18nkeyPrefix="admin.answers"
|
||||
/>
|
||||
|
||||
<Form.Control
|
||||
size="sm"
|
||||
type="input"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React, { FC } from 'react';
|
||||
import { ButtonGroup, Button, Form, Table, Stack } from 'react-bootstrap';
|
||||
import { Button, Form, Table, Stack } from 'react-bootstrap';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
|
@ -8,6 +8,7 @@ import {
|
|||
BaseUserCard,
|
||||
Empty,
|
||||
Pagination,
|
||||
QueryGroup,
|
||||
} from '@answer/components';
|
||||
import { useReportModal } from '@answer/hooks';
|
||||
import * as Type from '@answer/common/interface';
|
||||
|
@ -38,14 +39,7 @@ const Flags: FC = () => {
|
|||
const reportModal = useReportModal(refreshList);
|
||||
|
||||
const count = listData?.count || 0;
|
||||
const onFilterChange = (filter) => {
|
||||
if (filter === curFilter) {
|
||||
return;
|
||||
}
|
||||
urlSearchParams.set('page', '1');
|
||||
urlSearchParams.set('status', filter);
|
||||
setUrlSearchParams(urlSearchParams);
|
||||
};
|
||||
|
||||
const onTypeChange = (evt) => {
|
||||
urlSearchParams.set('type', evt.target.value);
|
||||
setUrlSearchParams(urlSearchParams);
|
||||
|
@ -64,20 +58,13 @@ const Flags: FC = () => {
|
|||
<>
|
||||
<h3 className="mb-4">{t('title')}</h3>
|
||||
<div className="d-flex justify-content-between align-items-center mb-3">
|
||||
<ButtonGroup size="sm">
|
||||
{flagFilterKeys.map((k) => {
|
||||
return (
|
||||
<Button
|
||||
key={k}
|
||||
size="sm"
|
||||
className="text-capitalize"
|
||||
onClick={() => onFilterChange(k)}
|
||||
variant={curFilter === k ? 'secondary' : 'outline-secondary'}>
|
||||
{t(k)}
|
||||
</Button>
|
||||
);
|
||||
})}
|
||||
</ButtonGroup>
|
||||
<QueryGroup
|
||||
data={flagFilterKeys}
|
||||
currentSort={curFilter}
|
||||
sortKey="status"
|
||||
i18nkeyPrefix="admin.flags"
|
||||
/>
|
||||
|
||||
<Form.Select
|
||||
value={curType}
|
||||
onChange={onTypeChange}
|
||||
|
|
|
@ -1,12 +1,5 @@
|
|||
import { FC } from 'react';
|
||||
import {
|
||||
ButtonGroup,
|
||||
Button,
|
||||
Form,
|
||||
Table,
|
||||
Stack,
|
||||
Badge,
|
||||
} from 'react-bootstrap';
|
||||
import { Button, Form, Table, Stack, Badge } from 'react-bootstrap';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
|
@ -17,6 +10,7 @@ import {
|
|||
Modal,
|
||||
BaseUserCard,
|
||||
Empty,
|
||||
QueryGroup,
|
||||
} from '@answer/components';
|
||||
import { ADMIN_LIST_STATUS } from '@answer/common/constants';
|
||||
import { useEditStatusModal, useReportModal } from '@answer/hooks';
|
||||
|
@ -37,7 +31,7 @@ const questionFilterItems: Type.AdminContentsFilterBy[] = [
|
|||
|
||||
const PAGE_SIZE = 20;
|
||||
const Questions: FC = () => {
|
||||
const [urlSearchParams, setUrlSearchParams] = useSearchParams();
|
||||
const [urlSearchParams] = useSearchParams();
|
||||
const curFilter = urlSearchParams.get('status') || questionFilterItems[0];
|
||||
const curPage = Number(urlSearchParams.get('page')) || 1;
|
||||
const { t } = useTranslation('translation', { keyPrefix: 'admin.questions' });
|
||||
|
@ -55,15 +49,6 @@ const Questions: FC = () => {
|
|||
|
||||
const closeModal = useReportModal(refreshList);
|
||||
|
||||
const onFilterChange = (filter) => {
|
||||
if (filter === curFilter) {
|
||||
return;
|
||||
}
|
||||
urlSearchParams.set('page', '1');
|
||||
urlSearchParams.set('status', filter);
|
||||
setUrlSearchParams(urlSearchParams);
|
||||
};
|
||||
|
||||
const handleCallback = (id, type) => {
|
||||
if (type === 'normal') {
|
||||
changeQuestionStatus(id, 'available').then(() => {
|
||||
|
@ -115,20 +100,13 @@ const Questions: FC = () => {
|
|||
<>
|
||||
<h3 className="mb-4">{t('page_title')}</h3>
|
||||
<div className="d-flex justify-content-between align-items-center mb-3">
|
||||
<ButtonGroup size="sm">
|
||||
{questionFilterItems.map((li) => {
|
||||
return (
|
||||
<Button
|
||||
key={li}
|
||||
size="sm"
|
||||
className="text-capitalize"
|
||||
onClick={() => onFilterChange(li)}
|
||||
variant={curFilter === li ? 'secondary' : 'outline-secondary'}>
|
||||
{t(li)}
|
||||
</Button>
|
||||
);
|
||||
})}
|
||||
</ButtonGroup>
|
||||
<QueryGroup
|
||||
data={questionFilterItems}
|
||||
currentSort={curFilter}
|
||||
sortKey="status"
|
||||
i18nkeyPrefix="admin.questions"
|
||||
/>
|
||||
|
||||
<Form.Control
|
||||
size="sm"
|
||||
type="input"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React, { FC, useState } from 'react';
|
||||
import { ButtonGroup, Button, Form, Table, Badge } from 'react-bootstrap';
|
||||
import { FC, useState } from 'react';
|
||||
import { Button, Form, Table, Badge } from 'react-bootstrap';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
|
@ -9,6 +9,7 @@ import {
|
|||
FormatTime,
|
||||
BaseUserCard,
|
||||
Empty,
|
||||
QueryGroup,
|
||||
} from '@answer/components';
|
||||
import * as Type from '@answer/common/interface';
|
||||
import { useChangeModal } from '@answer/hooks';
|
||||
|
@ -34,7 +35,7 @@ const Users: FC = () => {
|
|||
const { t } = useTranslation('translation', { keyPrefix: 'admin.users' });
|
||||
const [userName, setUserName] = useState('');
|
||||
|
||||
const [urlSearchParams, setUrlSearchParams] = useSearchParams();
|
||||
const [urlSearchParams] = useSearchParams();
|
||||
const curFilter = urlSearchParams.get('filter') || UserFilterKeys[0];
|
||||
const curPage = Number(urlSearchParams.get('page') || '1');
|
||||
const {
|
||||
|
@ -51,15 +52,6 @@ const Users: FC = () => {
|
|||
callback: refreshUsers,
|
||||
});
|
||||
|
||||
const onFilterChange = (filter) => {
|
||||
if (filter === urlSearchParams.get('filter')) {
|
||||
return;
|
||||
}
|
||||
urlSearchParams.set('page', '1');
|
||||
urlSearchParams.set('filter', filter);
|
||||
setUrlSearchParams(urlSearchParams);
|
||||
};
|
||||
|
||||
const handleClick = ({ user_id, status }) => {
|
||||
changeModal.onShow({
|
||||
id: user_id,
|
||||
|
@ -71,20 +63,13 @@ const Users: FC = () => {
|
|||
<>
|
||||
<h3 className="mb-4">{t('title')}</h3>
|
||||
<div className="d-flex justify-content-between align-items-center mb-3">
|
||||
<ButtonGroup size="sm">
|
||||
{UserFilterKeys.map((k) => {
|
||||
return (
|
||||
<Button
|
||||
key={k}
|
||||
size="sm"
|
||||
className="text-capitalize"
|
||||
onClick={() => onFilterChange(k)}
|
||||
variant={curFilter === k ? 'secondary' : 'outline-secondary'}>
|
||||
{t(k)}
|
||||
</Button>
|
||||
);
|
||||
})}
|
||||
</ButtonGroup>
|
||||
<QueryGroup
|
||||
data={UserFilterKeys}
|
||||
currentSort={curFilter}
|
||||
sortKey="filter"
|
||||
i18nkeyPrefix="admin.users"
|
||||
/>
|
||||
|
||||
<Form.Control
|
||||
className="d-none"
|
||||
size="sm"
|
||||
|
|
|
@ -1,17 +1,29 @@
|
|||
import { memo, FC } from 'react';
|
||||
import { ButtonGroup } from 'react-bootstrap';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Link, useLocation } from 'react-router-dom';
|
||||
|
||||
import { QueryGroup } from '@answer/components';
|
||||
|
||||
interface Props {
|
||||
count: number;
|
||||
order: string;
|
||||
}
|
||||
|
||||
const sortBtns = [
|
||||
{
|
||||
name: 'score',
|
||||
sort: 'default',
|
||||
},
|
||||
{
|
||||
name: 'newest',
|
||||
sort: 'updated',
|
||||
},
|
||||
];
|
||||
|
||||
const Index: FC<Props> = ({ count = 0, order = 'default' }) => {
|
||||
const { t } = useTranslation('translation', {
|
||||
keyPrefix: 'question_detail.answers',
|
||||
});
|
||||
const location = useLocation();
|
||||
|
||||
return (
|
||||
<div
|
||||
className="d-flex align-items-center justify-content-between mt-5 mb-3"
|
||||
|
@ -19,22 +31,11 @@ const Index: FC<Props> = ({ count = 0, order = 'default' }) => {
|
|||
<h5 className="mb-0">
|
||||
{count} {t('title')}
|
||||
</h5>
|
||||
<ButtonGroup size="sm">
|
||||
<Link
|
||||
to={`${location.pathname}?order=default`}
|
||||
className={`btn btn-outline-secondary ${
|
||||
order !== 'updated' ? 'active' : ''
|
||||
}`}>
|
||||
{t('score')}
|
||||
</Link>
|
||||
<Link
|
||||
to={`${location.pathname}?order=updated`}
|
||||
className={`btn btn-outline-secondary ${
|
||||
order === 'updated' ? 'active' : ''
|
||||
}`}>
|
||||
{t('newest')}
|
||||
</Link>
|
||||
</ButtonGroup>
|
||||
<QueryGroup
|
||||
data={sortBtns}
|
||||
currentSort={order === 'updated' ? 'newest' : 'score'}
|
||||
i18nkeyPrefix="question_detail.answers"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,65 +1,29 @@
|
|||
import { FC, memo } from 'react';
|
||||
import { ListGroupItem, ButtonGroup, Button } from 'react-bootstrap';
|
||||
import { useSearchParams, useNavigate, useLocation } from 'react-router-dom';
|
||||
import { ListGroupItem } from 'react-bootstrap';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const sortBtns = [
|
||||
{
|
||||
name: 'newest',
|
||||
},
|
||||
{
|
||||
name: 'active',
|
||||
},
|
||||
{
|
||||
name: 'score',
|
||||
},
|
||||
];
|
||||
import { QueryGroup } from '@answer/components';
|
||||
|
||||
const sortBtns = ['newest', 'active', 'score'];
|
||||
|
||||
interface Props {
|
||||
count: number;
|
||||
sort: string;
|
||||
}
|
||||
const Index: FC<Props> = ({ sort, count = 0 }) => {
|
||||
const [searchParams] = useSearchParams();
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const { t } = useTranslation('translation', {
|
||||
keyPrefix: 'search.sort_btns',
|
||||
});
|
||||
|
||||
const handleParams = (order): string => {
|
||||
const basePath = location.pathname;
|
||||
searchParams.delete('page');
|
||||
searchParams.set('order', order);
|
||||
const searchStr = searchParams.toString();
|
||||
return `${basePath}?${searchStr}`;
|
||||
};
|
||||
|
||||
const handleClick = (e, type) => {
|
||||
e.preventDefault();
|
||||
const str = handleParams(type);
|
||||
navigate(str);
|
||||
};
|
||||
|
||||
return (
|
||||
<ListGroupItem className="d-flex flex-wrap align-items-center justify-content-between divide-line pb-3 border-bottom px-0">
|
||||
<h5 className="mb-0">{t('counts', { count, keyPrefix: 'search' })}</h5>
|
||||
<ButtonGroup size="sm">
|
||||
{sortBtns.map((item) => {
|
||||
return (
|
||||
<Button
|
||||
as="a"
|
||||
variant="outline-secondary"
|
||||
active={sort === item.name}
|
||||
href={handleParams(item.name)}
|
||||
key={item.name}
|
||||
onClick={(e) => handleClick(e, item.name)}>
|
||||
{t(item.name)}
|
||||
</Button>
|
||||
);
|
||||
})}
|
||||
</ButtonGroup>
|
||||
<QueryGroup
|
||||
data={sortBtns}
|
||||
currentSort={sort}
|
||||
sortKey="order"
|
||||
i18nkeyPrefix="search.sort_btns"
|
||||
/>
|
||||
</ListGroupItem>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -60,10 +60,9 @@ const Index: FC<Props> = ({ data }) => {
|
|||
</div>
|
||||
|
||||
{data.object?.excerpt && (
|
||||
<p
|
||||
className="fs-14 text-truncate-2 mb-2 last-p text-break"
|
||||
dangerouslySetInnerHTML={{ __html: data.object.excerpt }}
|
||||
/>
|
||||
<p className="fs-14 text-truncate-2 mb-2 last-p text-break">
|
||||
{data.object.excerpt}
|
||||
</p>
|
||||
)}
|
||||
|
||||
{data.object?.tags?.map((item) => {
|
||||
|
|
|
@ -1,25 +1,18 @@
|
|||
import { useState } from 'react';
|
||||
import {
|
||||
Container,
|
||||
Row,
|
||||
Col,
|
||||
Card,
|
||||
ButtonGroup,
|
||||
Button,
|
||||
Form,
|
||||
} from 'react-bootstrap';
|
||||
import { useSearchParams, useNavigate } from 'react-router-dom';
|
||||
import { Container, Row, Col, Card, Button, Form } from 'react-bootstrap';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { useQueryTags, following } from '@answer/api';
|
||||
import { Tag, Pagination, PageTitle } from '@answer/components';
|
||||
import { Tag, Pagination, PageTitle, QueryGroup } from '@answer/components';
|
||||
import { formatCount } from '@answer/utils';
|
||||
|
||||
const sortBtns = ['popular', 'name', 'newest'];
|
||||
|
||||
const Tags = () => {
|
||||
const [urlSearch] = useSearchParams();
|
||||
const { t } = useTranslation('translation', { keyPrefix: 'tags' });
|
||||
const [searchTag, setSearchTag] = useState('');
|
||||
const navigate = useNavigate();
|
||||
|
||||
const page = Number(urlSearch.get('page')) || 1;
|
||||
const sort = urlSearch.get('sort');
|
||||
|
@ -36,10 +29,6 @@ const Tags = () => {
|
|||
setSearchTag(e.target.value);
|
||||
};
|
||||
|
||||
const handleSort = (param) => {
|
||||
navigate(`/tags?sort=${param}`);
|
||||
};
|
||||
|
||||
const handleFollow = (tag) => {
|
||||
following({
|
||||
object_id: tag.tag_id,
|
||||
|
@ -67,30 +56,12 @@ const Tags = () => {
|
|||
/>
|
||||
</Form.Group>
|
||||
</Form>
|
||||
<ButtonGroup size="sm">
|
||||
<Button
|
||||
variant={
|
||||
!sort || sort === 'popular'
|
||||
? 'secondary'
|
||||
: 'outline-secondary'
|
||||
}
|
||||
onClick={() => handleSort('popular')}>
|
||||
{t('sort_buttons.popular')}
|
||||
</Button>
|
||||
<Button
|
||||
variant={sort === 'name' ? 'secondary' : 'outline-secondary'}
|
||||
onClick={() => handleSort('name')}>
|
||||
{t('sort_buttons.name')}
|
||||
</Button>
|
||||
<Button
|
||||
className="text-capitalize"
|
||||
variant={
|
||||
sort === 'newest' ? 'secondary' : 'outline-secondary'
|
||||
}
|
||||
onClick={() => handleSort('newest')}>
|
||||
{t('sort_buttons.newest')}
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
<QueryGroup
|
||||
data={sortBtns}
|
||||
currentSort={sort || 'popular'}
|
||||
sortKey="sort"
|
||||
i18nkeyPrefix="tags.sort_buttons"
|
||||
/>
|
||||
</div>
|
||||
</Col>
|
||||
|
||||
|
|
|
@ -19,7 +19,9 @@ const Index: FC<Props> = ({ visible, tabName, data }) => {
|
|||
<ListGroup variant="flush">
|
||||
{data.map((item) => {
|
||||
return (
|
||||
<ListGroupItem className="py-3 px-0" key={item.question_id}>
|
||||
<ListGroupItem
|
||||
className="py-3 px-0"
|
||||
key={tabName === 'questions' ? item.question_id : item.id}>
|
||||
<h6 className="mb-2">
|
||||
<a
|
||||
className="text-break"
|
||||
|
|
|
@ -1,16 +1,9 @@
|
|||
import { FC, memo } from 'react';
|
||||
import { ButtonGroup, Button } from 'react-bootstrap';
|
||||
import { useSearchParams, useNavigate, useLocation } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const sortBtns = [
|
||||
{
|
||||
name: 'newest',
|
||||
},
|
||||
{
|
||||
name: 'score',
|
||||
},
|
||||
];
|
||||
import { QueryGroup } from '@answer/components';
|
||||
|
||||
const sortBtns = ['newest', 'score'];
|
||||
|
||||
interface Props {
|
||||
tabName: string;
|
||||
|
@ -24,25 +17,8 @@ const Index: FC<Props> = ({
|
|||
sort,
|
||||
count = 0,
|
||||
}) => {
|
||||
const [searchParams] = useSearchParams();
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
const { t } = useTranslation('translation', { keyPrefix: 'personal' });
|
||||
|
||||
const handleParams = (order): string => {
|
||||
const basePath = location.pathname;
|
||||
searchParams.delete('page');
|
||||
searchParams.set('order', order);
|
||||
const searchStr = searchParams.toString();
|
||||
return `${basePath}?${searchStr}`;
|
||||
};
|
||||
|
||||
const handleClick = (e, type) => {
|
||||
e.preventDefault();
|
||||
const str = handleParams(type);
|
||||
navigate(str);
|
||||
};
|
||||
|
||||
if (!visible) {
|
||||
return null;
|
||||
}
|
||||
|
@ -53,20 +29,11 @@ const Index: FC<Props> = ({
|
|||
{count} {t(tabName)}
|
||||
</h5>
|
||||
{(tabName === 'answers' || tabName === 'questions') && (
|
||||
<ButtonGroup size="sm">
|
||||
{sortBtns.map((item) => {
|
||||
return (
|
||||
<Button
|
||||
variant="outline-secondary"
|
||||
active={sort === item.name}
|
||||
href={handleParams(item.name)}
|
||||
key={item.name}
|
||||
onClick={(e) => handleClick(e, item.name)}>
|
||||
{t(item.name)}
|
||||
</Button>
|
||||
);
|
||||
})}
|
||||
</ButtonGroup>
|
||||
<QueryGroup
|
||||
data={sortBtns}
|
||||
currentSort={sort}
|
||||
i18nkeyPrefix="personal"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -18,7 +18,7 @@ const Index: FC<Props> = ({ visible, data }) => {
|
|||
<ListGroup variant="flush">
|
||||
{data.map((item) => {
|
||||
return (
|
||||
<ListGroupItem className="d-flex py-3 px-0" key={item}>
|
||||
<ListGroupItem className="d-flex py-3 px-0" key={item.object_id}>
|
||||
<div
|
||||
className={`me-3 text-end ${
|
||||
item.reputation > 0 ? 'text-success' : 'text-danger'
|
||||
|
|
Loading…
Reference in New Issue