mirror of https://gitee.com/answerdev/answer.git
Merge branch 'ui' of git.backyard.segmentfault.com:opensource/answer into ui
This commit is contained in:
commit
b893f489c2
|
@ -26,7 +26,8 @@ module.exports = {
|
|||
const config = configFunction(proxy, allowedHost);
|
||||
config.proxy = {
|
||||
'/answer': {
|
||||
target: 'http://10.0.10.98:2060',
|
||||
target: "http://10.0.20.84:8080",
|
||||
// target: 'http://10.0.10.98:2060',
|
||||
changeOrigin: true,
|
||||
secure: false,
|
||||
},
|
||||
|
|
|
@ -5,23 +5,35 @@ import { Avatar } from '@answer/components';
|
|||
|
||||
interface Props {
|
||||
data: any;
|
||||
showAvatar?: boolean;
|
||||
avatarSize?: string;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const Index: FC<Props> = ({
|
||||
data,
|
||||
showAvatar = true,
|
||||
avatarSize = '20px',
|
||||
className = 'fs-14',
|
||||
}) => {
|
||||
return (
|
||||
<div className={`text-secondary ${className}`}>
|
||||
<Link to={`/users/${data?.username}`}>
|
||||
<Avatar avatar={data?.avatar} size={avatarSize} className="me-1" />
|
||||
</Link>
|
||||
<Link to={`/users/${data?.username}`} className="me-1 text-break">
|
||||
{data?.display_name}
|
||||
</Link>
|
||||
{data.status !== 'deleted' ? (
|
||||
<Link to={`/users/${data?.username}`}>
|
||||
{showAvatar && (
|
||||
<Avatar avatar={data?.avatar} size={avatarSize} className="me-1" />
|
||||
)}
|
||||
<span className="me-1 text-break">{data?.display_name}</span>
|
||||
</Link>
|
||||
) : (
|
||||
<>
|
||||
{showAvatar && (
|
||||
<Avatar avatar={data?.avatar} size={avatarSize} className="me-1" />
|
||||
)}
|
||||
<span className="me-1 text-break">{data?.display_name}</span>
|
||||
</>
|
||||
)}
|
||||
|
||||
<span className="fw-bold">{data?.rank}</span>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -17,15 +17,20 @@ const ActionBar = ({
|
|||
onReply,
|
||||
onVote,
|
||||
onAction,
|
||||
userStatus = '',
|
||||
}) => {
|
||||
const { t } = useTranslation('translation', { keyPrefix: 'comment' });
|
||||
|
||||
return (
|
||||
<div className="d-flex justify-content-between fs-14">
|
||||
<div className="d-flex align-items-center">
|
||||
<Link to={`/users/${username}`}>{nickName}</Link>
|
||||
<span className="mx-1 text-secondary">•</span>
|
||||
<FormatTime time={createdAt} className="text-secondary me-3" />
|
||||
<div className="d-flex align-items-center text-secondary">
|
||||
{userStatus !== 'deleted' ? (
|
||||
<Link to={`/users/${username}`}>{nickName}</Link>
|
||||
) : (
|
||||
<span>{nickName}</span>
|
||||
)}
|
||||
<span className="mx-1">•</span>
|
||||
<FormatTime time={createdAt} className="me-3" />
|
||||
<Button
|
||||
variant="link"
|
||||
size="sm"
|
||||
|
|
|
@ -269,6 +269,7 @@ const Comment = ({ objectId, mode }) => {
|
|||
voteCount={item.vote_count}
|
||||
isVote={item.is_vote}
|
||||
memberActions={item.member_actions}
|
||||
userStatus={item.user_status}
|
||||
onReply={() => {
|
||||
handleReply(item.comment_id);
|
||||
}}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { FC, memo } from 'react';
|
||||
import { FC } from 'react';
|
||||
import { Pagination } from 'react-bootstrap';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useSearchParams, useNavigate, useLocation } from 'react-router-dom';
|
||||
|
@ -47,6 +47,7 @@ const PageItem = ({ page, currentPage, path }: PageItemProps) => {
|
|||
href={path}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
navigate(path);
|
||||
window.scrollTo(0, 0);
|
||||
}}>
|
||||
|
@ -111,7 +112,7 @@ const Index: FC<Props> = ({
|
|||
)}
|
||||
{currentPage === 4 && totalPage > 6 && (
|
||||
<PageItem
|
||||
key="6"
|
||||
key="page6"
|
||||
page={6}
|
||||
currentPage={currentPage}
|
||||
path={handleParams(6)}
|
||||
|
@ -133,13 +134,13 @@ const Index: FC<Props> = ({
|
|||
{currentPage >= 5 && (
|
||||
<>
|
||||
<PageItem
|
||||
key="prev2"
|
||||
key={realPage - 2}
|
||||
page={realPage - 2}
|
||||
currentPage={currentPage}
|
||||
path={handleParams(realPage - 2)}
|
||||
/>
|
||||
<PageItem
|
||||
key="prev1"
|
||||
key={realPage - 1}
|
||||
page={realPage - 1}
|
||||
currentPage={currentPage}
|
||||
path={handleParams(realPage - 1)}
|
||||
|
@ -194,4 +195,4 @@ const Index: FC<Props> = ({
|
|||
);
|
||||
};
|
||||
|
||||
export default memo(Index);
|
||||
export default Index;
|
||||
|
|
|
@ -5,7 +5,14 @@ import { useTranslation } from 'react-i18next';
|
|||
|
||||
import { useQuestionList } from '@answer/api';
|
||||
import type * as Type from '@answer/common/interface';
|
||||
import { Icon, Tag, Pagination, FormatTime, Empty } from '@answer/components';
|
||||
import {
|
||||
Icon,
|
||||
Tag,
|
||||
Pagination,
|
||||
FormatTime,
|
||||
Empty,
|
||||
BaseUserCard,
|
||||
} from '@answer/components';
|
||||
|
||||
const QuestionOrderKeys: Type.QuestionOrderBy[] = [
|
||||
'newest',
|
||||
|
@ -25,12 +32,11 @@ const QuestionLastUpdate = ({ q }) => {
|
|||
// question answered
|
||||
return (
|
||||
<>
|
||||
<a
|
||||
className="p-0"
|
||||
href={`/users/${q.last_answered_user_info.username}`}>
|
||||
{q.last_answered_user_info.display_name}
|
||||
</a>
|
||||
<span className="fw-bold px-1">{q.last_answered_user_info.rank}</span>
|
||||
<BaseUserCard
|
||||
data={q.last_answered_user_info}
|
||||
showAvatar={false}
|
||||
className="me-1"
|
||||
/>
|
||||
•
|
||||
<FormatTime
|
||||
time={q.update_time}
|
||||
|
@ -45,10 +51,11 @@ const QuestionLastUpdate = ({ q }) => {
|
|||
// question modified
|
||||
return (
|
||||
<>
|
||||
<a className="p-0" href={`/users/${q.update_user_info.username}`}>
|
||||
{q.update_user_info.display_name}
|
||||
</a>
|
||||
<span className="fw-bold px-1">{q.update_user_info.rank}</span>
|
||||
<BaseUserCard
|
||||
data={q.update_user_info}
|
||||
showAvatar={false}
|
||||
className="me-1"
|
||||
/>
|
||||
•
|
||||
<FormatTime
|
||||
time={q.edit_time}
|
||||
|
@ -62,10 +69,7 @@ const QuestionLastUpdate = ({ q }) => {
|
|||
// default: asked
|
||||
return (
|
||||
<>
|
||||
<a className="p-0" href={`/users/${q.user_info.username}`}>
|
||||
{q.user_info.display_name}
|
||||
</a>
|
||||
<strong className="px-1">{q.user_info.rank}</strong>
|
||||
<BaseUserCard data={q.user_info} showAvatar={false} className="me-1" />
|
||||
•
|
||||
<FormatTime
|
||||
time={q.create_time}
|
||||
|
|
|
@ -12,14 +12,22 @@ interface Props {
|
|||
const Index: FC<Props> = ({ data, time, preFix }) => {
|
||||
return (
|
||||
<div className="d-flex">
|
||||
<Link to={`/users/${data?.username}`}>
|
||||
{data?.status !== 'deleted' ? (
|
||||
<Link to={`/users/${data?.username}`}>
|
||||
<Avatar avatar={data?.avatar} size="40px" className="me-2" />
|
||||
</Link>
|
||||
) : (
|
||||
<Avatar avatar={data?.avatar} size="40px" className="me-2" />
|
||||
</Link>
|
||||
)}
|
||||
<div className="fs-14 text-secondary">
|
||||
<div>
|
||||
<Link to={`/users/${data?.username}`} className="me-1 text-break">
|
||||
{data?.display_name}
|
||||
</Link>
|
||||
{data?.status !== 'deleted' ? (
|
||||
<Link to={`/users/${data?.username}`} className="me-1 text-break">
|
||||
{data?.display_name}
|
||||
</Link>
|
||||
) : (
|
||||
<span className="me-1 text-break">{data?.display_name}</span>
|
||||
)}
|
||||
<span className="fw-bold">{data?.rank}</span>
|
||||
</div>
|
||||
{time && <FormatTime time={time} preFix={preFix} />}
|
||||
|
|
|
@ -848,7 +848,7 @@
|
|||
"interface": {
|
||||
"page_title": "Interface",
|
||||
"logo": {
|
||||
"label": "Logo",
|
||||
"label": "Logo (optional)",
|
||||
"msg": "Site logo cannot be empty.",
|
||||
"text": "You can upload your image or <1>reset</1> it to the site title text."
|
||||
},
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import { memo, FC } from 'react';
|
||||
import { ListGroupItem, Badge } from 'react-bootstrap';
|
||||
|
||||
import { Icon, Tag, FormatTime } from '@answer/components';
|
||||
import { Icon, Tag, FormatTime, BaseUserCard } from '@answer/components';
|
||||
import type { SearchResItem } from '@answer/common/interface';
|
||||
import { formatCount } from '@answer/utils';
|
||||
|
||||
interface Props {
|
||||
data: SearchResItem;
|
||||
|
@ -28,14 +27,8 @@ const Index: FC<Props> = ({ data }) => {
|
|||
</a>
|
||||
</div>
|
||||
<div className="d-flex flex-wrap align-items-center fs-14 text-secondary mb-2">
|
||||
<a href={`/users/${data.object?.user_info?.username}`}>
|
||||
{data.object?.user_info?.display_name}
|
||||
</a>
|
||||
{data.object?.user_info?.rank > 0 && (
|
||||
<span className="fw-bold ms-1">
|
||||
{formatCount(data.object.user_info.rank)}
|
||||
</span>
|
||||
)}
|
||||
<BaseUserCard data={data.object?.user_info} showAvatar={false} />
|
||||
|
||||
<span className="split-dot" />
|
||||
<FormatTime
|
||||
time={data.object?.created_at}
|
||||
|
|
|
@ -37,9 +37,13 @@ const Inbox = ({ data, handleReadNotification }) => {
|
|||
key={item.id}
|
||||
className={classNames('py-3', !item.is_read && 'warning')}>
|
||||
<div>
|
||||
<Link to={`/users/${item.user_info.username}`}>
|
||||
{item.user_info.display_name}
|
||||
</Link>{' '}
|
||||
{item.user_info.status !== 'deleted' ? (
|
||||
<Link to={`/users/${item.user_info.username}`}>
|
||||
{item.user_info.display_name}{' '}
|
||||
</Link>
|
||||
) : (
|
||||
<span>{item.user_info.display_name} </span>
|
||||
)}
|
||||
{item.notification_action}{' '}
|
||||
<Link to={url} onClick={() => handleReadNotification(item.id)}>
|
||||
{item.object_info.title}
|
||||
|
|
|
@ -2,7 +2,7 @@ import { FC, memo } from 'react';
|
|||
import { ListGroup, ListGroupItem } from 'react-bootstrap';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { Icon, FormatTime, Tag } from '@answer/components';
|
||||
import { Icon, FormatTime, Tag, BaseUserCard } from '@answer/components';
|
||||
|
||||
interface Props {
|
||||
visible: boolean;
|
||||
|
@ -31,15 +31,10 @@ const Index: FC<Props> = ({ visible, tabName, data }) => {
|
|||
</h6>
|
||||
<div className="d-flex align-items-center fs-14 text-secondary mb-2">
|
||||
{tabName === 'bookmarks' && (
|
||||
<div className="d-flex">
|
||||
<a
|
||||
href={`/users/${item.user_info?.username}`}
|
||||
className="me-1">
|
||||
{item.user_info?.display_name}
|
||||
</a>
|
||||
<strong>{item.user_info?.rank}</strong>
|
||||
<>
|
||||
<BaseUserCard data={item.user_info} showAvatar={false} />
|
||||
<span className="split-dot" />
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
<FormatTime
|
||||
time={item.create_time}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { FC, memo } from 'react';
|
||||
import { Badge, OverlayTrigger, Tooltip } from 'react-bootstrap';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import { Avatar, Icon } from '@answer/components';
|
||||
import type { UserInfoRes } from '@answer/common/interface';
|
||||
|
@ -16,14 +17,26 @@ const Index: FC<Props> = ({ data }) => {
|
|||
}
|
||||
return (
|
||||
<div className="d-flex mb-4">
|
||||
<a href={`/users/${data.username}`}>
|
||||
{data?.status !== 'deleted' ? (
|
||||
<Link to={`/users/${data.username}`} reloadDocument>
|
||||
<Avatar avatar={data.avatar} size="160px" />
|
||||
</Link>
|
||||
) : (
|
||||
<Avatar avatar={data.avatar} size="160px" />
|
||||
</a>
|
||||
)}
|
||||
|
||||
<div className="ms-4">
|
||||
<div className="d-flex align-items-center mb-2">
|
||||
<a href={`/users/${data.username}`} className="text-body h3 mb-0">
|
||||
{data.display_name}
|
||||
</a>
|
||||
{data?.status !== 'deleted' ? (
|
||||
<Link
|
||||
to={`/users/${data.username}`}
|
||||
className="text-body h3 mb-0"
|
||||
reloadDocument>
|
||||
{data.display_name}
|
||||
</Link>
|
||||
) : (
|
||||
<span className="text-body h3 mb-0">{data.display_name}</span>
|
||||
)}
|
||||
{data?.is_admin && (
|
||||
<div className="ms-2">
|
||||
<OverlayTrigger
|
||||
|
|
Loading…
Reference in New Issue