mirror of https://gitee.com/answerdev/answer.git
refactor(uir): Remove label page
This commit is contained in:
parent
5660017bea
commit
2790a3c189
|
@ -934,7 +934,7 @@ ui:
|
|||
smtp: SMTP
|
||||
branding: Branding
|
||||
legal: Legal
|
||||
labels: Labels
|
||||
write: Write
|
||||
dashboard:
|
||||
title: Dashboard
|
||||
welcome: Welcome to Answer Admin!
|
||||
|
@ -1135,32 +1135,21 @@ ui:
|
|||
page_title: Legal
|
||||
terms_of_service:
|
||||
label: Terms of Service
|
||||
msg: Terms of service cannot be empty.
|
||||
text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here."
|
||||
privacy_policy:
|
||||
label: Privacy Policy
|
||||
msg: Privacy policy cannot be empty.
|
||||
text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here."
|
||||
labels:
|
||||
title: Labels
|
||||
new_label: New Label
|
||||
name: Name
|
||||
color: color
|
||||
description: Description
|
||||
action: Action
|
||||
form:
|
||||
title: Create New Label
|
||||
back: Back
|
||||
display_name:
|
||||
label: Display Name
|
||||
url_slug:
|
||||
label: URL Slug
|
||||
text: Must use the character set “a-z”, “0-9”, “+ # - .”
|
||||
description:
|
||||
label: Description (optional)
|
||||
color:
|
||||
label: Color
|
||||
|
||||
write:
|
||||
page_title: Write
|
||||
recommend_tags:
|
||||
label: Recommend Tags
|
||||
text: "Please input tag slug above, one tag per line."
|
||||
required_tag:
|
||||
label: Required Tag
|
||||
text: "Every new question must have at least one recommend tag"
|
||||
reserved_tags:
|
||||
label: Reserved Tags
|
||||
text: "Reserved tags can only be added to a post by moderator."
|
||||
form:
|
||||
empty: cannot be empty
|
||||
invalid: is invalid
|
||||
|
|
|
@ -43,7 +43,7 @@ export const ADMIN_NAV_MENUS = [
|
|||
},
|
||||
{
|
||||
name: 'contents',
|
||||
child: [{ name: 'questions' }, { name: 'answers' }, { name: 'labels' }],
|
||||
child: [{ name: 'questions' }, { name: 'answers' }],
|
||||
},
|
||||
{
|
||||
name: 'users',
|
||||
|
|
|
@ -297,7 +297,7 @@ export interface AdminSettingsLegal {
|
|||
|
||||
export interface AdminSettingsWrite {
|
||||
recommend_tags: string;
|
||||
required_tags: string;
|
||||
required_tag: string;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,121 +0,0 @@
|
|||
import React, { FC, useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Button } from 'react-bootstrap';
|
||||
|
||||
import { SchemaForm, JSONSchema, initFormData, UISchema } from '@/components';
|
||||
import type * as Type from '@/common/interface';
|
||||
import { useToast } from '@/hooks';
|
||||
import { siteInfoStore } from '@/stores';
|
||||
import { useGeneralSetting, updateGeneralSetting } from '@/services';
|
||||
|
||||
interface IProps {
|
||||
onClose: () => void;
|
||||
}
|
||||
const LabelForm: FC<IProps> = ({ onClose }) => {
|
||||
const { t } = useTranslation('translation', {
|
||||
keyPrefix: 'admin.labels.form',
|
||||
});
|
||||
const Toast = useToast();
|
||||
const updateSiteInfo = siteInfoStore((state) => state.update);
|
||||
|
||||
const { data: setting } = useGeneralSetting();
|
||||
const schema: JSONSchema = {
|
||||
title: t('title'),
|
||||
required: ['name', 'site_url', 'contact_email'],
|
||||
properties: {
|
||||
display_name: {
|
||||
type: 'string',
|
||||
title: t('display_name.label'),
|
||||
},
|
||||
url_slug: {
|
||||
type: 'string',
|
||||
title: t('url_slug.label'),
|
||||
description: t('url_slug.text'),
|
||||
},
|
||||
description: {
|
||||
type: 'string',
|
||||
title: t('description.label'),
|
||||
description: t('description.text'),
|
||||
},
|
||||
color: {
|
||||
type: 'string',
|
||||
title: t('color.label'),
|
||||
},
|
||||
},
|
||||
};
|
||||
const uiSchema: UISchema = {
|
||||
color: {
|
||||
'ui:options': {
|
||||
type: 'color',
|
||||
},
|
||||
},
|
||||
};
|
||||
const [formData, setFormData] = useState(initFormData(schema));
|
||||
|
||||
const onSubmit = (evt) => {
|
||||
evt.preventDefault();
|
||||
evt.stopPropagation();
|
||||
|
||||
const reqParams: Type.AdminSettingsGeneral = {
|
||||
name: formData.name.value,
|
||||
description: formData.description.value,
|
||||
short_description: formData.short_description.value,
|
||||
site_url: formData.site_url.value,
|
||||
contact_email: formData.contact_email.value,
|
||||
};
|
||||
|
||||
updateGeneralSetting(reqParams)
|
||||
.then(() => {
|
||||
Toast.onShow({
|
||||
msg: t('update', { keyPrefix: 'toast' }),
|
||||
variant: 'success',
|
||||
});
|
||||
onClose();
|
||||
updateSiteInfo(reqParams);
|
||||
})
|
||||
.catch((err) => {
|
||||
if (err.isError && err.key) {
|
||||
formData[err.key].isInvalid = true;
|
||||
formData[err.key].errorMsg = err.value;
|
||||
}
|
||||
setFormData({ ...formData });
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!setting) {
|
||||
return;
|
||||
}
|
||||
const formMeta = {};
|
||||
Object.keys(setting).forEach((k) => {
|
||||
formMeta[k] = { ...formData[k], value: setting[k] };
|
||||
});
|
||||
setFormData({ ...formData, ...formMeta });
|
||||
}, [setting]);
|
||||
|
||||
const handleOnChange = (data) => {
|
||||
setFormData(data);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button
|
||||
size="sm"
|
||||
className="mb-4"
|
||||
variant="outline-secondary"
|
||||
onClick={onClose}>
|
||||
← {t('back')}
|
||||
</Button>
|
||||
<h3 className="mb-4">{t('title')}</h3>
|
||||
<SchemaForm
|
||||
schema={schema}
|
||||
formData={formData}
|
||||
onSubmit={onSubmit}
|
||||
uiSchema={uiSchema}
|
||||
onChange={handleOnChange}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default LabelForm;
|
|
@ -1,124 +0,0 @@
|
|||
import { FC, useState } from 'react';
|
||||
import { Button, Table } from 'react-bootstrap';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { Pagination, BaseUserCard, Empty } from '@/components';
|
||||
import * as Type from '@/common/interface';
|
||||
import { useChangeModal } from '@/hooks';
|
||||
import { useQueryUsers } from '@/services';
|
||||
|
||||
import CreateForm from './Form';
|
||||
|
||||
import '../index.scss';
|
||||
|
||||
const UserFilterKeys: Type.UserFilterBy[] = [
|
||||
'all',
|
||||
'inactive',
|
||||
'suspended',
|
||||
'deleted',
|
||||
];
|
||||
|
||||
const PAGE_SIZE = 10;
|
||||
const Users: FC = () => {
|
||||
const { t } = useTranslation('translation', { keyPrefix: 'admin.labels' });
|
||||
|
||||
const [urlSearchParams] = useSearchParams();
|
||||
const curFilter = urlSearchParams.get('filter') || UserFilterKeys[0];
|
||||
const curPage = Number(urlSearchParams.get('page') || '1');
|
||||
const curQuery = urlSearchParams.get('query') || '';
|
||||
|
||||
const [isCreate, setCreateState] = useState(true);
|
||||
const {
|
||||
data,
|
||||
isLoading,
|
||||
mutate: refreshUsers,
|
||||
} = useQueryUsers({
|
||||
page: curPage,
|
||||
page_size: PAGE_SIZE,
|
||||
query: curQuery,
|
||||
...(curFilter === 'all' ? {} : { status: curFilter }),
|
||||
});
|
||||
const changeModal = useChangeModal({
|
||||
callback: refreshUsers,
|
||||
});
|
||||
|
||||
const handleClick = ({ user_id, status }) => {
|
||||
changeModal.onShow({
|
||||
id: user_id,
|
||||
type: status,
|
||||
});
|
||||
};
|
||||
|
||||
if (isCreate) {
|
||||
return <CreateForm onClose={() => setCreateState(false)} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<h3 className="mb-4">{t('title')}</h3>
|
||||
<div className="d-flex justify-content-between align-items-center mb-3">
|
||||
<Button
|
||||
variant="outline-secondary"
|
||||
size="sm"
|
||||
onClick={() => setCreateState(true)}>
|
||||
{t('new_label')}
|
||||
</Button>
|
||||
</div>
|
||||
<Table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{t('name')}</th>
|
||||
<th style={{ width: '12%' }}>{t('color')}</th>
|
||||
<th style={{ width: '20%' }}>{t('description')}</th>
|
||||
|
||||
{curFilter !== 'deleted' ? (
|
||||
<th style={{ width: '10%' }}>{t('action')}</th>
|
||||
) : null}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="align-middle">
|
||||
{data?.list.map((user) => {
|
||||
return (
|
||||
<tr key={user.user_id}>
|
||||
<td>
|
||||
<BaseUserCard
|
||||
data={user}
|
||||
className="fs-6"
|
||||
avatarSize="24px"
|
||||
avatarSearchStr="s=48"
|
||||
/>
|
||||
</td>
|
||||
<td>{user.rank}</td>
|
||||
<td className="text-break">{user.e_mail}</td>
|
||||
|
||||
{curFilter !== 'deleted' ? (
|
||||
<td>
|
||||
{user.status !== 'deleted' && (
|
||||
<Button
|
||||
className="p-0 btn-no-border"
|
||||
variant="link"
|
||||
onClick={() => handleClick(user)}>
|
||||
{t('change')}
|
||||
</Button>
|
||||
)}
|
||||
</td>
|
||||
) : null}
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
</tbody>
|
||||
</Table>
|
||||
{Number(data?.count) <= 0 && !isLoading && <Empty />}
|
||||
<div className="mt-4 mb-2 d-flex justify-content-center">
|
||||
<Pagination
|
||||
currentPage={curPage}
|
||||
totalSize={data?.count || 0}
|
||||
pageSize={PAGE_SIZE}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Users;
|
|
@ -26,10 +26,15 @@ const Legal: FC = () => {
|
|||
title: t('recommend_tags.label'),
|
||||
description: t('recommend_tags.text'),
|
||||
},
|
||||
required_tags: {
|
||||
required_tag: {
|
||||
type: 'boolean',
|
||||
title: t('required_tags.label'),
|
||||
description: t('required_tags.text'),
|
||||
title: t('required_tag.label'),
|
||||
description: t('required_tag.text'),
|
||||
},
|
||||
reserved_tags: {
|
||||
type: 'string',
|
||||
title: t('reserved_tags.label'),
|
||||
description: t('reserved_tags.text'),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -40,9 +45,15 @@ const Legal: FC = () => {
|
|||
rows: 5,
|
||||
},
|
||||
},
|
||||
required_tags: {
|
||||
required_tag: {
|
||||
'ui:widget': 'switch',
|
||||
},
|
||||
reserved_tags: {
|
||||
'ui:widget': 'textarea',
|
||||
'ui:options': {
|
||||
rows: 5,
|
||||
},
|
||||
},
|
||||
};
|
||||
const [formData, setFormData] = useState(initFormData(schema));
|
||||
|
||||
|
@ -52,7 +63,7 @@ const Legal: FC = () => {
|
|||
|
||||
const reqParams: Type.AdminSettingsWrite = {
|
||||
recommend_tags: formData.recommend_tags.value,
|
||||
required_tags: formData.required_tags.value,
|
||||
required_tag: formData.required_tag.value,
|
||||
};
|
||||
|
||||
console.log(reqParams);
|
||||
|
|
|
@ -263,10 +263,6 @@ const routes: RouteNode[] = [
|
|||
path: 'write',
|
||||
page: 'pages/Admin/Write',
|
||||
},
|
||||
{
|
||||
path: 'labels',
|
||||
page: 'pages/Admin/Labels',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue