Merge branch 'ui' of git.backyard.segmentfault.com:opensource/answer into ui

This commit is contained in:
shuai 2022-09-30 12:16:19 +08:00
commit 8358ec3b50
21 changed files with 65 additions and 38 deletions

View File

@ -27,8 +27,8 @@ corepack prepare pnpm@latest --activate
clone the repo locally and run following command in your terminal: clone the repo locally and run following command in your terminal:
```shell ```shell
$ git clone `answer repo` answer $ git clone git@github.com:answerdev/answer.git answer
$ cd answer $ cd answer/ui
$ pnpm install $ pnpm install
$ pnpm run start $ pnpm run start
``` ```

View File

@ -301,6 +301,7 @@ export interface SearchResItem {
answer_count: number; answer_count: number;
accepted: boolean; accepted: boolean;
tags: TagBase[]; tags: TagBase[];
status?: string;
}; };
} }
export interface SearchRes extends ListResult<SearchResItem> { export interface SearchRes extends ListResult<SearchResItem> {

View File

@ -1 +1,2 @@
$link-hover-decoration: none; $link-hover-decoration: none;
$blue: #0033FF !default;

View File

@ -144,6 +144,7 @@ const QuestionList: FC<Props> = ({ source }) => {
<h5 className="text-wrap text-break"> <h5 className="text-wrap text-break">
<NavLink to={`/questions/${li.id}`} className="text-body"> <NavLink to={`/questions/${li.id}`} className="text-body">
{li.title} {li.title}
{li.status === 2 ? ` [${t('closed')}]` : ''}
</NavLink> </NavLink>
</h5> </h5>
<div className="d-flex align-items-center fs-14 text-secondary"> <div className="d-flex align-items-center fs-14 text-secondary">

View File

@ -689,6 +689,7 @@
"modified": "modified", "modified": "modified",
"answered": "answered", "answered": "answered",
"asked": "asked", "asked": "asked",
"closed": "closed",
"follow_a_tag": "Follow a tag" "follow_a_tag": "Follow a tag"
}, },
"personal": { "personal": {

View File

@ -61,7 +61,7 @@ a {
} }
.badge-tag:hover { .badge-tag:hover {
background: #9EC5FE; background: #9ec5fe;
} }
.divide-line { .divide-line {
@ -70,7 +70,6 @@ a {
.page-wrap { .page-wrap {
min-height: calc(100vh - 148px); min-height: calc(100vh - 148px);
overflow-y: auto;
} }
.btn-no-border, .btn-no-border,

View File

@ -30,7 +30,12 @@ const SearchQuestion = ({ similarQuestions }) => {
key={item.id} key={item.id}
href={`/questions/${item.id}`} href={`/questions/${item.id}`}
target="_blank"> target="_blank">
<span className="text-wrap text-break">{item.title}</span> <span className="text-wrap text-break">
{item.title}
{item.status === 'closed'
? ` [${t('closed', { keyPrefix: 'question' })}]`
: null}
</span>
{item.accepted_answer ? ( {item.accepted_answer ? (
<span className="ms-3 text-success"> <span className="ms-3 text-success">
<Icon type="bi" name="check-circle-fill" /> <Icon type="bi" name="check-circle-fill" />

View File

@ -269,12 +269,12 @@ const Ask = () => {
<PageTitle title={pageTitle} /> <PageTitle title={pageTitle} />
<Container className="pt-4 mt-2 mb-5"> <Container className="pt-4 mt-2 mb-5">
<Row className="justify-content-center"> <Row className="justify-content-center">
<Col sm={12} md={10}> <Col xxl={10} md={12}>
<h3 className="mb-4">{isEdit ? t('edit_title') : t('title')}</h3> <h3 className="mb-4">{isEdit ? t('edit_title') : t('title')}</h3>
</Col> </Col>
</Row> </Row>
<Row className="justify-content-center"> <Row className="justify-content-center">
<Col sm={12} md={7} className="mb-4 mb-md-0"> <Col xxl={7} lg={8} sm={12} className="mb-4 mb-md-0">
<Form noValidate onSubmit={handleSubmit}> <Form noValidate onSubmit={handleSubmit}>
{isEdit && ( {isEdit && (
<Form.Group controlId="revision" className="mb-3"> <Form.Group controlId="revision" className="mb-3">
@ -421,7 +421,7 @@ const Ask = () => {
)} )}
</Form> </Form>
</Col> </Col>
<Col sm={12} md={3}> <Col xxl={3} lg={4} sm={12}>
{focusType === 'title' && ( {focusType === 'title' && (
<Card className="mb-4"> <Card className="mb-4">
<Card.Header>{t('how_to_ask.title')}</Card.Header> <Card.Header>{t('how_to_ask.title')}</Card.Header>

View File

@ -50,6 +50,9 @@ const Index: FC<Props> = ({ data, initPage, hasAnswer }) => {
<h1 className="fs-3 mb-3 text-wrap text-break"> <h1 className="fs-3 mb-3 text-wrap text-break">
<Link className="text-body" reloadDocument to={`/questions/${data.id}`}> <Link className="text-body" reloadDocument to={`/questions/${data.id}`}>
{data.title} {data.title}
{data.status === 2
? ` [${t('closed', { keyPrefix: 'question' })}]`
: ''}
</Link> </Link>
</h1> </h1>
<div className="d-flex align-items-center fs-14 mb-3 text-secondary"> <div className="d-flex align-items-center fs-14 mb-3 text-secondary">

View File

@ -1,5 +1,10 @@
.fmt img { .fmt {
img {
max-width: 100%; max-width: 100%;
}
p {
word-break: break-all;
}
} }
.answer-item { .answer-item {

View File

@ -109,7 +109,7 @@ const Index = () => {
<PageTitle title={question?.title} /> <PageTitle title={question?.title} />
<Container className="pt-4 mt-2 mb-5"> <Container className="pt-4 mt-2 mb-5">
<Row className="justify-content-center"> <Row className="justify-content-center">
<Col lg={7}> <Col xxl={7} lg={8} sm={12}>
{question?.operation?.operation_type && ( {question?.operation?.operation_type && (
<Alert data={question.operation} /> <Alert data={question.operation} />
)} )}
@ -156,7 +156,7 @@ const Index = () => {
/> />
)} )}
</Col> </Col>
<Col lg={3}> <Col xxl={3} lg={4} sm={12}>
<RelatedQuestions id={question?.id || ''} /> <RelatedQuestions id={question?.id || ''} />
</Col> </Col>
</Row> </Row>

View File

@ -123,12 +123,12 @@ const Ask = () => {
<PageTitle title={t('edit_answer', { keyPrefix: 'page_title' })} /> <PageTitle title={t('edit_answer', { keyPrefix: 'page_title' })} />
<Container className="pt-4 mt-2 mb-5 edit-answer-wrap"> <Container className="pt-4 mt-2 mb-5 edit-answer-wrap">
<Row className="justify-content-center"> <Row className="justify-content-center">
<Col sm={12} md={10}> <Col xxl={10} md={12}>
<h3 className="mb-4">{t('title')}</h3> <h3 className="mb-4">{t('title')}</h3>
</Col> </Col>
</Row> </Row>
<Row className="justify-content-center"> <Row className="justify-content-center">
<Col sm={12} md={7} className="mb-4 mb-md-0"> <Col xxl={7} lg={8} sm={12} className="mb-4 mb-md-0">
<a href={`/questions/${qid}`} target="_blank" rel="noreferrer"> <a href={`/questions/${qid}`} target="_blank" rel="noreferrer">
<h5 className="mb-3">{data?.question.title}</h5> <h5 className="mb-3">{data?.question.title}</h5>
</a> </a>
@ -216,7 +216,7 @@ const Ask = () => {
</div> </div>
</Form> </Form>
</Col> </Col>
<Col sm={12} md={3}> <Col xxl={3} lg={4} sm={12}>
<Card className="mb-4"> <Card className="mb-4">
<Card.Header>{t('how_to_ask.title')}</Card.Header> <Card.Header>{t('how_to_ask.title')}</Card.Header>
<Card.Body> <Card.Body>

View File

@ -26,10 +26,10 @@ const Questions: FC = () => {
<PageTitle title={pageTitle} suffix={slogan} /> <PageTitle title={pageTitle} suffix={slogan} />
<Container className="pt-4 mt-2 mb-5"> <Container className="pt-4 mt-2 mb-5">
<Row className="justify-content-center"> <Row className="justify-content-center">
<Col lg={7}> <Col xxl={7} lg={8} sm={12}>
<QuestionList source="questions" /> <QuestionList source="questions" />
</Col> </Col>
<Col lg={3}> <Col xxl={3} lg={4} sm={12}>
<FollowingTags /> <FollowingTags />
<HotQuestions /> <HotQuestions />
</Col> </Col>

View File

@ -1,5 +1,6 @@
import { memo, FC } from 'react'; import { memo, FC } from 'react';
import { ListGroupItem, Badge } from 'react-bootstrap'; import { ListGroupItem, Badge } from 'react-bootstrap';
import { useTranslation } from 'react-i18next';
import { Icon, Tag, FormatTime, BaseUserCard } from '@answer/components'; import { Icon, Tag, FormatTime, BaseUserCard } from '@answer/components';
import type { SearchResItem } from '@answer/common/interface'; import type { SearchResItem } from '@answer/common/interface';
@ -8,6 +9,8 @@ interface Props {
data: SearchResItem; data: SearchResItem;
} }
const Index: FC<Props> = ({ data }) => { const Index: FC<Props> = ({ data }) => {
const { t } = useTranslation('translation', { keyPrefix: 'question' });
console.log('t: ', t);
if (!data?.object_type) { if (!data?.object_type) {
return null; return null;
} }
@ -24,6 +27,9 @@ const Index: FC<Props> = ({ data }) => {
className="h5 mb-0 text-body text-break" className="h5 mb-0 text-body text-break"
href={`/questions/${data.object.id}`}> href={`/questions/${data.object.id}`}>
{data.object.title} {data.object.title}
{data.object.status === 'closed'
? ` [${t('closed', { keyPrefix: 'question' })}]`
: null}
</a> </a>
</div> </div>
<div className="d-flex flex-wrap align-items-center fs-14 text-secondary mb-2"> <div className="d-flex flex-wrap align-items-center fs-14 text-secondary mb-2">
@ -51,10 +57,6 @@ const Index: FC<Props> = ({ data }) => {
)} )}
<span>{data.object?.answer_count}</span> <span>{data.object?.answer_count}</span>
</div> </div>
{/* <div className="d-flex align-items-center">
<Icon name="eye-fill fs-6 me-1" />
<span> 0</span>
</div> */}
</div> </div>
</div> </div>

View File

@ -32,7 +32,7 @@ const Index = () => {
<PageTitle title={pageTitle} /> <PageTitle title={pageTitle} />
<Container className="pt-4 mt-2 mb-5"> <Container className="pt-4 mt-2 mb-5">
<Row className="justify-content-center"> <Row className="justify-content-center">
<Col lg={7} className="mb-3"> <Col xxl={7} lg={8} sm={12} className="mb-3">
<Head data={extra} /> <Head data={extra} />
<ListGroup variant="flush" className="mb-5"> <ListGroup variant="flush" className="mb-5">
@ -53,7 +53,7 @@ const Index = () => {
/> />
</div> </div>
</Col> </Col>
<Col lg={3}> <Col xxl={3} lg={4} sm={12}>
<Tips /> <Tips />
</Col> </Col>
</Row> </Row>

View File

@ -58,7 +58,7 @@ const Questions: FC = () => {
<PageTitle title={pageTitle} /> <PageTitle title={pageTitle} />
<Container className="pt-4 mt-2 mb-5"> <Container className="pt-4 mt-2 mb-5">
<Row className="justify-content-center"> <Row className="justify-content-center">
<Col lg={7}> <Col xxl={7} lg={8} sm={12}>
<div className="tag-box mb-5"> <div className="tag-box mb-5">
<h3 className="mb-3"> <h3 className="mb-3">
<Link <Link
@ -90,7 +90,7 @@ const Questions: FC = () => {
</div> </div>
<QuestionList source="tag" /> <QuestionList source="tag" />
</Col> </Col>
<Col lg={3}> <Col xxl={3} lg={4} sm={12}>
<FollowingTags /> <FollowingTags />
<HotQuestions /> <HotQuestions />
</Col> </Col>

View File

@ -147,12 +147,12 @@ const Ask = () => {
<PageTitle title={t('edit_tag', { keyPrefix: 'page_title' })} /> <PageTitle title={t('edit_tag', { keyPrefix: 'page_title' })} />
<Container className="pt-4 mt-2 mb-5 edit-answer-wrap"> <Container className="pt-4 mt-2 mb-5 edit-answer-wrap">
<Row className="justify-content-center"> <Row className="justify-content-center">
<Col sm={12} md={10}> <Col xxl={10} md={12}>
<h3 className="mb-4">{t('title')}</h3> <h3 className="mb-4">{t('title')}</h3>
</Col> </Col>
</Row> </Row>
<Row className="justify-content-center"> <Row className="justify-content-center">
<Col sm={12} md={7} className="mb-4 mb-md-0"> <Col xxl={7} lg={8} sm={12} className="mb-4 mb-md-0">
<Form noValidate onSubmit={handleSubmit}> <Form noValidate onSubmit={handleSubmit}>
<Form.Group controlId="revision" className="mb-3"> <Form.Group controlId="revision" className="mb-3">
<Form.Label>{t('form.fields.revision.label')}</Form.Label> <Form.Label>{t('form.fields.revision.label')}</Form.Label>
@ -248,7 +248,7 @@ const Ask = () => {
</div> </div>
</Form> </Form>
</Col> </Col>
<Col sm={12} md={3}> <Col xxl={3} lg={4} sm={12}>
<Card className="mb-4"> <Card className="mb-4">
<Card.Header>{t('how_to_format.title')}</Card.Header> <Card.Header>{t('how_to_format.title')}</Card.Header>
<Card.Body> <Card.Body>

View File

@ -53,9 +53,9 @@ const Tags = () => {
<PageTitle title={t('tags', { keyPrefix: 'page_title' })} /> <PageTitle title={t('tags', { keyPrefix: 'page_title' })} />
<Container className="py-3 my-3"> <Container className="py-3 my-3">
<Row className="mb-4 d-flex justify-content-center"> <Row className="mb-4 d-flex justify-content-center">
<Col lg={10}> <Col xxl={10} sm={12}>
<h3 className="mb-4">{t('title')}</h3> <h3 className="mb-4">{t('title')}</h3>
<div className="d-flex justify-content-between align-items-center"> <div className="d-flex justify-content-between align-items-center flex-wrap">
<Form> <Form>
<Form.Group controlId="formBasicEmail"> <Form.Group controlId="formBasicEmail">
<Form.Control <Form.Control
@ -94,10 +94,16 @@ const Tags = () => {
</div> </div>
</Col> </Col>
<Col className="mt-4" lg={10}> <Col className="mt-4" xxl={10} sm={12}>
<Row> <Row>
{tags?.list?.map((tag) => ( {tags?.list?.map((tag) => (
<Col key={tag.slug_name} lg={3} md={4} className="mb-4"> <Col
key={tag.slug_name}
xs={12}
lg={3}
md={4}
sm={6}
className="mb-4">
<Card className="h-100"> <Card className="h-100">
<Card.Body className="d-flex flex-column align-items-start"> <Card.Body className="d-flex flex-column align-items-start">
<Tag className="mb-3" href={`/tags/${tag.slug_name}`}> <Tag className="mb-3" href={`/tags/${tag.slug_name}`}>

View File

@ -69,7 +69,7 @@ const Notifications = () => {
<PageTitle title={t('notifications', { keyPrefix: 'page_title' })} /> <PageTitle title={t('notifications', { keyPrefix: 'page_title' })} />
<Container className="pt-4 mt-2 mb-5"> <Container className="pt-4 mt-2 mb-5">
<Row className="justify-content-center"> <Row className="justify-content-center">
<Col xs={12} lg={7}> <Col xxl={7} lg={8} sm={12}>
<h3 className="mb-4">{t('title')}</h3> <h3 className="mb-4">{t('title')}</h3>
<div className="d-flex justify-content-between mb-3"> <div className="d-flex justify-content-between mb-3">
<ButtonGroup size="sm"> <ButtonGroup size="sm">
@ -120,7 +120,7 @@ const Notifications = () => {
</div> </div>
)} )}
</Col> </Col>
<Col xs={12} lg={3} /> <Col xxl={3} lg={4} sm={12} />
</Row> </Row>
</Container> </Container>
</> </>

View File

@ -27,6 +27,9 @@ const Index: FC<Props> = ({ visible, tabName, data }) => {
tabName === 'questions' ? item.question_id : item.id tabName === 'questions' ? item.question_id : item.id
}`}> }`}>
{item.title} {item.title}
{tabName === 'questions' && item.status === 'closed'
? ` [${t('closed', { keyPrefix: 'question' })}]`
: null}
</a> </a>
</h6> </h6>
<div className="d-flex align-items-center fs-14 text-secondary mb-2"> <div className="d-flex align-items-center fs-14 text-secondary mb-2">

View File

@ -57,10 +57,10 @@ const Personal: FC = () => {
{userInfo?.info?.status !== 'normal' && userInfo?.info?.status_msg && ( {userInfo?.info?.status !== 'normal' && userInfo?.info?.status_msg && (
<Alert data={userInfo?.info.status_msg} /> <Alert data={userInfo?.info.status_msg} />
)} )}
<Col lg={7}> <Col xxl={7} lg={8} sm={12}>
<UserInfo data={userInfo?.info} /> <UserInfo data={userInfo?.info} />
</Col> </Col>
<Col lg={3} className="d-flex justify-content-end"> <Col xxl={3} lg={4} sm={12} className="d-flex justify-content-end">
{isSelf && ( {isSelf && (
<div> <div>
<Button <Button
@ -78,7 +78,7 @@ const Personal: FC = () => {
<Col lg={10}> <Col lg={10}>
<NavBar tabName={tabName} slug={username} isSelf={isSelf} /> <NavBar tabName={tabName} slug={username} isSelf={isSelf} />
</Col> </Col>
<Col lg={7}> <Col xxl={7} lg={8} sm={12}>
<Overview <Overview
visible={tabName === 'overview'} visible={tabName === 'overview'}
introduction={userInfo?.info?.bio_html} introduction={userInfo?.info?.bio_html}
@ -111,7 +111,7 @@ const Personal: FC = () => {
</div> </div>
)} )}
</Col> </Col>
<Col lg={3}> <Col xxl={3} lg={4} sm={12}>
<h5 className="mb-3">Stats</h5> <h5 className="mb-3">Stats</h5>
{userInfo?.info && ( {userInfo?.info && (
<> <>