Initial commit

This commit is contained in:
JustSong
2023-04-22 20:39:27 +08:00
committed by GitHub
commit ab1f8a2bf4
87 changed files with 6933 additions and 0 deletions

View File

@@ -0,0 +1,47 @@
import React, { useEffect, useState } from 'react';
import { Header, Segment } from 'semantic-ui-react';
import { API, showError } from '../../helpers';
import { marked } from 'marked';
const About = () => {
const [about, setAbout] = useState('');
const displayAbout = async () => {
const res = await API.get('/api/about');
const { success, message, data } = res.data;
if (success) {
let HTMLAbout = marked.parse(data);
localStorage.setItem('about', HTMLAbout);
setAbout(HTMLAbout);
} else {
showError(message);
setAbout('加载关于内容失败...');
}
};
useEffect(() => {
displayAbout().then();
}, []);
return (
<>
<Segment>
{
about === '' ? <>
<Header as='h3'>关于</Header>
<p>可在设置页面设置关于内容支持 HTML & Markdown</p>
项目仓库地址
<a href="https://github.com/songquanpeng/gin-template">
https://github.com/songquanpeng/gin-template
</a>
</> : <>
<div dangerouslySetInnerHTML={{ __html: about}}></div>
</>
}
</Segment>
</>
);
};
export default About;

View File

@@ -0,0 +1,14 @@
import React from 'react';
import { Header, Segment } from 'semantic-ui-react';
import FilesTable from '../../components/FilesTable';
const File = () => (
<>
<Segment>
<Header as='h3'>管理文件</Header>
<FilesTable />
</Segment>
</>
);
export default File;

View File

@@ -0,0 +1,78 @@
import React, { useEffect } from 'react';
import { Grid, Header, Placeholder, Segment } from 'semantic-ui-react';
import { API, showError, showNotice } from '../../helpers';
const Home = () => {
const displayNotice = async () => {
const res = await API.get('/api/notice');
const { success, message, data } = res.data;
if (success) {
let oldNotice = localStorage.getItem('notice');
if (data !== oldNotice && data !== '') {
showNotice(data);
localStorage.setItem('notice', data);
}
} else {
showError(message);
}
};
useEffect(() => {
displayNotice().then();
}, []);
return (
<>
<Segment>
<Header as="h3">示例标题</Header>
<Grid columns={3} stackable>
<Grid.Column>
<Segment raised>
<Placeholder>
<Placeholder.Header image>
<Placeholder.Line />
<Placeholder.Line />
</Placeholder.Header>
<Placeholder.Paragraph>
<Placeholder.Line length="medium" />
<Placeholder.Line length="short" />
</Placeholder.Paragraph>
</Placeholder>
</Segment>
</Grid.Column>
<Grid.Column>
<Segment raised>
<Placeholder>
<Placeholder.Header image>
<Placeholder.Line />
<Placeholder.Line />
</Placeholder.Header>
<Placeholder.Paragraph>
<Placeholder.Line length="medium" />
<Placeholder.Line length="short" />
</Placeholder.Paragraph>
</Placeholder>
</Segment>
</Grid.Column>
<Grid.Column>
<Segment raised>
<Placeholder>
<Placeholder.Header image>
<Placeholder.Line />
<Placeholder.Line />
</Placeholder.Header>
<Placeholder.Paragraph>
<Placeholder.Line length="medium" />
<Placeholder.Line length="short" />
</Placeholder.Paragraph>
</Placeholder>
</Segment>
</Grid.Column>
</Grid>
</Segment>
</>
);
};
export default Home;

View File

@@ -0,0 +1,20 @@
import React from 'react';
import { Segment, Header } from 'semantic-ui-react';
const NotFound = () => (
<>
<Header
block
as="h4"
content="404"
attached="top"
icon="info"
className="small-icon"
/>
<Segment attached="bottom">
未找到所请求的页面
</Segment>
</>
);
export default NotFound;

View File

@@ -0,0 +1,46 @@
import React from 'react';
import { Segment, Tab } from 'semantic-ui-react';
import SystemSetting from '../../components/SystemSetting';
import { isRoot } from '../../helpers';
import OtherSetting from '../../components/OtherSetting';
import PersonalSetting from '../../components/PersonalSetting';
const Setting = () => {
let panes = [
{
menuItem: '个人设置',
render: () => (
<Tab.Pane attached={false}>
<PersonalSetting />
</Tab.Pane>
)
}
];
if (isRoot()) {
panes.push({
menuItem: '系统设置',
render: () => (
<Tab.Pane attached={false}>
<SystemSetting />
</Tab.Pane>
)
});
panes.push({
menuItem: '其他设置',
render: () => (
<Tab.Pane attached={false}>
<OtherSetting />
</Tab.Pane>
)
});
}
return (
<Segment>
<Tab menu={{ secondary: true, pointing: true }} panes={panes} />
</Segment>
);
};
export default Setting;

View File

