From 3622c664b627dca805f4af17b0cde491f982a625 Mon Sep 17 00:00:00 2001 From: CalciumIon <1808837298@qq.com> Date: Wed, 11 Dec 2024 16:11:27 +0800 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20=E4=BE=A7=E8=BE=B9=E6=A0=8F?= =?UTF-8?q?=E7=A7=BB=E5=8A=A8=E7=AB=AF=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/src/components/HeaderBar.js | 53 ++++++++++++++--------------- web/src/components/PageLayout.js | 40 ++++++++++++++++++++++ web/src/components/SiderBar.js | 18 ++-------- web/src/context/Style/index.js | 57 ++++++++++++++++++++++++++++++++ web/src/index.js | 26 +++------------ 5 files changed, 132 insertions(+), 62 deletions(-) create mode 100644 web/src/components/PageLayout.js create mode 100644 web/src/context/Style/index.js diff --git a/web/src/components/HeaderBar.js b/web/src/components/HeaderBar.js index 43bd96f9..4b284e26 100644 --- a/web/src/components/HeaderBar.js +++ b/web/src/components/HeaderBar.js @@ -9,17 +9,19 @@ import '../index.css'; import fireworks from 'react-fireworks'; import { + IconClose, IconHelpCircle, IconHome, - IconHomeStroked, - IconKey, + IconHomeStroked, IconIndentLeft, + IconKey, IconMenu, IconNoteMoneyStroked, IconPriceTag, IconUser } from '@douyinfe/semi-icons'; -import { Avatar, Dropdown, Layout, Nav, Switch } from '@douyinfe/semi-ui'; +import { Avatar, Button, Dropdown, Layout, Nav, Switch } from '@douyinfe/semi-ui'; import { stringToColor } from '../helpers/render'; import Text from '@douyinfe/semi-ui/lib/es/typography/text'; +import { StyleContext } from '../context/Style/index.js'; // HeaderBar Buttons let headerButtons = [ @@ -36,14 +38,7 @@ let buttons = [ text: '首页', itemKey: 'home', to: '/', - // icon: , }, - // { - // text: 'Playground', - // itemKey: 'playground', - // to: '/playground', - // // icon: , - // }, ]; if (localStorage.getItem('chat_link')) { @@ -56,9 +51,9 @@ if (localStorage.getItem('chat_link')) { const HeaderBar = () => { const [userState, userDispatch] = useContext(UserContext); + const [styleState, styleDispatch] = useContext(StyleContext); let navigate = useNavigate(); - const [showSidebar, setShowSidebar] = useState(false); const systemName = getSystemName(); const logo = getLogo(); const currentDate = new Date(); @@ -70,7 +65,6 @@ const HeaderBar = () => { currentDate.getDate() <= 24); async function logout() { - setShowSidebar(false); await API.get('/api/user/logout'); showSuccess('注销成功!'); userDispatch({ type: 'logout' }); @@ -128,16 +122,25 @@ const HeaderBar = () => { selectedKeys={[]} // items={headerButtons} onSelect={(key) => {}} - header={isMobile()?{ + header={styleState.isMobile?{ logo: ( - + <> + { + styleState.showSider ? + } theme="light" style={{ marginRight: 10 }} aria-label="展开侧边栏" onClick={ + () => styleDispatch({ type: 'SET_SIDER', payload: false }) + } />: + } theme="light" style={{ marginRight: 10 }} aria-label="关闭侧边栏" onClick={ + () => styleDispatch({ type: 'SET_SIDER', payload: true }) + } /> + } + > ), }:{ logo: ( ), text: systemName, - }} items={buttons} footer={ @@ -159,17 +162,15 @@ const HeaderBar = () => { )} } /> <> - {!isMobile() && ( - { - setTheme(checked); - }} - /> - )} + { + setTheme(checked); + }} + /> > {userState.user ? ( <> diff --git a/web/src/components/PageLayout.js b/web/src/components/PageLayout.js new file mode 100644 index 00000000..06f31f06 --- /dev/null +++ b/web/src/components/PageLayout.js @@ -0,0 +1,40 @@ +import HeaderBar from './HeaderBar.js'; +import { Layout } from '@douyinfe/semi-ui'; +import SiderBar from './SiderBar.js'; +import App from '../App.js'; +import FooterBar from './Footer.js'; +import { ToastContainer } from 'react-toastify'; +import React, { useContext } from 'react'; +import { StyleContext } from '../context/Style/index.js'; +const { Sider, Content, Header, Footer } = Layout; + + +const PageLayout = () => { + const [styleState, styleDispatch] = useContext(StyleContext); + + return ( + + + + + + + {styleState.showSider ? null : } + + + + + + + + + + + + + ) +} + +export default PageLayout; \ No newline at end of file diff --git a/web/src/components/SiderBar.js b/web/src/components/SiderBar.js index a7310382..58fea10d 100644 --- a/web/src/components/SiderBar.js +++ b/web/src/components/SiderBar.js @@ -31,14 +31,15 @@ import { Avatar, Dropdown, Layout, Nav, Switch } from '@douyinfe/semi-ui'; import { setStatusData } from '../helpers/data.js'; import { stringToColor } from '../helpers/render.js'; import { useSetTheme, useTheme } from '../context/Theme/index.js'; +import { StyleContext } from '../context/Style/index.js'; // HeaderBar Buttons const SiderBar = () => { - const [userState, userDispatch] = useContext(UserContext); + const [styleState, styleDispatch] = useContext(StyleContext); const [statusState, statusDispatch] = useContext(StatusContext); const defaultIsCollapsed = - isMobile() || localStorage.getItem('default_collapse_sidebar') === 'true'; + localStorage.getItem('default_collapse_sidebar') === 'true'; const [selectedKeys, setSelectedKeys] = useState(['home']); const [isCollapsed, setIsCollapsed] = useState(defaultIsCollapsed); @@ -196,7 +197,6 @@ const SiderBar = () => { useEffect(() => { loadStatus().then(() => { setIsCollapsed( - isMobile() || localStorage.getItem('default_collapse_sidebar') === 'true', ); }); @@ -239,7 +239,6 @@ const SiderBar = () => { { }} footer={ <> - {isMobile() && ( - { - setTheme(checked); - }} - /> - )} > } > diff --git a/web/src/context/Style/index.js b/web/src/context/Style/index.js new file mode 100644 index 00000000..341fa912 --- /dev/null +++ b/web/src/context/Style/index.js @@ -0,0 +1,57 @@ +// contexts/User/index.jsx + +import React, { useState, useEffect } from 'react'; +import { isMobile } from '../../helpers/index.js'; + +export const StyleContext = React.createContext({ + dispatch: () => null, +}); + +export const StyleProvider = ({ children }) => { + const [state, setState] = useState({ + isMobile: false, + showSider: false, + }); + + const dispatch = (action) => { + if ('type' in action) { + switch (action.type) { + case 'TOGGLE_SIDER': + setState(prev => ({ ...prev, showSider: !prev.showSider })); + break; + case 'SET_SIDER': + setState(prev => ({ ...prev, showSider: action.payload })); + break; + case 'SET_MOBILE': + setState(prev => ({ ...prev, isMobile: action.payload })); + break; + default: + setState(prev => ({ ...prev, ...action })); + } + } else { + setState(prev => ({ ...prev, ...action })); + } + }; + + useEffect(() => { + const updateIsMobile = () => { + dispatch({ type: 'SET_MOBILE', payload: isMobile() }); + }; + + updateIsMobile(); + + // Optionally, add event listeners to handle window resize + window.addEventListener('resize', updateIsMobile); + + // Cleanup event listener on component unmount + return () => { + window.removeEventListener('resize', updateIsMobile); + }; + }, []); + + return ( + + {children} + + ); +}; diff --git a/web/src/index.js b/web/src/index.js index 3def4a93..407eec1b 100644 --- a/web/src/index.js +++ b/web/src/index.js @@ -13,6 +13,8 @@ import { Layout } from '@douyinfe/semi-ui'; import SiderBar from './components/SiderBar'; import { ThemeProvider } from './context/Theme'; import FooterBar from './components/Footer'; +import { StyleProvider } from './context/Style/index.js'; +import PageLayout from './components/PageLayout.js'; // initialization @@ -24,27 +26,9 @@ root.render( - - - - - - - - - - - - - - - - - - - + + + From 64e085dc4c18552332dcc4ddf6c6036f8423ad71 Mon Sep 17 00:00:00 2001 From: CalciumIon <1808837298@qq.com> Date: Wed, 11 Dec 2024 17:19:03 +0800 Subject: [PATCH 2/3] =?UTF-8?q?feat:=20=E9=A6=96=E9=A1=B5=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/src/components/HeaderBar.js | 48 +++++++++++++++++++++------------ web/src/index.css | 8 ++++++ web/src/pages/Home/index.js | 2 ++ 3 files changed, 41 insertions(+), 17 deletions(-) diff --git a/web/src/components/HeaderBar.js b/web/src/components/HeaderBar.js index 4b284e26..fc879ee1 100644 --- a/web/src/components/HeaderBar.js +++ b/web/src/components/HeaderBar.js @@ -33,14 +33,6 @@ let headerButtons = [ }, ]; -let buttons = [ - { - text: '首页', - itemKey: 'home', - to: '/', - }, -]; - if (localStorage.getItem('chat_link')) { headerButtons.splice(1, 0, { name: '聊天', @@ -64,6 +56,19 @@ const HeaderBar = () => { currentDate.getDate() >= 9 && currentDate.getDate() <= 24); + let buttons = [ + { + text: '首页', + itemKey: 'home', + to: '/', + }, + { + text: '控制台', + itemKey: 'detail', + to: '/', + }, + ]; + async function logout() { await API.get('/api/user/logout'); showSuccess('注销成功!'); @@ -102,21 +107,30 @@ const HeaderBar = () => { { const routerMap = { about: '/about', login: '/login', register: '/register', + detail: '/detail', home: '/', }; return ( - - {itemElement} - + { + if (props.itemKey === 'home') { + styleDispatch({ type: 'SET_SIDER', payload: true }); + } else { + styleDispatch({ type: 'SET_SIDER', payload: false }); + } + }}> + + {itemElement} + + ); }} selectedKeys={[]} @@ -127,10 +141,10 @@ const HeaderBar = () => { <> { styleState.showSider ? - } theme="light" style={{ marginRight: 10 }} aria-label="展开侧边栏" onClick={ + } theme="light" aria-label="展开侧边栏" onClick={ () => styleDispatch({ type: 'SET_SIDER', payload: false }) } />: - } theme="light" style={{ marginRight: 10 }} aria-label="关闭侧边栏" onClick={ + } theme="light" aria-label="关闭侧边栏" onClick={ () => styleDispatch({ type: 'SET_SIDER', payload: true }) } /> } diff --git a/web/src/index.css b/web/src/index.css index 5d752fb5..2596cd61 100644 --- a/web/src/index.css +++ b/web/src/index.css @@ -17,6 +17,10 @@ body { flex-direction: column; } +#root > section > header > section > div > div > div > div.semi-navigation-header-list-outer > div.semi-navigation-list-wrapper > ul > div > a > li > span{ + font-weight: 600 !important; +} + @media only screen and (max-width: 767px) { .semi-table-tbody, .semi-table-row, @@ -39,6 +43,10 @@ body { row-gap: 3px; column-gap: 10px; } + + .semi-navigation-horizontal .semi-navigation-header { + margin-right: 0; + } } .semi-table-tbody > .semi-table-row > .semi-table-row-cell { diff --git a/web/src/pages/Home/index.js b/web/src/pages/Home/index.js index 0ae4890a..1f58d719 100644 --- a/web/src/pages/Home/index.js +++ b/web/src/pages/Home/index.js @@ -3,11 +3,13 @@ import { Card, Col, Row } from '@douyinfe/semi-ui'; import { API, showError, showNotice, timestamp2string } from '../../helpers'; import { StatusContext } from '../../context/Status'; import { marked } from 'marked'; +import { StyleContext } from '../../context/Style/index.js'; const Home = () => { const [statusState] = useContext(StatusContext); const [homePageContentLoaded, setHomePageContentLoaded] = useState(false); const [homePageContent, setHomePageContent] = useState(''); + const [styleState, styleDispatch] = useContext(StyleContext); const displayNotice = async () => { const res = await API.get('/api/notice'); From 713de36ecd8a0634683557534d7f0c139a0a5996 Mon Sep 17 00:00:00 2001 From: CalciumIon <1808837298@qq.com> Date: Wed, 11 Dec 2024 17:28:59 +0800 Subject: [PATCH 3/3] feat: Enhance EditRedemption component with default name handling --- web/src/pages/Redemption/EditRedemption.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/web/src/pages/Redemption/EditRedemption.js b/web/src/pages/Redemption/EditRedemption.js index 2711a172..73cd3c38 100644 --- a/web/src/pages/Redemption/EditRedemption.js +++ b/web/src/pages/Redemption/EditRedemption.js @@ -7,7 +7,7 @@ import { showError, showSuccess, } from '../../helpers'; -import { renderQuotaWithPrompt } from '../../helpers/render'; +import { getQuotaPerUnit, renderQuota, renderQuotaWithPrompt } from '../../helpers/render'; import { AutoComplete, Button, @@ -66,11 +66,16 @@ const EditRedemption = (props) => { }, [props.editingRedemption.id]); const submit = async () => { - if (!isEdit && inputs.name === '') return; + let name = inputs.name; + if (!isEdit && inputs.name === '') { + // set default name + name = '兑换码-' + renderQuota(quota); + } setLoading(true); let localInputs = inputs; localInputs.count = parseInt(localInputs.count); localInputs.quota = parseInt(localInputs.quota); + localInputs.name = name; let res; if (isEdit) { res = await API.put(`/api/redemption/`, {