@@ -11,18 +11,18 @@ | |||||
z-index: 9999; | z-index: 9999; | ||||
border-bottom: 3px solid #0C489E; | border-bottom: 3px solid #0C489E; | ||||
} | } | ||||
#navbar{ | |||||
#navbar div{ | |||||
display: flex; | display: flex; | ||||
align-items: center; | align-items: center; | ||||
justify-content: center; | justify-content: center; | ||||
} | } | ||||
#navbar li{ | |||||
#navbar div li{ | |||||
list-style: none; | list-style: none; | ||||
padding: 0 20px; | padding: 0 20px; | ||||
position: relative; | position: relative; | ||||
} | } | ||||
#navbar li a{ | |||||
#navbar div li a{ | |||||
text-decoration: none; | text-decoration: none; | ||||
font-size: 1.5rem; | font-size: 1.5rem; | ||||
font-weight: 600; | font-weight: 600; | ||||
@@ -30,11 +30,11 @@ | |||||
color: black; | color: black; | ||||
transition: 0.3s ease-in-out; | transition: 0.3s ease-in-out; | ||||
} | } | ||||
#navbar li a:hover{ | |||||
#navbar div li a:hover{ | |||||
color: #0C489E; | color: #0C489E; | ||||
} | } | ||||
#navbar li a:hover::after, | |||||
#navbar li a:focus::after{ | |||||
#navbar div li a:hover::after, | |||||
#navbar div li a:focus::after{ | |||||
content: ""; | content: ""; | ||||
width: 60%; | width: 60%; | ||||
height: 2px; | height: 2px; | ||||
@@ -62,14 +62,27 @@ | |||||
text-align: center; | text-align: center; | ||||
} | } | ||||
#sidebar{ | #sidebar{ | ||||
font-size: 1.3rem; | |||||
font-weight: 600; | |||||
font-family: 微軟正黑體; | |||||
} | |||||
#sidebartop{ | |||||
align-items: center; | |||||
justify-content: center; | |||||
padding: 0; | |||||
display: flex; | |||||
} | |||||
#sidebarbottom{ | |||||
align-items: center; | align-items: center; | ||||
justify-content: center; | justify-content: center; | ||||
padding: 0; | padding: 0; | ||||
display: flex; | |||||
} | } | ||||
#sidebar li{ | #sidebar li{ | ||||
list-style: none; | list-style: none; | ||||
padding: 0 20px; | padding: 0 20px; | ||||
position: relative; | position: relative; | ||||
text-align: left; | |||||
} | } | ||||
#sidebar li a{ | #sidebar li a{ | ||||
text-decoration: none; | text-decoration: none; | ||||
@@ -1,4 +1,4 @@ | |||||
import useJwt from 'auth/jwt/coreUseJwt' | |||||
import useJwt from 'auth/jwt/coreUseJwt'; | |||||
/** | /** | ||||
* Return if user is logged in | * Return if user is logged in | ||||
@@ -6,16 +6,16 @@ import useJwt from 'auth/jwt/coreUseJwt' | |||||
* e.g. If you are using cookies to store the application please update this function | * e.g. If you are using cookies to store the application please update this function | ||||
*/ | */ | ||||
// eslint-disable-next-line arrow-body-style | // eslint-disable-next-line arrow-body-style | ||||
export const hostname = "localhost" | |||||
const hostPort = "8080" | |||||
export const hostPath = `http://${hostname}:${hostPort}` | |||||
export const apiPath = `${hostPath}/api` | |||||
export const hostname = 'localhost'; | |||||
const hostPort = '8090'; | |||||
export const hostPath = `http://${hostname}:${hostPort}`; | |||||
export const apiPath = `${hostPath}/api`; | |||||
export const isUserLoggedIn = () => { | export const isUserLoggedIn = () => { | ||||
return localStorage.getItem('userData') && localStorage.getItem(useJwt.jwtConfig.storageTokenKeyName) | |||||
} | |||||
return localStorage.getItem('userData') && localStorage.getItem(useJwt.jwtConfig.storageTokenKeyName); | |||||
}; | |||||
export const getUserData = () => JSON.parse(localStorage.getItem('userData')) | |||||
export const getUserData = () => JSON.parse(localStorage.getItem('userData')); | |||||
/** | /** | ||||
* This function is used for demo purpose route navigation | * This function is used for demo purpose route navigation | ||||
@@ -25,9 +25,9 @@ export const getUserData = () => JSON.parse(localStorage.getItem('userData')) | |||||
* NOTE: If you have different pages to navigate based on user ability then this function can be useful. However, you need to update it. | * NOTE: If you have different pages to navigate based on user ability then this function can be useful. However, you need to update it. | ||||
* @param {String} userRole Role of user | * @param {String} userRole Role of user | ||||
*/ | */ | ||||
export const getHomeRouteForLoggedInUser = userRole => { | |||||
if (userRole === 'admin') return '/' | |||||
if (userRole === 'user') return '/' | |||||
if (userRole === 'client') return {name: 'access-control'} | |||||
return {name: 'auth-login'} | |||||
} | |||||
export const getHomeRouteForLoggedInUser = (userRole) => { | |||||
if (userRole === 'admin') return '/'; | |||||
if (userRole === 'user') return '/'; | |||||
if (userRole === 'client') return { name: 'access-control' }; | |||||
return { name: 'auth-login' }; | |||||
}; |
@@ -2,6 +2,9 @@ import PropTypes from 'prop-types'; | |||||
import React | import React | ||||
,{useState} | ,{useState} | ||||
from 'react'; | from 'react'; | ||||
import {useDispatch} from "react-redux"; | |||||
import {useNavigate} from "react-router-dom"; | |||||
// material-ui | // material-ui | ||||
// import { useTheme } from '@mui/material/styles'; | // import { useTheme } from '@mui/material/styles'; | ||||
import { | import { | ||||
@@ -28,7 +31,7 @@ import { | |||||
// useMediaQuery | // useMediaQuery | ||||
} from '@mui/material'; | } from '@mui/material'; | ||||
import MenuIcon from '@mui/icons-material/Menu'; | |||||
import MenuIcon from '@mui/icons-material/Menu'; | |||||
// project import | // project import | ||||
// import AppBarStyled from './AppBarStyled'; | // import AppBarStyled from './AppBarStyled'; | ||||
// import HeaderContent from './HeaderContent'; | // import HeaderContent from './HeaderContent'; | ||||
@@ -37,6 +40,7 @@ import MobileLogo from 'components/MobileLogo'; | |||||
import Profile from './HeaderContent/Profile'; | import Profile from './HeaderContent/Profile'; | ||||
import "assets/style/navbarStyles.css"; | import "assets/style/navbarStyles.css"; | ||||
import {isUserLoggedIn} from "utils/Utils"; | import {isUserLoggedIn} from "utils/Utils"; | ||||
import { handleLogoutFunction } from 'auth/index'; | |||||
// assets | // assets | ||||
// import { MenuFoldOutlined,MenuOutlined } from '@ant-design/icons'; | // import { MenuFoldOutlined,MenuOutlined } from '@ant-design/icons'; | ||||
@@ -50,29 +54,71 @@ const drawerWidth = 240; | |||||
function Header(props) { | function Header(props) { | ||||
const { window } = props; | const { window } = props; | ||||
const [mobileOpen, setMobileOpen] = useState(false); | const [mobileOpen, setMobileOpen] = useState(false); | ||||
const dispatch = useDispatch() | |||||
const navigate = useNavigate() | |||||
const handleDrawerToggle = () => { | const handleDrawerToggle = () => { | ||||
setMobileOpen((prevState) => !prevState); | setMobileOpen((prevState) => !prevState); | ||||
}; | }; | ||||
const handleLogout = async () => { | |||||
dispatch(handleLogoutFunction()); | |||||
//await handleLogoutFunction(); | |||||
navigate('/login'); | |||||
}; | |||||
const loginContent = ( | |||||
<div> | |||||
<li> | |||||
<Link className="userSearchview" to='/userSearchview'>User</Link> | |||||
</li> | |||||
<li> | |||||
<Link className="usergroupSearchview" to='/usergroupSearchview'>User Group</Link> | |||||
</li> | |||||
</div> | |||||
); | |||||
const logoutContent = ( | |||||
<div> | |||||
<li> | |||||
<Link className="login" to='/login'>登入</Link> | |||||
</li> | |||||
<li> | |||||
<Link className="register" to='/register'>申請</Link> | |||||
</li> | |||||
</div> | |||||
); | |||||
const drawer = ( | const drawer = ( | ||||
<Box onClick={handleDrawerToggle} sx={{ textAlign: 'center' }}> | |||||
<Typography variant="h6" sx={{ my: 2 }}> | |||||
PNSPS | |||||
</Typography> | |||||
<Divider /> | |||||
<ul id="sidebar"> | |||||
<li> | |||||
<Link className="login" to='/login'>登入</Link> | |||||
</li> | |||||
<li> | |||||
<Link className="register" to='/register'>申請</Link> | |||||
</li> | |||||
</ul> | |||||
<Divider /> | |||||
{} | |||||
<Profile /> | |||||
</Box> | |||||
isUserLoggedIn() ? | |||||
<Stack id="sidebar" direction="column" justifyContent="center" alignItems="center" onClick={handleDrawerToggle} sx={{ textAlign: 'center' }}> | |||||
<Typography variant="h6" sx={{ my: 2 }}> | |||||
PNSPS | |||||
</Typography> | |||||
<Divider /> | |||||
<loginContent></loginContent> | |||||
<ul id="sidebartop"> | |||||
{loginContent} | |||||
</ul> | |||||
<Divider /> | |||||
<ul id="sidebarbottom"> | |||||
<li> | |||||
<Link className="logout" onClick={handleLogout}>登出</Link> | |||||
</li> | |||||
</ul> | |||||
</Stack> | |||||
: | |||||
<Stack id="sidebar" direction="column" justifyContent="center" alignItems="center" onClick={handleDrawerToggle} sx={{ textAlign: 'center' }}> | |||||
<Typography variant="h6" sx={{ my: 2 }}> | |||||
PNSPS | |||||
</Typography> | |||||
<Divider /> | |||||
<loginContent></loginContent> | |||||
<ul id="sidebartop"> | |||||
{logoutContent} | |||||
</ul> | |||||
<Divider /> | |||||
</Stack> | |||||
); | ); | ||||
const container = window !== undefined ? () => window().document.body : undefined; | const container = window !== undefined ? () => window().document.body : undefined; | ||||
@@ -113,12 +159,7 @@ function Header(props) { | |||||
spacing={1} | spacing={1} | ||||
> | > | ||||
<ul id="navbar" width="100%" > | <ul id="navbar" width="100%" > | ||||
<li> | |||||
<Link className="userSearchview" to='/userSearchview'>User</Link> | |||||
</li> | |||||
<li> | |||||
<Link className="usergroupSearchview" to='/usergroupSearchview'>User Group</Link> | |||||
</li> | |||||
{loginContent} | |||||
</ul> | </ul> | ||||
<Profile /> | <Profile /> | ||||
</Stack> | </Stack> | ||||
@@ -178,12 +219,7 @@ function Header(props) { | |||||
spacing={1} | spacing={1} | ||||
> | > | ||||
<ul id="navbar" width="100%" > | <ul id="navbar" width="100%" > | ||||
<li> | |||||
<Link className="login" to='/login'>登入</Link> | |||||
</li> | |||||
<li> | |||||
<Link className="register" to='/register'>申請</Link> | |||||
</li> | |||||
{logoutContent} | |||||
</ul> | </ul> | ||||
{/* <Profile /> */} | {/* <Profile /> */} | ||||
</Stack> | </Stack> | ||||
@@ -26,6 +26,9 @@ import { Formik } from 'formik'; | |||||
//import FirebaseSocial from './FirebaseSocial'; | //import FirebaseSocial from './FirebaseSocial'; | ||||
import AnimateButton from 'components/@extended/AnimateButton'; | import AnimateButton from 'components/@extended/AnimateButton'; | ||||
//import {AbilityContext} from "@src/utility/context/Can" | //import {AbilityContext} from "@src/utility/context/Can" | ||||
import {apiPath} from "auth/utils"; | |||||
import {POST_LOGIN} from "utils/ApiPathConst"; | |||||
// assets | // assets | ||||
import { EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons'; | import { EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons'; | ||||
import axios from "axios"; | import axios from "axios"; | ||||
@@ -57,7 +60,7 @@ const AuthLogin = () => { | |||||
}; | }; | ||||
const tryLogin = () => { | const tryLogin = () => { | ||||
axios.post('http://localhost:8090/api/login', | |||||
axios.post(`${apiPath}${POST_LOGIN}`, | |||||
{ | { | ||||
"username": userName, | "username": userName, | ||||
"password": userPassword | "password": userPassword | ||||
@@ -1,41 +1,36 @@ | |||||
import { | |||||
Grid, | |||||
Button, | |||||
TextField, | |||||
} from '@mui/material'; | |||||
import { Grid, Button, TextField } from '@mui/material'; | |||||
import { useState } from 'react'; | import { useState } from 'react'; | ||||
import axios from "axios"; | |||||
import axios from 'axios'; | |||||
const TestMailPage = ()=>{ | |||||
const TestMailPage = () => { | |||||
const [host, setHost] = useState('http://localhost:8090/api/test'); | |||||
const [mail, setMail] = useState(''); | |||||
const [host, setHost] = useState("http://localhost:8080/api/test"); | |||||
const [mail, setMail] = useState(""); | |||||
const hostChange = (event) => { | |||||
setHost(event.target.value); | |||||
}; | |||||
const hostChange = (event)=>{ | |||||
setHost(event.target.value); | |||||
} | |||||
const mailChange = (event) => { | |||||
setMail(event.target.value); | |||||
}; | |||||
const mailChange = (event)=>{ | |||||
setMail(event.target.value); | |||||
} | |||||
const doMailTest = ()=>{ | |||||
axios.post(host, { | |||||
email: mail | |||||
}) | |||||
.then((response) => { | |||||
console.log(response.data); | |||||
// Handle data | |||||
}) | |||||
.catch((error) => { | |||||
console.log(error); | |||||
}) | |||||
} | |||||
const doMailTest = () => { | |||||
axios.post(host, { | |||||
email: mail | |||||
}) | |||||
.then((response) => { | |||||
console.log(response.data); | |||||
// Handle data | |||||
}) | |||||
.catch((error) => { | |||||
console.log(error); | |||||
}) | |||||
}; | |||||
return ( | |||||
<Grid | |||||
return ( | |||||
<Grid | |||||
container | container | ||||
alignItems="center" | |||||
alignItems='center' | |||||
sx={{ | sx={{ | ||||
maxWidth: { xs: 1, lg: 1000 }, | maxWidth: { xs: 1, lg: 1000 }, | ||||
margin: { xs: 2.5, md: 3 }, | margin: { xs: 2.5, md: 3 }, | ||||
@@ -45,9 +40,9 @@ const TestMailPage = ()=>{ | |||||
} | } | ||||
}} | }} | ||||
spacing={3}> | spacing={3}> | ||||
<Grid item xs={12}><TextField id="hostField" label="Outlined" variant="filled" onChange={hostChange} value={host} fullWidth /></Grid> | |||||
<Grid item xs={12}><TextField id="mailField" label="Outlined" variant="filled" onChange={mailChange} value={mail} fullWidth /></Grid> | |||||
<Grid item xs={12}><Button variant="contained" onClick={doMailTest}>Test</Button></Grid> | |||||
<Grid item xs={12}><TextField id='hostField' label='Outlined' variant='filled' onChange={hostChange} value={host} fullWidth /></Grid> | |||||
<Grid item xs={12}><TextField id='mailField' label='Outlined' variant='filled' onChange={mailChange} value={mail} fullWidth /></Grid> | |||||
<Grid item xs={12}><Button variant='contained' onClick={doMailTest}>Test</Button></Grid> | |||||
</Grid> | </Grid> | ||||
); | ); | ||||
}; | }; | ||||
@@ -1,10 +1,19 @@ | |||||
export const GET_GROUP_LIST_PATH = "/group" | |||||
export const GET_GROUP_COMBO_PATH = "/group/combo" | |||||
export const GET_GROUP_MEMBER_LIST_PATH = "/group/member" | |||||
export const GET_GROUP_AUTH_LIST = "/group/auth/combo" | |||||
export const GET_USER_PATH = "/user" | |||||
export const GET_PUBLIC_USER_PATH = "/user/public" | |||||
export const GET_AUTH_LIST = "/user/auth/combo" | |||||
export const GET_USER_COMBO_LIST = "/user/combo" | |||||
export const POST_PUBLIC_USER_REGISTER = "/user/register" | |||||
// GET request | |||||
//Group Config | |||||
export const GET_GROUP_LIST_PATH = '/group'; | |||||
export const GET_GROUP_COMBO_PATH = '/group/combo'; | |||||
export const GET_GROUP_MEMBER_LIST_PATH = '/group/member'; | |||||
export const GET_GROUP_AUTH_LIST = '/group/auth/combo'; | |||||
export const GET_USER_PATH = '/user'; | |||||
export const GET_PUBLIC_USER_PATH = '/user/public'; | |||||
export const GET_AUTH_LIST = '/user/auth/combo'; | |||||
export const GET_USER_COMBO_LIST = '/user/combo'; | |||||
// POST request | |||||
//Login | |||||
export const POST_LOGIN = '/login'; | |||||
//register | |||||
export const POST_PUBLIC_USER_REGISTER = '/user/register'; |