Merge branch 'feat/ui-1.0.2' into 'test'

feat(HotQuestions): Hot questions maximum request 6 items

See merge request opensource/answer!389
This commit is contained in:
贾海涛(龙笛) 2022-12-27 10:15:25 +00:00
commit 748f7bdeb6
11 changed files with 110 additions and 1141 deletions

View File

@ -841,6 +841,11 @@ ui:
confirm_new_email_invalid: >-
Sorry, this confirmation link is no longer valid. Perhaps your email was
already changed?
unsubscribe:
page_title: Unsubscribe
success_title: Unsubscribe Successful
success_desc: You have been successfully removed from this subscriber list and wont receive any further emails from us.
link: Change settings
question:
following_tags: Following Tags
edit: Edit

File diff suppressed because it is too large Load Diff

View File

@ -26,6 +26,7 @@ const Index: FC<Props> = ({ data }) => {
answerId: data.object.id,
});
}
return (
<ListGroupItem className="py-3 px-0 border-start-0 border-end-0 bg-transparent">
<div className="mb-2 clearfix">

View File

@ -31,13 +31,15 @@ const Index = () => {
const getProfile = () => {
getLoggedUserInfo().then((res) => {
setFormData({
notice_switch: {
value: res.notice_status === 1,
isInvalid: false,
errorMsg: '',
},
});
if (res) {
setFormData({
notice_switch: {
value: res.notice_status === 1,
isInvalid: false,
errorMsg: '',
},
});
}
});
};

View File

@ -43,12 +43,14 @@ const Index: React.FC = () => {
});
const getProfile = () => {
getLoggedUserInfo().then((res) => {
formData.display_name.value = res.display_name;
formData.bio.value = res.bio;
formData.avatar.value = res.avatar;
formData.location.value = res.location;
formData.website.value = res.website;
setFormData({ ...formData });
if (res) {
formData.display_name.value = res.display_name;
formData.bio.value = res.bio;
formData.avatar.value = res.avatar;
formData.location.value = res.location;
formData.website.value = res.website;
setFormData({ ...formData });
}
});
};

View File

@ -0,0 +1,36 @@
import { FC, memo, useEffect } from 'react';
import { Container, Row, Col } from 'react-bootstrap';
import { Link, useSearchParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { unsubscribe } from '@/services';
import { usePageTags } from '@/hooks';
const Index: FC = () => {
const { t } = useTranslation('translation', { keyPrefix: 'unsubscribe' });
usePageTags({
title: t('page_title'),
});
const [searchParams] = useSearchParams();
const code = searchParams.get('code');
useEffect(() => {
if (code) {
unsubscribe(code);
}
}, [code]);
return (
<Container className="pt-4 mt-2 mb-5">
<Row className="justify-content-center">
<Col lg={6}>
<h3 className="text-center mt-3 mb-5">{t('success_title')}</h3>
<p className="text-center">{t('success_desc')}</p>
<div className="text-center">
<Link to="/users/settings/notify">{t('link')}</Link>
</div>
</Col>
</Row>
</Container>
);
};
export default memo(Index);

View File

@ -337,6 +337,10 @@ const routes: RouteNode[] = [
},
],
},
{
path: '/users/unsubscribe',
page: 'pages/Users/Unsubscribe',
},
],
},
{

View File

@ -20,7 +20,7 @@ export const useQuestionList = (params: Type.QueryQuestionsReq) => {
export const useHotQuestions = (
params: Type.QueryQuestionsReq = {
page: 1,
page_size: 10,
page_size: 6,
order: 'frequent',
},
) => {

View File

@ -257,3 +257,8 @@ export const getAppSettings = () => {
export const reopenQuestion = (params: { question_id: string }) => {
return request.put('/answer/api/v1/question/reopen', params);
};
export const unsubscribe = (code: string) => {
const apiUrl = '/answer/api/v1/user/email/notification';
return request.put(apiUrl, { code });
};

View File

@ -81,20 +81,13 @@ function formatUptime(value) {
return `< 1 ${t('dates.hour')}`;
}
function escapeRemove(str) {
function escapeRemove(str: string) {
if (!str || typeof str !== 'string') return str;
const arrEntities = {
lt: '<',
gt: '>',
nbsp: ' ',
amp: '&',
quot: '"',
'#39': "'",
};
return str.replace(/&(lt|gt|nbsp|amp|quot|#39);/gi, function (all, t) {
return arrEntities[t];
});
let temp: HTMLDivElement | null = document.createElement('div');
temp.innerHTML = str;
const output = temp?.innerText || temp.textContent;
temp = null;
return output;
}
function mixColor(color_1, color_2, weight) {
function d2h(d) {

View File

@ -8,12 +8,23 @@ const differentCurrent = (target: string, base?: string) => {
return targetUrl.toString() !== window.location.href;
};
const storageLoginRedirect = () => {
const { pathname } = window.location;
if (pathname !== RouteAlias.login && pathname !== RouteAlias.register) {
const loc = window.location;
const redirectUrl = loc.href.replace(loc.origin, '');
Storage.set(REDIRECT_PATH_STORAGE_KEY, redirectUrl);
}
};
/**
* only navigate if not same as current url
* @param pathname
* @param callback
*/
const navigate = (pathname: string, callback: Function) => {
if (pathname === RouteAlias.login) {
storageLoginRedirect();
}
if (differentCurrent(pathname)) {
callback();
}
@ -23,12 +34,7 @@ const navigate = (pathname: string, callback: Function) => {
* auto navigate to login page with redirect info
*/
const navigateToLogin = () => {
const { pathname } = window.location;
if (pathname !== RouteAlias.login && pathname !== RouteAlias.register) {
const loc = window.location;
const redirectUrl = loc.href.replace(loc.origin, '');
Storage.set(REDIRECT_PATH_STORAGE_KEY, redirectUrl);
}
storageLoginRedirect();
navigate(RouteAlias.login, () => {
window.location.replace(RouteAlias.login);
});