@@ -0,0 +1,77 @@
import React, { useState } from 'react';
import { Button, Form, Header, Segment } from 'semantic-ui-react';
import { API, showError, showSuccess } from '../../helpers';
const AddUser = () => {
const originInputs = {
username: '',
display_name: '',
password: '',
};
const [inputs, setInputs] = useState(originInputs);
const { username, display_name, password } = inputs;
const handleInputChange = (e, { name, value }) => {
setInputs((inputs) => ({ ...inputs, [name]: value }));
};
const submit = async () => {
if (inputs.username === '' || inputs.password === '') return;
const res = await API.post(`/api/user/`, inputs);
const { success, message } = res.data;
if (success) {
showSuccess('用户账户创建成功!');
setInputs(originInputs);
} else {
showError(message);
}
};
return (
<>
<Segment>
<Header as="h3">创建新用户账户</Header>
<Form autoComplete="off">
<Form.Field>
<Form.Input
label="用户名"
name="username"
placeholder={'请输入用户名'}
onChange={handleInputChange}
value={username}
autoComplete="off"
required
/>
</Form.Field>
<Form.Field>
<Form.Input
label="显示名称"
name="display_name"
placeholder={'请输入显示名称'}
onChange={handleInputChange}
value={display_name}
autoComplete="off"
/>
</Form.Field>
<Form.Field>
<Form.Input
label="密码"
name="password"
type={'password'}
placeholder={'请输入密码'}
onChange={handleInputChange}
value={password}
autoComplete="off"
required
/>
</Form.Field>
<Button type={'submit'} onClick={submit}>
提交
</Button>
</Form>
</Segment>
</>
);
};
export default AddUser;

View File

@@ -0,0 +1,132 @@
import React, { useEffect, useState } from 'react';
import { Button, Form, Header, Segment } from 'semantic-ui-react';
import { useParams } from 'react-router-dom';
import { API, showError, showSuccess } from '../../helpers';
const EditUser = () => {
const params = useParams();
const userId = params.id;
const [loading, setLoading] = useState(true);
const [inputs, setInputs] = useState({
username: '',
display_name: '',
password: '',
github_id: '',
wechat_id: '',
email: '',
});
const { username, display_name, password, github_id, wechat_id, email } =
inputs;
const handleInputChange = (e, { name, value }) => {
setInputs((inputs) => ({ ...inputs, [name]: value }));
};
const loadUser = async () => {
let res = undefined;
if (userId) {
res = await API.get(`/api/user/${userId}`);
} else {
res = await API.get(`/api/user/self`);
}
const { success, message, data } = res.data;
if (success) {
data.password = '';
setInputs(data);
} else {
showError(message);
}
setLoading(false);
};
useEffect(() => {
loadUser().then();
}, []);
const submit = async () => {
let res = undefined;
if (userId) {
res = await API.put(`/api/user/`, { ...inputs, id: parseInt(userId) });
} else {
res = await API.put(`/api/user/self`, inputs);
}
const { success, message } = res.data;
if (success) {
showSuccess('用户信息更新成功!');
} else {
showError(message);
}
};
return (
<>
<Segment loading={loading}>
<Header as='h3'>更新用户信息</Header>
<Form autoComplete='off'>
<Form.Field>
<Form.Input
label='用户名'
name='username'
placeholder={'请输入新的用户名'}
onChange={handleInputChange}
value={username}
autoComplete='off'
/>
</Form.Field>
<Form.Field>
<Form.Input
label='密码'
name='password'
type={'password'}
placeholder={'请输入新的密码'}
onChange={handleInputChange}
value={password}
autoComplete='off'
/>
</Form.Field>
<Form.Field>
<Form.Input
label='显示名称'
name='display_name'
placeholder={'请输入新的显示名称'}
onChange={handleInputChange}
value={display_name}
autoComplete='off'
/>
</Form.Field>
<Form.Field>
<Form.Input
label='已绑定的 GitHub 账户'
name='github_id'
value={github_id}
autoComplete='off'
placeholder='此项只读,需要用户通过个人设置页面的相关绑定按钮进行绑定,不可直接修改'
readOnly
/>
</Form.Field>
<Form.Field>
<Form.Input
label='已绑定的微信账户'
name='wechat_id'
value={wechat_id}
autoComplete='off'
placeholder='此项只读,需要用户通过个人设置页面的相关绑定按钮进行绑定,不可直接修改'
readOnly
/>
</Form.Field>
<Form.Field>
<Form.Input
label='已绑定的邮箱账户'
name='email'
value={email}
autoComplete='off'
placeholder='此项只读,需要用户通过个人设置页面的相关绑定按钮进行绑定,不可直接修改'
readOnly
/>
</Form.Field>
<Button onClick={submit}>提交</Button>
</Form>
</Segment>
</>
);
};
export default EditUser;

View File

@@ -0,0 +1,14 @@
import React from 'react';
import { Segment, Header } from 'semantic-ui-react';
import UsersTable from '../../components/UsersTable';
const User = () => (
<>
<Segment>
<Header as='h3'>管理用户</Header>
<UsersTable/>
</Segment>
</>
);
export default User;