| @@ -152,9 +152,9 @@ const Profile = () => { | |||
| <Stack> | |||
| <Typography style={{ color: 'black',fontFamily: "微軟正黑體", fontSize: "1.2rem" }} variant="subtitle1">我的帳戶</Typography> | |||
| <Typography variant="body2" color="textSecondary"> | |||
| {userData == null ? "" : userData.fullName} | |||
| {userData == null ? "" : userData.fullenName} | |||
| </Typography> | |||
| {/* <Typography variant="subtitle1">{userData == null ? "" : userData.fullName}</Typography> */} | |||
| {/* <Typography variant="subtitle1">{userData == null ? "" : userData.fullenName}</Typography> */} | |||
| </Stack> | |||
| </Stack> | |||
| </Grid> | |||
| @@ -41,7 +41,7 @@ import AdminLogo from 'components/AdminLogo'; | |||
| import MobileLogo from 'components/MobileLogo'; | |||
| import Profile from './HeaderContent/Profile'; | |||
| import "assets/style/navbarStyles.css"; | |||
| import {isUserLoggedIn,isAdminLoggedIn} from "utils/Utils"; | |||
| import {isUserLoggedIn,isGLDLoggedIn} from "utils/Utils"; | |||
| import { handleLogoutFunction } from 'auth/index'; | |||
| // assets | |||
| @@ -71,7 +71,7 @@ function Header(props) { | |||
| }; | |||
| const loginContent = ( | |||
| isAdminLoggedIn() ? | |||
| isGLDLoggedIn() ? | |||
| <div id="adminContent"> | |||
| <li> | |||
| <Link className="dashboard" to='/dashboard'>Dashboard</Link> | |||
| @@ -180,7 +180,7 @@ function Header(props) { | |||
| <Box> | |||
| <AppBar component="nav"> | |||
| <Toolbar id ="nav" width="100%"> | |||
| {isAdminLoggedIn() | |||
| {isGLDLoggedIn() | |||
| ?<Stack | |||
| direction="row" | |||
| justifyContent="flex-start" | |||
| @@ -43,14 +43,16 @@ const AuthWrapper = ({ children }) => ( | |||
| justifyContent="space-between" | |||
| alignItems="center" | |||
| spacing={2}> | |||
| <Grid item xs={12} md={8} sx={{ ml: 4, mt: 3 ,display: { xs: 'none', sm: 'block' }}}> | |||
| <Grid item xs={12} md={8} lg={8} xl={9} sx={{ ml: 4, mt: 3 ,display: { xs: 'none', sm: 'block' }}}> | |||
| <Typography style={{textAlign: "center",fontFamily: "微軟正黑體",fontSize: "1.6rem"}}>香港特別行政區政府</Typography> | |||
| <Typography style={{textAlign: "center",fontFamily: "微軟正黑體",fontSize: "1.6rem",fontWeight:"bold"}}>憲報</Typography> | |||
| </Grid> | |||
| <Grid | |||
| item | |||
| xs={12} | |||
| md={3} | |||
| md={4} | |||
| lg={4} | |||
| xl={4} | |||
| container | |||
| justifyContent="right" | |||
| alignItems="center" | |||
| @@ -70,8 +70,10 @@ const AuthLogin = () => { | |||
| setPosts(response.data); | |||
| const userData = { | |||
| id: response.data.id, | |||
| fullName: response.data.name, | |||
| fullenName: response.data.name, | |||
| fullchName: response.data.chName, | |||
| email: response.data.email, | |||
| type: response.data.type, | |||
| role: response.data.role, | |||
| abilities: response.data.abilities, | |||
| //avatar: require('src/assets/images/users/avatar-3.png').default, | |||
| @@ -55,12 +55,8 @@ const AuthLoginCustom = () => { | |||
| // let [posts, setPosts] = useState([]); | |||
| const [isValid, setisValid] = useState(false); | |||
| // const [isSuccess, setSuccess] = useState(); | |||
| // const [isSumitting, setSumitting] = useState(); | |||
| const [open, setOpen] = React.useState(false); | |||
| // useEffect(() => { | |||
| // // console.log("POST: " + posts.accessToken); | |||
| // },[posts]); | |||
| const [isButtonDisabled, setIsButtonDisabled] = useState(true); | |||
| const handleMouseDownPassword = (event) => { | |||
| event.preventDefault(); | |||
| @@ -72,10 +68,13 @@ const AuthLoginCustom = () => { | |||
| useJwt | |||
| .login({username: values.username, password: values.password}) | |||
| .then((response) => { | |||
| console.log("123") | |||
| const userData = { | |||
| id: response.data.id, | |||
| fullName: response.data.name, | |||
| fullenName: response.data.name, | |||
| fullchName: response.data.chName, | |||
| email: response.data.email, | |||
| type: response.data.type, | |||
| role: response.data.role, | |||
| abilities: response.data.abilities, | |||
| //avatar: require('src/assets/images/users/avatar-3.png').default, | |||
| @@ -90,6 +89,7 @@ const AuthLoginCustom = () => { | |||
| // setSuccess(false) | |||
| setOpen(true) | |||
| console.error(error) | |||
| console.log("321") | |||
| }); | |||
| }else{ | |||
| setOpen(true) | |||
| @@ -121,9 +121,11 @@ const AuthLoginCustom = () => { | |||
| ) | |||
| { | |||
| setisValid(true) | |||
| setIsButtonDisabled(false); | |||
| return isValid | |||
| }else{ | |||
| setisValid(false) | |||
| setIsButtonDisabled(true); | |||
| return isValid | |||
| } | |||
| }; | |||
| @@ -134,27 +136,22 @@ const AuthLoginCustom = () => { | |||
| var lowerCase = /[a-z]/g; | |||
| var upperCase = /[A-Z]/g; | |||
| var numbers = /[0-9]/g; | |||
| var symbol = /^(?=.*[!@#%&])/; | |||
| if (!new_pass.match(lowerCase)) { | |||
| return false; | |||
| } else if (!new_pass.match(upperCase)) { | |||
| return false; | |||
| } else if (!new_pass.match(numbers)) { | |||
| return false; | |||
| } else if (new_pass.length < 8) { | |||
| } else if (!new_pass.match(symbol)) { | |||
| return false; | |||
| } else if (new_pass.length < 8) { | |||
| return false; | |||
| } else { | |||
| return true; | |||
| } | |||
| } | |||
| // function handle6Digi(value) { | |||
| // if (value.length < 6) { | |||
| // return false; | |||
| // } else { | |||
| // return true; | |||
| // } | |||
| // } | |||
| const handleClose = () => { | |||
| setOpen(false); | |||
| }; | |||
| @@ -235,15 +232,23 @@ const AuthLoginCustom = () => { | |||
| <Grid item xs={12}> | |||
| <AnimateButton> | |||
| <Button disableElevation | |||
| fullWidth size="large" type="submit" variant="contained" color="primary"> | |||
| <Button disableElevation disabled={isButtonDisabled} | |||
| fullWidth size="large" type="submit" variant="contained" color="primary" | |||
| sx={{ | |||
| "&.Mui-disabled": { | |||
| background: "#bbdefb", | |||
| color: "#fff", | |||
| border: "2px solid", | |||
| borderColor: "#e7e7e7" | |||
| } | |||
| }}> | |||
| 登錄 | |||
| </Button> | |||
| </AnimateButton> | |||
| </Grid> | |||
| <Grid item xs={12}> | |||
| <Stack direction="row" justifyContent="space-between" alignItems="center" spacing={2}> | |||
| <Link variant="h6" component={RouterLink} to="" color="text.primary"> | |||
| <Link variant="h6" component={RouterLink} to="" color="primary"> | |||
| <Typography align="center"> | |||
| 忘記密碼? | |||
| </Typography> | |||
| @@ -252,7 +257,7 @@ const AuthLoginCustom = () => { | |||
| </Grid> | |||
| <Grid item xs={12}> | |||
| <Stack direction="row" justifyContent="space-between" alignItems="center" spacing={2}> | |||
| <Button fullWidth size="large" variant="outlined" startIcon={<img src={iAmSmartICon} alt="iAM Smart" width="30" />}>智方便登入</Button> | |||
| <Button size="large" variant="outlined" startIcon={<img src={iAmSmartICon} alt="iAM Smart" width="30" />}>智方便登入</Button> | |||
| </Stack> | |||
| </Grid> | |||
| <Grid item xs={12}> | |||
| @@ -265,14 +270,6 @@ const AuthLoginCustom = () => { | |||
| <Button fullWidth size="large" variant="outlined" href="/register" >建立/重新啟動帳戶</Button> | |||
| </Stack> | |||
| </Grid> | |||
| {/* <Grid item xs={12}>*/} | |||
| {/* <Divider>*/} | |||
| {/* <Typography variant="caption"> Login with</Typography>*/} | |||
| {/* </Divider>*/} | |||
| {/*</Grid>*/} | |||
| {/*<Grid item xs={12}>*/} | |||
| {/* <FirebaseSocial />*/} | |||
| {/*</Grid> */} | |||
| </Grid> | |||
| <PasswordAlertDialog open={open} handleClose={handleClose}/> | |||
| </form> | |||
| @@ -313,14 +313,17 @@ const BusCustomFormWizard = (props) => { | |||
| var lowerCase = /[a-z]/g; | |||
| var upperCase = /[A-Z]/g; | |||
| var numbers = /[0-9]/g; | |||
| var symbol = /^(?=.*[!@#%&])/; | |||
| if (!new_pass.match(lowerCase)) { | |||
| return false; | |||
| } else if (!new_pass.match(upperCase)) { | |||
| return false; | |||
| } else if (!new_pass.match(numbers)) { | |||
| return false; | |||
| } else if (new_pass.length < 8) { | |||
| } else if (!new_pass.match(symbol)) { | |||
| return false; | |||
| } else if (new_pass.length < 8) { | |||
| return false; | |||
| } else { | |||
| return true; | |||
| } | |||
| @@ -334,12 +334,15 @@ const CustomFormWizard = (props) => { | |||
| var lowerCase = /[a-z]/g; | |||
| var upperCase = /[A-Z]/g; | |||
| var numbers = /[0-9]/g; | |||
| var symbol = /^(?=.*[!@#%&])/; | |||
| if (!new_pass.match(lowerCase)) { | |||
| return false; | |||
| } else if (!new_pass.match(upperCase)) { | |||
| return false; | |||
| } else if (!new_pass.match(numbers)) { | |||
| return false; | |||
| } else if (!new_pass.match(symbol)) { | |||
| return false; | |||
| } else if (new_pass.length < 8) { | |||
| return false; | |||
| } else { | |||
| @@ -849,6 +852,7 @@ const CustomFormWizard = (props) => { | |||
| options={address5ComboList} | |||
| onChange={(event, newValue) => { | |||
| setSelectedAddress5(newValue); | |||
| // if() | |||
| }} | |||
| sx={{"& .MuiInputBase-root": { height: "41px" },"#address5-combo":{padding: "0px 0px 0px 0px"}, "& .MuiAutocomplete-endAdornment": { top: "auto" },}} | |||
| @@ -1085,7 +1089,7 @@ const CustomFormWizard = (props) => { | |||
| <Stack spacing={1} direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}> | |||
| <Typography display="inline" variant="h4" sx={{ color: 'primary.primary'}}>身份證明文件</Typography> | |||
| <Typography display="inline" variant="h6" sx={{ fontSize: 12,color: 'primary.primary'}}>請上傳你的 有效身份證明文件 的數碼檔案,以驗證你的身份。</Typography> | |||
| <Typography display="inline" variant="h6" sx={{ fontSize: 12,color: 'primary.primary'}}>如: 香港身份證; 護照; 中國內地身份證等</Typography> | |||
| <Typography display="inline" variant="h6" sx={{ fontSize: 12,color: 'primary.primary'}}>如: 香港身份證; 護照; 中國內地身份證; 專業執業証書等</Typography> | |||
| <Stack mt={1} direction="row" justifyContent="flex-start" alignItems="center" spacing={2}> | |||
| <Button variant="contained" component="label" sx={{ fontSize: 12,height:'40px'}}>上傳身份證明文件 | |||
| <input | |||
| @@ -0,0 +1,41 @@ | |||
| // import { useState } from 'react'; | |||
| // material-ui | |||
| import { | |||
| // Avatar, | |||
| // AvatarGroup, | |||
| // Box, | |||
| // Button, | |||
| Grid, | |||
| // List, | |||
| // ListItemAvatar, | |||
| // ListItemButton, | |||
| // ListItemSecondaryAction, | |||
| // ListItemText, | |||
| // MenuItem, | |||
| // Stack, | |||
| // TextField, | |||
| Typography | |||
| } from '@mui/material'; | |||
| // project import | |||
| // import Loadable from 'components/Loadable'; | |||
| // import { lazy } from 'react'; | |||
| // ==============================|| DASHBOARD - DEFAULT ||============================== // | |||
| const DashboardDefault = () => { | |||
| const userData = JSON.parse(localStorage.getItem("userData")); | |||
| return ( | |||
| <Grid container rowSpacing={4.5} columnSpacing={2.75} sx={{minHeight: '80vh'}}> | |||
| <Grid item xs={12} ml={2} mt={1}> | |||
| <Typography variant="h5">Moring, {userData.fullenName}</Typography> | |||
| </Grid> | |||
| </Grid> | |||
| ); | |||
| }; | |||
| export default DashboardDefault; | |||
| @@ -171,11 +171,11 @@ const UserInformationCard = ({isCollectData, updateUserObject,userData}) => { | |||
| <Grid item xs={7} s={7} md={7} lg={6}> | |||
| <TextField | |||
| fullWidth | |||
| {...register("fullName", | |||
| {...register("fullenName", | |||
| { | |||
| value: currentUserData.fullname, | |||
| value: currentUserData.fullenName, | |||
| })} | |||
| id='fullName' | |||
| id='fullenName' | |||
| /> | |||
| </Grid> | |||
| </Grid> | |||
| @@ -53,7 +53,7 @@ const UserSearchForm = ({applySearch}) => { | |||
| const temp = { | |||
| username: data.userName, | |||
| fullName: data.fullName, | |||
| fullenName: data.fullenName, | |||
| post: data.post, | |||
| // subDivision: subDivision, | |||
| email: data.email, | |||
| @@ -107,8 +107,8 @@ const UserSearchForm = ({applySearch}) => { | |||
| <Grid item xs={9} s={6} md={5} lg={3} sx={{ml:3, mr:3, mb:3}}> | |||
| <TextField | |||
| fullWidth | |||
| {...register("fullName")} | |||
| id="fullName" | |||
| {...register("fullenName")} | |||
| id="fullenName" | |||
| label="Full Name" | |||
| /> | |||
| </Grid> | |||
| @@ -28,7 +28,7 @@ const UserSearchForm_Individual = ({applySearch}) => { | |||
| const temp = { | |||
| username: data.userName, | |||
| fullName: data.fullName, | |||
| fullenName: data.fullenName, | |||
| email: data.email, | |||
| phone: data.phone, | |||
| accountFilter: accountFilter, | |||
| @@ -68,8 +68,8 @@ const UserSearchForm_Individual = ({applySearch}) => { | |||
| <Grid item xs={9} s={6} md={5} lg={3} sx={{ml:3, mr:3, mb:3}}> | |||
| <TextField | |||
| fullWidth | |||
| {...register("fullName")} | |||
| id="fullName" | |||
| {...register("fullenName")} | |||
| id="fullenName" | |||
| label="Full Name" | |||
| /> | |||
| </Grid> | |||
| @@ -29,7 +29,7 @@ const UserSearchForm_Organization = ({applySearch}) => { | |||
| const temp = { | |||
| username: data.userName, | |||
| fullName: data.fullName, | |||
| fullenName: data.fullenName, | |||
| email: data.email, | |||
| phone: data.phone, | |||
| brNoStr: data.brNoStr, | |||
| @@ -90,8 +90,8 @@ const UserSearchForm_Organization = ({applySearch}) => { | |||
| <Grid item xs={9} s={6} md={5} lg={3} sx={{ml:3, mr:3, mb:3}}> | |||
| <TextField | |||
| fullWidth | |||
| {...register("fullName")} | |||
| id="fullName" | |||
| {...register("fullenName")} | |||
| id="fullenName" | |||
| label="Full Name" | |||
| /> | |||
| </Grid> | |||
| @@ -0,0 +1,40 @@ | |||
| // import { useState } from 'react'; | |||
| // material-ui | |||
| import { | |||
| // Avatar, | |||
| // AvatarGroup, | |||
| // Box, | |||
| // Button, | |||
| Grid, | |||
| // List, | |||
| // ListItemAvatar, | |||
| // ListItemButton, | |||
| // ListItemSecondaryAction, | |||
| // ListItemText, | |||
| // MenuItem, | |||
| // Stack, | |||
| // TextField, | |||
| Typography | |||
| } from '@mui/material'; | |||
| // project import | |||
| // import Loadable from 'components/Loadable'; | |||
| // import { lazy } from 'react'; | |||
| // ==============================|| DASHBOARD - DEFAULT ||============================== // | |||
| const DashboardDefault = () => { | |||
| return ( | |||
| <Grid container rowSpacing={4.5} columnSpacing={2.75} sx={{minHeight: '80vh'}}> | |||
| <Grid item xs={12} ml={2} mt={1}> | |||
| <Typography variant="h5">我的公共啟事</Typography> | |||
| </Grid> | |||
| </Grid> | |||
| ); | |||
| }; | |||
| export default DashboardDefault; | |||
| @@ -0,0 +1,32 @@ | |||
| import { lazy } from 'react'; | |||
| // project import | |||
| import Loadable from 'components/Loadable'; | |||
| import MainLayout from 'layout/MainLayout'; | |||
| // render - dashboard | |||
| const DashboardDefault = Loadable(lazy(() => import('pages/gldDashboard'))); | |||
| // ==============================|| MAIN ROUTING ||============================== // | |||
| const GLDUserRoutes = { | |||
| path: '/', | |||
| element: <MainLayout />, | |||
| children: [ | |||
| { | |||
| path: '/', | |||
| element: <DashboardDefault /> | |||
| }, | |||
| { | |||
| path: '/', | |||
| children: [ | |||
| { | |||
| path: 'dashboard', | |||
| element: <DashboardDefault /> | |||
| } | |||
| ] | |||
| }, | |||
| ] | |||
| }; | |||
| export default GLDUserRoutes; | |||
| @@ -5,7 +5,6 @@ import Loadable from 'components/Loadable'; | |||
| import MainLayout from 'layout/MainLayout'; | |||
| // render - dashboard | |||
| const DashboardDefault = Loadable(lazy(() => import('pages/dashboard'))); | |||
| // render - sample page | |||
| const SamplePage = Loadable(lazy(() => import('pages/extra-pages/SamplePage'))); | |||
| @@ -22,19 +21,6 @@ const MainRoutes = { | |||
| path: '/', | |||
| element: <MainLayout />, | |||
| children: [ | |||
| { | |||
| path: '/', | |||
| element: <DashboardDefault /> | |||
| }, | |||
| { | |||
| path: '/', | |||
| children: [ | |||
| { | |||
| path: 'dashboard', | |||
| element: <DashboardDefault /> | |||
| } | |||
| ] | |||
| }, | |||
| { | |||
| path: 'color', | |||
| element: <Color /> | |||
| @@ -0,0 +1,32 @@ | |||
| import { lazy } from 'react'; | |||
| // project import | |||
| import Loadable from 'components/Loadable'; | |||
| import MainLayout from 'layout/MainLayout'; | |||
| // render - dashboard | |||
| const DashboardDefault = Loadable(lazy(() => import('pages/publicDashboard'))); | |||
| // ==============================|| MAIN ROUTING ||============================== // | |||
| const PublicDashboard = { | |||
| path: '/', | |||
| element: <MainLayout />, | |||
| children: [ | |||
| { | |||
| path: '/', | |||
| element: <DashboardDefault /> | |||
| }, | |||
| { | |||
| path: '/', | |||
| children: [ | |||
| { | |||
| path: 'dashboard', | |||
| element: <DashboardDefault /> | |||
| } | |||
| ] | |||
| }, | |||
| ] | |||
| }; | |||
| export default PublicDashboard; | |||
| @@ -1,8 +1,15 @@ | |||
| // project import | |||
| import LoginRoutes from './LoginRoutes' | |||
| import MainRoutes from './MainRoutes' | |||
| import PublicUserRoutes from './PublicUserRoutes' | |||
| import GLDUserRoutes from './GLDUserRoutes' | |||
| import {useRoutes} from 'react-router-dom' | |||
| import {isUserLoggedIn,isAdminLoggedIn} from "utils/Utils"; | |||
| import {isUserLoggedIn, | |||
| // isAdminLoggedIn, | |||
| isGLDLoggedIn, | |||
| isINDLoggedIn, | |||
| isORGLoggedIn, | |||
| } from "utils/Utils"; | |||
| import {Navigate} from "react-router"; | |||
| import { | |||
| setupAxiosInterceptors, | |||
| @@ -36,7 +43,9 @@ console.log(); | |||
| ] | |||
| }, | |||
| isUserLoggedIn() ? MainRoutes : LoginRoutes, | |||
| isUserLoggedIn()&&isAdminLoggedIn() ? SettingRoutes : LoginRoutes, | |||
| isUserLoggedIn()&&isINDLoggedIn()||isUserLoggedIn()&&isORGLoggedIn() ? PublicUserRoutes : LoginRoutes, | |||
| isUserLoggedIn()&&isGLDLoggedIn() ? SettingRoutes : LoginRoutes, | |||
| isUserLoggedIn()&&isGLDLoggedIn() ? GLDUserRoutes : LoginRoutes, | |||
| !isUserLoggedIn()?{ | |||
| path: '*', | |||
| element: <Navigate to="/login"/> | |||
| @@ -62,7 +62,22 @@ export const isAdminLoggedIn = () =>{ | |||
| if (localStorage.getItem('userData') != null){ | |||
| return JSON.parse(localStorage.getItem('userData')).role === 'admin' | |||
| } | |||
| } | |||
| } | |||
| export const isGLDLoggedIn = () =>{ | |||
| if (localStorage.getItem('userData') != null){ | |||
| return JSON.parse(localStorage.getItem('userData')).type === 'GLD' | |||
| } | |||
| } | |||
| export const isINDLoggedIn = () =>{ | |||
| if (localStorage.getItem('userData') != null){ | |||
| return JSON.parse(localStorage.getItem('userData')).type === 'IND' | |||
| } | |||
| } | |||
| export const isORGLoggedIn = () =>{ | |||
| if (localStorage.getItem('userData') != null){ | |||
| return JSON.parse(localStorage.getItem('userData')).type === 'ORG' | |||
| } | |||
| } | |||
| /** | |||
| ** This function is used for demo purpose route navigation | |||
| ** In real app you won't need this function because your app will navigate to same route for each users regardless of ability | |||