feat: add message editor (close #59)

This commit is contained in:
JustSong
2023-05-09 09:36:01 +08:00
parent 4796b7dd69
commit d8aaec9b84
6 changed files with 244 additions and 38 deletions
+17
View File
@@ -18,6 +18,7 @@ import { StatusContext } from './context/Status';
import Message from './pages/Message';
import Channel from './pages/Channel';
import EditChannel from './pages/Channel/EditChannel';
import EditMessage from './pages/Message/EditMessage';
const Home = lazy(() => import('./pages/Home'));
const About = lazy(() => import('./pages/About'));
@@ -141,6 +142,22 @@ function App() {
</PrivateRoute>
}
/>
<Route
path='/editor'
element={
<PrivateRoute>
<EditMessage />
</PrivateRoute>
}
/>
<Route
path='/editor/:id'
element={
<PrivateRoute>
<EditMessage />
</PrivateRoute>
}
/>
<Route
path='/login'
element={
+5
View File
@@ -18,6 +18,11 @@ const headerButtons = [
to: '/message',
icon: 'mail',
},
{
name: '编辑',
to: '/editor',
icon: 'edit',
},
{
name: '通道',
to: '/channel',
+10
View File
@@ -11,6 +11,7 @@ import { API, openPage, showError, showSuccess, showWarning } from '../helpers';
import { ITEMS_PER_PAGE } from '../constants';
import { renderTimestamp } from '../helpers/render';
import { Link } from 'react-router-dom';
function renderStatus(status) {
switch (status) {
@@ -317,6 +318,15 @@ const MessagesTable = () => {
>
查看
</Button>
<Button
size={'small'}
primary
loading={loading}
as={Link}
to={'/editor/' + message.id}
>
编辑
</Button>
<Button
size={'small'}
color={'yellow'}
+16 -38
View File
@@ -1,6 +1,7 @@
import React, { useEffect, useState } from 'react';
import { Button, Form, Grid, Header, Message } from 'semantic-ui-react';
import { API, showError, showSuccess, testChannel } from '../helpers';
import { loadUser, loadUserChannels } from '../helpers/loader';
const PushSetting = () => {
let [user, setUser] = useState({
@@ -16,44 +17,19 @@ const PushSetting = () => {
setUser((inputs) => ({ ...inputs, [name]: value }));
};
const loadUser = async () => {
let res = await API.get(`/api/user/self`);
const { success, message, data } = res.data;
if (success) {
if (data.channel === '') {
data.channel = 'email';
}
if (data.token === ' ') {
data.token = '';
}
setUser(data);
} else {
showError(message);
}
setLoading(false);
};
const loadUserChannels = async () => {
let res = await API.get(`/api/channel?brief=true`);
const { success, message, data } = res.data;
if (success) {
data.forEach((channel) => {
channel.key = channel.name;
channel.text = channel.name;
channel.value = channel.name;
if (channel.description === '') {
channel.description = '无备注信息';
}
});
setChannels(data);
} else {
showError(message);
}
};
useEffect(() => {
loadUser().then();
loadUserChannels().then();
const loader = async () => {
let user = await loadUser();
if (user) {
setUser(user);
}
let channels = await loadUserChannels();
if (channels) {
setChannels(channels);
}
setLoading(false);
};
loader().then();
}, []);
const submit = async (which) => {
@@ -106,7 +82,9 @@ const PushSetting = () => {
<Button onClick={() => submit('general')} loading={loading}>
保存
</Button>
<Button onClick={() => testChannel(user.username, user.token, '')}>测试</Button>
<Button onClick={() => testChannel(user.username, user.token, '')}>
测试
</Button>
</Form>
</Grid.Column>
</Grid>
+38
View File
@@ -0,0 +1,38 @@
import { API } from './api';
import { showError } from './utils';
export const loadUser = async () => {
let res = await API.get(`/api/user/self`);
const { success, message, data } = res.data;
if (success) {
if (data.channel === '') {
data.channel = 'email';
}
if (data.token === ' ') {
data.token = '';
}
return data;
} else {
showError(message);
return null;
}
};
export const loadUserChannels = async () => {
let res = await API.get(`/api/channel?brief=true`);
const { success, message, data } = res.data;
if (success) {
data.forEach((channel) => {
channel.key = channel.name;
channel.text = channel.name;
channel.value = channel.name;
if (channel.description === '') {
channel.description = '无备注信息';
}
});
return data;
} else {
showError(message);
return null;
}
};
+158
View File
@@ -0,0 +1,158 @@
import React, { useEffect, useState } from 'react';
import { Button, Form, Segment } from 'semantic-ui-react';
import { useParams } from 'react-router-dom';
import { API, showError, showSuccess } from '../../helpers';
import { loadUser, loadUserChannels } from '../../helpers/loader';
const EditMessage = () => {
const params = useParams();
const messageId = params.id;
const isEditing = messageId !== undefined;
let [user, setUser] = useState({
id: '',
username: '',
channel: '',
token: '',
});
let [channels, setChannels] = useState([]);
const [loading, setLoading] = useState(isEditing);
const originInputs = {
title: '',
description: '',
content: '',
url: '',
channel: '',
to: '',
async: false,
};
const [inputs, setInputs] = useState(originInputs);
const { title, description, content, url, channel, to, async } = inputs;
const handleInputChange = (e, { name, value }) => {
setInputs((inputs) => ({ ...inputs, [name]: value }));
};
const loadMessage = async () => {
let res = await API.get(`/api/message/${messageId}`);
const { success, message, data } = res.data;
if (success) {
data.id = 0;
setInputs(data);
} else {
showError(message);
}
setLoading(false);
};
useEffect(() => {
if (isEditing) {
loadMessage().then();
}
const loader = async () => {
let user = await loadUser();
if (user) {
setUser(user);
}
let channels = await loadUserChannels();
if (channels) {
setChannels(channels);
}
};
loader().then();
}, []);
const send = async () => {
if (!description && !content) return;
let res = await API.post(`/push/${user.username}/`, {
...inputs,
token: user.token,
});
const { success, message } = res.data;
if (success) {
if (isEditing) {
showSuccess('消息重发成功!');
} else {
showSuccess('消息发送成功!');
setInputs(originInputs);
}
} else {
showError(message);
}
};
return (
<>
<Segment loading={loading} className={'clearing'}>
<Form>
<Form.Group widths='equal'>
<Form.Input
label='标题'
placeholder='请输入消息标题'
value={inputs.title}
name='title'
onChange={handleInputChange}
/>
<Form.Input
label='接收者'
placeholder='请输入接收者,不填使用默认接收者'
value={inputs.to}
name='to'
onChange={handleInputChange}
/>
<Form.Select
label='推送方式'
placeholder='请选择推送方式,否则使用默认方式'
name='channel'
options={channels}
value={inputs.channel}
onChange={handleInputChange}
/>
</Form.Group>
<Form.Group widths='equal'>
<Form.Input
label='描述'
placeholder='请输入消息描述'
value={inputs.description}
name='description'
onChange={handleInputChange}
/>
</Form.Group>
<Form.Group widths='equal'>
<Form.TextArea
label='内容'
placeholder='请输入消息内容'
value={inputs.content}
name='content'
onChange={handleInputChange}
style={{ minHeight: 200, fontFamily: 'JetBrains Mono, Consolas' }}
/>
</Form.Group>
<Form.Group widths='equal'>
<Form.Input
label='链接'
placeholder='请输入消息链接'
value={inputs.url}
type={'url'}
name='content'
onChange={handleInputChange}
/>
</Form.Group>
<Button type='submit' floated='right' onClick={send}>
发送
</Button>
<Button
floated='right'
onClick={() => {
handleInputChange(null, { name: 'async', value: !async });
}}
>
{async ? '异步' : '同步'}
</Button>
</Form>
</Segment>
</>
);
};
export default EditMessage;