diff --git a/package-lock.json b/package-lock.json
index 2557cee..79d81e7 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4961,6 +4961,11 @@
}
}
},
+ "css-mediaquery": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/css-mediaquery/-/css-mediaquery-0.1.2.tgz",
+ "integrity": "sha1-aiw3NEkoYYYxxUvTPO3TAdoYvqA="
+ },
"css-select": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/css-select/-/css-select-2.0.2.tgz",
@@ -7014,13 +7019,11 @@
},
"balanced-match": {
"version": "1.0.0",
- "bundled": true,
- "optional": true
+ "bundled": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
- "optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -7033,18 +7036,15 @@
},
"code-point-at": {
"version": "1.1.0",
- "bundled": true,
- "optional": true
+ "bundled": true
},
"concat-map": {
"version": "0.0.1",
- "bundled": true,
- "optional": true
+ "bundled": true
},
"console-control-strings": {
"version": "1.1.0",
- "bundled": true,
- "optional": true
+ "bundled": true
},
"core-util-is": {
"version": "1.0.2",
@@ -7147,8 +7147,7 @@
},
"inherits": {
"version": "2.0.3",
- "bundled": true,
- "optional": true
+ "bundled": true
},
"ini": {
"version": "1.3.5",
@@ -7158,7 +7157,6 @@
"is-fullwidth-code-point": {
"version": "1.0.0",
"bundled": true,
- "optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@@ -7171,20 +7169,17 @@
"minimatch": {
"version": "3.0.4",
"bundled": true,
- "optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
},
"minimist": {
"version": "0.0.8",
- "bundled": true,
- "optional": true
+ "bundled": true
},
"minipass": {
"version": "2.3.5",
"bundled": true,
- "optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@@ -7201,7 +7196,6 @@
"mkdirp": {
"version": "0.5.1",
"bundled": true,
- "optional": true,
"requires": {
"minimist": "0.0.8"
}
@@ -7274,8 +7268,7 @@
},
"number-is-nan": {
"version": "1.0.1",
- "bundled": true,
- "optional": true
+ "bundled": true
},
"object-assign": {
"version": "4.1.1",
@@ -7285,7 +7278,6 @@
"once": {
"version": "1.4.0",
"bundled": true,
- "optional": true,
"requires": {
"wrappy": "1"
}
@@ -7391,7 +7383,6 @@
"string-width": {
"version": "1.0.2",
"bundled": true,
- "optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@@ -10740,6 +10731,14 @@
"resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.2.tgz",
"integrity": "sha512-lbRZ2mE3Q9RtLjxZBZ9+IMl68DKIXaVAhwvwn9pmjnPLS0h/6kyBMgNhqi1xFJ/2yv6cSyv0jbiZavZv93JkkA=="
},
+ "matchmediaquery": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/matchmediaquery/-/matchmediaquery-0.3.0.tgz",
+ "integrity": "sha512-u0dlv+VENJ+3YepvwSPBieuvnA6DWfaYa/ctwysAR13y4XLJNyt7bEVKzNj/Nvjo+50d88Pj+xL9xaSo6JmX/w==",
+ "requires": {
+ "css-mediaquery": "^0.1.2"
+ }
+ },
"material-colors": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/material-colors/-/material-colors-1.2.6.tgz",
@@ -14837,6 +14836,60 @@
}
}
},
+ "react-html-parser": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/react-html-parser/-/react-html-parser-2.0.2.tgz",
+ "integrity": "sha512-XeerLwCVjTs3njZcgCOeDUqLgNIt/t+6Jgi5/qPsO/krUWl76kWKXMeVs2LhY2gwM6X378DkhLjur0zUQdpz0g==",
+ "requires": {
+ "htmlparser2": "^3.9.0"
+ },
+ "dependencies": {
+ "domelementtype": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
+ "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w=="
+ },
+ "domhandler": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
+ "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==",
+ "requires": {
+ "domelementtype": "1"
+ }
+ },
+ "htmlparser2": {
+ "version": "3.10.0",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.0.tgz",
+ "integrity": "sha512-J1nEUGv+MkXS0weHNWVKJJ+UrLfePxRWpN3C9bEi9fLxL2+ggW94DQvgYVXsaT30PGwYRIZKNZXuyMhp3Di4bQ==",
+ "requires": {
+ "domelementtype": "^1.3.0",
+ "domhandler": "^2.3.0",
+ "domutils": "^1.5.1",
+ "entities": "^1.1.1",
+ "inherits": "^2.0.1",
+ "readable-stream": "^3.0.6"
+ }
+ },
+ "readable-stream": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.1.1.tgz",
+ "integrity": "sha512-DkN66hPyqDhnIQ6Jcsvx9bFjhw214O4poMBcIMgPVpQvNy9a0e0Uhg5SqySyDKAmUlwt8LonTBz1ezOnM8pUdA==",
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ },
+ "string_decoder": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz",
+ "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==",
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
"react-images": {
"version": "0.5.19",
"resolved": "https://registry.npmjs.org/react-images/-/react-images-0.5.19.tgz",
@@ -15119,6 +15172,16 @@
"resize-observer-polyfill": "^1.5.0"
}
},
+ "react-responsive": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/react-responsive/-/react-responsive-6.1.1.tgz",
+ "integrity": "sha512-Po6pOEz70Agp+2lUmTxAnhfdkk0zp0IFgo/6bGcxv/S4Pa1sz0YG06WzkrIcASbyKSQ8x6AkcggeozXW3zj3kA==",
+ "requires": {
+ "hyphenate-style-name": "^1.0.0",
+ "matchmediaquery": "^0.3.0",
+ "prop-types": "^15.6.1"
+ }
+ },
"react-responsive-carousel": {
"version": "3.1.46",
"resolved": "https://registry.npmjs.org/react-responsive-carousel/-/react-responsive-carousel-3.1.46.tgz",
diff --git a/package.json b/package.json
index 97c107f..8590e64 100644
--- a/package.json
+++ b/package.json
@@ -17,7 +17,9 @@
"dev:parcel": "node scripts/dev-parcel.js",
"deploy": "rsync -chavzP -e \"ssh -p 2222\" --stats dist/ root@209.58.165.19:/home/apps/giift/giift-customer-btn",
"deploy:giift": "rsync -chavzP -e \"ssh -p 2222\" --stats dist/ root@209.58.165.19:/home/apps/giift/giift-customer",
- "dev2:parcel": "node scripts/link-assets.js; parcel public/index.parcel.html --out-file index.html --global $"
+ "dev2:parcel": "node scripts/link-assets.js; parcel public/index.parcel.html --out-file index.html --global $",
+ "build2:parcel:prod": "node scripts/link-assets.js; parcel build public/index.parcel.html --out-file index.html --detailed-report --no-source-maps",
+ "build:deploy": "npm run build:parcel:prod && npm run deploy"
},
"author": "Asacreative",
"repository": {
@@ -112,6 +114,7 @@
"react-handsontable": "^0.3.1",
"react-helmet": "^5.2.0",
"react-hot-loader": "^4.6.3",
+ "react-html-parser": "^2.0.2",
"react-images": "^0.5.13",
"react-infinite-scroller": "^1.2.4",
"react-intl": "^2.8.0",
@@ -123,6 +126,7 @@
"react-native-vector-icons": "^5.0.0",
"react-number-format": "^3.0.3",
"react-prop-types": "^0.4.0",
+ "react-responsive": "^6.1.1",
"react-responsive-carousel": "^3.1.46",
"react-router": "^4.2.0",
"react-router-dom": "^4.2.2",
diff --git a/src/common/pages/App/index.js b/src/common/pages/App/index.js
index 1b32474..a3bd293 100644
--- a/src/common/pages/App/index.js
+++ b/src/common/pages/App/index.js
@@ -480,7 +480,7 @@ class App extends React.Component {
.bind(this, '/app/dashboard')} to={LINKS.DASHBOARD}>Home
- Vouchers
+ className="menuAkun">Vouchers */}
@@ -865,9 +865,9 @@ class App extends React.Component {
style={{ padding: '0px 16px 0px', fontSize: 14 }}
disabled={true}
primaryText={{this.authStore.userProfile.username || 'Username'} }
+ style={{ fontWeight: 500 }}>{this.props.appstate.userData.email|| 'Username'}}
secondaryText={
{_.capitalize(this.authStore.userProfile.role) || 'role'}
}
+ style={{ fontWeight: 400 }}>{_.capitalize(this.props.appstate.userData.role) || 'role'}}
/>
diff --git a/src/common/pages/Login/LoginBtn.js b/src/common/pages/Login/LoginBtn.js
index 99a09eb..6f55470 100644
--- a/src/common/pages/Login/LoginBtn.js
+++ b/src/common/pages/Login/LoginBtn.js
@@ -1,6 +1,7 @@
import React from 'react';
import withStyles from "@material-ui/core/styles/withStyles";
import {styles} from '../Register/registerStyle';
+import {notification} from 'antd';
import Grid from '@material-ui/core/Grid';
import Paper from '@material-ui/core/Paper';
@@ -43,7 +44,43 @@ class BTNLoginPage extends React.Component{
this.authStore = props.appstate.auth;
}
- handleChange = name => event => {
+ componentDidMount() {
+ const urlParams = new URLSearchParams(window.location.search);
+
+ if(urlParams.has('key')) {
+ this.setState({
+ isLoading: true
+ });
+
+ this.authStore.verifyEmail(urlParams.get('key')).then((res) => {
+ if(res.login_request_id) {
+ notification.open({
+ message: 'Email Verification',
+ description: 'Email verification success'
+ });
+ this.setState({
+ isLoading: false
+ });
+ this.props.history.push({
+ pathname:LINKS.OTP,
+ search:'?login_request_id='+res.login_request_id+'&expired_at='+res.expired_at
+ });
+ //redirect to otp page
+ } else {
+ notification.open({
+ message: 'Email Verification',
+ description: res.message
+ });
+ this.setState({
+ isLoading: false
+ });
+ // res.message
+ }
+ })
+ }
+ }
+
+ handleChange = name => event => {
this.setState({
[name]: event.target.value,
});
@@ -74,6 +111,16 @@ class BTNLoginPage extends React.Component{
else if(res.state == "email_verification"){
this.setState({isNeedEmailVerification:true,isLoading:false});
}
+ else if(res.state == "phone_verification"){
+ this.authStore.otpData = res;
+ setTimeout(()=>{
+ this.props.history.push({
+ pathname:LINKS.OTP,
+ search:'?login_request_id='+res.login_request_id+'&expired_at='+res.expired_at
+ });
+ this.setState({isLoading:false});
+ },1000);
+ }
}).catch(err => {
console.log("err login",err);
this.setState({loginFailed:true,isLoading:false});
@@ -131,15 +178,15 @@ class BTNLoginPage extends React.Component{
{
- this.state.isNeedEmailVerification &&
+ this.state.isNeedEmailVerification &&
Your account still need email verification
- Still not received any email? Resend email
+ Still not received any email? this.authStore.resendEmail(this.state.email)}>Resend email
-
+
this.setState({isNeedEmailVerification : false})} fullWidth variant="contained" style={{background:'#ffeb3b'}}>
Back to Login
@@ -149,7 +196,7 @@ class BTNLoginPage extends React.Component{
}
{
- !this.state.isNeedEmailVerification &&
+ !this.state.isNeedEmailVerification &&
Login to BTN Point
@@ -195,7 +242,7 @@ class BTNLoginPage extends React.Component{
}
-
+
@@ -205,4 +252,4 @@ class BTNLoginPage extends React.Component{
}
}
-export default withStyles(styles)(BTNLoginPage);
\ No newline at end of file
+export default withStyles(styles)(BTNLoginPage);
diff --git a/src/common/pages/Otp/index.js b/src/common/pages/Otp/index.js
index 9329a15..0da308b 100644
--- a/src/common/pages/Otp/index.js
+++ b/src/common/pages/Otp/index.js
@@ -19,9 +19,9 @@ 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 Text from 'material-ui/TextField';
+import moment from 'moment';
import { Link } from 'react-router-dom';
import {inject, observer} from 'mobx-react';
import {LINKS} from "../../routes";
@@ -30,6 +30,8 @@ import {LINKS} from "../../routes";
@observer
class OtpPage extends React.Component{
otp = [];
+ urlParams = new URLSearchParams(window.location.search);
+
constructor(props) {
super(props);
this.props = props;
@@ -42,7 +44,10 @@ class OtpPage extends React.Component{
isNeedEmailVerification: false,
otp: [],
otpText : "",
- isResending: false
+ otpData : {},
+ isResending: false,
+ isOtpExpired : false,
+ isOtpWrong: false,
};
this.defaultState = Object.assign({}, this.state);
this.authStore = props.appstate.auth;
@@ -50,7 +55,27 @@ class OtpPage extends React.Component{
componentDidMount(){
this.otp[0].focus();
- console.log("otp",this.otp);
+ if(this.urlParams.has('login_request_id') && this.urlParams.has('expired_at')) {
+ console.log(this.urlParams);
+ this.setState({
+ otpData:{
+ login_request_id : this.urlParams.get('login_request_id'),
+ expired_at : this.urlParams.get('expired_at')
+ }
+ });
+ }
+ else{
+ this.setState({otpData:this.authStore.otpData});
+ }
+ }
+
+ checkIsExpired(){
+ console.log(Date.parse(Date().toISOString()),this.state.otpData.expired_at);
+ if(Date.parse(Date().toISOString()) < Date.parse(this.state.otpData.expired_at)){
+ return false;
+ }else{
+ return true
+ }
}
handleChange = name => event => {
@@ -67,31 +92,58 @@ class OtpPage extends React.Component{
}
login = () => {
- console.log("otpText",this.state.otpText);
+ let data = {
+ code : this.state.otpText,
+ login_request_id : this.state.otpData.login_request_id
+ }
+ console.log("data",data);
this.setState({isLoading:true});
- setTimeout(()=>{
- this.setState({isLoading:false});
- },1000);
- // this.authStore.login(data).then(res => {
- // if(!res.need_email_verification){
- // setTimeout(()=>{
- // this.props.history.push(LINKS.DASHBOARD);
- // this.setState({isLoading:false});
- // },1000);
- // }
- // else{
- // this.setState({isNeedEmailVerification:true});
- // }
- // }).catch(err => {
- // this.setState({loginFailed:true,isLoading:false});
- // setTimeout(()=>this.setState({loginFailed:false}),3000);
- // });
- };
+ // if(this.checkIsExpired){
+ // this.setState({isOtpExpired:true});
+ // setTimeout(()=>{
+ // this.setState({isOtpExpired:false});
+ // },2000);
+ // }
+ // else{
+ this.authStore.validateOtp(data).then(res=>{
+ setTimeout(()=>{
+ this.props.history.push(LINKS.DASHBOARD);
+ this.setState({isLoading:false});
+ },1000);
+ }).catch(err=>{
+ setTimeout(()=>{
+ this.setState({isLoading:false,isOtpWrong:true});
+ },2000);
+ setTimeout(()=>{
+ this.setState({isOtpWrong:false});
+ },4000)
+ });
+ // }
+
+ };
render(){
const { classes } = this.props;
return (
+
this.setState({isOtpWrong:false})}
+ ContentProps={{
+ 'aria-describedby': 'message-id',
+ }}
+ message={Wrong OTP code }
+ />
+ this.setState({isOtpExpired:false})}
+ ContentProps={{
+ 'aria-describedby': 'message-id',
+ }}
+ message={Your OTP code has expired }
+ />
{[0, 1, 2, 3, 4, 5].map(x => (
- this.setState({otpText:this.state.otpText+event.target.value})} autoFocus={true} ref={(input) => { this.otp[x] = input; }} key={x} id={x} inputStyle={{textAlign:'center'}} style={{width:'100%'}} type="tel" maxlength="1"/>
+ this.setState({otpText:this.state.otpText+event.target.value})} autoFocus={true} ref={(input) => { this.otp[x] = input; }} key={x} id={x} inputStyle={{textAlign:'center'}} style={{width:'100%'}} type="tel" maxLength="1"/>
))}
@@ -148,4 +200,4 @@ class OtpPage extends React.Component{
}
}
-export default withStyles(styles)(OtpPage);
\ No newline at end of file
+export default withStyles(styles)(OtpPage);
diff --git a/src/common/pages/Register/index.js b/src/common/pages/Register/index.js
index a594576..e7af026 100644
--- a/src/common/pages/Register/index.js
+++ b/src/common/pages/Register/index.js
@@ -9,7 +9,7 @@ import {
message,
Button,
Spin,
- Icon
+ Icon, notification
} from 'antd';
import css from 'reactcss';
import RegisterForm from './Form';
@@ -68,8 +68,15 @@ export default class ComponentName extends React.Component {
.authStore
.register(value)
.then(res => {
- message.success(res.message);
+ notification.open({
+ message: 'Register Success',
+ description: 'Please check your email to continue'
+ });
+ this.props.history.push({
+ pathname:LINKS.LOGIN
+ });
this.setState({isLoading: false, isSuccess: true})
+ // this
})
.catch(err => {
if (err && err.errors && err.errors[0] && err.errors[0].message) {
diff --git a/src/common/pages/Register/registerStyle.js b/src/common/pages/Register/registerStyle.js
index 24f9058..ba9b023 100644
--- a/src/common/pages/Register/registerStyle.js
+++ b/src/common/pages/Register/registerStyle.js
@@ -33,4 +33,4 @@ export const styles = theme => ({
background : yellow['500'],
padding : 20
}
-});
\ No newline at end of file
+});
diff --git a/src/common/pages/RegisterNew/index.js b/src/common/pages/RegisterNew/index.js
index 9cd62c4..88e3aaf 100644
--- a/src/common/pages/RegisterNew/index.js
+++ b/src/common/pages/RegisterNew/index.js
@@ -22,6 +22,7 @@ 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");
@@ -40,6 +41,8 @@ class RegisterPage extends React.Component {
fileList_ktp: [],
fileList_photo: [],
+ query: {},
+
// form
confirmPassword: "",
phone_number: "",
@@ -65,6 +68,18 @@ class RegisterPage extends React.Component {
}
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();
}
@@ -114,6 +129,15 @@ class RegisterPage extends React.Component {
};
register = () => {
+
+ if (this.state.upload_photo === '') {
+ return message.warning("please upload photo");
+ }
+
+ if (this.state.upload_ktp === '') {
+ return message.warning("please upload ktp");
+ }
+
this.setState({ isLoading: true });
let data = {
fullname: this.state.full_name,
@@ -129,12 +153,15 @@ class RegisterPage extends React.Component {
district_id: this.state.district,
subdistrict_id: this.state.subdistrict,
zip_code: this.state.zip_code,
+ referal: this.state.query.referal,
additional_data: {}
};
this.authStore.register(data).then(res => {
+ message.success("Please check your email to confirm your account");
setTimeout(() => {
this.setState({ isLoading: false });
- }, 1000);
+ this.props.history.push(LINKS.LOGIN);
+ }, 250);
}).catch(err => {
this.setState({ isLoading: false });
@@ -194,7 +221,7 @@ class RegisterPage extends React.Component {
return this.http.upload(file)
.then(res => {
this.setState({
- [`upload_${key}`]: res.path
+ [`upload_${key}`]: appConfig.apiUrl + res.path.slice(1,res.path.length)
});
return res;
})
@@ -253,7 +280,9 @@ class RegisterPage extends React.Component {
-
+
@@ -336,7 +365,10 @@ class RegisterPage extends React.Component {
showUploadList={false}
{...this.createUploadProps("ktp")}
>
- {upload_ktp ? : uploadButtonKtp}
+ {upload_ktp ? : uploadButtonKtp}
@@ -348,7 +380,10 @@ class RegisterPage extends React.Component {
showUploadList={false}
{...this.createUploadProps("photo")}
>
- {upload_photo ? : uploadButtonPhoto}
+ {upload_photo ? : uploadButtonPhoto}
@@ -476,9 +511,29 @@ class RegisterPage extends React.Component {
+
+ {
+ this.setState({
+ query: {
+ ...this.state.query,
+ referal: event.target.value
+ }
+ })
+ }}
+ margin="normal"
+ type={"text"}
+ fullWidth
+ variant="outlined"
+ />
+
-
+
{this.state.isLoading ? : "Sign Up"}
diff --git a/src/common/pages/RegisterNew/styles.js b/src/common/pages/RegisterNew/styles.js
index 88b6b1d..7f6ce1b 100644
--- a/src/common/pages/RegisterNew/styles.js
+++ b/src/common/pages/RegisterNew/styles.js
@@ -10,7 +10,8 @@ export const styles = theme => ({
},
gridContainer : {
flex :1,
- justifyContent:'center'
+ justifyContent: 'center',
+ flexDirection: 'column'
},
registerContainer: {
marginTop : 50
@@ -34,4 +35,4 @@ export const styles = theme => ({
background : yellow['500'],
padding : 20
},
-});
\ No newline at end of file
+});
diff --git a/src/common/pages/Vouchers/Checkout/index.js b/src/common/pages/Vouchers/Checkout/index.js
index f0f1ac9..0a23dd7 100644
--- a/src/common/pages/Vouchers/Checkout/index.js
+++ b/src/common/pages/Vouchers/Checkout/index.js
@@ -1,24 +1,28 @@
import React from 'react';
import {inject, observer} from 'mobx-react';
import {
- FlatButton,
Divider
-} from 'material-ui';
+} from '@material-ui/core';
import { Affix, Card, Slider, Select, Row, Col, Icon, Tag,Rate, Button, Checkbox , DatePicker, Alert, Input ,Avatar} from 'antd';
import {startCase} from 'lodash';
-import LoadingDialog from "../../LoadingDialog";
-import Loader from 'react-loader-advanced';
import './style.scss';
-import {DIALOG} from "../../../stores/global_ui";
-import EmptyComponent from '../../EmptyComponent';
-import NavigationArrowBack from 'material-ui/svg-icons/navigation/arrow-back';
-import {LINKS} from "../../../routes";
-import {Route} from "react-router-dom";
+import { withStyles } from '@material-ui/core/styles';
import get from 'lodash.get';
+import MediaQuery from 'react-responsive';
+
+const styles = theme => ({
+ button: {
+ margin: theme.spacing.unit,
+ },
+ divider: {
+ marginBottom: 10,
+ marginTop: 10,
+ }
+});
@inject('appstate')
@observer
-export default class CheckoutVouchers extends React.Component {
+export class CheckoutVouchers extends React.Component {
constructor(props) {
super(props);
this.props = props;
@@ -41,7 +45,7 @@ export default class CheckoutVouchers extends React.Component {
}
render() {
-
+ const {classes} = this.props;
const logoUrl = (this.props.vouchersStore.dataItems.images.logo) ? get(this.vouchersStore.dataItems, 'images.logo', '') : 'http://lorempixel.com/400/200';
let image = logoUrl;
@@ -51,8 +55,8 @@ export default class CheckoutVouchers extends React.Component {
}
return (
-
-
+
+
@@ -61,7 +65,7 @@ export default class CheckoutVouchers extends React.Component {
-
+
@@ -70,26 +74,30 @@ export default class CheckoutVouchers extends React.Component {
-
+
-
+
Jenis Layanan
-
-
:
-
-
+
+
+
:
+
+
+
{this.props.vouchersStore.dataItems.name} - {this.props.vouchersStore.skuName}
-
+
Point
-
-
:
-
-
+
+
+
:
+
+
+
{(+this.props.vouchersStore.skuPrice || 0).toFixed(0)} Points
@@ -98,15 +106,15 @@ export default class CheckoutVouchers extends React.Component {
-
-
+
+
Point
{this.props.appstate.wallet.data.point || 0} Points
-
+
Total Pembayaran Point
@@ -122,3 +130,5 @@ export default class CheckoutVouchers extends React.Component {
)
}
}
+
+export default withStyles(styles)(CheckoutVouchers);
diff --git a/src/common/pages/Vouchers/Checkout/style.scss b/src/common/pages/Vouchers/Checkout/style.scss
index e928943..477240c 100644
--- a/src/common/pages/Vouchers/Checkout/style.scss
+++ b/src/common/pages/Vouchers/Checkout/style.scss
@@ -1,4 +1,53 @@
-.imageCard{
- max-width: 20vw;
- max-height: 20vw;
+@media(min-width: 1000px){
+ .imageCard{
+ width: 20vw;
+ height: 25vh;
+ }
+
+ .upper-card{
+ width: 60vw;
+ margin-left: -1vw;
+ margin-bottom: 15px;
+ }
+
+ .bottom-card{
+ width: 60vw;
+ margin-left: -1vw;
+ }
+
+ .right-container{
+ //background-color: red;
+ height: 25vh;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ //align-items: center;
+ }
+}
+
+@media(max-width: 999px){
+ .imageCard{
+ width: 80vw;
+ height: 25vh;
+ margin-bottom: 30px;
+ }
+
+ .upper-card{
+ width: 90vw;
+ margin-left: -3.5vw;
+ margin-bottom: 15px;
+ }
+
+ .bottom-card{
+ width: 90vw;
+ margin-left: -3.5vw;
+ }
+
+ .right-container{
+ margin-left: -2.5vw;
+ }
+}
+
+.checkout-parent{
+ //width: 100%;
}
diff --git a/src/common/pages/Vouchers/Modal/index.js b/src/common/pages/Vouchers/Modal/index.js
index f8b43a8..36d4d56 100644
--- a/src/common/pages/Vouchers/Modal/index.js
+++ b/src/common/pages/Vouchers/Modal/index.js
@@ -7,6 +7,7 @@ import { Route } from 'react-router-dom'
import {LINKS} from "../../../routes";
import NumberFormat from 'react-number-format';
import get from 'lodash.get';
+import ReactHtmlParser from "react-html-parser";
const Option = Select.Option;
@@ -83,7 +84,7 @@ export default class ModalVouchersComponent extends React.Component {
flex: 0.7,
padding: 30
}}>
-
{data.description}
+
{ReactHtmlParser(data.description)}
{(additional_data.information != null) &&
diff --git a/src/common/pages/Vouchers/Payment/index.js b/src/common/pages/Vouchers/Payment/index.js
index ebf93cf..0199c49 100644
--- a/src/common/pages/Vouchers/Payment/index.js
+++ b/src/common/pages/Vouchers/Payment/index.js
@@ -8,12 +8,14 @@ import { Affix, Card, Slider, Select, Row, Col, Icon, Tag,Rate, Button, Checkbox
import {startCase} from 'lodash';
import LoadingDialog from "../../LoadingDialog";
import Loader from 'react-loader-advanced';
-// import './style.scss';
+import './style.scss';
import {DIALOG} from "../../../stores/global_ui";
import EmptyComponent from '../../EmptyComponent';
import NavigationArrowBack from 'material-ui/svg-icons/navigation/arrow-back';
import {LINKS} from "../../../routes";
import {APP_TYPE} from "../../../config/app";
+import get from "lodash.get";
+import ReactHtmlParser, { processNodes, convertNodeToElement, htmlparser2 } from 'react-html-parser';
const Panel = Collapse.Panel;
@@ -34,7 +36,7 @@ export default class PaymentVouchers extends React.Component {
}
componentDidMount() {
-
+ console.log(this.props.vouchersStore, 'this.props.vouchersStore this.props.vouchersStore this.props.vouchersStore')
}
render() {
@@ -51,16 +53,23 @@ export default class PaymentVouchers extends React.Component {
const qty = 1;
const total = price * qty;
- let applicationName = 'Giift';
- let applicationLogo = 'http://giift.asacreative.com/giift_logo_wide.4d15de72.png';
- if(APP_TYPE === 'btn') {
- applicationName = 'BTN';
- applicationLogo = 'http://btn-redemption-2.bangun-kreatif.com/dr6u0fppdi4xy.cloudfront.net/FilesDirectory/Albilad/ImgIconImage/logo-btn.png';
+ // let applicationName = 'Giift';
+ // let applicationLogo = 'http://giift.asacreative.com/giift_logo_wide.4d15de72.png';
+ // if(APP_TYPE === 'btn') {
+ // applicationName = 'BTN';
+ // applicationLogo = 'http://btn-redemption-2.bangun-kreatif.com/dr6u0fppdi4xy.cloudfront.net/FilesDirectory/Albilad/ImgIconImage/logo-btn.png';
+ // }
+ const logoUrl = (this.props.vouchersStore.dataItems.images.logo) ? get(this.vouchersStore.dataItems, 'images.logo', '') : 'http://lorempixel.com/400/200';
+
+ let image = logoUrl;
+
+ if (!image.includes('http')) {
+ image = this.http.appendImagePath(image);
}
return(
-
+
@@ -94,25 +103,27 @@ export default class PaymentVouchers extends React.Component {
-
-
-
-
- Points {applicationName}
+
+
+
+
+ {this.props.vouchersStore.dataItems.name} - {this.props.vouchersStore.skuName}
+
+
+ BTN Points Payment
-
-
-
+
}>
-
- Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.
- Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.
-
+
+ {ReactHtmlParser(this.props.vouchersStore.dataItems.description)}
+ {/*
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. */}
+ {/*Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. */}
+
diff --git a/src/common/pages/Vouchers/Payment/style.scss b/src/common/pages/Vouchers/Payment/style.scss
new file mode 100644
index 0000000..a94c708
--- /dev/null
+++ b/src/common/pages/Vouchers/Payment/style.scss
@@ -0,0 +1,50 @@
+.upper-card{
+
+}
+
+.bottom-card{
+
+}
+
+@media(min-width: 1000px){
+ .image-logo{
+ width: 10vw;
+ height: 10vh;
+ }
+
+ .item-container{
+ height: 10vh;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ .item-name{
+ padding-top: 1vh;
+ margin-bottom: -0.25vh;
+ font-size: 1.35em;
+ }
+
+ .item-points{
+ font-size: 0.95em;
+ color: #aaa;
+ }
+ }
+}
+
+@media(max-width: 999px){
+ .image-logo{
+ width: 25vw;
+ height: 10vh;
+ }
+
+ .item-container{
+ .item-name{
+ font-size: 1.15em;
+ margin-bottom: -0.25vh;
+ }
+
+ .item-points{
+ font-size: 0.75em;
+ color: #aaa;
+ }
+ }
+}
diff --git a/src/common/pages/Vouchers/Stepper/index.js b/src/common/pages/Vouchers/Stepper/index.js
index db027d9..990bf94 100644
--- a/src/common/pages/Vouchers/Stepper/index.js
+++ b/src/common/pages/Vouchers/Stepper/index.js
@@ -1,26 +1,41 @@
import {inject, observer} from "mobx-react";
+import PropTypes from 'prop-types';
import React from "react";
import './style.scss';
-import {
- Step,
- Stepper,
- StepLabel,
-} from 'material-ui/Stepper';
+import Button from '@material-ui/core/Button';
import RaisedButton from 'material-ui/RaisedButton';
import FlatButton from 'material-ui/FlatButton';
import NavigationArrowBack from 'material-ui/svg-icons/navigation/arrow-back';
-import {Divider} from "material-ui";
+import {Divider} from "@material-ui/core";
import CheckoutVouchers from "../Checkout";
import PaymentVouchers from "../Payment";
import {LINKS} from "../../../routes";
import {notification, Modal} from "antd";
import FinishVouchers from "../Finish";
+import { withStyles } from '@material-ui/core/styles';
+import Stepper from '@material-ui/core/Stepper';
+import Step from '@material-ui/core/Step';
+import StepLabel from '@material-ui/core/StepLabel';
+import MediaQuery from 'react-responsive';
const confirm = Modal.confirm;
+const styles = theme => ({
+ button: {
+ margin: theme.spacing.unit,
+ },
+ input: {
+ display: 'none',
+ },
+ divider: {
+ marginBottom: 10,
+ marginTop: 10,
+ }
+});
+
@inject('appstate')
@observer
-export default class VoucherStepperComponent extends React.Component {
+export class VoucherStepper extends React.Component {
constructor(props) {
super(props);
@@ -38,7 +53,7 @@ export default class VoucherStepperComponent extends React.Component {
componentWillMount() {
if(!this.vouchersStore.dataItems.name){
// alert('jalan')
- this.props.history.push(LINKS.VOUCHERS);
+ this.props.history.push(LINKS.DASHBOARD);
}
// alert('engga')
}
@@ -51,6 +66,7 @@ export default class VoucherStepperComponent extends React.Component {
title: 'Anda yakin mau menukarkan voucher?',
content: 'Sistem akan langsung memotong point anda ketika anda menekan tombol konfirmasi dibawah.',
onOk: () => {
+ this.globalUI.showDialogLoading();
this.vouchersStore.buyVoucher(this.vouchersStore.skuId)
.then(res => {
const openNotificationWithIcon = (type) => {
@@ -94,19 +110,24 @@ export default class VoucherStepperComponent extends React.Component {
};
renderButton = () => {
+ const {classes} = this.props;
return(
- this.props.history.goBack() : this.handlePrev}
- style={{marginRight: 12}}
- />
-
+ {/* this.props.history.goBack() : this.handlePrev}*/}
+ {/*style={{marginRight: 12}}*/}
+ {/*/>*/}
+ this.props.history.goBack() : this.handlePrev} className={classes.button}>Back
+
+ {this.state.stepIndex === 2 ? 'Finish' : 'Next'}
+
+ {/* */}
);
};
@@ -126,6 +147,7 @@ export default class VoucherStepperComponent extends React.Component {
render() {
const {finished, stepIndex} = this.state;
+ const {classes} = this.props;
const contentStyle = {margin: '0 16px'};
if(!this.vouchersStore.dataItems.name){
@@ -147,36 +169,36 @@ export default class VoucherStepperComponent extends React.Component {
{/* */}
{/* */}
-
-
- Checkout your Voucher
-
-
- Process your Payment
-
-
- Finish
-
-
-
+
+
+
+ Checkout your Voucher
+
+
+ Process your Payment
+
+
+ Finish
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/*
*/}
@@ -184,3 +206,9 @@ export default class VoucherStepperComponent extends React.Component {
}
}
+
+VoucherStepper.propTypes = {
+ classes: PropTypes.object.isRequired,
+};
+
+export default withStyles(styles)(VoucherStepper);
diff --git a/src/common/pages/Vouchers/Stepper/style.scss b/src/common/pages/Vouchers/Stepper/style.scss
index f4639bd..7729811 100644
--- a/src/common/pages/Vouchers/Stepper/style.scss
+++ b/src/common/pages/Vouchers/Stepper/style.scss
@@ -1,9 +1,23 @@
.stepper{
margin-top: 5vh;
- .divider-container{
- max-width: 65vw;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ //background-color: #fff;
+ @media(min-width: 1000px){
+ .divider-container{
+ width: 60vw;
+ }
+ .stepper-container{
+ width: 60vw;
+ }
}
- .stepper-container{
- max-width: 65vw;
+ @media(max-width: 999px){
+ .divider-container{
+ width: 90vw;
+ }
+ .stepper-container{
+ width: 90vw;
+ }
}
}
diff --git a/src/common/pages/Wallet/index.js b/src/common/pages/Wallet/index.js
index 1b9b1a1..d3c3b42 100644
--- a/src/common/pages/Wallet/index.js
+++ b/src/common/pages/Wallet/index.js
@@ -53,6 +53,7 @@ export default class WalletComponent extends React.Component {
}
componentDidMount() {
+ this.props.appstate.transaction.getAll();
this.purchasedItemStore.getAll().then(res => {
console.log(res, 'ini purchased items')
})
@@ -74,38 +75,39 @@ export default class WalletComponent extends React.Component {
const voucher =
;
const points =
;
- const data = [
- {
- id: faker.random.uuid(),
- created_at: faker.date.past(),
- type: 'Points',
- amount: faker.commerce.price()
- },
- {
- id: faker.random.uuid(),
- created_at: faker.date.past(),
- type: 'Points',
- amount: faker.commerce.price()
- },
- {
- id: faker.random.uuid(),
- created_at: faker.date.past(),
- type: 'Voucher',
- amount: faker.commerce.price()
- },
- {
- id: faker.random.uuid(),
- created_at: faker.date.past(),
- type: 'Voucher',
- amount: faker.commerce.price()
- },
- {
- id: faker.random.uuid(),
- created_at: faker.date.past(),
- type: 'Points',
- amount: faker.commerce.price()
- },
- ];
+ // const data = [
+ // {
+ // id: faker.random.uuid(),
+ // created_at: faker.date.past(),
+ // type: 'Points',
+ // amount: faker.commerce.price()
+ // },
+ // {
+ // id: faker.random.uuid(),
+ // created_at: faker.date.past(),
+ // type: 'Points',
+ // amount: faker.commerce.price()
+ // },
+ // {
+ // id: faker.random.uuid(),
+ // created_at: faker.date.past(),
+ // type: 'Voucher',
+ // amount: faker.commerce.price()
+ // },
+ // {
+ // id: faker.random.uuid(),
+ // created_at: faker.date.past(),
+ // type: 'Voucher',
+ // amount: faker.commerce.price()
+ // },
+ // {
+ // id: faker.random.uuid(),
+ // created_at: faker.date.past(),
+ // type: 'Points',
+ // amount: faker.commerce.price()
+ // },
+ // ];
+ const data = this.props.appstate.transaction.list;
const columns = [{
title: 'Id',
diff --git a/src/common/stores/authenticaton.js b/src/common/stores/authenticaton.js
index d4ba8d7..2e20726 100644
--- a/src/common/stores/authenticaton.js
+++ b/src/common/stores/authenticaton.js
@@ -9,7 +9,7 @@ export class Authentication {
@observable isLoggingIn = false;
@observable isInviting = false;
@observable removingUser = false;
- @observable isNeedEmailVerification = false;
+ // @observable isNeedEmailVerification = false;
@observable userWallet = {};
@observable userProfile = {
email : '',
@@ -37,6 +37,7 @@ export class Authentication {
// airline_settings: []
// }
};
+ @observable otpData = {}
constructor(context) {
this.context = context;
@@ -51,9 +52,10 @@ export class Authentication {
return this.http.post("authentication/login", data)
.then(res => {
this.isLoggingIn = false;
- this.isNeedEmailVerification = res.need_email_verification;
- this.context.setToken(res.token);
- this.context.loadDataAfterLogin();
+ if(res.token) {
+ this.context.setToken(res.token);
+ this.context.loadDataAfterLogin();
+ }
return res;
})
.catch(err => {
@@ -73,6 +75,13 @@ export class Authentication {
})
}
+ @action
+ verifyEmail(key) {
+ return this.http.post('authentication/email_verification', {
+ key
+ })
+ }
+
@action
logout() {
this.context.setToken("");
@@ -117,6 +126,31 @@ export class Authentication {
})
}
+ @action
+ resendEmail(data) {
+ this.isRegistering = true;
+ return this.http.post("authentication/resend_email_verification", data)
+ .then(res => {
+ return res;
+ })
+ .catch(err => {
+ throw err;
+ })
+ }
+
+ @action
+ validateOtp(data) {
+ return this.http.post("authentication/validate_otp", data)
+ .then(res => {
+ this.context.setToken(res.token);
+ this.context.loadDataAfterLogin();
+ return res;
+ })
+ .catch(err => {
+ throw err;
+ })
+ }
+
createCookie(name,value,days) {
let expires
if (days) {
diff --git a/src/common/stores/transaction.js b/src/common/stores/transaction.js
index c943449..8cea6ab 100644
--- a/src/common/stores/transaction.js
+++ b/src/common/stores/transaction.js
@@ -98,7 +98,7 @@ export default class Transaction {
};
}
- // @action
+ // @action
// getAll() {
// this.isLoading = true;
// return this.http.get("transaction")
@@ -111,7 +111,7 @@ export default class Transaction {
@action
getAll() {
this.isLoading = true;
- return this.http.get("transaction")
+ return this.http.get("transactions")
.then(res => {
this.list = res;
this.isLoading = false;