Complete main UI #37

Merged
FatttSnake merged 192 commits from FatttSnake into dev 2024-02-23 16:31:17 +08:00
9 changed files with 159 additions and 8 deletions
Showing only changes of commit 4d072e0de8 - Show all commits

8
package-lock.json generated
View File

@@ -23,7 +23,8 @@
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-router": "^6.20.1", "react-router": "^6.20.1",
"react-router-dom": "^6.20.1", "react-router-dom": "^6.20.1",
"size-sensor": "^1.0.2" "size-sensor": "^1.0.2",
"vanilla-tilt": "^1.8.1"
}, },
"devDependencies": { "devDependencies": {
"@svgr/core": "^8.1.0", "@svgr/core": "^8.1.0",
@@ -7933,6 +7934,11 @@
"spdx-expression-parse": "^3.0.0" "spdx-expression-parse": "^3.0.0"
} }
}, },
"node_modules/vanilla-tilt": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/vanilla-tilt/-/vanilla-tilt-1.8.1.tgz",
"integrity": "sha512-hPB1XUsnh+SIeVSW2beb5RnuFxz4ZNgxjGD78o52F49gS4xaoLeEMh9qrQnJrnEn/vjjBI7IlxrrXmz4tGV0Kw=="
},
"node_modules/vite": { "node_modules/vite": {
"version": "5.0.6", "version": "5.0.6",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.0.6.tgz", "resolved": "https://registry.npmjs.org/vite/-/vite-5.0.6.tgz",

View File

@@ -29,7 +29,8 @@
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-router": "^6.20.1", "react-router": "^6.20.1",
"react-router-dom": "^6.20.1", "react-router-dom": "^6.20.1",
"size-sensor": "^1.0.2" "size-sensor": "^1.0.2",
"vanilla-tilt": "^1.8.1"
}, },
"devDependencies": { "devDependencies": {
"@svgr/core": "^8.1.0", "@svgr/core": "^8.1.0",

View File

@@ -0,0 +1,40 @@
@use '@/assets/css/constants' as constants;
[data-component=system] {
.root-content {
padding: 30px;
gap: 20px;
flex-wrap: wrap;
justify-content: flex-start;
> .card-box {
width: 200px;
height: 360px;
flex: 0 0 auto;
cursor: pointer;
.common-card {
width: 100%;
height: 100%;
margin-top: 100px;
text-align: center;
gap: 42px;
> * {
flex: 0 0 auto;
display: block;
}
.icon {
color: constants.$production-color;
font-size: constants.$SIZE_ICON_XL;
}
.text {
font-weight: bolder;
font-size: 2em;
}
}
}
}
}

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path d="M810.666667 384a128 128 0 0 0-120.32 85.333333H128a42.666667 42.666667 0 0 0 0 85.333334h562.346667A128 128 0 1 0 810.666667 384zM128 298.666667h50.346667a128 128 0 0 0 240.64 0H896a42.666667 42.666667 0 0 0 0-85.333334H418.986667a128 128 0 0 0-240.64 0H128a42.666667 42.666667 0 0 0 0 85.333334zM896 725.333333h-306.346667a128 128 0 0 0-240.64 0H128a42.666667 42.666667 0 0 0 0 85.333334h221.013333a128 128 0 0 0 240.64 0H896a42.666667 42.666667 0 0 0 0-85.333334z" /></svg>

After

Width:  |  Height:  |  Size: 548 B

View File

@@ -1,12 +1,16 @@
import React from 'react' import React from 'react'
import { hasPermission } from '@/util/auth' import { hasPathPermission, hasPermission } from '@/util/auth'
interface PermissionProps extends React.PropsWithChildren { interface PermissionProps extends React.PropsWithChildren {
operationCode?: string operationCode?: string
path?: string
} }
const Permission: React.FC<PermissionProps> = (props) => { const Permission: React.FC<PermissionProps> = (props) => {
if (!props.operationCode || hasPermission(props.operationCode)) { if (
(!props.operationCode || hasPermission(props.operationCode)) &&
(!props.path || hasPathPermission(props.path))
) {
return props.children return props.children
} }

View File

@@ -213,6 +213,7 @@ const OnlineInfo: React.FC = () => {
} }
setIsLoading(true) setIsLoading(true)
setCurrentOnlineCount(-1)
void r_sys_statistics_online({ scope: _scope }).then((res) => { void r_sys_statistics_online({ scope: _scope }).then((res) => {
const response = res.data const response = res.data

View File

@@ -1,7 +1,105 @@
import React from 'react' import React from 'react'
import Icon from '@ant-design/icons'
import VanillaTilt, { TiltOptions } from 'vanilla-tilt'
import '@/assets/css/pages/system/index.scss'
import HideScrollbar from '@/components/common/HideScrollbar'
import FitFullScreen from '@/components/common/FitFullScreen'
import FlexBox from '@/components/common/FlexBox'
import Card from '@/components/common/Card'
import Permission from '@/components/common/Permission.tsx'
interface CommonCardProps
extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement> {
icon: IconComponent
description?: React.ReactNode
options?: TiltOptions
url?: string
}
const CommonCard = forwardRef<HTMLDivElement, CommonCardProps>((props) => {
const navigate = useNavigate()
const cardRef = useRef<HTMLDivElement>(null)
const {
style,
ref,
icon,
description,
options = {
reverse: true,
max: 8,
glare: true,
scale: 1.03
},
url,
children,
..._props
} = props
useEffect(() => {
cardRef.current && VanillaTilt.init(cardRef.current, options)
}, [options])
const handleCardOnClick = () => {
url && navigate(url)
}
return (
<Card
style={{ overflow: 'visible', ...style }}
ref={cardRef}
{..._props}
onClick={handleCardOnClick}
>
<FlexBox className={'common-card'}>
<Icon component={icon} className={'icon'} />
<div className={'text'}>{children}</div>
<div className={'description'}>{description}</div>
</FlexBox>
</Card>
)
})
const System: React.FC = () => { const System: React.FC = () => {
return <></> return (
<>
<FitFullScreen data-component={'system'}>
<HideScrollbar isShowVerticalScrollbar autoHideWaitingTime={500}>
<FlexBox direction={'horizontal'} className={'root-content'}>
<Permission path={'/system/statistics'}>
<CommonCard icon={IconFatwebAnalysis} url={'statistics'}>
</CommonCard>
</Permission>
<Permission path={'/system/settings'}>
<CommonCard icon={IconFatwebOption} url={'settings'}>
</CommonCard>
</Permission>
<Permission path={'/system/user'}>
<CommonCard icon={IconFatwebUser} url={'user'}>
</CommonCard>
</Permission>
<Permission path={'/system/role'}>
<CommonCard icon={IconFatwebRole} url={'role'}>
</CommonCard>
</Permission>
<Permission path={'/system/group'}>
<CommonCard icon={IconFatwebGroup} url={'group'}>
</CommonCard>
</Permission>
<Permission path={'/system/log'}>
<CommonCard icon={IconFatwebLog} url={'log'}>
</CommonCard>
</Permission>
</FlexBox>
</HideScrollbar>
</FitFullScreen>
</>
)
} }
export default System export default System

View File

@@ -47,8 +47,8 @@ const root: RouteJsonObject[] = [
absolutePath: '/system', absolutePath: '/system',
id: 'systemFramework', id: 'systemFramework',
component: React.lazy(() => import('@/pages/SystemFramework')), component: React.lazy(() => import('@/pages/SystemFramework')),
children: setTitle(system, '系统置'), children: setTitle(system, '系统置'),
name: '系统置', name: '系统置',
auth: true, auth: true,
permission: true permission: true
}, },

View File

@@ -27,7 +27,7 @@ const system: RouteJsonObject[] = [
id: 'system-settings', id: 'system-settings',
component: React.lazy(() => import('@/pages/system/Settings')), component: React.lazy(() => import('@/pages/system/Settings')),
name: '系统设置', name: '系统设置',
icon: React.lazy(() => import('~icons/fatweb/setting.jsx')), icon: React.lazy(() => import('~icons/fatweb/option.jsx')),
menu: true, menu: true,
autoHide: true autoHide: true
}, },