Ver código fonte

iamSmart

master
Anna Ho 1 ano atrás
pai
commit
ccbeeab0fd
4 arquivos alterados com 1259 adições e 170 exclusões
  1. +217
    -0
      src/pages/authentication/IAmSmartRegister.js
  2. +1020
    -0
      src/pages/authentication/auth-forms/IAmSmartFormWizard.js
  3. +17
    -170
      src/pages/iAmSmart/AuthCallback/index.js
  4. +5
    -0
      src/routes/LoginRoutes.js

+ 217
- 0
src/pages/authentication/IAmSmartRegister.js Ver arquivo

@@ -0,0 +1,217 @@
// import { Link } from 'react-router-dom';
import React, {
useState
// ,useEffect
} from 'react';

// material-ui
import {
Stepper,
Step,
StepButton,
// Grid,
Stack,
Typography,
Button,
} from '@mui/material';
import VisibilityIcon from '@mui/icons-material/Visibility';
import { GET_USERNAME } from "utils/ApiPathConst";

// project import
import Loadable from 'components/Loadable';
import { lazy } from 'react';
import { notifyActionError } from 'utils/CommonFunction';
import axios from "axios";
const CustomFormWizard = Loadable(lazy(() => import('./auth-forms/IAmSmartFormWizard')));
const AuthWrapper = Loadable(lazy(() => import('./AuthWrapperCustom')));
// ================================|| REGISTER ||================================ //
const stepStyle = {
width: "40%",
boxShadow: 1,
backgroundColor: "#FFFFFF",
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 Register = () => {
const [activeStep, setActiveStep] = useState(0);
const [completed, setCompleted] = useState([false]);
const [updateValid, setUpdateValid] = useState(false);
const [username, setUsername] = useState("");

const totalSteps = () => {
return steps.length;
};

const completedSteps = () => {
return Object.keys(completed).length;
};

const isLastStep = () => {
return activeStep === totalSteps() - 1;
};

const allStepsCompleted = () => {
return completedSteps() === totalSteps();
};

const handleCheckUsername = async () => {
const response = await axios.get(`${GET_USERNAME}`, {
params: {
username: username,
}
})
return Number(response.data[0]) === 1
}

const handleNext = async () => {
const test = await handleCheckUsername()
if (test) {
notifyActionError("此用戶登入名稱已被注冊,請使用其他用戶登入名稱")
} else {
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);
scrollToTop();
}
};

const handleBack = () => {
scrollToTop();
setActiveStep((prevActiveStep) => prevActiveStep - 1);
};

const scrollToTop = () => {
window.scrollTo(0, 0);
};

const handleReset = () => {
setActiveStep(0);
setCompleted({});
};

return (
// <AuthWrapper>
<Stack sx={{ width: '100%', fontSize: '2rem', paddingTop: '65px', bgcolor: 'backgroundColor.default' }} alignItems="center">
<Stepper activeStep={activeStep} sx={stepStyle}>
{steps.map((label, index) => (
<Step key={label} completed={completed[index]} readOnly={true}>
{
index < 2 ?
(<StepButton
// onClick={handleStep(index)}
>
<Typography variant="step1">{label}</Typography>
</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)}
>
<Typography variant="step1">{label}</Typography>
</StepButton>)
}

</Step>
))}
</Stepper>
{allStepsCompleted() ? (
<React.Fragment>
<Typography variant="h4" sx={{ mt: 2, mb: 1 }}>
All steps completed - you&apos;re finished
</Typography>
<Stack direction="row" sx={{ pt: 2 }}>
<Stack sx={{ flex: '1 1 auto' }} />
<Button onClick={handleReset}><Typography variant="h5">Reset</Typography></Button>
</Stack>
</React.Fragment>
) : (
<React.Fragment>
<AuthWrapper>
<CustomFormWizard setUpdateValid={setUpdateValid} step={activeStep} setUsername={setUsername}/>
{/* <CustomFormWizard step={activeStep} /> */}
</AuthWrapper>
<Stack direction="row" sx={{ pb: 2 }}>
{activeStep === 2 || activeStep === 0 ? (
<Button
color="inherit"
disabled={true}
onClick={handleBack}
sx={{ mr: 1 }}
>
<Typography variant="h5">返回</Typography>
</Button>
) : (
<Button
color="inherit"
disabled={activeStep === 0}
onClick={handleBack}
sx={{ mr: 1 }}
>
<Typography variant="h5">返回</Typography>
</Button>
)
}
<Stack sx={{ flex: '1 1 auto' }} />
{activeStep === totalSteps() - 2 ?
(
<Button variant="outlined" onClick={handleNext} sx={{ mr: 1 }}>
<Typography variant="h5">提交</Typography>
</Button>
) : (activeStep === totalSteps() - 1 ?
(
<Button variant="outlined" color="inherit"
disabled={true} sx={{ mr: 1 }}>
<Typography variant="h5">提交</Typography>
</Button>
) :
(
// <Button disabled={updateValid} variant="outlined" onClick={handleNext} sx={{ mr: 1 }}>
<Button disabled={!updateValid} variant="outlined" onClick={handleNext} sx={{ mr: 1 }}>
<Typography variant="h5">繼續</Typography>
</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 Register;

+ 1020
- 0
src/pages/authentication/auth-forms/IAmSmartFormWizard.js
Diferenças do arquivo suprimidas por serem muito extensas
Ver arquivo


+ 17
- 170
src/pages/iAmSmart/AuthCallback/index.js Ver arquivo

@@ -1,195 +1,42 @@
// 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 * as HttpUtils from "utils/HttpUtils";
import * as UrlUtils from "utils/ApiPathConst";
//import { iAmSmartPath, clientId, getBowerType , iAmSmartCallbackPath} from 'auth/utils'

import { useNavigate } from "react-router-dom";
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({});
const navigate = useNavigate()

React.useEffect(() => {
if(params.code){
setOnReady(true);
setProps({});
getPrfile();
}
getPrfile();
}, []);

function getPrfile(){
HttpUtils.post({
url: UrlUtils.GET_SMART_PROFILE,
params:{
code: params.code
},
onSuccess: () => {

}
});
}

function displayErrorMsg(errorMsg) {
return <Typography variant="errorMessage1">{errorMsg}</Typography>
let params = new URLSearchParams(window.location.search)
if(params.get("code")){
HttpUtils.post({
url: UrlUtils.GET_SMART_PROFILE,
params:{
code: params.get("code")
},
onSuccess: (responseData) => {
navigate('/iAmSmartRegisterFrom', { state: { responseData: responseData } });
}
});
}
}

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>

);
};


+ 5
- 0
src/routes/LoginRoutes.js Ver arquivo

@@ -10,6 +10,7 @@ const AuthLogin = Loadable(lazy(() => import('pages/authentication/Login')));
const AuthRegister = Loadable(lazy(() => import('pages/authentication/RegisterCustom')));
const RegisterForm = Loadable(lazy(() => import('pages/authentication/Register')));
const BusRegisterForm = Loadable(lazy(() => import('pages/authentication/BusRegister')));
const IAmSmartRegister = Loadable(lazy(() => import('pages/authentication/IAmSmartRegister')));
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')));
@@ -45,6 +46,10 @@ const LoginRoutes = {
path: 'registerFromOrganization',
element: <BusRegisterForm />
},
{
path: 'iAmSmartRegisterFrom',
element: <IAmSmartRegister />
},
{
path: 'error',
element: <ErrorPage/>


Carregando…
Cancelar
Salvar