Skip to content

Instantly share code, notes, and snippets.

@aversan
Created November 20, 2019 16:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aversan/a401dc906577c2cb5aac76ca19dde6f4 to your computer and use it in GitHub Desktop.
Save aversan/a401dc906577c2cb5aac76ca19dde6f4 to your computer and use it in GitHub Desktop.
// @flow
import React, { Component, Fragment } from 'react';
import styled from 'styled-components';
import { Grid, Button, Segment } from 'semantic-ui-react';
import { translate } from 'react-i18next';
import _ from 'lodash';
import { Meteor } from 'meteor/meteor';
import { withRouter } from 'react-router';
import { devprint } from '../../../../api/helpers';
import { clearExtractedData, getUserImageURI } from '../../../helpers/file-processing';
import { IdentityVerificationFormTranslated } from './IdentityVerificationForm';
import { AddressVerificationFormTranslated } from './AddressVerificationForm';
import { PhoneVerificationFormTranslated } from './PhoneVerificationForm';
import { getFullCountryName } from './molecules/country-list';
import { StyledSegment } from './StyledFormComponents';
const StyledMessage = styled(Segment)`
&.ui.segment {
width: 100%;
}
`;
/**
* @pure: ?false
* @hasTests: false
*/
type Props = {
userId?: string,
location?: Object,
};
type State = {
identity?: {
firstName: string,
lastName: string,
dateOfBirth: string,
placeOfBirth: string,
citizenship: string,
passport: string,
issuedBy: string,
issueDate: string,
expiryDate: string,
passportFile: string,
passportFile2: string,
passportFile3: string,
passportFile4: string,
passportFile5: string,
selfieFile: string,
},
address?: {
country: string,
city: string,
address: string,
addressFile: string,
addressFile2: string,
},
phone: string,
zipHash: string,
dataHash: string,
loading: bool,
editable: bool,
validationStatus: string,
serverError: bool,
};
class CryptopassViewFormInner extends Component<Props, State> {
state = {
identity: {
firstName: '',
lastName: '',
dateOfBirth: '',
placeOfBirth: '',
citizenship: '',
passport: '',
issuedBy: '',
issueDate: '',
expiryDate: '',
passportFile: '',
passportFile2: '',
passportFile3: '',
passportFile4: '',
passportFile5: '',
selfieFile: '',
},
address: {
country: '',
city: '',
address: '',
addressFile: '',
addressFile2: '',
},
phone: '',
dataHash: '',
loading: true,
editable: false,
validationStatus: '',
serverError: false,
};
static defaultProps = {
userId: null,
location: null,
};
componentDidMount() {
const { userId } = this.props;
const USER_ID = userId;
Meteor.call('getDataHash', { USER_ID }, (er, re) => {
if (er) {
console.log(er);
} else {
Meteor.call(
'invokeGetClient', {
privateKey: '',
contractId: '',
address: '',
},
[
`0x${re}`,
],
(err, res) => {
const flag = res.data.infoJson['Evaluation Stack'][0].value[0].value;
console.log('User: ', res);
console.log('response :', flag);
console.log('error :', err);
this.setState(prevState => ({
...prevState,
validationStatus: flag,
}));
}
);
}
});
Meteor.call('readJSON', { userId }, (error, response) => {
if (error) {
devprint(`readJSON failed: ${error}`);
} else if (!response) {
devprint(`invalid response: ${typeof response}`);
} else {
const jsonData = JSON.stringify(response);
Meteor.call('getDataHash', { data: jsonData }, (hashError, dataHash) => {
if (hashError) {
devprint(`getDataHash data.json failed: ${hashError}`);
} else {
this.setState(prevState => ({
...prevState,
dataHash,
}));
}
});
const citizenship = getFullCountryName(response.identity.citizenship);
const country = getFullCountryName(response.address.country);
const identityImageTypeField = {
pass: 'passportFile',
pass2: 'passportFile2',
pass3: 'passportFile3',
pass4: 'passportFile4',
pass5: 'passportFile5',
selfie: 'selfieFile',
};
const addressImageTypeField = {
adr: 'addressFile',
adr2: 'addressFile2',
};
devprint(`response: ${response}`);
this.setState(prevState => ({
...prevState,
identity: {
...response.identity,
citizenship,
},
address: {
...response.address,
country,
},
phone: response.phone,
loading: false,
}));
_.forEach(identityImageTypeField, (field, type) => {
getUserImageURI({ userId, type }, (imageURI) => {
this.setState(prevState => ({
...prevState,
identity: {
...prevState.identity,
[field]: imageURI,
},
}));
});
});
_.forEach(addressImageTypeField, (field, type) => {
getUserImageURI({ userId, type }, (imageURI) => {
this.setState(prevState => ({
...prevState,
address: {
...prevState.address,
[field]: imageURI,
},
}));
});
});
}
});
window.addEventListener('beforeunload', this.clearData);
}
componentWillUnmount() {
window.removeEventListener('beforeunload', this.clearData);
}
clearData = () => {
const { userId } = this.props;
sessionStorage.clear();
clearExtractedData(userId);
}
handleSend = () => {
const { userId, location } = this.props;
const {
identity, address, phone, dataHash,
} = this.state;
Meteor.call('sendData', {
userId,
identity,
address,
phone,
dataHash,
zipHash: location.state.zipHash,
});
Meteor.call('updateUserData', {
userId,
identity,
address,
phone,
dataHash,
zipHash: location.state.zipHash,
validationStatus: 'pending',
}, (err) => {
if (err) {
this.setState({ serverError: true });
} else {
this.setState({ validationStatus: 'pending' });
const USER_ID = userId;
Meteor.call('getDataHash', { USER_ID }, (er, re) => {
if (er) {
console.log(er);
} else {
Meteor.call(
'invokeKycClient', {
privateKey: '',
contractId: '',
address: '',
},
[
'0x6e8cd3239898142738039e79b31ae4c2ed74e45b',
`0x${re}`,
'1',
'222222222',
],
);
}
});
}
});
};
render() {
const {
identity,
address,
phone,
loading,
editable,
validationStatus,
serverError,
} = this.state;
const {
userId,
t,
} = this.props;
const viewForm = (
<Fragment>
<IdentityVerificationFormTranslated loading={loading} editable={editable} {...identity} userId={userId} />
<AddressVerificationFormTranslated loading={loading} editable={editable} {...address} userId={userId} />
<PhoneVerificationFormTranslated loading={loading} editable={editable} phone={phone} userId={userId} />
{
// validationStatus !== 'pending' &&
// location && location.state && !!location.state.zipHash &&
<StyledSegment padded>
<Grid centered>
<Grid.Column mobile={16} tablet={8} computer={8}>
<Button positive fluid onClick={this.handleSend} disabled={loading}>{t('viewForm.Send for KYC')}</Button>
</Grid.Column>
</Grid>
</StyledSegment>
}
</Fragment>
);
const pendingMessage = (
<StyledMessage inverted padded="very" size="massive" color="orange" textAlign="center">
{t('validateForm.Pending')}
</StyledMessage>
);
const approvedMessage = (
<StyledMessage inverted padded="very" size="massive" color="green" textAlign="center">
{t('validateForm.Approved')}
</StyledMessage>
);
const rejectedMessage = (
<StyledMessage inverted padded="very" size="massive" color="red" textAlign="center">
{t('validateForm.Rejected')}
</StyledMessage>
);
const errorServerMessage = (<StyledMessage inverted padded size="massive" color="red" textAlign="center">{t('validateForm.Server Error')}</StyledMessage>);
let render;
switch (validationStatus) {
case '1':
render = [
pendingMessage,
viewForm,
];
break;
case '2':
render = [
approvedMessage,
viewForm,
];
break;
case '3':
render = [
rejectedMessage,
viewForm,
];
break;
default:
render = [
viewForm,
];
}
return (
<div className="UserInterface" style={{ minHeight: '100%' }}>
<div className="UserInterface">
{render}
{
serverError &&
errorServerMessage
}
</div>
</div>
);
}
}
export const CryptopassViewForm = withRouter(translate('common')(CryptopassViewFormInner));
// @flow
import React, { Component } from 'react';
import _ from 'lodash';
import sessionHelper from '../../../helpers/session-storage';
import { devprint } from '../../../../api/helpers';
export function FormHOC(WrappedComponent) {
return class Container extends Component {
state = {
language: 'en',
};
registerFormik = (formik) => {
this.formik = formik;
};
shouldComponentUpdate(nextProps) {
const {
i18n,
isResetting,
} = nextProps;
if (
i18n.language !== this.state.language
&& this.formik
) {
const {
values,
setFieldTouched,
touched,
errors,
} = this.formik;
const valuesKeys = Object.keys(values);
const errorsKeys = Object.keys(errors);
_.forEach(valuesKeys, (field) => {
if (!errorsKeys.includes(field)) {
setFieldTouched(field, !touched[field]);
}
});
devprint(this.formik);
this.setState({ language: i18n.language });
}
if (
isResetting
&& this.formik
) {
this.formik.handleReset();
}
return true;
}
render() {
const props = {
...this.props,
...this.state,
sessionHlp: sessionHelper,
registerFormik: this.registerFormik,
};
return <WrappedComponent {...props} />;
}
};
}
// @flow
import { withFormik } from 'formik';
import Yup from 'yup';
import sessionHelper from '../../../../helpers/session-storage';
import { ONLY_LETTERS, DD_MM_YYYY } from '../../../../constants.js';
export function IdentityForm(form) {
return withFormik({
mapPropsToValues({
firstName,
lastName,
dateOfBirth,
placeOfBirth,
citizenship,
passport,
issuedBy,
issueDate,
expiryDate,
filePass,
fileSelfie,
filePassResult,
fileSelfieResult,
sessionHlp,
email,
t,
nextStep,
}) {
return {
firstName: firstName || sessionHelper('firstName'),
lastName: lastName || sessionHelper('lastName'),
dateOfBirth: dateOfBirth || sessionHelper('dateOfBirth'),
placeOfBirth: placeOfBirth || sessionHelper('placeOfBirth'),
passport: passport || sessionHelper('passport'),
citizenship: citizenship || sessionHelper('citizenship'),
issuedBy: issuedBy || sessionHelper('issuedBy'),
issueDate: issueDate || sessionHelper('issueDate'),
expiryDate: expiryDate || sessionHelper('expiryDate'),
filePass: filePass || '',
fileSelfie: fileSelfie || '',
filePassResult: filePassResult || '0',
fileSelfieResult: fileSelfieResult || '0',
sessionHlp,
nextStep,
email,
t: t || undefined,
};
},
validate: (values) => {
const errors = {};
const dateFieldNames = ['dateOfBirth', 'issueDate', 'expiryDate'];
const fileFieldNames = ['filePassResult', 'fileSelfieResult'];
dateFieldNames.forEach((name) => {
if (!values[name]) {
errors[name] = values.t('validations.Should not be empty');
} else if (!DD_MM_YYYY.test(values[name])) {
errors[name] = values.t('validations.Specify the correct date');
}
});
fileFieldNames.forEach((name) => {
if (!values[name] || values[name] === '0') {
errors[name] = values.t('validations.A photo should not be empty');
}
});
return errors;
},
validationSchema: values => Yup.object().shape({
firstName: Yup.string()
.required(values.t('validations.Should not be empty'))
.matches(ONLY_LETTERS, values.t('validations.Please enter only letters')),
lastName: Yup.string()
.required(values.t('validations.Should not be empty'))
.matches(ONLY_LETTERS, values.t('validations.Please enter only letters')),
placeOfBirth: Yup.string()
.required(values.t('validations.Should not be empty'))
.matches(ONLY_LETTERS, values.t('validations.Please enter only letters')),
citizenship: Yup.string()
.required(values.t('validations.Should not be empty')),
passport: Yup.string()
.required(values.t('validations.Should not be empty')),
issuedBy: Yup.string()
.required(values.t('validations.Should not be empty')),
}),
handleSubmit(values) {
const username = {
username: values.email,
};
sessionStorage.setItem('username', JSON.stringify(username));
values.nextStep(2);
const secondStep = document.getElementById('step2');
setTimeout(() => {
secondStep.scrollIntoView();
}, 200);
},
})(form);
}
// @flow
import { Meteor } from 'meteor/meteor';
import { withFormik } from 'formik';
import Yup from 'yup';
export function LoginForm(form) {
return withFormik({
mapPropsToValues({
email,
pwd,
t,
sessionHlp,
}) {
return {
email: email || sessionHlp('login', 'email'),
pwd: pwd || '',
t: t || undefined,
sessionHlp,
};
},
validationSchema: values => Yup.object().shape({
email: Yup.string()
.required(values.t('validations.Should not be empty'))
.email(values.t('validations.Invalid email address')),
pwd: Yup.string()
.required(values.t('validations.Should not be empty')),
}),
handleSubmit({
email,
pwd,
sessionHlp,
}, {
setErrors,
}) {
const login = {
email,
};
sessionStorage.setItem('login', JSON.stringify(login));
Meteor.loginWithPassword(email, pwd, (error) => {
if (error) {
setErrors({
onServer: error.reason,
});
}
});
if (email !== sessionHlp('username', 'username')) {
sessionStorage.clear();
}
},
})(form);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment