diff --git a/.umirc.ts b/.umirc.ts index 4554415e..956eb57d 100644 --- a/.umirc.ts +++ b/.umirc.ts @@ -1,10 +1,4 @@ import { defineConfig } from 'umi'; -import { - SmileOutlined, - CrownOutlined, - TabletOutlined, - AntDesignOutlined, -} from '@ant-design/icons'; export default defineConfig({ hash: true, diff --git a/package.json b/package.json index d0af7016..0d6e03f3 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "celebrate": "^13.0.3", "codemirror": "^5.59.4", "cors": "^2.8.5", + "darkreader": "^4.9.27", "dotenv": "^8.2.0", "errorhandler": "^1.5.1", "event-dispatch": "^0.4.1", diff --git a/src/layouts/defaultProps.tsx b/src/layouts/defaultProps.tsx index 07bb4c29..735833ef 100644 --- a/src/layouts/defaultProps.tsx +++ b/src/layouts/defaultProps.tsx @@ -5,8 +5,8 @@ import { SettingOutlined, CodeOutlined, FolderOutlined, - LockOutlined, RadiusSettingOutlined, + ControlOutlined, } from '@ant-design/icons'; import logo from '@/assets/logo.png'; @@ -28,7 +28,7 @@ export default { { path: '/config', name: '配置文件', - icon: , + icon: , component: '@/pages/config/index', }, { @@ -62,9 +62,9 @@ export default { component: '@/pages/log/index', }, { - path: '/password', - name: '修改密码', - icon: , + path: '/setting', + name: '系统设置', + icon: , component: '@/pages/password/index', }, ], @@ -72,8 +72,8 @@ export default { location: { pathname: '/', }, - fixSiderbar: true, navTheme: 'light', + fixSiderbar: true, contentWidth: 'Fixed', splitMenus: false, logo: logo, diff --git a/src/layouts/index.less b/src/layouts/index.less index 77d80496..52a2c941 100644 --- a/src/layouts/index.less +++ b/src/layouts/index.less @@ -15,9 +15,10 @@ body { .ant-pro-grid-content.wide { max-width: unset; - height: calc(100vh - 72px); overflow: auto; - .ant-pro-page-container-children-content{ + .ant-pro-page-container-children-content { overflow: auto; + min-height: calc(100vh - 96px); + background-color: #fff; } } diff --git a/src/layouts/index.tsx b/src/layouts/index.tsx index 3a240827..8a0e45aa 100644 --- a/src/layouts/index.tsx +++ b/src/layouts/index.tsx @@ -1,11 +1,10 @@ import React, { useEffect, useState } from 'react'; -import { Button, Descriptions, Result, Avatar, Space, Statistic } from 'antd'; -import { LikeOutlined, UserOutlined } from '@ant-design/icons'; -import ProLayout, { - PageContainer, - PageLoading, - SettingDrawer, -} from '@ant-design/pro-layout'; +import ProLayout from '@ant-design/pro-layout'; +import { + enable as enableDarkMode, + disable as disableDarkMode, + setFetchMethod, +} from 'darkreader'; import defaultProps from './defaultProps'; import { Link, history } from 'umi'; import config from '@/utils/config'; @@ -19,11 +18,26 @@ export default function (props: any) { history.push('/login'); } }, []); + useEffect(() => { if (props.location.pathname === '/') { history.push('/cookie'); } }, [props.location.pathname]); + + useEffect(() => { + const colorScheme = + window.matchMedia('(prefers-color-scheme: dark)').matches && 'dark'; + const theme = + localStorage.getItem('qinglong_dark_theme') || colorScheme || 'light'; + setFetchMethod(window.fetch); + if (theme === 'dark') { + enableDarkMode({ darkSchemeTextColor: '#fff' }); + } else if (theme === 'light') { + disableDarkMode(); + } + }, []); + if (props.location.pathname === '/login') { return props.children; } @@ -41,11 +55,6 @@ export default function (props: any) { } return {defaultDom}; }} - // rightContentRender={() => ( - //
- // } /> - //
- // )} {...defaultProps} > {props.children} diff --git a/src/pages/login/index.less b/src/pages/login/index.less index ee452a3d..23075564 100644 --- a/src/pages/login/index.less +++ b/src/pages/login/index.less @@ -26,7 +26,7 @@ width: 320px; height: 320px; padding: 36px; - // box-shadow: 0 0 100px rgba(0, 0, 0, 0.08); + box-shadow: 0 0 100px rgba(0, 0, 0, 0.08); } @media (min-width: @screen-md-min) { @@ -36,10 +36,6 @@ background-position: center 110px; background-size: 100%; } - - .content { - padding: 32px 0 24px; - } } .top { @@ -49,26 +45,14 @@ .header { height: 44px; line-height: 44px; - a { - display: flex; - align-items: center; - justify-content: center; - } + display: flex; + align-items: center; + justify-content: center; } .logo { - height: 44px; - margin-right: 16px; - vertical-align: top; -} - -.title { - position: relative; - top: 2px; - color: @heading-color; - font-weight: 600; - font-size: 33px; - font-family: Avenir, 'Helvetica Neue', Arial, Helvetica, sans-serif; + width: 40px; + margin-right: 8px; } .desc { @@ -79,8 +63,7 @@ } .main { - width: 320px; - margin: 25px auto 0; + margin: 35px auto 0; @media screen and (max-width: @screen-sm) { width: 95%; max-width: 320px; diff --git a/src/pages/login/index.tsx b/src/pages/login/index.tsx index c27fc3a1..355640b9 100644 --- a/src/pages/login/index.tsx +++ b/src/pages/login/index.tsx @@ -44,10 +44,8 @@ const Login = () => {
- - logo - {config.siteName} - + logo + {config.siteName}
diff --git a/src/pages/password/index.tsx b/src/pages/password/index.tsx deleted file mode 100644 index 9b200972..00000000 --- a/src/pages/password/index.tsx +++ /dev/null @@ -1,97 +0,0 @@ -import React, { PureComponent, Fragment, useState, useEffect } from 'react'; -import { Button, notification, Input, Form } from 'antd'; -import config from '@/utils/config'; -import { PageContainer } from '@ant-design/pro-layout'; -import { Controlled as CodeMirror } from 'react-codemirror2'; -import { request } from '@/utils/http'; - -const Password = () => { - const [width, setWdith] = useState('100%'); - const [marginLeft, setMarginLeft] = useState(0); - const [marginTop, setMarginTop] = useState(-72); - const [value, setValue] = useState(''); - const [loading, setLoading] = useState(true); - - const handleOk = (values: any) => { - request - .post(`${config.apiPrefix}auth?t=${Date.now()}`, { - data: { - username: values.username, - password: values.password, - }, - }) - .then((data) => { - if (data.err == 0) { - localStorage.setItem(config.authKey, 'true'); - } else { - notification.open({ - message: data.msg, - }); - } - }) - .catch(function (error) { - console.log(error); - }); - }; - - useEffect(() => { - if (document.body.clientWidth < 768) { - setWdith('auto'); - setMarginLeft(0); - setMarginTop(0); - } else { - setWdith('100%'); - setMarginLeft(0); - setMarginTop(-72); - } - }, []); - - return ( - -
- - - - - - - -
-
- ); -}; - -export default Password; diff --git a/src/pages/password/index.less b/src/pages/setting/index.less similarity index 100% rename from src/pages/password/index.less rename to src/pages/setting/index.less diff --git a/src/pages/setting/index.tsx b/src/pages/setting/index.tsx new file mode 100644 index 00000000..a2af9962 --- /dev/null +++ b/src/pages/setting/index.tsx @@ -0,0 +1,148 @@ +import React, { useState, useEffect } from 'react'; +import { Button, notification, Input, Form, Radio, Tabs } from 'antd'; +import config from '@/utils/config'; +import { PageContainer } from '@ant-design/pro-layout'; +import { request } from '@/utils/http'; +import { + enable as enableDarkMode, + disable as disableDarkMode, + setFetchMethod, +} from 'darkreader'; + +const optionsWithDisabled = [ + { label: '亮色', value: 'light' }, + { label: '暗色', value: 'dark' }, + { label: '跟随系统', value: 'auto' }, +]; + +const Password = () => { + const [width, setWdith] = useState('100%'); + const [marginLeft, setMarginLeft] = useState(0); + const [marginTop, setMarginTop] = useState(-72); + const [value, setValue] = useState(''); + const [loading, setLoading] = useState(true); + const colorScheme = + window.matchMedia('(prefers-color-scheme: dark)').matches && 'dark'; + const defaultDarken = + localStorage.getItem('qinglong_dark_theme') || colorScheme; + const [theme, setTheme] = useState(defaultDarken); + + const handleOk = (values: any) => { + request + .post(`${config.apiPrefix}auth?t=${Date.now()}`, { + data: { + username: values.username, + password: values.password, + }, + }) + .then((data) => { + if (data.err == 0) { + localStorage.setItem(config.authKey, 'true'); + } else { + notification.open({ + message: data.msg, + }); + } + }) + .catch(function (error) { + console.log(error); + }); + }; + + const themeChange = (e: any) => { + setTheme(e.target.value); + localStorage.setItem('qinglong_dark_theme', e.target.value); + }; + + useEffect(() => { + if (document.body.clientWidth < 768) { + setWdith('auto'); + setMarginLeft(0); + setMarginTop(0); + } else { + setWdith('100%'); + setMarginLeft(0); + setMarginTop(-72); + } + }, []); + + useEffect(() => { + setFetchMethod(window.fetch); + if (theme === 'dark') { + enableDarkMode({ darkSchemeTextColor: '#fff' }); + } else if (theme === 'light') { + disableDarkMode(); + } else { + enableDarkMode({ darkSchemeTextColor: '#fff' }); + } + }, [theme]); + + return ( + + + +
+ + + + + + + +
+
+ +
+ + + +
+
+
+
+ ); +}; + +export default Password;