| @@ -14,6 +14,53 @@ export const apiPath = window.location.hostname.match("localhost")?`${hostPath}/ | |||||
| //export const apiPath = `/api`; | //export const apiPath = `/api`; | ||||
| export const paymentPath = `https://pnspsdev.gld.gov.hk/payment`; | export const paymentPath = `https://pnspsdev.gld.gov.hk/payment`; | ||||
| export const iAmSmartPath = `https://<iAM_Smart_domain>`; | export const iAmSmartPath = `https://<iAM_Smart_domain>`; | ||||
| export const clientId = "cf61fa7c121e4869966f69c8694b1cd2"; | |||||
| export const iAmSmartCallbackPath = () => { | |||||
| let hostname = window.location.hostname; | |||||
| if (hostname.match("localhost")) { | |||||
| hostname = "pnspsuat.gld.gov.hk"; | |||||
| } | |||||
| return hostname; | |||||
| }; | |||||
| export const getNonce = () => { | |||||
| let hostname = window.location.hostname; | |||||
| if (hostname.match("localhost")) { | |||||
| hostname = "pnspsuat.gld.gov.hk"; | |||||
| } | |||||
| return hostname; | |||||
| }; | |||||
| export const getBowerType = () => { | |||||
| console.log(navigator.userAgent) | |||||
| // const regex = /Mobi|Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Mi|huawei|Opera Mini|SAMSUNG|Samsung|SGH-[I|N|T]|GT-[I|N]|SM-[A|N|P|T|Z]|SHV-E|SCH-[I|J|R|S]|SPH-L/i; | |||||
| // if(!regex.test(navigator.userAgent)) | |||||
| if (navigator.userAgent.indexOf("Edg") != -1) { | |||||
| if (navigator.userAgent.match(/Android/i)) return "Android_Edge" | |||||
| if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) return "iOS_Edge" | |||||
| return "PC_Browser" | |||||
| } else if (navigator.userAgent.indexOf("Chrome") != -1) { | |||||
| if (navigator.userAgent.match(/Android/i)) return "Android_Chrome" | |||||
| if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) return "iOS_Chrome" | |||||
| return "PC_Browser" | |||||
| } else if (navigator.userAgent.indexOf("Safari") != -1) { | |||||
| if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) return "iOS_Safari" | |||||
| return "PC_Browser" | |||||
| } else if (navigator.userAgent.indexOf("Firefox") != -1) { | |||||
| if (navigator.userAgent.match(/Android/i)) return "Android_Firefox" | |||||
| if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) return "iOS_Firefox" | |||||
| return "PC_Browser" | |||||
| } else if (navigator.userAgent.match(/SAMSUNG|Samsung|SGH-[I|N|T]|GT-[I|N]|SM-[A|N|P|T|Z]|SHV-E|SCH-[I|J|R|S]|SPH-L/i)) { | |||||
| return "Android_Samsung" | |||||
| } else if (navigator.userAgent.match(/huawei/i)) { | |||||
| return "Android_Huawei" | |||||
| } else if (navigator.userAgent.match(/Mi/i)) { | |||||
| return "Android_Xiaomi" | |||||
| } | |||||
| return "PC_Browser"; | |||||
| } | |||||
| export const isUserLoggedIn = () => { | export const isUserLoggedIn = () => { | ||||
| @@ -1,76 +1,148 @@ | |||||
| // material-ui | // material-ui | ||||
| import {Link, Button, Card , Box, Grid } from '@mui/material'; | |||||
| import { | |||||
| Dialog, DialogTitle, DialogContent, | |||||
| 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/bg_ml.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'; | ||||
| import { iAmSmartPath, clientId, getBowerType , iAmSmartCallbackPath} from 'auth/utils' | |||||
| import * as React from 'react'; | |||||
| // ================================|| LOGIN ||================================ // | // ================================|| LOGIN ||================================ // | ||||
| const RegisterCustom = () => ( | |||||
| <Stack justifyContent="center" sx={{ minHeight: '100vh', bgcolor: 'backgroundColor.default' }}> | |||||
| <img src={banner} alt="banner" width="100%" height="200px"/> | |||||
| <center> | |||||
| <Card | |||||
| sx={{ | |||||
| maxWidth: { xs: 1, lg: 1000 }, | |||||
| margin: { xs: 2.5, md: 3 }, | |||||
| '& > *': { | |||||
| flexGrow: 1, | |||||
| flexBasis: '50%' | |||||
| }, | |||||
| backgroundColor: "secondary" | |||||
| }} | |||||
| > | |||||
| <Box alignItems="center"> | |||||
| <Grid container> | |||||
| <Grid item xs={12} md={12}> | |||||
| <Typography mt={4} variant="h2">立即成為<strong style={{color: '#FF5733'}}>憲報刊登公告</strong>用戶</Typography> | |||||
| <Typography variant="body1">只需4-5分鐘</Typography> | |||||
| </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" />}><Typography variant="h5">以「智方便」繼續</Typography></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> | |||||
| const RegisterCustom = () => { | |||||
| const [isPopUp, setIsPopUp] = React.useState(false); | |||||
| const registerWithIAmSmart = () => { | |||||
| setIsPopUp(true); | |||||
| } | |||||
| const getQRWithIAmSmart = () => { | |||||
| let callbackUrl = "https://"+iAmSmartCallbackPath()+"/iamsmart/authcallback"; | |||||
| let url = iAmSmartPath + "/api/v1/auth/getQR" | |||||
| + "?clientID=" + clientId | |||||
| + "&responseType=code" | |||||
| +"&source=" + getBowerType() | |||||
| +"&redirectURI="+encodeURIComponent(callbackUrl) | |||||
| +"&scope="+encodeURIComponent("eidapi_auth eidapi_profiles") | |||||
| +"&lang=zh-HK"//en-US, zh-HK, or zh-CN | |||||
| //+"&state=" | |||||
| +"&brokerPage=false" | |||||
| window.location.assign(url); | |||||
| } | |||||
| <Typography m={5}>或</Typography> | |||||
| return ( | |||||
| <Stack justifyContent="center" sx={{ minHeight: '100vh', bgcolor: 'backgroundColor.default' }}> | |||||
| <img src={banner} alt="banner" width="100%" height="200px" /> | |||||
| <center> | |||||
| <Card | |||||
| sx={{ | |||||
| maxWidth: { xs: 1, lg: 1000 }, | |||||
| margin: { xs: 2.5, md: 3 }, | |||||
| '& > *': { | |||||
| flexGrow: 1, | |||||
| flexBasis: '50%' | |||||
| }, | |||||
| backgroundColor: "secondary" | |||||
| }} | |||||
| <Button href="/registerFrom" variant="contained"><Typography variant="h5">申請個人用戶</Typography></Button> | |||||
| > | |||||
| <Box alignItems="center"> | |||||
| <Grid container> | |||||
| <Grid item xs={12} md={12}> | |||||
| <Typography mt={4} variant="h2">立即成為<strong style={{ color: '#FF5733' }}>憲報刊登公告</strong>用戶</Typography> | |||||
| <Typography variant="body1">只需4-5分鐘</Typography> | |||||
| </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" onClick={registerWithIAmSmart} startIcon={<img src={iAmSmartICon} alt="iAM Smart" width="30" />}><Typography variant="h5">以「智方便」繼續</Typography></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="https://www.iamsmart.gov.hk/tc/">了解更多</Link> | |||||
| </Box> | |||||
| <Typography m={5}>或</Typography> | |||||
| <Button href="/registerFrom" variant="contained"><Typography variant="h5">申請個人用戶</Typography></Button> | |||||
| <Typography ml={4} mr={4} mt={4} variant="body1" display="block" sx={{fontWeight: 'bold'}} gutterBottom> | |||||
| 需上載身份證明文件數碼檔案以進行網上申請。 | |||||
| <br/>如:香港身份證; 護照; 中國內地身份證; 專業執業証書等 | |||||
| <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" sx={{ mt: 0.5 }}><Typography variant="h5">申請機構/公司用戶</Typography></Button> | |||||
| <Typography ml={4} mr={4} mt={4} variant="body1" display="block" sx={{ fontWeight: 'bold' }} gutterBottom> | |||||
| 需上載以下任何一份證明文件以進行網上申請。 | |||||
| <br />如:商業登記證;專業執業證書 | |||||
| </Typography> | |||||
| </Grid> | |||||
| </Grid> | |||||
| </Box> | |||||
| </Box> | |||||
| </Card > | |||||
| </center> | |||||
| <Dialog open={isPopUp} onClose={() => setIsPopUp(false)} > | |||||
| <DialogTitle></DialogTitle> | |||||
| <DialogContent> | |||||
| <Typography variant="h3" > | |||||
| 授權「智方便」提供個人資料 | |||||
| </Typography> | |||||
| <Typography variant="h5" style={{ padding: '4px' }}> | |||||
| 為完成開戶並建立與「智方便」的連接,請授權「智方便」提供以下個人資料: | |||||
| </Typography> | |||||
| </DialogContent> | |||||
| <DialogContent > | |||||
| <Grid container style={{ paddingLeft: '16px' }}> | |||||
| <Grid item xs={6} > | |||||
| <Typography style={{ padding: '4px' }}> | |||||
| - 中文姓名 | |||||
| </Typography> | |||||
| <Typography style={{ padding: '4px' }}> | |||||
| - 英文姓名 | |||||
| </Typography> | |||||
| <Typography style={{ padding: '4px' }}> | |||||
| - 身份證號碼 | |||||
| </Typography> | </Typography> | ||||
| </Grid> | </Grid> | ||||
| <Grid item xs={12} md={6} sx={{ borderLeft: 1 ,borderColor: 'grey.500' }}> | |||||
| <Typography mb={4} variant="h3">機構/公司用戶</Typography> | |||||
| <Button href="/registerFromOrganization" variant="contained" sx={{mt:0.5}}><Typography variant="h5">申請機構/公司用戶</Typography></Button> | |||||
| <Typography ml={4} mr={4} mt={4} variant="body1" display="block" sx={{fontWeight: 'bold'}} gutterBottom> | |||||
| 需上載以下任何一份證明文件以進行網上申請。 | |||||
| <br/>如:商業登記證;專業執業證書 | |||||
| <Grid item xs={6} > | |||||
| <Typography style={{ padding: '4px' }}> | |||||
| - 電郵地址 | |||||
| </Typography> | |||||
| <Typography style={{ padding: '4px' }}> | |||||
| - 手機號碼 | |||||
| </Typography> | |||||
| <Typography style={{ padding: '4px' }}> | |||||
| - 住宅地址 | |||||
| </Typography> | </Typography> | ||||
| </Grid> | </Grid> | ||||
| </Grid> | </Grid> | ||||
| </Box> | |||||
| </Box> | |||||
| </Card > | |||||
| </center> | |||||
| </Stack> | |||||
| </DialogContent> | |||||
| <DialogContent align="right"> | |||||
| <Button variant="outlined" onClick={getQRWithIAmSmart} startIcon={<img src={iAmSmartICon} alt="iAM Smart" width="30" />}><Typography variant="h5">使用「智方便」自動填表</Typography></Button> | |||||
| <br /> | |||||
| <Link href="https://www.iamsmart.gov.hk/tc/">了解更多</Link> | |||||
| </DialogContent> | |||||
| </Dialog> | |||||
| </Stack> | |||||
| ); | |||||
| ); | |||||
| }; | |||||
| export default RegisterCustom; | export default RegisterCustom; | ||||
| @@ -0,0 +1,185 @@ | |||||
| // material-ui | |||||
| import { | |||||
| Grid, | |||||
| Typography, | |||||
| Stack, | |||||
| Card, | |||||
| FormHelperText, | |||||
| InputLabel, OutlinedInput, | |||||
| } from '@mui/material'; | |||||
| import * as React from "react"; | |||||
| import { useFormik, FormikProvider } from 'formik'; | |||||
| import * as yup from 'yup'; | |||||
| import { useParams } from "react-router-dom"; | |||||
| //import { iAmSmartPath, clientId, getBowerType , iAmSmartCallbackPath} from 'auth/utils' | |||||
| import Loadable from 'components/Loadable'; | |||||
| const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); | |||||
| import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png' | |||||
| const BackgroundHead = { | |||||
| backgroundImage: `url(${titleBackgroundImg})`, | |||||
| width: '100%', | |||||
| height: '100%', | |||||
| backgroundSize: 'contain', | |||||
| backgroundRepeat: 'no-repeat', | |||||
| backgroundColor: '#0C489E', | |||||
| backgroundPosition: 'right' | |||||
| } | |||||
| // ==============================|| DASHBOARD - DEFAULT ||============================== // | |||||
| const Index = () => { | |||||
| const params = useParams(); | |||||
| const [onReady, setOnReady] = React.useState(false); | |||||
| const [checkUsername, setCheckUsername] = React.useState(false); | |||||
| const [props, setProps] = React.useState({}); | |||||
| React.useEffect(() => { | |||||
| if(params.code){ | |||||
| setOnReady(true); | |||||
| setProps({}); | |||||
| } | |||||
| }, []); | |||||
| // function loadIAmSmartProfile(){ | |||||
| // } | |||||
| function displayErrorMsg(errorMsg) { | |||||
| return <Typography variant="errorMessage1">{errorMsg}</Typography> | |||||
| } | |||||
| const formik = useFormik({ | |||||
| initialValues: ({ | |||||
| username: '', | |||||
| enName: '', | |||||
| email: '', | |||||
| address1: '', | |||||
| address2: '', | |||||
| address3: '', | |||||
| password: '', | |||||
| phone: '', | |||||
| phoneCountryCode: '852', | |||||
| }), | |||||
| validationSchema: yup.object().shape({ | |||||
| username: yup.string().min(6, displayErrorMsg('用戶名稱最少6位')).required(displayErrorMsg('請輸入用戶名稱')) | |||||
| .matches(/^[aA-zZ0-9\s]+$/, { message: displayErrorMsg("用戶名稱不包含特殊字符") }) | |||||
| .matches(/^\S*$/, { message: displayErrorMsg('用戶名稱不包含空格') }), | |||||
| enName: yup.string().max(255).required(displayErrorMsg('請輸入英文姓名')), | |||||
| chName: yup.string().max(255).required(displayErrorMsg('請輸入中文姓名')), | |||||
| address1: yup.string().max(255).required(displayErrorMsg('請輸入第一行地址')), | |||||
| address2: yup.string().max(255).required(displayErrorMsg('請輸入第二行地址')), | |||||
| address3: yup.string().max(255).required(displayErrorMsg('請輸入第三行地址')), | |||||
| email: yup.string().email(displayErrorMsg('請輸入電郵格式')).max(255).required(displayErrorMsg('請輸入電郵')), | |||||
| phoneCountryCode: yup.string().min(2, displayErrorMsg('請輸入最少2位數字')).required(displayErrorMsg('請輸入國際區號')), | |||||
| phone: yup.string().min(8, displayErrorMsg('請輸入最少8位數字')).required(displayErrorMsg('請輸入聯絡電話')), | |||||
| }, ['username']), | |||||
| }); | |||||
| return ( | |||||
| !onReady ? | |||||
| <LoadingComponent /> | |||||
| : | |||||
| <FormikProvider value={formik}> | |||||
| <Grid container sx={{ minHeight: '110vh', backgroundColor: '#fff' }} direction="column" justifyContent="flex-start" alignItems="center" style={{ backgroundColor: "#F2F2F2" }} > | |||||
| <Grid item xs={12} width="100%"> | |||||
| <div style={BackgroundHead} width="100%"> | |||||
| <Stack direction="row" height='70px'> | |||||
| <Typography ml={15} color='#FFF' variant="h4" sx={{ pt: 2 }}>iAmSmart 登記</Typography> | |||||
| </Stack> | |||||
| </div> | |||||
| </Grid> | |||||
| {/*row 1*/} | |||||
| <Grid item xs={12} md={12}> | |||||
| <Grid container justifyContent="flex-start" alignItems="center" > | |||||
| <Card | |||||
| sx={{ | |||||
| maxWidth: { xs: 1, lg: 1000 }, | |||||
| margin: { xs: 2.5, md: 3 }, | |||||
| '& > *': { | |||||
| flexGrow: 1, | |||||
| flexBasis: '50%' | |||||
| }, | |||||
| backgroundColor: "secondary", | |||||
| p:8, | |||||
| pl:16, | |||||
| pr:16 | |||||
| }} | |||||
| > | |||||
| <Grid container spacing={3} > | |||||
| <Grid item xs={12} md={12}> | |||||
| <Stack direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}> | |||||
| <div style={{ borderBottom: "3px solid #1A4399", width: "100%", margin_right: "15px" }}> | |||||
| <Typography display="inline" variant="h3" sx={{ color: '#1A4399' }}>成為個人用戶</Typography> | |||||
| </div> | |||||
| <Typography mt={0.25} variant="h6" sx={{ color: '#f10000' }}>註有*的項目必須輸入資料</Typography> | |||||
| <Typography mt={0.25} variant="h4" sx={{ color: 'primary.primary' }}>用戶資料</Typography> | |||||
| {/* <Typography component={Link} to="/login" variant="body1" sx={{ textDecoration: 'none' }} color="primary"> | |||||
| Already have an account? | |||||
| </Typography> */} | |||||
| </Stack> | |||||
| </Grid> | |||||
| <Grid item xs={12} md={12}> | |||||
| <Grid container spacing={1}> | |||||
| <Grid item xs={12} md={12} > | |||||
| <Stack spacing={1}> | |||||
| <InputLabel htmlFor="username-signup"> | |||||
| <Typography variant="h5"> | |||||
| 用戶登入名稱 | |||||
| <span style={{ color: '#f10000' }}>*</span> | |||||
| </Typography> | |||||
| </InputLabel> | |||||
| <OutlinedInput | |||||
| id="username-login" | |||||
| type="text" | |||||
| value={formik.values.username.trim()} | |||||
| name="username" | |||||
| onChange={(e) => { | |||||
| setCheckUsername(false) | |||||
| props.username = e.target.value | |||||
| formik.handleChange(e) | |||||
| }} | |||||
| placeholder="用戶登入名稱" | |||||
| fullWidth | |||||
| error={Boolean((formik.touched.username && formik.errors.username) || checkUsername)} | |||||
| onBlur={formik.handleBlur} | |||||
| inputProps={{ | |||||
| onKeyDown: (e) => { | |||||
| if (e.key === 'Enter') { | |||||
| e.preventDefault(); | |||||
| } | |||||
| }, | |||||
| }} | |||||
| /> | |||||
| {formik.touched.username && formik.errors.username && ( | |||||
| <FormHelperText error id="helper-text-username-signup"> | |||||
| {formik.errors.username} | |||||
| </FormHelperText> | |||||
| )} | |||||
| {checkUsername && ( | |||||
| <FormHelperText error id="helper-text-username-signup"> | |||||
| 此用戶登入名稱已被注冊,請使用其他用戶登入名稱 | |||||
| </FormHelperText> | |||||
| )} | |||||
| </Stack> | |||||
| </Grid> | |||||
| </Grid> | |||||
| </Grid> | |||||
| </Grid> | |||||
| </Card> | |||||
| </Grid> | |||||
| </Grid> | |||||
| {/*row 2*/} | |||||
| </Grid > | |||||
| </FormikProvider> | |||||
| ); | |||||
| }; | |||||
| export default Index; | |||||
| @@ -0,0 +1,66 @@ | |||||
| // material-ui | |||||
| import { | |||||
| Grid, | |||||
| Typography, | |||||
| Stack, | |||||
| } from '@mui/material'; | |||||
| import * as React from "react"; | |||||
| import Loadable from 'components/Loadable'; | |||||
| const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); | |||||
| import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png' | |||||
| const BackgroundHead = { | |||||
| backgroundImage: `url(${titleBackgroundImg})`, | |||||
| width: '100%', | |||||
| height: '100%', | |||||
| backgroundSize: 'contain', | |||||
| backgroundRepeat: 'no-repeat', | |||||
| backgroundColor: '#0C489E', | |||||
| backgroundPosition: 'right' | |||||
| } | |||||
| // ==============================|| DASHBOARD - DEFAULT ||============================== // | |||||
| const Index = () => { | |||||
| const [onReady, setOnReady] = React.useState(false); | |||||
| React.useEffect(() => { | |||||
| setOnReady(true); | |||||
| }, []); | |||||
| return ( | |||||
| !onReady ? | |||||
| <LoadingComponent /> | |||||
| : | |||||
| <Grid container sx={{ minHeight: '110vh', backgroundColor: '#fff' }} direction="column" justifyContent="flex-start" alignItems="center" > | |||||
| <Grid item xs={12} width="100%"> | |||||
| <div style={BackgroundHead} width="100%"> | |||||
| <Stack direction="row" height='70px'> | |||||
| <Typography ml={15} color='#FFF' variant="h4" sx={{ pt: 2 }}>iAmSmart 登入失敗</Typography> | |||||
| </Stack> | |||||
| </div> | |||||
| </Grid> | |||||
| {/*row 1*/} | |||||
| <Grid item xs={12} md={12} > | |||||
| <Grid container justifyContent="flex-start" alignItems="center" > | |||||
| <center> | |||||
| <Grid item xs={12} md={12} > | |||||
| <Typography variant="h3" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "center" }}> | |||||
| 連接 iAM Smart 時出現錯誤,請重試。 | |||||
| </Typography> | |||||
| </Grid> | |||||
| </center> | |||||
| </Grid> | |||||
| </Grid> | |||||
| {/*row 2*/} | |||||
| </Grid > | |||||
| ); | |||||
| }; | |||||
| export default Index; | |||||
| @@ -0,0 +1,66 @@ | |||||
| // material-ui | |||||
| import { | |||||
| Grid, | |||||
| Typography, | |||||
| Stack, | |||||
| } from '@mui/material'; | |||||
| import * as React from "react"; | |||||
| import Loadable from 'components/Loadable'; | |||||
| const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); | |||||
| import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png' | |||||
| const BackgroundHead = { | |||||
| backgroundImage: `url(${titleBackgroundImg})`, | |||||
| width: '100%', | |||||
| height: '100%', | |||||
| backgroundSize: 'contain', | |||||
| backgroundRepeat: 'no-repeat', | |||||
| backgroundColor: '#0C489E', | |||||
| backgroundPosition: 'right' | |||||
| } | |||||
| // ==============================|| DASHBOARD - DEFAULT ||============================== // | |||||
| const Index = () => { | |||||
| const [onReady, setOnReady] = React.useState(false); | |||||
| React.useEffect(() => { | |||||
| setOnReady(true); | |||||
| }, []); | |||||
| return ( | |||||
| !onReady ? | |||||
| <LoadingComponent /> | |||||
| : | |||||
| <Grid container sx={{ minHeight: '110vh', backgroundColor: '#fff' }} direction="column" justifyContent="flex-start" alignItems="center" > | |||||
| <Grid item xs={12} width="100%"> | |||||
| <div style={BackgroundHead} width="100%"> | |||||
| <Stack direction="row" height='70px'> | |||||
| <Typography ml={15} color='#FFF' variant="h4" sx={{ pt: 2 }}>iAmSmart 成功登入</Typography> | |||||
| </Stack> | |||||
| </div> | |||||
| </Grid> | |||||
| {/*row 1*/} | |||||
| <Grid item xs={12} md={12} > | |||||
| <Grid container justifyContent="flex-start" alignItems="center" > | |||||
| <center> | |||||
| <Grid item xs={12} md={12} > | |||||
| <Typography variant="h3" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "center" }}> | |||||
| iAmSmart 成功登入 | |||||
| </Typography> | |||||
| </Grid> | |||||
| </center> | |||||
| </Grid> | |||||
| </Grid> | |||||
| {/*row 2*/} | |||||
| </Grid > | |||||
| ); | |||||
| }; | |||||
| export default Index; | |||||
| @@ -11,6 +11,11 @@ const AuthRegister = Loadable(lazy(() => import('pages/authentication/RegisterCu | |||||
| 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 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 IAmSmart_FailCallback = Loadable(lazy(() => import('pages/iAmSmart/FailCallback'))); | |||||
| const IAmSmart_SuccessCallback = Loadable(lazy(() => import('pages/iAmSmart/SuccessCallback'))); | |||||
| const IAmSmart_AuthCallback = Loadable(lazy(() => import('pages/iAmSmart/AuthCallback'))); | |||||
| //TODO: this page for testing only, please remove at prod | |||||
| const TestMailPage = Loadable(lazy(() => import('pages/pnspsNotifyTest'))); | const TestMailPage = Loadable(lazy(() => import('pages/pnspsNotifyTest'))); | ||||
| const VerifyPage = Loadable(lazy(() => import('pages/authentication/Verify'))); | const VerifyPage = Loadable(lazy(() => import('pages/authentication/Verify'))); | ||||
| @@ -20,6 +25,10 @@ const LoginRoutes = { | |||||
| path: '/', | path: '/', | ||||
| element: <MainLayout />, | element: <MainLayout />, | ||||
| children: [ | children: [ | ||||
| {//TODO: this page for testing only, please remove at prod | |||||
| path: 'testMailPage', | |||||
| element: <TestMailPage/> | |||||
| }, | |||||
| { | { | ||||
| path: 'login', | path: 'login', | ||||
| element: <AuthLogin /> | element: <AuthLogin /> | ||||
| @@ -40,6 +49,18 @@ const LoginRoutes = { | |||||
| path: 'error', | path: 'error', | ||||
| element: <ErrorPage/> | element: <ErrorPage/> | ||||
| }, | }, | ||||
| { | |||||
| path: 'iamsmart/authcallback', | |||||
| element: <IAmSmart_AuthCallback/> | |||||
| }, | |||||
| { | |||||
| path: 'iamsmart/loginfallback', | |||||
| element: <IAmSmart_FailCallback/> | |||||
| }, | |||||
| { | |||||
| path: 'iamsmart/logincallback', | |||||
| element: <IAmSmart_SuccessCallback/> | |||||
| }, | |||||
| { | { | ||||
| path: 'testMailPage', | path: 'testMailPage', | ||||
| element: <TestMailPage/> | element: <TestMailPage/> | ||||