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 - +
} - +
@@ -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 ? avatar : uploadButtonKtp} + {upload_ktp ? avatar : uploadButtonKtp} @@ -348,7 +380,10 @@ class RegisterPage extends React.Component { showUploadList={false} {...this.createUploadProps("photo")} > - {upload_photo ? avatar : uploadButtonPhoto} + {upload_photo ? avatar : 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" + /> +
-
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}}*/} + {/*/>*/} + + + {/**/}
    ); }; @@ -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 + + + + + + + + + + + + + + + + + + {/**/}
    - {finished ? ( -

    - { - event.preventDefault(); - this.setState({stepIndex: 0, finished: false}); - }} - > - Click here - to reset the example. -

    - ) : ( -
    -

    {this.getStepContent(stepIndex)}

    -
    - )} + {this.getStepContent(stepIndex)}
    @@ -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;