فهرست منبع

feat: update index page

JustSong 2 سال پیش
والد
کامیت
f2a296cd87
5فایلهای تغییر یافته به همراه120 افزوده شده و 55 حذف شده
  1. 3 0
      web/src/App.js
  2. 19 0
      web/src/context/Status/index.js
  3. 20 0
      web/src/context/Status/reducer.js
  4. 13 11
      web/src/index.js
  5. 65 44
      web/src/pages/Home/index.js

+ 3 - 0
web/src/App.js

@@ -14,12 +14,14 @@ import PasswordResetForm from './components/PasswordResetForm';
 import GitHubOAuth from './components/GitHubOAuth';
 import PasswordResetConfirm from './components/PasswordResetConfirm';
 import { UserContext } from './context/User';
+import { StatusContext } from './context/Status';
 
 const Home = lazy(() => import('./pages/Home'));
 const About = lazy(() => import('./pages/About'));
 
 function App() {
   const [userState, userDispatch] = useContext(UserContext);
+  const [statusState, statusDispatch] = useContext(StatusContext);
 
   const loadUser = () => {
     let user = localStorage.getItem('user');
@@ -33,6 +35,7 @@ function App() {
     const { success, data } = res.data;
     if (success) {
       localStorage.setItem('status', JSON.stringify(data));
+      statusDispatch({ type: 'set', payload: data });
       localStorage.setItem('footer_html', data.footer_html);
       let currentVersion = localStorage.getItem('version');
       if (currentVersion && currentVersion !== data.version) {

+ 19 - 0
web/src/context/Status/index.js

@@ -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 - 0
web/src/context/Status/reducer.js

@@ -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,
+};

+ 13 - 11
web/src/index.js

@@ -10,20 +10,22 @@ import './index.css';
 import { UserProvider } from './context/User';
 import { ToastContainer } from 'react-toastify';
 import 'react-toastify/dist/ReactToastify.css';
-
+import { StatusProvider } from './context/Status';
 
 const root = ReactDOM.createRoot(document.getElementById('root'));
 root.render(
   <React.StrictMode>
-    <UserProvider>
-      <BrowserRouter>
-        <Header />
-        <Container className={'main-content'}>
-          <App />
-        </Container>
-        <ToastContainer/>
-        <Footer />
-      </BrowserRouter>
-    </UserProvider>
+    <StatusProvider>
+      <UserProvider>
+        <BrowserRouter>
+          <Header />
+          <Container className={'main-content'}>
+            <App />
+          </Container>
+          <ToastContainer />
+          <Footer />
+        </BrowserRouter>
+      </UserProvider>
+    </StatusProvider>
   </React.StrictMode>
 );

+ 65 - 44
web/src/pages/Home/index.js

@@ -1,8 +1,11 @@
-import React, { useEffect } from 'react';
-import { Grid, Header, Placeholder, Segment } from 'semantic-ui-react';
+import React, { useContext, useEffect } from 'react';
+import { Card, Grid, Header, Segment } from 'semantic-ui-react';
 import { API, showError, showNotice } from '../../helpers';
+import { StatusContext } from '../../context/Status';
 
 const Home = () => {
+  const [statusState, statusDispatch] = useContext(StatusContext);
+
   const displayNotice = async () => {
     const res = await API.get('/api/notice');
     const { success, message, data } = res.data;
@@ -17,57 +20,75 @@ const Home = () => {
     }
   };
 
+  const getStartTimeString = () => {
+    const timestamp = statusState?.status?.start_time;
+    const date = new Date(timestamp * 1000);
+    return date.toLocaleString();
+  };
+
   useEffect(() => {
     displayNotice().then();
   }, []);
   return (
     <>
       <Segment>
-        <Header as="h3">示例标题</Header>
-        <Grid columns={3} stackable>
+        <Header as='h3'>系统状况</Header>
+        <Grid columns={2} 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>
+            <Card fluid>
+              <Card.Content>
+                <Card.Header>系统信息</Card.Header>
+                <Card.Meta>系统信息总览</Card.Meta>
+                <Card.Description>
+                  <p>名称:{statusState?.status?.system_name}</p>
+                  <p>版本:{statusState?.status?.version}</p>
+                  <p>
+                    源码:
+                    <a
+                      href='https://github.com/songquanpeng/message-pusher'
+                      target='_blank'
+                    >
+                      GitHub 仓库地址
+                    </a>
+                  </p>
+                  <p>启动时间:{getStartTimeString()}</p>
+                </Card.Description>
+              </Card.Content>
+            </Card>
           </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>
+            <Card fluid>
+              <Card.Content>
+                <Card.Header>系统配置</Card.Header>
+                <Card.Meta>系统配置总览</Card.Meta>
+                <Card.Description>
+                  <p>
+                    邮箱验证:
+                    {statusState?.status?.email_verification === true
+                      ? '已启用'
+                      : '未启用'}
+                  </p>
+                  <p>
+                    GitHub 身份验证:
+                    {statusState?.status?.github_oauth === true
+                      ? '已启用'
+                      : '未启用'}
+                  </p>
+                  <p>
+                    微信身份验证:
+                    {statusState?.status?.wechat_login === true
+                      ? '已启用'
+                      : '未启用'}
+                  </p>
+                  <p>
+                    Turnstile 用户校验:
+                    {statusState?.status?.turnstile_check === true
+                      ? '已启用'
+                      : '未启用'}
+                  </p>
+                </Card.Description>
+              </Card.Content>
+            </Card>
           </Grid.Column>
         </Grid>
       </Segment>