Index page is done
This commit is contained in:
parent
78b4acddc6
commit
09be65e035
@ -14,6 +14,7 @@ import PasswordResetForm from './components/PasswordResetForm';
|
|||||||
import GitHubOAuth from './components/GitHubOAuth';
|
import GitHubOAuth from './components/GitHubOAuth';
|
||||||
import PasswordResetConfirm from './components/PasswordResetConfirm';
|
import PasswordResetConfirm from './components/PasswordResetConfirm';
|
||||||
import { UserContext } from './context/User';
|
import { UserContext } from './context/User';
|
||||||
|
import { StatusContext } from './context/Status';
|
||||||
import Channel from './pages/Channel';
|
import Channel from './pages/Channel';
|
||||||
import Token from './pages/Token';
|
import Token from './pages/Token';
|
||||||
import EditToken from './pages/Token/EditToken';
|
import EditToken from './pages/Token/EditToken';
|
||||||
@ -26,6 +27,7 @@ const About = lazy(() => import('./pages/About'));
|
|||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const [userState, userDispatch] = useContext(UserContext);
|
const [userState, userDispatch] = useContext(UserContext);
|
||||||
|
const [statusState, statusDispatch] = useContext(StatusContext);
|
||||||
|
|
||||||
const loadUser = () => {
|
const loadUser = () => {
|
||||||
let user = localStorage.getItem('user');
|
let user = localStorage.getItem('user');
|
||||||
@ -39,6 +41,7 @@ function App() {
|
|||||||
const { success, data } = res.data;
|
const { success, data } = res.data;
|
||||||
if (success) {
|
if (success) {
|
||||||
localStorage.setItem('status', JSON.stringify(data));
|
localStorage.setItem('status', JSON.stringify(data));
|
||||||
|
statusDispatch({ type: 'set', payload: data });
|
||||||
localStorage.setItem('footer_html', data.footer_html);
|
localStorage.setItem('footer_html', data.footer_html);
|
||||||
if (
|
if (
|
||||||
data.version !== process.env.REACT_APP_VERSION &&
|
data.version !== process.env.REACT_APP_VERSION &&
|
||||||
|
19
web/src/context/Status/index.js
Normal file
19
web/src/context/Status/index.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// contexts/User/index.jsx
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { initialState, reducer } from './reducer';
|
||||||
|
|
||||||
|
export const StatusContext = React.createContext({
|
||||||
|
state: initialState,
|
||||||
|
dispatch: () => null,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const StatusProvider = ({ children }) => {
|
||||||
|
const [state, dispatch] = React.useReducer(reducer, initialState);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<StatusContext.Provider value={[state, dispatch]}>
|
||||||
|
{children}
|
||||||
|
</StatusContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
20
web/src/context/Status/reducer.js
Normal file
20
web/src/context/Status/reducer.js
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
export const reducer = (state, action) => {
|
||||||
|
switch (action.type) {
|
||||||
|
case 'set':
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
status: action.payload,
|
||||||
|
};
|
||||||
|
case 'unset':
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
status: undefined,
|
||||||
|
};
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const initialState = {
|
||||||
|
status: undefined,
|
||||||
|
};
|
@ -10,20 +10,22 @@ import './index.css';
|
|||||||
import { UserProvider } from './context/User';
|
import { UserProvider } from './context/User';
|
||||||
import { ToastContainer } from 'react-toastify';
|
import { ToastContainer } from 'react-toastify';
|
||||||
import 'react-toastify/dist/ReactToastify.css';
|
import 'react-toastify/dist/ReactToastify.css';
|
||||||
|
import { StatusProvider } from './context/Status';
|
||||||
|
|
||||||
const root = ReactDOM.createRoot(document.getElementById('root'));
|
const root = ReactDOM.createRoot(document.getElementById('root'));
|
||||||
root.render(
|
root.render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
<UserProvider>
|
<StatusProvider>
|
||||||
<BrowserRouter>
|
<UserProvider>
|
||||||
<Header />
|
<BrowserRouter>
|
||||||
<Container className={'main-content'}>
|
<Header />
|
||||||
<App />
|
<Container className={'main-content'}>
|
||||||
</Container>
|
<App />
|
||||||
<ToastContainer/>
|
</Container>
|
||||||
<Footer />
|
<ToastContainer />
|
||||||
</BrowserRouter>
|
<Footer />
|
||||||
</UserProvider>
|
</BrowserRouter>
|
||||||
|
</UserProvider>
|
||||||
|
</StatusProvider>
|
||||||
</React.StrictMode>
|
</React.StrictMode>
|
||||||
);
|
);
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
import React, { useEffect } from 'react';
|
import React, { useContext, useEffect } from 'react';
|
||||||
import { Grid, Header, Placeholder, Segment } from 'semantic-ui-react';
|
import { Card, Grid, Header, Segment } from 'semantic-ui-react';
|
||||||
import { API, showError, showNotice } from '../../helpers';
|
import { API, showError, showNotice, timestamp2string } from '../../helpers';
|
||||||
|
import { StatusContext } from '../../context/Status';
|
||||||
|
|
||||||
const Home = () => {
|
const Home = () => {
|
||||||
|
const [statusState, statusDispatch] = useContext(StatusContext);
|
||||||
|
|
||||||
const displayNotice = async () => {
|
const displayNotice = async () => {
|
||||||
const res = await API.get('/api/notice');
|
const res = await API.get('/api/notice');
|
||||||
const { success, message, data } = res.data;
|
const { success, message, data } = res.data;
|
||||||
@ -17,57 +20,74 @@ const Home = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getStartTimeString = () => {
|
||||||
|
const timestamp = statusState?.status?.start_time;
|
||||||
|
return timestamp2string(timestamp);
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
displayNotice().then();
|
displayNotice().then();
|
||||||
}, []);
|
}, []);
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Segment>
|
<Segment>
|
||||||
<Header as="h3">示例标题</Header>
|
<Header as='h3'>系统状况</Header>
|
||||||
<Grid columns={3} stackable>
|
<Grid columns={2} stackable>
|
||||||
<Grid.Column>
|
<Grid.Column>
|
||||||
<Segment raised>
|
<Card fluid>
|
||||||
<Placeholder>
|
<Card.Content>
|
||||||
<Placeholder.Header image>
|
<Card.Header>系统信息</Card.Header>
|
||||||
<Placeholder.Line />
|
<Card.Meta>系统信息总览</Card.Meta>
|
||||||
<Placeholder.Line />
|
<Card.Description>
|
||||||
</Placeholder.Header>
|
<p>名称:{statusState?.status?.system_name}</p>
|
||||||
<Placeholder.Paragraph>
|
<p>版本:{statusState?.status?.version}</p>
|
||||||
<Placeholder.Line length="medium" />
|
<p>
|
||||||
<Placeholder.Line length="short" />
|
源码:
|
||||||
</Placeholder.Paragraph>
|
<a
|
||||||
</Placeholder>
|
href='https://github.com/songquanpeng/one-api'
|
||||||
</Segment>
|
target='_blank'
|
||||||
|
>
|
||||||
|
https://github.com/songquanpeng/one-api
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
<p>启动时间:{getStartTimeString()}</p>
|
||||||
|
</Card.Description>
|
||||||
|
</Card.Content>
|
||||||
|
</Card>
|
||||||
</Grid.Column>
|
</Grid.Column>
|
||||||
|
|
||||||
<Grid.Column>
|
<Grid.Column>
|
||||||
<Segment raised>
|
<Card fluid>
|
||||||
<Placeholder>
|
<Card.Content>
|
||||||
<Placeholder.Header image>
|
<Card.Header>系统配置</Card.Header>
|
||||||
<Placeholder.Line />
|
<Card.Meta>系统配置总览</Card.Meta>
|
||||||
<Placeholder.Line />
|
<Card.Description>
|
||||||
</Placeholder.Header>
|
<p>
|
||||||
<Placeholder.Paragraph>
|
邮箱验证:
|
||||||
<Placeholder.Line length="medium" />
|
{statusState?.status?.email_verification === true
|
||||||
<Placeholder.Line length="short" />
|
? '已启用'
|
||||||
</Placeholder.Paragraph>
|
: '未启用'}
|
||||||
</Placeholder>
|
</p>
|
||||||
</Segment>
|
<p>
|
||||||
</Grid.Column>
|
GitHub 身份验证:
|
||||||
|
{statusState?.status?.github_oauth === true
|
||||||
<Grid.Column>
|
? '已启用'
|
||||||
<Segment raised>
|
: '未启用'}
|
||||||
<Placeholder>
|
</p>
|
||||||
<Placeholder.Header image>
|
<p>
|
||||||
<Placeholder.Line />
|
微信身份验证:
|
||||||
<Placeholder.Line />
|
{statusState?.status?.wechat_login === true
|
||||||
</Placeholder.Header>
|
? '已启用'
|
||||||
<Placeholder.Paragraph>
|
: '未启用'}
|
||||||
<Placeholder.Line length="medium" />
|
</p>
|
||||||
<Placeholder.Line length="short" />
|
<p>
|
||||||
</Placeholder.Paragraph>
|
Turnstile 用户校验:
|
||||||
</Placeholder>
|
{statusState?.status?.turnstile_check === true
|
||||||
</Segment>
|
? '已启用'
|
||||||
|
: '未启用'}
|
||||||
|
</p>
|
||||||
|
</Card.Description>
|
||||||
|
</Card.Content>
|
||||||
|
</Card>
|
||||||
</Grid.Column>
|
</Grid.Column>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Segment>
|
</Segment>
|
||||||
|
Loading…
Reference in New Issue
Block a user