diff --git a/spug_web2/.eslintrc.cjs b/spug_web2/.eslintrc.cjs index ced1608..e424d5e 100644 --- a/spug_web2/.eslintrc.cjs +++ b/spug_web2/.eslintrc.cjs @@ -16,6 +16,7 @@ module.exports = { 'warn', { allowConstantExport: true }, ], + 'react/prop-types': 'off', }, globals: { t: 'readonly', diff --git a/spug_web2/package.json b/spug_web2/package.json index 595852f..1a2c026 100644 --- a/spug_web2/package.json +++ b/spug_web2/package.json @@ -10,7 +10,9 @@ "preview": "vite preview" }, "dependencies": { - "antd": "^5.11.5", + "@ant-design/icons": "^5.2.6", + "antd": "^5.12.4", + "dayjs": "^1.11.10", "i18next": "^23.7.7", "react": "^18.2.0", "react-dom": "^18.2.0", diff --git a/spug_web2/src/App.jsx b/spug_web2/src/App.jsx index 383583d..6c210a7 100644 --- a/spug_web2/src/App.jsx +++ b/spug_web2/src/App.jsx @@ -1,11 +1,47 @@ -import {useTranslation } from 'react-i18next' +import {createBrowserRouter, RouterProvider} from 'react-router-dom' +import {ConfigProvider, App as AntdApp, theme} from 'antd' +import zhCN from 'antd/locale/zh_CN' +import enUS from 'antd/locale/en_US' +import dayjs from 'dayjs' +import routes from './routes.jsx' +import {session, SContext} from '@/libs' +import {useImmer} from 'use-immer' +import './i18n.js' +dayjs.locale(session.lang) -function App(props) { - const {t} = useTranslation() - window.t = t +const router = createBrowserRouter(routes) - return props.children +function App() { + const [S, updateS] = useImmer({theme: session.theme}) + + return ( + + + + + + + + ) } export default App \ No newline at end of file diff --git a/spug_web2/src/assets/logo-spug-white.png b/spug_web2/src/assets/logo-spug-white.png deleted file mode 100644 index d8af69b..0000000 Binary files a/spug_web2/src/assets/logo-spug-white.png and /dev/null differ diff --git a/spug_web2/src/assets/logo-white.png b/spug_web2/src/assets/logo-white.png deleted file mode 100644 index 8e43656..0000000 Binary files a/spug_web2/src/assets/logo-white.png and /dev/null differ diff --git a/spug_web2/src/assets/logo-spug-txt.png b/spug_web2/src/assets/spug-default.png similarity index 100% rename from spug_web2/src/assets/logo-spug-txt.png rename to spug_web2/src/assets/spug-default.png diff --git a/spug_web2/src/i18n.js b/spug_web2/src/i18n.js index 0d2ddaa..61ebb85 100644 --- a/spug_web2/src/i18n.js +++ b/spug_web2/src/i18n.js @@ -1,8 +1,9 @@ import i18n from 'i18next' import {initReactI18next} from 'react-i18next' +import {session} from '@/libs' i18n.use(initReactI18next).init({ - lng: localStorage.getItem('lang') || 'zh', + lng: session.lang, resources: { en: { translation: { @@ -12,6 +13,15 @@ i18n.use(initReactI18next).init({ '批量执行': 'Batch', '执行任务': 'Task', '文件分发': 'Transfer', + '重置': 'Reset', + '展示字段': 'Columns Display', + '年龄': 'Age', + 'page': 'Total {{total}} items', + } + }, + zh: { + translation: { + 'page': '共 {{total}} 条', } } } diff --git a/spug_web2/src/layout/Header.jsx b/spug_web2/src/layout/Header.jsx index 8b83401..d962c13 100644 --- a/spug_web2/src/layout/Header.jsx +++ b/spug_web2/src/layout/Header.jsx @@ -1,10 +1,22 @@ -import {Layout, Flex, Dropdown, theme} from 'antd' +import {useContext} from 'react' +import {Layout, Flex, Dropdown} from 'antd' import {AiOutlineTranslation} from 'react-icons/ai' -import css from './header.module.scss' +import {IoSunny, IoMoon} from 'react-icons/io5' +import {SContext} from '@/libs' +import css from './index.module.scss' import i18n from '@/i18n.js' +import logo from "@/assets/spug-default.png"; function Header() { - const {token: {colorBgContainer}} = theme.useToken() + const {S: {theme}, updateS} = useContext(SContext) + + function handleThemeChange() { + const newTheme = theme === 'light' ? 'dark' : 'light' + localStorage.setItem('theme', newTheme) + updateS(draft => { + draft.theme = newTheme + }) + } function handleLangChange({key}) { localStorage.setItem('lang', key) @@ -19,9 +31,9 @@ function Header() { key: 'en', }] - console.log('lang', i18n.language) return ( - + + logo
admin
@@ -29,6 +41,9 @@ function Header() { +
+ {theme === 'light' ? : } +
) diff --git a/spug_web2/src/layout/header.module.scss b/spug_web2/src/layout/header.module.scss deleted file mode 100644 index 66f3668..0000000 --- a/spug_web2/src/layout/header.module.scss +++ /dev/null @@ -1,18 +0,0 @@ -.header { - padding: 0 8px; - - .item { - height: 48px; - display: flex; - align-items: center; - justify-content: center; - padding: 0 16px; - font-weight: 600; - cursor: pointer; - transition: all 0.1s ease-in-out; - - &:hover { - background: #f1f1f1; - } - } -} \ No newline at end of file diff --git a/spug_web2/src/layout/index.jsx b/spug_web2/src/layout/index.jsx index e3a3d5e..bc60b49 100644 --- a/spug_web2/src/layout/index.jsx +++ b/spug_web2/src/layout/index.jsx @@ -1,18 +1,14 @@ -import {useState} from 'react' import {Outlet, useMatches, useNavigate} from 'react-router-dom' -import {Layout, Breadcrumb, Flex, Menu, theme} from 'antd' +import {Layout, Flex, Menu, theme} from 'antd' import Header from './Header.jsx' import {menus} from '@/routes' -import logo1 from '@/assets/logo-spug-white.png' -import logo2 from '@/assets/logo-white.png' +import css from './index.module.scss' function LayoutIndex() { - const [collapsed, setCollapsed] = useState(false) - const {token: {colorBgContainer, colorTextTertiary}} = theme.useToken() + const {token: {colorTextTertiary}} = theme.useToken() const navigate = useNavigate() const matches = useMatches() - const crumbs = matches.map(x => ({title: x.handle.crumb, href: x.pathname})) function handleMenuClick({key}) { navigate(key) @@ -21,29 +17,20 @@ function LayoutIndex() { const selectedKey = matches[matches.length - 1]?.pathname return ( - - - {collapsed ? ( - logo - ) : ( - logo - )} - - - +
-
- - -
- -
+ + + + + + + + Copyright © 2023 OpenSpug All Rights Reserved. + + - - - Copyright © 2023 OpenSpug All Rights Reserved. - - ) diff --git a/spug_web2/src/layout/index.module.scss b/spug_web2/src/layout/index.module.scss new file mode 100644 index 0000000..2e92d0d --- /dev/null +++ b/spug_web2/src/layout/index.module.scss @@ -0,0 +1,46 @@ +.header { + position: sticky; + top: 0; + z-index: 999; + padding: 0 8px; + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + border-bottom: 1px solid var(--ant-color-border); + background: var(--ant-color-bg-container); + + .logo { + margin-left: 16px; + height: 30px; + } + + .item { + height: 47px; + display: flex; + align-items: center; + justify-content: center; + padding: 0 12px; + font-weight: 600; + cursor: pointer; + transition: all 0.1s ease-in-out; + + &:hover { + background: var(--ant-color-fill-secondary); + } + } +} + +.sider { + :global(.ant-menu) { + height: 100%; + } + + :global(.ant-layout-sider-trigger) { + border-inline-end: 1px solid var(--ant-color-split); + } +} + +.menu { + border-inline-end: none; +} \ No newline at end of file diff --git a/spug_web2/src/libs/index.js b/spug_web2/src/libs/index.js index c750766..e0e157e 100644 --- a/spug_web2/src/libs/index.js +++ b/spug_web2/src/libs/index.js @@ -1,7 +1,11 @@ +import React from 'react' import http from './http' import session from './session' +const SContext = React.createContext({}) +export * from './utils.js' export { http, session, -} \ No newline at end of file + SContext, +} diff --git a/spug_web2/src/libs/session.js b/spug_web2/src/libs/session.js index d1e6493..03fa021 100644 --- a/spug_web2/src/libs/session.js +++ b/spug_web2/src/libs/session.js @@ -3,6 +3,8 @@ import {isSubArray} from "@/libs/utils.js"; class Session { constructor() { this._session = {}; + this.lang = localStorage.getItem('lang') || 'zh'; + this.theme = localStorage.getItem('theme') || 'light'; const tmp = localStorage.getItem('session'); if (tmp) { try { diff --git a/spug_web2/src/main.jsx b/spug_web2/src/main.jsx index cb27969..92babb7 100644 --- a/spug_web2/src/main.jsx +++ b/spug_web2/src/main.jsx @@ -1,30 +1,9 @@ import React from 'react' import ReactDOM from 'react-dom/client' -import {createBrowserRouter, RouterProvider} from 'react-router-dom' -import {ConfigProvider, App, theme} from 'antd' -import routes from './routes.jsx' -import './i18n.js' - - -const router = createBrowserRouter(routes) +import App from './App.jsx' ReactDOM.createRoot(document.getElementById('root')).render( - - - - - + ) diff --git a/spug_web2/src/routes.jsx b/spug_web2/src/routes.jsx index 37fd665..f97c77f 100644 --- a/spug_web2/src/routes.jsx +++ b/spug_web2/src/routes.jsx @@ -11,7 +11,6 @@ let routes = [ path: '/', element: , errorElement: , - title: t('首页'), children: [ { path: 'home', @@ -72,17 +71,5 @@ function routes2menu(routes, parentPath = '') { return menu } -function handle(routes) { - for (const route of routes) { - if (route.children) { - route.children = handle(route.children) - } - route.handle = {crumb: route.title} - } - return routes -} - -routes = handle(routes) - export const menus = routes2menu(routes[0].children) export default routes \ No newline at end of file