Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
new-api
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
ab3bf484
authored
Dec 11, 2024
by
Calcium-Ion
Committed by
GitHub
Dec 11, 2024
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #609 from Calcium-Ion/mobile
feat: 界面美化
parents
e6540e26
6b9e80e9
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
179 additions
and
79 deletions
+179
-79
web/src/components/HeaderBar.js
+56
-41
web/src/components/PageLayout.js
+41
-0
web/src/components/SiderBar.js
+3
-15
web/src/context/Style/index.js
+57
-0
web/src/index.css
+8
-0
web/src/index.js
+5
-21
web/src/pages/Home/index.js
+2
-0
web/src/pages/Redemption/EditRedemption.js
+7
-2
No files found.
web/src/components/HeaderBar.js
View file @
ab3bf484
...
...
@@ -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
=
[
...
...
@@ -31,21 +33,6 @@ let headerButtons = [
},
];
let
buttons
=
[
{
text
:
'首页'
,
itemKey
:
'home'
,
to
:
'/'
,
// icon: <IconHomeStroked />,
},
// {
// text: 'Playground',
// itemKey: 'playground',
// to: '/playground',
// // icon: <IconNoteMoneyStroked />,
// },
];
if
(
localStorage
.
getItem
(
'chat_link'
))
{
headerButtons
.
splice
(
1
,
0
,
{
name
:
'聊天'
,
...
...
@@ -56,9 +43,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
();
...
...
@@ -69,8 +56,20 @@ const HeaderBar = () => {
currentDate
.
getDate
()
>=
9
&&
currentDate
.
getDate
()
<=
24
);
let
buttons
=
[
{
text
:
'首页'
,
itemKey
:
'home'
,
to
:
'/'
,
},
{
text
:
'控制台'
,
itemKey
:
'detail'
,
to
:
'/'
,
},
];
async
function
logout
()
{
setShowSidebar
(
false
);
await
API
.
get
(
'/api/user/logout'
);
showSuccess
(
'注销成功!'
);
userDispatch
({
type
:
'logout'
});
...
...
@@ -108,36 +107,54 @@ const HeaderBar = () => {
<
div
style
=
{{
width
:
'100%'
}}
>
<
Nav
mode
=
{
'horizontal'
}
// bodyStyle={{ height: 100 }}
renderWrapper
=
{({
itemElement
,
isSubNav
,
isInSubNav
,
props
})
=>
{
const
routerMap
=
{
about
:
'/about'
,
login
:
'/login'
,
register
:
'/register'
,
detail
:
'/detail'
,
home
:
'/'
,
};
return
(
<
Link
style
=
{{
textDecoration
:
'none'
}}
to
=
{
routerMap
[
props
.
itemKey
]}
>
{
itemElement
}
<
/Link
>
<
div
onClick
=
{(
e
)
=>
{
if
(
props
.
itemKey
===
'home'
)
{
styleDispatch
({
type
:
'SET_SIDER'
,
payload
:
true
});
}
else
{
styleDispatch
({
type
:
'SET_SIDER'
,
payload
:
false
});
}
}}
>
<
Link
className
=
"header-bar-text"
style
=
{{
textDecoration
:
'none'
}}
to
=
{
routerMap
[
props
.
itemKey
]}
>
{
itemElement
}
<
/Link
>
<
/div
>
);
}}
selectedKeys
=
{[]}
// items={headerButtons}
onSelect
=
{(
key
)
=>
{}}
header
=
{
isMobile
()
?{
header
=
{
styleState
.
isMobile
?{
logo
:
(
<
img
src
=
{
logo
}
alt
=
'logo'
style
=
{{
marginRight
:
'0.75em'
}}
/
>
<>
{
styleState
.
showSider
?
<
Button
icon
=
{
<
IconMenu
/>
}
theme
=
"light"
aria
-
label
=
"展开侧边栏"
onClick
=
{
()
=>
styleDispatch
({
type
:
'SET_SIDER'
,
payload
:
false
})
}
/>
:
<
Button
icon
=
{
<
IconIndentLeft
/>
}
theme
=
"light"
aria
-
label
=
"关闭侧边栏"
onClick
=
{
()
=>
styleDispatch
({
type
:
'SET_SIDER'
,
payload
:
true
})
}
/
>
}
<
/
>
),
}:{
logo
:
(
<
img
src
=
{
logo
}
alt
=
'logo'
/>
),
text
:
systemName
,
}}
items
=
{
buttons
}
footer
=
{
...
...
@@ -159,17 +176,15 @@ const HeaderBar = () => {
)}
<
Nav
.
Item
itemKey
=
{
'about'
}
icon
=
{
<
IconHelpCircle
/>
}
/
>
<>
{
!
isMobile
()
&&
(
<
Switch
checkedText
=
'🌞'
size
=
{
'large'
}
checked
=
{
theme
===
'dark'
}
uncheckedText
=
'🌙'
onChange
=
{(
checked
)
=>
{
setTheme
(
checked
);
}}
/
>
)}
<
Switch
checkedText
=
'🌞'
size
=
{
'large'
}
checked
=
{
theme
===
'dark'
}
uncheckedText
=
'🌙'
onChange
=
{(
checked
)
=>
{
setTheme
(
checked
);
}}
/
>
<
/
>
{
userState
.
user
?
(
<>
...
...
web/src/components/PageLayout.js
0 → 100644
View file @
ab3bf484
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
(
<
Layout
style
=
{{
height
:
'100vh'
,
display
:
'flex'
,
flexDirection
:
'column'
}}
>
<
Header
>
<
HeaderBar
/>
<
/Header
>
<
Layout
style
=
{{
flex
:
1
,
overflow
:
'hidden'
}}
>
<
Sider
>
{
styleState
.
showSider
?
null
:
<
SiderBar
/>
}
<
/Sider
>
<
Layout
>
<
Content
style
=
{{
overflowY
:
'auto'
,
padding
:
'24px'
}}
>
<
App
/>
<
/Content
>
<
Layout
.
Footer
>
<
FooterBar
><
/FooterBar
>
<
/Layout.Footer
>
<
/Layout
>
<
/Layout
>
<
ToastContainer
/>
<
/Layout
>
)
}
export
default
PageLayout
;
\ No newline at end of file
web/src/components/SiderBar.js
View file @
ab3bf484
...
...
@@ -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
(
User
Context
);
const
[
styleState
,
styleDispatch
]
=
useContext
(
Style
Context
);
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 = () => {
<
Nav
style
=
{{
maxWidth
:
220
,
height
:
'100%'
}}
defaultIsCollapsed
=
{
isMobile
()
||
localStorage
.
getItem
(
'default_collapse_sidebar'
)
===
'true'
}
isCollapsed
=
{
isCollapsed
}
...
...
@@ -284,17 +283,6 @@ const SiderBar = () => {
}}
footer
=
{
<>
{
isMobile
()
&&
(
<
Switch
checkedText
=
'🌞'
size
=
{
'small'
}
checked
=
{
theme
===
'dark'
}
uncheckedText
=
'🌙'
onChange
=
{(
checked
)
=>
{
setTheme
(
checked
);
}}
/
>
)}
<
/
>
}
>
...
...
web/src/context/Style/index.js
0 → 100644
View file @
ab3bf484
// 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
(
<
StyleContext
.
Provider
value
=
{[
state
,
dispatch
]}
>
{
children
}
<
/StyleContext.Provider
>
);
};
web/src/index.css
View file @
ab3bf484
...
...
@@ -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
{
...
...
web/src/index.js
View file @
ab3bf484
...
...
@@ -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(
<
UserProvider
>
<
BrowserRouter
>
<
ThemeProvider
>
<
Layout
style
=
{{
height
:
'100vh'
,
display
:
'flex'
,
flexDirection
:
'column'
}}
>
<
Header
>
<
HeaderBar
/>
<
/Header
>
<
Layout
style
=
{{
flex
:
1
,
overflow
:
'hidden'
}}
>
<
Sider
>
<
SiderBar
/>
<
/Sider
>
<
Layout
>
<
Content
style
=
{{
overflowY
:
'auto'
,
padding
:
'24px'
}}
>
<
App
/>
<
/Content
>
<
Layout
.
Footer
>
<
FooterBar
><
/FooterBar
>
<
/Layout.Footer
>
<
/Layout
>
<
/Layout
>
<
ToastContainer
/>
<
/Layout
>
<
StyleProvider
>
<
PageLayout
/>
<
/StyleProvider
>
<
/ThemeProvider
>
<
/BrowserRouter
>
<
/UserProvider
>
...
...
web/src/pages/Home/index.js
View file @
ab3bf484
...
...
@@ -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'
);
...
...
web/src/pages/Redemption/EditRedemption.js
View file @
ab3bf484
...
...
@@ -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/`
,
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment