Merge pull request #204 from answerdev/feat/1.0.5/ui

Feat/1.0.5/UI
This commit is contained in:
haitao.jarvis
2023-02-15 16:47:38 +08:00
committed by GitHub
6 changed files with 38 additions and 128 deletions
-118
View File
@@ -1,118 +0,0 @@
# Answer
`Answer` is a modern Q&A community application ✨
To learn more about the philosophy and goals of the project, visit [Answer](https://answer.dev).
## ⚙️ Prerequisites
- [Node.js](https://nodejs.org/) `>=16.17`
- [pnpm](https://pnpm.io/) `>=7`
pnpm is required by building the Answer project. To installing the pnpm tools with below commands:
```bash
corepack enable
corepack prepare pnpm@v7.12.2 --activate
```
With Node.js v16.17 or newer, you may install the latest version of pnpm by just specifying the tag:
```bash
corepack prepare pnpm@latest --activate
```
## 🔨 Development
clone the repo locally and run following command in your terminal:
```shell
$ git clone git@github.com:answerdev/answer.git answer
$ cd answer/ui
$ pnpm install
$ pnpm start
```
now, your browser should already open automatically, and autoload `http://localhost:3000`.
you can also manually visit it.
## 👷 Workflow
when cloning repo, and run `pnpm install` to init dependencies. you can use project commands below:
- `pnpm start` run Answer web locally.
- `pnpm build` build Answer for production
- `pnpm lint` lint and fix the code style
## 🌍 I18n(Multi-language)
If you need to add or edit a language entry, just go to the `/i18n/en_US.yaml` file,
all front-end language entries are placed under the `ui` field.
If you would like to help us with the i18n translation, please visit [Answer@Crowdin](https://crowdin.com/translate/answer)
## 💡 Project instructions
```
.
├── cmd
├── configs
├── docs
├── i18n
├── en_US.yaml (basic language file)
├── i18n.yaml (language list)
├── internal
├── ...
└── ui (front-end project starts here)
├── build (built results directory, usually without concern)
├── public (html template for public)
├── scripts (some scripting tools on front-end project)
├── src (almost all front-end resources are here)
├── assets (static resources)
├── common (project information/data defined here)
├── components (all components of the project)
├── hooks (all hooks of the project)
├── i18n (Used only to initialize the front-end i18n tool)
├── pages (all pages of the project)
├── router (Project routing definition)
├── services (all data api of the project)
├── stores (all data stores of the project)
├── utils (all utils of the project)
```
## 🤝 Contributing
#### Fix Bug
If you find a bug, please don't hesitate to [submit an issue](https://github.com/answerdev/answer/issues) to us.
If you can fix it, please include a note with your issue submission.
If it is a bug definitely, you can submit your PR after we confirm it, which will ensure you don't do anything useless.
#### Code Review & Comment
In our development, some codes are not logical we know. If you find it, please don't hesitate to submit PR to us.
In the same way, some function has no comment. We would appreciate it if you could help us supplement it.
#### Translation
All our translations are placed in the i18n directory.
1. If you find that the corresponding key in the language you are using does not have a translation, you can submit your translation.
2. If you want to submit a new language translation, please add your language to the `i18n.yaml` file.
#### Features or Plugin
1. We developed the features for the plan based on the [roadmap](https://github.com/orgs/answerdev/projects/1). If you are suggestions for new functions, please confirm whether they have been planned.
2. Plugins will be available in the future, so stay tuned.
## 📱Environment Support
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br />Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br />Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br />Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br />Safari |
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| last 2 versions | last 2 versions | last 2 versions | last 2 versions |
## ⭐ Built with
- [TypeScript](https://www.typescriptlang.org/) - strongly typed JavaScript
- [React.js](https://reactjs.org/) - Our front end is a React.js app
- [React Router](https://reactrouter.com/en/main) - Router library
- [Bootstrap](https://getbootstrap.com/) - UI library.
- [React Bootstrap](https://react-bootstrap.github.io/) - UI Library(rebuilt for React)
- [axios](https://github.com/axios/axios) - Request library
- [SWR](https://swr.bootcss.com/) - Request library
- [react-i18next](https://react.i18next.com/) - International library
- [zustand](https://github.com/pmndrs/zustand) - State-management library
+12 -5
View File
@@ -15,6 +15,7 @@ import {
Link,
useNavigate,
useLocation,
useMatch,
} from 'react-router-dom';
import classnames from 'classnames';
@@ -35,16 +36,22 @@ import './index.scss';
const Header: FC = () => {
const navigate = useNavigate();
const { user, clear: clearUserStore } = loggedUserInfoStore();
const { t } = useTranslation();
const location = useLocation();
const [urlSearch] = useSearchParams();
const q = urlSearch.get('q');
const { user, clear: clearUserStore } = loggedUserInfoStore();
const { t } = useTranslation();
const [searchStr, setSearch] = useState('');
const siteInfo = siteInfoStore((state) => state.siteInfo);
const brandingInfo = brandingStore((state) => state.branding);
const loginSetting = loginSettingStore((state) => state.login);
const { data: redDot } = useQueryNotificationStatus();
const location = useLocation();
const tagMatch = useMatch('/tags/:slugName');
let askUrl = '/questions/ask';
if (tagMatch && tagMatch.params.slugName) {
askUrl = `${askUrl}?tags=${tagMatch.params.slugName}`;
}
const handleInput = (val) => {
setSearch(val);
};
@@ -189,7 +196,7 @@ const Header: FC = () => {
<Nav.Item className="lg-none mt-3 pb-1">
<Link
to="/questions/ask"
to={askUrl}
className="text-capitalize text-nowrap btn btn-light">
{t('btns.add_question')}
</Link>
@@ -202,7 +209,7 @@ const Header: FC = () => {
<Nav className="d-flex align-items-center flex-lg-nowrap">
<Nav.Item className="me-3">
<Link
to="/questions/ask"
to={askUrl}
className={classnames('text-capitalize text-nowrap btn', {
'btn-light': navbarStyle !== 'theme-light',
'btn-primary': navbarStyle === 'theme-light',
+4 -1
View File
@@ -98,7 +98,10 @@ const Flags: FC = () => {
<small className="text-secondary">
Flagged {li.object_type}
</small>
<BaseUserCard data={li.reported_user} className="mt-2" />
<BaseUserCard
data={li.reported_user}
className="mt-2 fs-14"
/>
<a
href={pathFactory.questionLanding(
li.question_id,
+3 -3
View File
@@ -294,7 +294,7 @@ const Index: FC = () => {
<h5>{t('warn_title')}</h5>
<p>
<Trans
i18nKey="install.warn_description"
i18nKey="install.warn_desc"
components={{ 1: <code /> }}
/>{' '}
<Trans i18nKey="install.install_now">
@@ -313,7 +313,7 @@ const Index: FC = () => {
<h5>{t('db_failed')}</h5>
<p>
<Trans
i18nKey="install.db_failed_description"
i18nKey="install.db_failed_desc"
components={{ 1: <code /> }}
/>
</p>
@@ -323,7 +323,7 @@ const Index: FC = () => {
{step === 8 && (
<div>
<h5>{t('installed')}</h5>
<p>{t('installed_description')}</p>
<p>{t('installed_desc')}</p>
</div>
)}
</Card.Body>
+14 -1
View File
@@ -1,6 +1,6 @@
import React, { useState, useEffect, useRef } from 'react';
import { Container, Row, Col, Form, Button, Card } from 'react-bootstrap';
import { useParams, useNavigate } from 'react-router-dom';
import { useParams, useNavigate, useSearchParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import dayjs from 'dayjs';
@@ -16,6 +16,7 @@ import {
useQueryRevisions,
postAnswer,
useQueryQuestionByTitle,
getTagsBySlugName,
} from '@/services';
import { handleFormError } from '@/utils';
import { pathFactory } from '@/router/pathFactory';
@@ -77,6 +78,17 @@ const Ask = () => {
const { qid } = useParams();
const navigate = useNavigate();
const [searchParams] = useSearchParams();
const initQueryTags = () => {
const queryTags = searchParams.get('tags');
if (!queryTags) {
return;
}
getTagsBySlugName(queryTags).then((tags) => {
// eslint-disable-next-line @typescript-eslint/no-use-before-define
handleTagsChange(tags);
});
};
const isEdit = qid !== undefined;
const { data: similarQuestions = { list: [] } } = useQueryQuestionByTitle(
@@ -85,6 +97,7 @@ const Ask = () => {
useEffect(() => {
if (!isEdit) {
resetForm();
initQueryTags();
}
}, [isEdit]);
const { data: revisions = [] } = useQueryRevisions(qid);
+5
View File
@@ -58,3 +58,8 @@ export const useTagInfo = ({ id = '', name = '' }) => {
export const followTags = (params) => {
return request.put('/answer/api/v1/follow/tags', params);
};
export const getTagsBySlugName = (slugNames: string) => {
const apiUrl = `/answer/api/v1/tags?tags=${encodeURIComponent(slugNames)}`;
return request.get<Type.TagInfo[]>(apiUrl);
};