This commit is contained in:
yang fan 2023-08-10 13:51:54 +00:00
parent 9c436921d1
commit 1aebe2bdd2
7 changed files with 83 additions and 20 deletions

View File

@ -447,8 +447,8 @@ const ChannelsTable = () => {
<Button size='small' loading={loading} onClick={testAllChannels}> <Button size='small' loading={loading} onClick={testAllChannels}>
测试所有已启用通道 测试所有已启用通道
</Button> </Button>
<Button size='small' onClick={updateAllChannelsBalance} {/* <Button size='small' onClick={updateAllChannelsBalance}
loading={loading || updatingBalance}>更新所有已启用通道余额</Button> loading={loading || updatingBalance}>更新所有已启用通道余额</Button> */}
<Pagination <Pagination
floated='right' floated='right'
activePage={activePage} activePage={activePage}

View File

@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { Button, Form, Label, Message, Pagination, Table } from 'semantic-ui-react'; import { Button, Form, Label, Popup, Pagination, Table } from 'semantic-ui-react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { API, copy, showError, showInfo, showSuccess, showWarning, timestamp2string } from '../helpers'; import { API, copy, showError, showInfo, showSuccess, showWarning, timestamp2string } from '../helpers';
@ -240,15 +240,25 @@ const RedemptionsTable = () => {
> >
复制 复制
</Button> </Button>
<Popup
trigger={
<Button size='small' negative>
删除
</Button>
}
on='click'
flowing
hoverable
>
<Button <Button
size={'small'}
negative negative
onClick={() => { onClick={() => {
manageRedemption(redemption.id, 'delete', idx); manageRedemption(redemption.id, 'delete', idx);
}} }}
> >
删除 确认删除
</Button> </Button>
</Popup>
<Button <Button
size={'small'} size={'small'}
disabled={redemption.status === 3} // used disabled={redemption.status === 3} // used

View File

@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { Button, Divider, Form, Grid, Header, Input, Message } from 'semantic-ui-react'; import { Button, Divider, Form, Grid, Header, Modal, Message } from 'semantic-ui-react';
import { API, removeTrailingSlash, showError } from '../helpers'; import { API, removeTrailingSlash, showError } from '../helpers';
const SystemSetting = () => { const SystemSetting = () => {
@ -33,6 +33,7 @@ const SystemSetting = () => {
let [loading, setLoading] = useState(false); let [loading, setLoading] = useState(false);
const [EmailDomainWhitelist, setEmailDomainWhitelist] = useState([]); const [EmailDomainWhitelist, setEmailDomainWhitelist] = useState([]);
const [restrictedDomainInput, setRestrictedDomainInput] = useState(''); const [restrictedDomainInput, setRestrictedDomainInput] = useState('');
const [showModal, setShowModal] = useState(false);
const getOptions = async () => { const getOptions = async () => {
const res = await API.get('/api/option/'); const res = await API.get('/api/option/');
@ -95,6 +96,10 @@ const SystemSetting = () => {
}; };
const handleInputChange = async (e, { name, value }) => { const handleInputChange = async (e, { name, value }) => {
if (name === 'PasswordLoginEnabled' && inputs[name] === 'true') {
setShowModal(true);
return; // 早些返回,暂时不更新状态
}
if ( if (
name === 'Notice' || name === 'Notice' ||
name.startsWith('SMTP') || name.startsWith('SMTP') ||
@ -243,6 +248,32 @@ const SystemSetting = () => {
name='PasswordLoginEnabled' name='PasswordLoginEnabled'
onChange={handleInputChange} onChange={handleInputChange}
/> />
{
showModal &&
<Modal
open={showModal}
onClose={() => setShowModal(false)}
size={'tiny'}
style={{ maxWidth: '450px' }}
>
<Modal.Header>提示</Modal.Header>
<Modal.Content>
<p>取消密码登录将导致未绑定其他登录方式的用户含Root管理员无法通过密码登录,确认取消?</p>
</Modal.Content>
<Modal.Actions>
<Button onClick={() => setShowModal(false)}>取消</Button>
<Button
primary
onClick={async () => {
setShowModal(false);
await updateOption('PasswordLoginEnabled', 'false');
}}
>
确定
</Button>
</Modal.Actions>
</Modal>
}
<Form.Checkbox <Form.Checkbox
checked={inputs.PasswordRegisterEnabled === 'true'} checked={inputs.PasswordRegisterEnabled === 'true'}
label='允许通过密码进行注册' label='允许通过密码进行注册'

View File

@ -1,6 +1,11 @@
import { toast } from 'react-toastify'; import { toast } from 'react-toastify';
import { toastConstants } from '../constants'; import { toastConstants } from '../constants';
import React from 'react';
const HTMLToastContent = ({ htmlContent }) => {
return <div dangerouslySetInnerHTML={{ __html: htmlContent }} />;
};
export default HTMLToastContent;
export function isAdmin() { export function isAdmin() {
let user = localStorage.getItem('user'); let user = localStorage.getItem('user');
if (!user) return false; if (!user) return false;
@ -107,8 +112,12 @@ export function showInfo(message) {
toast.info(message, showInfoOptions); toast.info(message, showInfoOptions);
} }
export function showNotice(message) { export function showNotice(message, isHTML = false) {
if (isHTML) {
toast(<HTMLToastContent htmlContent={message} />, showNoticeOptions);
} else {
toast.info(message, showNoticeOptions); toast.info(message, showNoticeOptions);
}
} }
export function openPage(url) { export function openPage(url) {

View File

@ -1,6 +1,6 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { Button, Form, Header, Input, Message, Segment } from 'semantic-ui-react'; import { Button, Form, Header, Input, Message, Segment } from 'semantic-ui-react';
import { useParams } from 'react-router-dom'; import { useParams, useNavigate } from 'react-router-dom';
import { API, showError, showInfo, showSuccess, verifyJSON } from '../../helpers'; import { API, showError, showInfo, showSuccess, verifyJSON } from '../../helpers';
import { CHANNEL_OPTIONS } from '../../constants'; import { CHANNEL_OPTIONS } from '../../constants';
@ -12,9 +12,14 @@ const MODEL_MAPPING_EXAMPLE = {
const EditChannel = () => { const EditChannel = () => {
const params = useParams(); const params = useParams();
const navigate = useNavigate();
const channelId = params.id; const channelId = params.id;
const isEdit = channelId !== undefined; const isEdit = channelId !== undefined;
const [loading, setLoading] = useState(isEdit); const [loading, setLoading] = useState(isEdit);
const handleCancel = () => {
navigate('/channel');
};
const originInputs = { const originInputs = {
name: '', name: '',
type: 1, type: 1,
@ -382,6 +387,7 @@ const EditChannel = () => {
) )
} }
<Button type={isEdit ? 'button' : 'submit'} positive onClick={submit}>提交</Button> <Button type={isEdit ? 'button' : 'submit'} positive onClick={submit}>提交</Button>
<Button onClick={handleCancel}>取消</Button>
</Form> </Form>
</Segment> </Segment>
</> </>

View File

@ -15,7 +15,8 @@ const Home = () => {
if (success) { if (success) {
let oldNotice = localStorage.getItem('notice'); let oldNotice = localStorage.getItem('notice');
if (data !== oldNotice && data !== '') { if (data !== oldNotice && data !== '') {
showNotice(data); const htmlNotice = marked(data);
showNotice(htmlNotice, true);
localStorage.setItem('notice', data); localStorage.setItem('notice', data);
} }
} else { } else {

View File

@ -1,11 +1,12 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { Button, Form, Header, Segment } from 'semantic-ui-react'; import { Button, Form, Header, Segment } from 'semantic-ui-react';
import { useParams } from 'react-router-dom'; import { useParams, useNavigate } from 'react-router-dom';
import { API, downloadTextAsFile, showError, showSuccess } from '../../helpers'; import { API, downloadTextAsFile, showError, showSuccess } from '../../helpers';
import { renderQuota, renderQuotaWithPrompt } from '../../helpers/render'; import { renderQuota, renderQuotaWithPrompt } from '../../helpers/render';
const EditRedemption = () => { const EditRedemption = () => {
const params = useParams(); const params = useParams();
const navigate = useNavigate();
const redemptionId = params.id; const redemptionId = params.id;
const isEdit = redemptionId !== undefined; const isEdit = redemptionId !== undefined;
const [loading, setLoading] = useState(isEdit); const [loading, setLoading] = useState(isEdit);
@ -17,6 +18,10 @@ const EditRedemption = () => {
const [inputs, setInputs] = useState(originInputs); const [inputs, setInputs] = useState(originInputs);
const { name, quota, count } = inputs; const { name, quota, count } = inputs;
const handleCancel = () => {
navigate('/redemption');
};
const handleInputChange = (e, { name, value }) => { const handleInputChange = (e, { name, value }) => {
setInputs((inputs) => ({ ...inputs, [name]: value })); setInputs((inputs) => ({ ...inputs, [name]: value }));
}; };
@ -113,6 +118,7 @@ const EditRedemption = () => {
</> </>
} }
<Button positive onClick={submit}>提交</Button> <Button positive onClick={submit}>提交</Button>
<Button onClick={handleCancel}>取消</Button>
</Form> </Form>
</Segment> </Segment>
</> </>