feat: resend otp
This commit is contained in:
parent
40921c6af5
commit
534d1dfa96
|
@ -77,12 +77,13 @@ class BTNLoginPage extends React.Component{
|
||||||
// res.message
|
// res.message
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
} else {
|
||||||
|
|
||||||
//redirect register
|
//redirect register
|
||||||
this.props.history.replace(LINKS.REGISTER);
|
this.props.history.replace(LINKS.REGISTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
handleChange = name => event => {
|
handleChange = name => event => {
|
||||||
this.setState({
|
this.setState({
|
||||||
[name]: event.target.value,
|
[name]: event.target.value,
|
||||||
|
|
|
@ -82,9 +82,19 @@ class OtpPage extends React.Component{
|
||||||
|
|
||||||
resendCode = () => {
|
resendCode = () => {
|
||||||
this.setState({isResending:true});
|
this.setState({isResending:true});
|
||||||
setTimeout(()=>{
|
|
||||||
|
return this.props.appstate.http.post('authentication/resend_otp_by_login_request', {
|
||||||
|
login_request_id: this.state.otpData.login_request_id
|
||||||
|
}).then(res => {
|
||||||
|
this.setState({
|
||||||
|
otpData:{
|
||||||
|
login_request_id : res.login_request_id,
|
||||||
|
expired_at : res.expired_at
|
||||||
|
}
|
||||||
|
});
|
||||||
|
message.info('Kirim ulang sukses');
|
||||||
this.setState({isResending:false});
|
this.setState({isResending:false});
|
||||||
},3000);
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
login = () => {
|
login = () => {
|
||||||
|
@ -160,9 +170,9 @@ class OtpPage extends React.Component{
|
||||||
<Typography variant="h6" gutterBottom>
|
<Typography variant="h6" gutterBottom>
|
||||||
Masukkan Kode OTP Anda
|
Masukkan Kode OTP Anda
|
||||||
</Typography>
|
</Typography>
|
||||||
{/*<Typography variant="subtitle2" gutterBottom>*/}
|
<Typography variant="subtitle2" gutterBottom>
|
||||||
{/*Still not received OTP Code? <a onClick={()=>this.resendCode()}>Resend Code</a>*/}
|
Belum menerima OTP? <a onClick={()=>this.resendCode()}>Kirim Ulang</a>
|
||||||
{/*</Typography>*/}
|
</Typography>
|
||||||
<Grid container justify="center" spacing={8}>
|
<Grid container justify="center" spacing={8}>
|
||||||
{[0, 1, 2, 3, 4, 5].map(x => (
|
{[0, 1, 2, 3, 4, 5].map(x => (
|
||||||
<Grid item xs={1}>
|
<Grid item xs={1}>
|
||||||
|
|
|
@ -545,7 +545,7 @@ class RegisterPage extends React.Component {
|
||||||
<div style={{ padding: 5, marginTop: 20 }}>
|
<div style={{ padding: 5, marginTop: 20 }}>
|
||||||
<Button
|
<Button
|
||||||
fullWidth
|
fullWidth
|
||||||
variant="contained" style={{ backgroundColor: '#ffeb3b' }} onClick={this.register}>
|
variant="contained" style={{ backgroundColor: '#ffeb3b',marginBottom: 16 }} onClick={this.register}>
|
||||||
{this.state.isLoading ? <CircularProgress className={classes.progress} /> : "Daftar"}
|
{this.state.isLoading ? <CircularProgress className={classes.progress} /> : "Daftar"}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
|
|
326
src/common/pages/ResendOtp/index.js
Normal file
326
src/common/pages/ResendOtp/index.js
Normal file
|
@ -0,0 +1,326 @@
|
||||||
|
import React from 'react';
|
||||||
|
import withStyles from "@material-ui/core/styles/withStyles";
|
||||||
|
import { styles } from './styles';
|
||||||
|
import Grid from '@material-ui/core/Grid';
|
||||||
|
import Paper from '@material-ui/core/Paper';
|
||||||
|
import Typography from '@material-ui/core/Typography';
|
||||||
|
import TextField from '@material-ui/core/TextField';
|
||||||
|
import Visibility from '@material-ui/icons/Visibility';
|
||||||
|
import VisibilityOff from '@material-ui/icons/VisibilityOff';
|
||||||
|
import Button from '@material-ui/core/Button';
|
||||||
|
import Hidden from '@material-ui/core/Hidden';
|
||||||
|
import InputAdornment from '@material-ui/core/InputAdornment';
|
||||||
|
import IconButton from '@material-ui/core/IconButton';
|
||||||
|
import CircularProgress from '@material-ui/core/CircularProgress';
|
||||||
|
import Snackbar from '@material-ui/core/Snackbar';
|
||||||
|
|
||||||
|
import { Link } from 'react-router-dom'
|
||||||
|
import { inject, observer } from "mobx-react";
|
||||||
|
import schema from 'async-validator'
|
||||||
|
import { startCase } from 'lodash';
|
||||||
|
import { Upload, Icon, message } from 'antd';
|
||||||
|
|
||||||
|
import AutoComplete from './../../components/AutoComplete';
|
||||||
|
import {appConfig} from "../../config/app";
|
||||||
|
import {LINKS} from "../../routes";
|
||||||
|
|
||||||
|
// const province = require("./../../../../assets/data/province.json");
|
||||||
|
// const city = require("./../../../../assets/data/city.json");
|
||||||
|
// const district = require("./../../../../assets/data/district.json");
|
||||||
|
// const subdistrict = require("./../../../../assets/data/subdistrict.json");
|
||||||
|
|
||||||
|
@withStyles(styles)
|
||||||
|
@inject('appstate')
|
||||||
|
@observer
|
||||||
|
export class ResendOtp extends React.Component {
|
||||||
|
state = {
|
||||||
|
showPassword: false,
|
||||||
|
showConfirmPassword: false,
|
||||||
|
openDialog: false,
|
||||||
|
isLoading: false,
|
||||||
|
|
||||||
|
fileList_ktp: [],
|
||||||
|
fileList_photo: [],
|
||||||
|
|
||||||
|
query: {},
|
||||||
|
|
||||||
|
// form
|
||||||
|
confirmPassword: "",
|
||||||
|
phone_number: "",
|
||||||
|
email: "",
|
||||||
|
password: "",
|
||||||
|
full_name: "",
|
||||||
|
no_ktp: '',
|
||||||
|
upload_ktp: '',
|
||||||
|
upload_photo: '',
|
||||||
|
address: '',
|
||||||
|
province: '',
|
||||||
|
city: '',
|
||||||
|
district: '',
|
||||||
|
sub_district: '',
|
||||||
|
zip_code: '',
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.authStore = props.appstate.auth;
|
||||||
|
this.http = props.appstate.http;
|
||||||
|
this.place = props.appstate.places;
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
let {location:{search}} = this.props;
|
||||||
|
search = search.substr(1);
|
||||||
|
|
||||||
|
const query = search.split("&")
|
||||||
|
.map(q => q.split('='))
|
||||||
|
.reduce((all, q) => {
|
||||||
|
all[q[0]] = q[1];
|
||||||
|
return all;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
this.setState({query});
|
||||||
|
|
||||||
|
this.place.getAllProvince();
|
||||||
|
}
|
||||||
|
|
||||||
|
onChangeProvince = (value) => {
|
||||||
|
this.setState({
|
||||||
|
province: value
|
||||||
|
});
|
||||||
|
this.place.getCitiesByProvince(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
onChangeCity = (value) => {
|
||||||
|
this.setState({
|
||||||
|
city: value
|
||||||
|
});
|
||||||
|
this.place.getDistrictByCity(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
onChangeDistrict = (value) => {
|
||||||
|
this.setState({
|
||||||
|
district: value
|
||||||
|
});
|
||||||
|
this.place.getSubdistrictByDistrict(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
onChangeSubdistrict = (value) => {
|
||||||
|
this.setState({
|
||||||
|
subdistrict: value
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
handleChange = name => event => {
|
||||||
|
this.setState({
|
||||||
|
[name]: event.target.value,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
viewPassword = () => {
|
||||||
|
this.setState({
|
||||||
|
showPassword: !this.state.showPassword
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
viewConfirmPassword = () => {
|
||||||
|
this.setState({
|
||||||
|
showConfirmPassword: !this.state.showConfirmPassword
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
resendOtp = () => {
|
||||||
|
return this.props.appstate.http.post('authentication/resend_otp', {
|
||||||
|
phone_number: this.state.phone_number
|
||||||
|
}).then(res => {
|
||||||
|
//message.success("Please check your email to confirm your account");this.props.history.push(LINKS.LOGIN);
|
||||||
|
setTimeout(() => {
|
||||||
|
this.setState({ isLoading: false });
|
||||||
|
|
||||||
|
this.props.history.push({
|
||||||
|
pathname:LINKS.OTP,
|
||||||
|
search:'?login_request_id='+res.login_request_id+'&expired_at='+res.expired_at
|
||||||
|
});
|
||||||
|
// this.props.history.push(LINKS.LOGIN);
|
||||||
|
}, 250);
|
||||||
|
}).catch(err => {
|
||||||
|
if (err.type === 'BodyValidationError') {
|
||||||
|
message.error(err.detail[0].message);
|
||||||
|
} else {
|
||||||
|
message.error(err.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
handleChangeUploadKtp = (info) => {
|
||||||
|
if (info.file.status === 'uploading') {
|
||||||
|
this.setState({ loading: true });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (info.file.status === 'done') {
|
||||||
|
// Get this url from response in real world.
|
||||||
|
getBase64(info.file.originFileObj, imageUrl => this.setState({
|
||||||
|
upload_ktp,
|
||||||
|
loading: false,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
handleChangeUploadPhoto = (info) => {
|
||||||
|
if (info.file.status === 'uploading') {
|
||||||
|
this.setState({ loading: true });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (info.file.status === 'done') {
|
||||||
|
// Get this url from response in real world.
|
||||||
|
getBase64(info.file.originFileObj, imageUrl => this.setState({
|
||||||
|
upload_photo,
|
||||||
|
loading: false,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
uploadOnChange = (key, info) => {
|
||||||
|
let fileList = info.fileList;
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
[`fileList_${key}`]: fileList
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
createUploadProps = (key) => {
|
||||||
|
return {
|
||||||
|
name: 'file',
|
||||||
|
multiple: false,
|
||||||
|
action: appConfig.apiUrl + 'upload',
|
||||||
|
customRequest: ({file, onProgress, onSuccess}) => {
|
||||||
|
this.setState({
|
||||||
|
uploading: true
|
||||||
|
});
|
||||||
|
this.http.upload(file)
|
||||||
|
.then(res => {
|
||||||
|
this.setState({
|
||||||
|
[`upload_${key}`]: appConfig.apiUrl + res.path.slice(1,res.path.length)
|
||||||
|
});
|
||||||
|
return res;
|
||||||
|
})
|
||||||
|
.then(res => {
|
||||||
|
message.success(`${file.name} file uploaded successfully.`);
|
||||||
|
|
||||||
|
const fileList = this.state[`fileList_${key}`];
|
||||||
|
|
||||||
|
console.log(key, fileList, this.state);
|
||||||
|
|
||||||
|
const selectedIndex = fileList.findIndex(f => f.name === file.name);
|
||||||
|
|
||||||
|
fileList[selectedIndex].status = "done";
|
||||||
|
fileList[selectedIndex].path = res.path;
|
||||||
|
onSuccess(fileList[selectedIndex]);
|
||||||
|
// form.setFieldsValue({path: res.path});
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
uploading: false,
|
||||||
|
// fileList: []
|
||||||
|
[`fileList_${key}`]: [fileList[selectedIndex]]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
abort: () => {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fileList: this.state[`fileList_${key}`],
|
||||||
|
onChange: (info) => this.uploadOnChange(key, info),
|
||||||
|
onRemove: file => true
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { classes } = this.props;
|
||||||
|
|
||||||
|
const uploadButtonKtp = (
|
||||||
|
<div>
|
||||||
|
<Icon type={this.state.loading ? 'loading' : 'plus'} />
|
||||||
|
<div className="ant-upload-text">Upload KTP</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
const uploadButtonPhoto = (
|
||||||
|
<div>
|
||||||
|
<Icon type={this.state.loading ? 'loading' : 'plus'} />
|
||||||
|
<div className="ant-upload-text">Upload Photo</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
const upload_ktp = this.state.upload_ktp;
|
||||||
|
const upload_photo = this.state.upload_photo;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={classes.container}>
|
||||||
|
{/*<AlertSuccess open={appStore.global_ui.openSuccess} onClose={()=>appStore.global_ui.closeAlertSuccess()}/>*/}
|
||||||
|
|
||||||
|
<Grid container spacing={0} className={classes.gridContainer}>
|
||||||
|
<Grid item cols={12} className={classes.logoContainer}>
|
||||||
|
<img src={require('../../../../assets/images/logo_new.png')} className={classes.logo} />
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12} sm={12} md={10} lg={10} className={classes.registerContainer} style={{
|
||||||
|
alignSelf: 'center'
|
||||||
|
}}>
|
||||||
|
<Grid container spacing={24} className={classes.registerPaper}>
|
||||||
|
<Hidden smDown>
|
||||||
|
<Grid item xs={5}>
|
||||||
|
<img src={require('../../../../assets/images/register_image_2.png')} width={"80%"} />
|
||||||
|
<Typography style={{ color: '#FFF' }} variant={"h6"}>
|
||||||
|
Tukarkan point!
|
||||||
|
</Typography>
|
||||||
|
<Typography style={{ color: '#FFF' }} variant={"subtitle2"}>
|
||||||
|
Dapatkan promo dan keuntungan dengan BTN
|
||||||
|
</Typography>
|
||||||
|
</Grid>
|
||||||
|
</Hidden>
|
||||||
|
<Grid item xs={12} sm={12} md={7} style={{ paddingLeft: 50, paddingRight: 50 }}>
|
||||||
|
<Paper className={classes.formRegister}>
|
||||||
|
<Typography variant="h6" gutterBottom>
|
||||||
|
Daftar Sekarang
|
||||||
|
</Typography>
|
||||||
|
{/*<Typography variant="subtitle2" gutterBottom>*/}
|
||||||
|
{/*Already have an account? <Link to={"/login"} replace>Back to Login</Link>*/}
|
||||||
|
{/*</Typography>*/}
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'row'
|
||||||
|
}}>
|
||||||
|
<Grid item xs={12} sm={12} md={12} style={{ paddingLeft: 5, paddingRight: 5 }}>
|
||||||
|
<TextField
|
||||||
|
id="phone"
|
||||||
|
label="Nomer Telfon"
|
||||||
|
value={this.state.phone_number}
|
||||||
|
onChange={this.handleChange('phone_number')}
|
||||||
|
margin="normal"
|
||||||
|
type={"number"}
|
||||||
|
variant="outlined"
|
||||||
|
fullWidth
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div style={{ padding: 5, marginTop: 20 }}>
|
||||||
|
<Button
|
||||||
|
fullWidth
|
||||||
|
variant="contained" style={{ backgroundColor: '#ffeb3b' }} onClick={this.resendOtp}>
|
||||||
|
{this.state.isLoading ? <CircularProgress className={classes.progress} /> : "Kirim ulang OTP"}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</Paper>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
38
src/common/pages/ResendOtp/styles.js
Normal file
38
src/common/pages/ResendOtp/styles.js
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
import yellow from '@material-ui/core/colors/yellow';
|
||||||
|
export const styles = theme => ({
|
||||||
|
container : {
|
||||||
|
flex :1,
|
||||||
|
flexGrow : 1,
|
||||||
|
height : '100%',
|
||||||
|
backgroundColor:'#024f8e',
|
||||||
|
marginTop: '-56px',
|
||||||
|
paddingBottom:50
|
||||||
|
},
|
||||||
|
gridContainer : {
|
||||||
|
flex :1,
|
||||||
|
justifyContent: 'center',
|
||||||
|
flexDirection: 'column'
|
||||||
|
},
|
||||||
|
registerContainer: {
|
||||||
|
marginTop : 50
|
||||||
|
},
|
||||||
|
formRegister : {
|
||||||
|
padding : 20,
|
||||||
|
display : 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
textAlign : 'center'
|
||||||
|
},
|
||||||
|
registerPaper : {
|
||||||
|
flex :1,
|
||||||
|
flexDirection : 'row',
|
||||||
|
justifyContent:'center'
|
||||||
|
},
|
||||||
|
logo : {
|
||||||
|
width : '200px'
|
||||||
|
},
|
||||||
|
logoContainer : {
|
||||||
|
textAlign : 'center',
|
||||||
|
background : yellow['500'],
|
||||||
|
padding : 20
|
||||||
|
},
|
||||||
|
});
|
|
@ -14,6 +14,7 @@ import OtpPage from "./pages/Otp";
|
||||||
import RegisterCompletedComponent from "./pages/RegisterCompleted";
|
import RegisterCompletedComponent from "./pages/RegisterCompleted";
|
||||||
import ResendEmail from "./pages/ResendEmail";
|
import ResendEmail from "./pages/ResendEmail";
|
||||||
import ConfirmationCompletedComponent from "./pages/ConfirmationCompleted";
|
import ConfirmationCompletedComponent from "./pages/ConfirmationCompleted";
|
||||||
|
import {ResendOtp} from "./pages/ResendOtp";
|
||||||
|
|
||||||
export const LINKS = {
|
export const LINKS = {
|
||||||
ROOT: '/',
|
ROOT: '/',
|
||||||
|
@ -82,6 +83,7 @@ export const LINKS = {
|
||||||
ORDER_DETAIL_AIRLINES_WO_ID: '/app/order_detail_airline',
|
ORDER_DETAIL_AIRLINES_WO_ID: '/app/order_detail_airline',
|
||||||
REGISTER: '/register',
|
REGISTER: '/register',
|
||||||
RESEND_EMAIL: '/resend_email',
|
RESEND_EMAIL: '/resend_email',
|
||||||
|
RESEND_OTP: '/resend_otp',
|
||||||
REGISTER_COMPLETED: '/register_completed',
|
REGISTER_COMPLETED: '/register_completed',
|
||||||
CONFIRMATION_COMPLETED: '/confirmation_completed',
|
CONFIRMATION_COMPLETED: '/confirmation_completed',
|
||||||
LOGIN: '/login',
|
LOGIN: '/login',
|
||||||
|
@ -166,6 +168,7 @@ export default class Routes extends React.Component {
|
||||||
}}/>)}/>
|
}}/>)}/>
|
||||||
<Route exact path={LINKS.REGISTER} component={RegisterComponent}/>
|
<Route exact path={LINKS.REGISTER} component={RegisterComponent}/>
|
||||||
<Route exact path={LINKS.RESEND_EMAIL} component={ResendEmail}/>
|
<Route exact path={LINKS.RESEND_EMAIL} component={ResendEmail}/>
|
||||||
|
<Route exact path={LINKS.RESEND_OTP} component={ResendOtp}/>
|
||||||
<Route exact path={LINKS.REGISTER_COMPLETED} component={RegisterCompletedComponent}/>
|
<Route exact path={LINKS.REGISTER_COMPLETED} component={RegisterCompletedComponent}/>
|
||||||
<Route exact path={LINKS.CONFIRMATION_COMPLETED} component={ConfirmationCompletedComponent}/>
|
<Route exact path={LINKS.CONFIRMATION_COMPLETED} component={ConfirmationCompletedComponent}/>
|
||||||
<Route exact path={LINKS.LOGIN} component={LoginBTNComponent}/>
|
<Route exact path={LINKS.LOGIN} component={LoginBTNComponent}/>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user