| @@ -43,6 +43,29 @@ | |||||
| top: -4px; | top: -4px; | ||||
| left: 20px; | left: 20px; | ||||
| } | } | ||||
| #navbar div li ul { | |||||
| background: white; | |||||
| visibility: hidden; | |||||
| opacity: 0; | |||||
| min-width: 16rem; | |||||
| position: absolute; | |||||
| /* transition: all 0.5s ease; */ | |||||
| left: 0; | |||||
| display: none; | |||||
| padding-left: 0px; | |||||
| /* border: 1px solid #0C489E; */ | |||||
| background-clip: padding-box; | |||||
| border: 1px solid rgba(0,0,0,.15); | |||||
| border-radius: 0.25rem; | |||||
| } | |||||
| #navbar div li:hover > ul, | |||||
| #navbar div li:focus-within > ul, | |||||
| #navbar div li ul:hover, | |||||
| #navbar div li ul:focus { | |||||
| visibility: visible; | |||||
| opacity: 1; | |||||
| display: block | |||||
| } | |||||
| #systemTitle{ | #systemTitle{ | ||||
| text-decoration: none; | text-decoration: none; | ||||
| font-size: 1.3rem; | font-size: 1.3rem; | ||||
| @@ -94,4 +117,24 @@ | |||||
| } | } | ||||
| #sidebar li a:hover{ | #sidebar li a:hover{ | ||||
| color: #0C489E; | color: #0C489E; | ||||
| } | |||||
| } | |||||
| #sidebar div li ul { | |||||
| background: white; | |||||
| visibility: hidden; | |||||
| opacity: 0; | |||||
| min-width: 16rem; | |||||
| position: absolute; | |||||
| /* transition: all 0.5s ease; */ | |||||
| left: 0; | |||||
| display: none; | |||||
| padding-left: 0px; | |||||
| /* border: 1px solid #0C489E; */ | |||||
| } | |||||
| #sidebar div li:hover > ul, | |||||
| #sidebar div li:focus-within > ul, | |||||
| #sidebar div li ul:hover, | |||||
| #sidebar div li ul:focus { | |||||
| visibility: visible; | |||||
| opacity: 1; | |||||
| display: block | |||||
| } | |||||
| @@ -0,0 +1,51 @@ | |||||
| // material-ui | |||||
| // import { useTheme } from '@mui/material/styles'; | |||||
| /** | |||||
| * if you want to use image instead of <svg> uncomment following. | |||||
| * | |||||
| * import logoDark from 'assets/images/logo-dark.svg'; | |||||
| * import logo from 'assets/images/logo.svg'; | |||||
| * | |||||
| */ | |||||
| // ==============================|| LOGO SVG ||============================== // | |||||
| const AdminLogo = () => { | |||||
| // const theme = useTheme(); | |||||
| return ( | |||||
| /** | |||||
| * if you want to use image instead of svg uncomment following, and comment out <svg> element. | |||||
| * | |||||
| * <img src={logo} alt="Mantis" width="100" /> | |||||
| * | |||||
| */ | |||||
| <> | |||||
| <svg width="90" height="45" viewBox="18 0 10 35" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||||
| <defs> | |||||
| <clipPath id="clipPath22"> | |||||
| <path d="m0 256h213v-256h-213z"/> | |||||
| </clipPath> | |||||
| </defs> | |||||
| <g transform="translate(-31.999 -25.836)"> | |||||
| <g transform="matrix(.35278 0 0 -.35278 46.979 25.836)"> | |||||
| <path d="m0 0h16.273v-37.417l17.85-0.035v-12.864h-34.123z" fill="#00a650"/> | |||||
| </g> | |||||
| <g transform="matrix(.35278 0 0 -.35278 16.798 99.848)"> | |||||
| <g clipPath="url(#clipPath22)"> | |||||
| <g transform="translate(82.049 183.46)"> | |||||
| <path d="m0 0c-17.536-0.633-27.516-14.176-27.516-28.318 0-14.143 9.241-28.019 27.563-28.071 3.447-9e-3 8.679 1.279 21.255 17.378l-17.808 0.07v10.335l34.132 0.061v-35.705l-10.467 3.577 0.045 12.858c-12.924-19.307-24.442-19.361-26.895-19.378-23.677-0.157-39.268 17.825-39.268 38.884s14.944 37.674 38.959 38.589z" fill="#1c63b7"/> | |||||
| </g> | |||||
| <g transform="translate(119.64 176.52)"> | |||||
| <path d="m0 0-10.391 0.041v11.372c3.151 1.943 6.524 3.573 10.424 4.515 3.633 0.879 7.526 1.321 11.567 1.321 24.407 0 39.006-17.548 39.006-38.608s-14.633-39.843-39.006-38.608c-2.765 0.14-3.93 0.531-7.946 1.652l0.055 9.924c3.341-0.628 3.344-0.529 7.891-1.047 17.298-1.971 27.561 13.927 27.561 28.069 0 14.143-10.11 28.09-27.561 28.09-4.162 0-8.175-0.816-11.567-2.433l-0.033-4.288" fill="#1c63b7"/> | |||||
| </g> | |||||
| </g> | |||||
| </g> | |||||
| </g> | |||||
| </svg> | |||||
| </> | |||||
| ); | |||||
| }; | |||||
| export default AdminLogo; | |||||
| @@ -0,0 +1,42 @@ | |||||
| import PropTypes from 'prop-types'; | |||||
| import { Link } from 'react-router-dom'; | |||||
| // material-ui | |||||
| import { ButtonBase } from '@mui/material'; | |||||
| import { useDispatch, useSelector } from 'react-redux'; | |||||
| // project import | |||||
| import Logo from './AdminLogo'; | |||||
| import config from 'config'; | |||||
| import { activeItem } from 'store/reducers/menu'; | |||||
| import { Stack } from '@mui/material'; | |||||
| // ==============================|| MAIN LOGO ||============================== // | |||||
| const LogoSection = ({ sx, to }) => { | |||||
| const { defaultId } = useSelector((state) => state.menu); | |||||
| const dispatch = useDispatch(); | |||||
| return ( | |||||
| <Stack direction="column" justifyContent="center" alignItems="center" > | |||||
| <ButtonBase | |||||
| disableRipple | |||||
| component={Link} | |||||
| onClick={() => dispatch(activeItem({ openItem: [defaultId] }))} | |||||
| to={!to ? config.defaultPath : to} | |||||
| sx={sx} | |||||
| > | |||||
| <Logo /> | |||||
| </ButtonBase> | |||||
| <span id="systemTitle" >PNSPS</span> | |||||
| </Stack> | |||||
| ); | |||||
| }; | |||||
| LogoSection.propTypes = { | |||||
| sx: PropTypes.object, | |||||
| to: PropTypes.string | |||||
| }; | |||||
| export default LogoSection; | |||||
| @@ -30,16 +30,18 @@ import { | |||||
| Drawer, | Drawer, | ||||
| // useMediaQuery | // useMediaQuery | ||||
| } from '@mui/material'; | } from '@mui/material'; | ||||
| import MenuIcon from '@mui/icons-material/Menu'; | import MenuIcon from '@mui/icons-material/Menu'; | ||||
| import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'; | |||||
| // project import | // project import | ||||
| // import AppBarStyled from './AppBarStyled'; | // import AppBarStyled from './AppBarStyled'; | ||||
| // import HeaderContent from './HeaderContent'; | // import HeaderContent from './HeaderContent'; | ||||
| import Logo from 'components/Logo'; | import Logo from 'components/Logo'; | ||||
| import AdminLogo from 'components/AdminLogo'; | |||||
| import MobileLogo from 'components/MobileLogo'; | 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,isAdminLoggedIn} from "utils/Utils"; | |||||
| import { handleLogoutFunction } from 'auth/index'; | import { handleLogoutFunction } from 'auth/index'; | ||||
| // assets | // assets | ||||
| @@ -48,6 +50,7 @@ import { handleLogoutFunction } from 'auth/index'; | |||||
| import { Link } from "react-router-dom"; | import { Link } from "react-router-dom"; | ||||
| const drawerWidth = 240; | const drawerWidth = 240; | ||||
| // const navItems = ['Home', 'About', 'Contact']; | // const navItems = ['Home', 'About', 'Contact']; | ||||
| // ==============================|| MAIN LAYOUT - HEADER ||============================== // | // ==============================|| MAIN LAYOUT - HEADER ||============================== // | ||||
| @@ -68,18 +71,60 @@ function Header(props) { | |||||
| }; | }; | ||||
| const loginContent = ( | const loginContent = ( | ||||
| <div> | |||||
| isAdminLoggedIn() ? | |||||
| <div id="adminContent"> | |||||
| <li> | |||||
| <Link className="dashboard" to='/dashboard'>Dashboard</Link> | |||||
| </li> | |||||
| <li> | |||||
| <Link className="application" to='/dashboard'>Application</Link> | |||||
| </li> | |||||
| <li> | |||||
| <Link className="proof" to='/dashboard'>Proof</Link> | |||||
| </li> | |||||
| <li> | |||||
| <Link className="payment" to='/dashboard'>Payment</Link> | |||||
| </li> | |||||
| <li> | |||||
| <Link className="client" >Client<KeyboardArrowDownIcon/></Link> | |||||
| <ul className='dropdown'> | |||||
| <li> | |||||
| <Link className="userSearchview" to='/userSearchview'>User</Link> | |||||
| </li> | |||||
| <li> | |||||
| <Link className="indUser" to='/indUser'>Individual User</Link> | |||||
| </li> | |||||
| <li> | |||||
| <Link className="orgUser" to='/orgUser'>Organization User</Link> | |||||
| </li> | |||||
| <li> | |||||
| <Link className="usergroupSearchview" to='/usergroupSearchview'>User Group</Link> | |||||
| </li> | |||||
| </ul> | |||||
| </li> | |||||
| <li> | |||||
| <Link className="logout" onClick={handleLogout}>Logout</Link> | |||||
| </li> | |||||
| </div> | |||||
| : | |||||
| <div id="individualUserContent"> | |||||
| <li> | |||||
| <Link className="dashboard" to='/dashboard'>主頁</Link> | |||||
| </li> | |||||
| <li> | |||||
| <Link className="myDocumet" to='/dashboard'>我的公共啟示</Link> | |||||
| </li> | |||||
| <li> | <li> | ||||
| <Link className="userSearchview" to='/userSearchview'>User</Link> | |||||
| <Link className="documentRecord" to='/dashboard'>校對記錄</Link> | |||||
| </li> | </li> | ||||
| <li> | <li> | ||||
| <Link className="indUser" to='/indUser'>Individual User</Link> | |||||
| <Link className="paymentRecord" to='/dashboard'>付款記錄</Link> | |||||
| </li> | </li> | ||||
| <li> | <li> | ||||
| <Link className="orgUser" to='/orgUser'>Organization User</Link> | |||||
| <Link className="userSetting" to='/dashboard'>設定</Link> | |||||
| </li> | </li> | ||||
| <li> | <li> | ||||
| <Link className="usergroupSearchview" to='/usergroupSearchview'>User Group</Link> | |||||
| <Link className="logout" onClick={handleLogout}>登出</Link> | |||||
| </li> | </li> | ||||
| </div> | </div> | ||||
| ); | ); | ||||
| @@ -96,7 +141,7 @@ function Header(props) { | |||||
| ); | ); | ||||
| const drawer = ( | const drawer = ( | ||||
| isUserLoggedIn() ? | |||||
| isUserLoggedIn()? | |||||
| <Stack id="sidebar" direction="column" justifyContent="center" alignItems="center" onClick={handleDrawerToggle} sx={{ textAlign: 'center' }}> | <Stack id="sidebar" direction="column" justifyContent="center" alignItems="center" onClick={handleDrawerToggle} sx={{ textAlign: 'center' }}> | ||||
| <Typography variant="h6" sx={{ my: 2 }}> | <Typography variant="h6" sx={{ my: 2 }}> | ||||
| PNSPS | PNSPS | ||||
| @@ -127,35 +172,62 @@ function Header(props) { | |||||
| const container = window !== undefined ? () => window().document.body : undefined; | const container = window !== undefined ? () => window().document.body : undefined; | ||||
| return ( | return ( | ||||
| isUserLoggedIn() ? | |||||
| isUserLoggedIn() ? | |||||
| // User Login success | |||||
| <Box> | <Box> | ||||
| <AppBar component="nav"> | <AppBar component="nav"> | ||||
| <Toolbar id ="nav" width="100%"> | <Toolbar id ="nav" width="100%"> | ||||
| <Stack | |||||
| direction="row" | |||||
| justifyContent="flex-start" | |||||
| alignItems="center" | |||||
| spacing={0} | |||||
| > | |||||
| <Box sx={{flexGrow: 1,display: { xs: 'none', sm: 'block' } }}> | |||||
| <Logo/> | |||||
| <span id="systemTitle" >公共啟事提交及繳費系統</span> | |||||
| </Box> | |||||
| <IconButton | |||||
| color="inherit" | |||||
| aria-label="open drawer" | |||||
| edge="start" | |||||
| onClick={handleDrawerToggle} | |||||
| sx={{ mr: 2, display: { sm: 'none' } }} | |||||
| > | |||||
| <MenuIcon style={{ color: '#0C489E' }} /> | |||||
| </IconButton> | |||||
| <Box sx={{mr: 2, display: { sm: 'none' } }}> | |||||
| <MobileLogo/> | |||||
| <span id="mobileTitle" >公共啟事提交及繳費系統</span> | |||||
| </Box> | |||||
| </Stack> | |||||
| <Box sx={{display: { xs: 'none', sm: 'block' } ,width:"75%"}}> | |||||
| {isAdminLoggedIn() | |||||
| ?<Stack | |||||
| direction="row" | |||||
| justifyContent="flex-start" | |||||
| alignItems="center" | |||||
| spacing={0} | |||||
| > | |||||
| <Box sx={{display: { xs: 'none', sm: 'block' } }}> | |||||
| <AdminLogo/> | |||||
| </Box> | |||||
| <IconButton | |||||
| color="inherit" | |||||
| aria-label="open drawer" | |||||
| edge="start" | |||||
| onClick={handleDrawerToggle} | |||||
| sx={{ mr: 2, display: { sm: 'none' } }} | |||||
| > | |||||
| <MenuIcon style={{ color: '#0C489E' }} /> | |||||
| </IconButton> | |||||
| <Box sx={{mr: 2, display: { sm: 'none' } }}> | |||||
| <MobileLogo/> | |||||
| <span id="mobileTitle" >PNSPS</span> | |||||
| </Box> | |||||
| </Stack>: | |||||
| <Stack | |||||
| direction="row" | |||||
| justifyContent="flex-start" | |||||
| alignItems="center" | |||||
| spacing={0} | |||||
| > | |||||
| <Box sx={{flexGrow: 1,display: { xs: 'none', sm: 'block' } }}> | |||||
| <Logo/> | |||||
| <span id="systemTitle" >公共啟事提交及繳費系統</span> | |||||
| </Box> | |||||
| <IconButton | |||||
| color="inherit" | |||||
| aria-label="open drawer" | |||||
| edge="start" | |||||
| onClick={handleDrawerToggle} | |||||
| sx={{ mr: 2, display: { sm: 'none' } }} | |||||
| > | |||||
| <MenuIcon style={{ color: '#0C489E' }} /> | |||||
| </IconButton> | |||||
| <Box sx={{mr: 2, display: { sm: 'none' } }}> | |||||
| <MobileLogo/> | |||||
| <span id="mobileTitle" >公共啟事提交及繳費系統</span> | |||||
| </Box> | |||||
| </Stack> | |||||
| } | |||||
| <Box sx={{display: { xs: 'none', sm: 'block' } ,width:"100%"}}> | |||||
| <Stack | <Stack | ||||
| direction="row" | direction="row" | ||||
| justifyContent="space-between" | justifyContent="space-between" | ||||
| @@ -0,0 +1,205 @@ | |||||
| // import { Link } from 'react-router-dom'; | |||||
| import React,{useState} from 'react'; | |||||
| // material-ui | |||||
| import { | |||||
| Stepper, | |||||
| Step, | |||||
| StepButton, | |||||
| // Grid, | |||||
| Stack, | |||||
| Typography, | |||||
| Button, | |||||
| } from '@mui/material'; | |||||
| import VisibilityIcon from '@mui/icons-material/Visibility'; | |||||
| // project import | |||||
| import BusCustomFormWizard from './auth-forms/BusCustomFormWizard'; | |||||
| import AuthWrapper from './AuthWrapperCustom'; | |||||
| // ================================|| REGISTER ||================================ // | |||||
| const stepStyle = { | |||||
| width:"80%", | |||||
| boxShadow: 2, | |||||
| backgroundColor: "rgba(0,0,0,0.1)", | |||||
| padding: 2, | |||||
| "& .Mui-active": { | |||||
| "&.MuiStepIcon-root": { | |||||
| color: "warning.main", | |||||
| fontSize: "2rem", | |||||
| }, | |||||
| "& .MuiStepConnector-line": { | |||||
| borderColor: "warning.main" | |||||
| } | |||||
| }, | |||||
| "& .Mui-completed": { | |||||
| "&.MuiStepIcon-root": { | |||||
| color: "secondary.main", | |||||
| fontSize: "2rem", | |||||
| }, | |||||
| "& .MuiStepConnector-line": { | |||||
| borderColor: "secondary.main" | |||||
| } | |||||
| } | |||||
| } | |||||
| const steps = ['個人資料', '預覽', '完成提交']; | |||||
| const BusRegister = () => { | |||||
| const [activeStep, setActiveStep] = useState(0); | |||||
| const [completed, setCompleted] = useState([false]); | |||||
| const [isValid, setisValid] = useState(null); | |||||
| const updateValid = (value) => { | |||||
| setisValid(value); | |||||
| console.log(value) | |||||
| }; | |||||
| const totalSteps = () => { | |||||
| return steps.length; | |||||
| }; | |||||
| const completedSteps = () => { | |||||
| return Object.keys(completed).length; | |||||
| }; | |||||
| const isLastStep = () => { | |||||
| return activeStep === totalSteps() - 1; | |||||
| }; | |||||
| const allStepsCompleted = () => { | |||||
| return completedSteps() === totalSteps(); | |||||
| }; | |||||
| const handleNext = () => { | |||||
| console.log("test 1") | |||||
| const newActiveStep = | |||||
| isLastStep() && !allStepsCompleted() | |||||
| ? // It's the last step, but not all steps have been completed, | |||||
| // find the first step that has been completed | |||||
| steps.findIndex((step, i) => !(i in completed)) | |||||
| : activeStep + 1; | |||||
| setActiveStep(newActiveStep); | |||||
| console.log(newActiveStep) | |||||
| }; | |||||
| const handleBack = () => { | |||||
| setActiveStep((prevActiveStep) => prevActiveStep - 1); | |||||
| }; | |||||
| const handleStep = (step) => () => { | |||||
| setActiveStep(step); | |||||
| }; | |||||
| // const handleComplete = () => { | |||||
| // const newCompleted = completed; | |||||
| // newCompleted[activeStep] = true; | |||||
| // setCompleted(newCompleted); | |||||
| // handleNext(); | |||||
| // }; | |||||
| const handleReset = () => { | |||||
| setActiveStep(0); | |||||
| setCompleted({}); | |||||
| }; | |||||
| return( | |||||
| // <AuthWrapper> | |||||
| <Stack sx={{ width: '100%',fontSize: '2rem'}} alignItems="center"> | |||||
| <Stepper activeStep={activeStep} sx={stepStyle}> | |||||
| {steps.map((label, index) => ( | |||||
| <Step key={label} completed={completed[index]}> | |||||
| { | |||||
| index < 2 ? | |||||
| (<StepButton onClick={handleStep(index)}> | |||||
| {label} | |||||
| </StepButton>) : | |||||
| (<StepButton | |||||
| sx={activeStep === 2 ? { "& .MuiSvgIcon-root": { color: "warning.main", fontSize: "2rem" } } : allStepsCompleted() ? { "& .MuiSvgIcon-root": { color: "secondary.main", fontSize: "2rem" } } : { color: "rgba(0, 0, 0, 0.38)" }} | |||||
| icon={<VisibilityIcon />} | |||||
| onClick={handleStep(index)} | |||||
| > | |||||
| {label} | |||||
| </StepButton>) | |||||
| } | |||||
| </Step> | |||||
| ))} | |||||
| </Stepper> | |||||
| {allStepsCompleted() ? ( | |||||
| <React.Fragment> | |||||
| <Typography sx={{ mt: 2, mb: 1 }}> | |||||
| All steps completed - you're finished | |||||
| </Typography> | |||||
| <Stack direction="row" sx={{ pt: 2 }}> | |||||
| <Stack sx={{ flex: '1 1 auto' }} /> | |||||
| <Button onClick={handleReset}>Reset</Button> | |||||
| </Stack> | |||||
| </React.Fragment> | |||||
| ) : ( | |||||
| <React.Fragment> | |||||
| <AuthWrapper> | |||||
| <BusCustomFormWizard updateValid={updateValid} step={activeStep} /> | |||||
| {/* <CustomFormWizard step={activeStep} /> */} | |||||
| </AuthWrapper> | |||||
| <Stack direction="row" sx={{ pt: 2 }}> | |||||
| { activeStep === totalSteps() - 1 ? ( | |||||
| <Button | |||||
| color="inherit" | |||||
| disabled={true} | |||||
| onClick={handleBack} | |||||
| sx={{ mr: 1 }} | |||||
| > | |||||
| 返回 | |||||
| </Button> | |||||
| ):( | |||||
| <Button | |||||
| color="inherit" | |||||
| disabled={activeStep === 0} | |||||
| onClick={handleBack} | |||||
| sx={{ mr: 1 }} | |||||
| > | |||||
| 返回 | |||||
| </Button> | |||||
| ) | |||||
| } | |||||
| <Stack sx={{ flex: '1 1 auto' }} /> | |||||
| {activeStep === totalSteps() - 2 ? | |||||
| ( | |||||
| <Button onClick={handleNext} sx={{ mr: 1 }}> | |||||
| 完成 | |||||
| </Button> | |||||
| ) : ( activeStep === totalSteps() - 1 ? | |||||
| ( | |||||
| <Button color="inherit" | |||||
| disabled={true} sx={{ mr: 1 }}> | |||||
| 完成 | |||||
| </Button> | |||||
| ): | |||||
| ( | |||||
| <Button disabled={isValid===false} onClick={handleNext} sx={{ mr: 1 }}> | |||||
| 繼續 | |||||
| </Button> | |||||
| ) | |||||
| )} | |||||
| {/* {activeStep !== steps.length && | |||||
| (completed[activeStep] ? ( | |||||
| <Typography variant="caption" sx={{ display: 'inline-block' }}> | |||||
| Step {activeStep + 1} already completed | |||||
| </Typography> | |||||
| ) : ( | |||||
| <Button onClick={handleComplete}> | |||||
| {completedSteps() === totalSteps() - 1 | |||||
| ? 'Finish' | |||||
| : 'Complete Step'} | |||||
| </Button> | |||||
| ))} */} | |||||
| </Stack> | |||||
| </React.Fragment> | |||||
| )} | |||||
| </Stack > | |||||
| // </AuthWrapper> | |||||
| ); | |||||
| }; | |||||
| export default BusRegister; | |||||
| @@ -4,7 +4,7 @@ | |||||
| import {Link, Button, Card , Box, Grid } from '@mui/material'; | import {Link, Button, Card , Box, Grid } from '@mui/material'; | ||||
| import Typography from '@mui/material/Typography'; | import Typography from '@mui/material/Typography'; | ||||
| import iAmSmartICon from 'assets/images/icons/icon_iAmSmart.png'; | import iAmSmartICon from 'assets/images/icons/icon_iAmSmart.png'; | ||||
| import banner from 'assets/images/banner.jpg'; | |||||
| import banner from 'assets/images/bg_ml.jpg'; | |||||
| import { Stack } from '../../../node_modules/@mui/material/index'; | import { Stack } from '../../../node_modules/@mui/material/index'; | ||||
| @@ -15,10 +15,7 @@ import { Stack } from '../../../node_modules/@mui/material/index'; | |||||
| const RegisterCustom = () => ( | const RegisterCustom = () => ( | ||||
| <Stack justifyContent="center" sx={{ minHeight: '100vh' }}> | <Stack justifyContent="center" sx={{ minHeight: '100vh' }}> | ||||
| <img src={banner} alt="banner" width="100%" /> | |||||
| <img src={banner} alt="banner" width="100%" height="200px"/> | |||||
| <center> | <center> | ||||
| <Card | <Card | ||||
| sx={{ | sx={{ | ||||
| @@ -31,41 +28,45 @@ const RegisterCustom = () => ( | |||||
| }} | }} | ||||
| > | > | ||||
| <Box alignItems="center"> | <Box alignItems="center"> | ||||
| <Typography mt={4} variant="h1">立即成為<strong style={{color: '#FF5733'}}>憲報刊登公告</strong>用戶</Typography> | |||||
| <Typography variant="body1">只需4-5分鐘</Typography> | |||||
| <Grid mt={5} mb={5} container > | |||||
| <Grid item xs={6} sx={{ borderRight: 1 , borderColor: 'grey.500' }}> | |||||
| <Typography mb={4} variant="h3">個人用戶</Typography> | |||||
| <Button variant="outlined" startIcon={<img src={iAmSmartICon} alt="iAM Smart" width="30" />}>以「智方便」繼續</Button> | |||||
| <Box mt={4} ml={2} mr={2} bgcolor="grey.100" p={1.5} > | |||||
| <Typography textAlign='justify' variant="body1" display="block" gutterBottom> | |||||
| 你可點擊「智方便」按鈕,系統會自動輸入個人資料,或自行輸入個人資料,以即時啟動憲報刊登公告帳戶。 | |||||
| <br/>如欲使用「智方便」提供個人資料,請先下載「智方便」流動應用程式並登記成為「智方便」用戶。 | |||||
| </Typography> | |||||
| <Link href="#">了解更多</Link> | |||||
| </Box> | |||||
| <Typography m={5}>或</Typography> | |||||
| <Button href="/registerFrom" variant="contained">申請個人用戶</Button> | |||||
| <Typography ml={4} mr={4} mt={4} variant="body1" display="block" sx={{fontWeight: 'bold'}} gutterBottom> | |||||
| 需上載身份證明文件數碼檔案以進行網上申請。 | |||||
| <br/>如:香港身份證;護照;往來港澳通行證等 | |||||
| </Typography> | |||||
| </Grid> | |||||
| <Grid item xs={6} sx={{ borderLeft: 1 ,borderColor: 'grey.500' }}> | |||||
| <Typography mb={4} variant="h3">機構/公司用戶</Typography> | |||||
| <Button href="/registerFrom" variant="contained">申請機構/公司用戶</Button> | |||||
| <Typography ml={4} mr={4} mt={4} variant="body1" display="block" sx={{fontWeight: 'bold'}} gutterBottom> | |||||
| 需上載以下任何一份證明文件以進行網上申請。 | |||||
| <br/>如:商業登記證;專業執業證書 | |||||
| </Typography> | |||||
| <Grid container> | |||||
| <Grid item xs={12} md={12}> | |||||
| <Typography mt={4} variant="h1">立即成為<strong style={{color: '#FF5733'}}>憲報刊登公告</strong>用戶</Typography> | |||||
| <Typography variant="body1">只需4-5分鐘</Typography> | |||||
| </Grid> | </Grid> | ||||
| </Grid> | </Grid> | ||||
| <Box mt={3} mb={3}> | |||||
| <Grid container > | |||||
| <Grid item xs={12} md={6} sx={{ borderRight: 1 , borderColor: 'grey.500' }}> | |||||
| <Typography mb={4} variant="h3">個人用戶</Typography> | |||||
| <Button variant="outlined" startIcon={<img src={iAmSmartICon} alt="iAM Smart" width="30" />}>以「智方便」繼續</Button> | |||||
| <Box mt={4} ml={2} mr={2} bgcolor="grey.100" p={1.5} > | |||||
| <Typography textAlign='justify' variant="body1" display="block" gutterBottom> | |||||
| 你可點擊「智方便」按鈕,系統會自動輸入個人資料,或自行輸入個人資料,以即時啟動憲報刊登公告帳戶。 | |||||
| <br/>如欲使用「智方便」提供個人資料,請先下載「智方便」流動應用程式並登記成為「智方便」用戶。 | |||||
| </Typography> | |||||
| <Link href="#">了解更多</Link> | |||||
| </Box> | |||||
| <Typography m={5}>或</Typography> | |||||
| <Button href="/registerFrom" variant="contained">申請個人用戶</Button> | |||||
| <Typography ml={4} mr={4} mt={4} variant="body1" display="block" sx={{fontWeight: 'bold'}} gutterBottom> | |||||
| 需上載身份證明文件數碼檔案以進行網上申請。 | |||||
| <br/>如:香港身份證;護照;往來港澳通行證等 | |||||
| </Typography> | |||||
| </Grid> | |||||
| <Grid item xs={12} md={6} sx={{ borderLeft: 1 ,borderColor: 'grey.500' }}> | |||||
| <Typography mb={4} variant="h3">機構/公司用戶</Typography> | |||||
| <Button href="/registerFromOrganization" variant="contained">申請機構/公司用戶</Button> | |||||
| <Typography ml={4} mr={4} mt={4} variant="body1" display="block" sx={{fontWeight: 'bold'}} gutterBottom> | |||||
| 需上載以下任何一份證明文件以進行網上申請。 | |||||
| <br/>如:商業登記證;專業執業證書 | |||||
| </Typography> | |||||
| </Grid> | |||||
| </Grid> | |||||
| </Box> | |||||
| </Box> | </Box> | ||||
| </Card > | </Card > | ||||
| </center> | </center> | ||||
| @@ -100,7 +100,7 @@ const AuthLoginCustom = () => { | |||||
| submit: null | submit: null | ||||
| }} | }} | ||||
| validationSchema={Yup.object().shape({ | validationSchema={Yup.object().shape({ | ||||
| username: Yup.string().email('Must be a valid email').max(255).required('Email is required'), | |||||
| username: Yup.string().max(255).required('請輸入用戶名稱'), | |||||
| password: Yup.string().max(255).required('請輸入密碼'), | password: Yup.string().max(255).required('請輸入密碼'), | ||||
| })} | })} | ||||
| onSubmit={async (values, { setErrors, setStatus, setSubmitting }) => { | onSubmit={async (values, { setErrors, setStatus, setSubmitting }) => { | ||||
| @@ -141,11 +141,11 @@ const AuthLoginCustom = () => { | |||||
| <InputLabel htmlFor="password-login">密碼</InputLabel> | <InputLabel htmlFor="password-login">密碼</InputLabel> | ||||
| <OutlinedInput | <OutlinedInput | ||||
| fullWidth | fullWidth | ||||
| error={Boolean(touched.password && errors.password)} | |||||
| // error={Boolean(touched.password && errors.password)} | |||||
| id="password-login" | id="password-login" | ||||
| type={showPassword ? 'text' : 'password'} | type={showPassword ? 'text' : 'password'} | ||||
| name="password" | name="password" | ||||
| onBlur={handleBlur} | |||||
| // onBlur={handleBlur} | |||||
| onChange={onPasswordChange} | onChange={onPasswordChange} | ||||
| endAdornment={ | endAdornment={ | ||||
| <InputAdornment position="end"> | <InputAdornment position="end"> | ||||
| @@ -162,11 +162,11 @@ const AuthLoginCustom = () => { | |||||
| } | } | ||||
| placeholder="" | placeholder="" | ||||
| /> | /> | ||||
| {touched.password && errors.password && ( | |||||
| {/* {touched.password && errors.password && ( | |||||
| <FormHelperText error id="standard-weight-helper-text-password-login"> | <FormHelperText error id="standard-weight-helper-text-password-login"> | ||||
| {errors.password} | {errors.password} | ||||
| </FormHelperText> | </FormHelperText> | ||||
| )} | |||||
| )} */} | |||||
| </Stack> | </Stack> | ||||
| </Grid> | </Grid> | ||||
| @@ -0,0 +1,85 @@ | |||||
| // material-ui | |||||
| import * as React from 'react'; | |||||
| import { | |||||
| DataGrid, | |||||
| // GridActionsCellItem, | |||||
| } from "@mui/x-data-grid"; | |||||
| // import EditIcon from '@mui/icons-material/Edit'; | |||||
| import {useEffect} from "react"; | |||||
| // import {useNavigate} from "react-router-dom"; | |||||
| // import { useTheme } from '@mui/material/styles'; | |||||
| // import Checkbox from '@mui/material/Checkbox'; | |||||
| // ==============================|| EVENT TABLE ||============================== // | |||||
| export default function UploadFileTable({recordList}) { | |||||
| const [rows, setRows] = React.useState(recordList); | |||||
| const [rowModesModel] = React.useState({}); | |||||
| // const theme = useTheme(); | |||||
| // const navigate = useNavigate() | |||||
| useEffect(() => { | |||||
| setRows(recordList); | |||||
| }, [recordList]); | |||||
| // const handleEditClick = (id) => () => { | |||||
| // navigate('/user/'+ id); | |||||
| // }; | |||||
| const columns = [ | |||||
| // { | |||||
| // field: 'actions', | |||||
| // type: 'actions', | |||||
| // headerName: 'Actions', | |||||
| // width: 100, | |||||
| // cellClassName: 'actions', | |||||
| // getActions: ({id}) => { | |||||
| // return [ | |||||
| // <GridActionsCellItem | |||||
| // key="OutSave" | |||||
| // icon={<EditIcon/>} | |||||
| // label="Edit" | |||||
| // className="textPrimary" | |||||
| // onClick={handleEditClick(id)} | |||||
| // color="primary" | |||||
| // />] | |||||
| // }, | |||||
| // }, | |||||
| { | |||||
| id: 'name', | |||||
| field: 'name', | |||||
| headerName: 'Name', | |||||
| flex: 1, | |||||
| }, | |||||
| { | |||||
| id: 'size', | |||||
| field: 'size', | |||||
| headerName: 'Size', | |||||
| flex: 1, | |||||
| }, | |||||
| { | |||||
| id: 'type', | |||||
| field: 'type', | |||||
| headerName: 'Type', | |||||
| flex: 1, | |||||
| }, | |||||
| ]; | |||||
| return ( | |||||
| <div style={{height: 400, width: '100%'}}> | |||||
| <DataGrid | |||||
| rows={rows} | |||||
| columns={columns} | |||||
| editMode="row" | |||||
| rowModesModel={rowModesModel} | |||||
| initialState={{ | |||||
| pagination: { | |||||
| paginationModel: {page: 0, pageSize: 5}, | |||||
| }, | |||||
| }} | |||||
| pageSizeOptions={[5, 10]} | |||||
| autoHeight | |||||
| /> | |||||
| </div> | |||||
| ); | |||||
| } | |||||
| @@ -9,6 +9,7 @@ import MainLayout from 'layout/MainLayout'; | |||||
| const AuthLogin = Loadable(lazy(() => import('pages/authentication/Login'))); | const AuthLogin = Loadable(lazy(() => import('pages/authentication/Login'))); | ||||
| const AuthRegister = Loadable(lazy(() => import('pages/authentication/RegisterCustom'))); | const AuthRegister = Loadable(lazy(() => import('pages/authentication/RegisterCustom'))); | ||||
| const RegisterForm = Loadable(lazy(() => import('pages/authentication/Register'))); | const RegisterForm = Loadable(lazy(() => import('pages/authentication/Register'))); | ||||
| const BusRegisterForm = Loadable(lazy(() => import('pages/authentication/BusRegister'))); | |||||
| const ErrorPage = Loadable(lazy(() => import('pages/extra-pages/ErrorPage'))); | const ErrorPage = Loadable(lazy(() => import('pages/extra-pages/ErrorPage'))); | ||||
| const TestMailPage = Loadable(lazy(() => import('pages/pnspsNotifyTest'))); | const TestMailPage = Loadable(lazy(() => import('pages/pnspsNotifyTest'))); | ||||
| @@ -30,6 +31,10 @@ const LoginRoutes = { | |||||
| path: 'registerFrom', | path: 'registerFrom', | ||||
| element: <RegisterForm /> | element: <RegisterForm /> | ||||
| }, | }, | ||||
| { | |||||
| path: 'registerFromOrganization', | |||||
| element: <BusRegisterForm /> | |||||
| }, | |||||
| { | { | ||||
| path: 'error', | path: 'error', | ||||
| element: <ErrorPage/> | element: <ErrorPage/> | ||||
| @@ -58,7 +58,11 @@ export const formatDateToMonthShort = (value, toTimeForCurrentDay = true) => { | |||||
| */ | */ | ||||
| export const isUserLoggedIn = () => localStorage.getItem('userData') != null | export const isUserLoggedIn = () => localStorage.getItem('userData') != null | ||||
| export const getUserData = () => JSON.parse(localStorage.getItem('userData')) | export const getUserData = () => JSON.parse(localStorage.getItem('userData')) | ||||
| export const isAdminLoggedIn = () =>{ | |||||
| if (localStorage.getItem('userData') != null){ | |||||
| return JSON.parse(localStorage.getItem('userData')).role === 'admin' | |||||
| } | |||||
| } | |||||
| /** | /** | ||||
| ** This function is used for demo purpose route navigation | ** 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 | ** In real app you won't need this function because your app will navigate to same route for each users regardless of ability | ||||