@krowdy/kds-auth
Version:
React components that implement Google's Material Design.
617 lines (548 loc) • 20.8 kB
JavaScript
import _regeneratorRuntime from "@babel/runtime/regenerator";
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
import _extends from "@babel/runtime/helpers/esm/extends";
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
import React, { forwardRef, useCallback, useImperativeHandle, useMemo, useState } from 'react';
import clsx from 'clsx';
import { Button, Checkbox, makeStyles, TextField, FormControlLabel, IconButton, Typography, CircularProgress } from '@krowdy/kds-core';
import { Visibility as VisibilityIcon, VisibilityOff as VisibilityOffIcon } from '@material-ui/icons';
import GoogleButton from './GoogleButton';
import MicrosoftButton from './MicrosoftButton';
import { useAuth } from '../utils';
import { ViewType } from '../AuthContext/utils';
var inputLabels = {
login: 'Correo o celular',
newPassword: 'Nueva contraseña',
'only-email': 'Correo electrónico',
'only-phone': 'Número de celular',
password: 'Contraseña',
'phone-and-email': 'Correo o celular',
verify: 'Código de verificación'
};
var errorMessages = {
login: 'Error al verificar cuenta, comunícate con soporte.',
newCode: 'Código caducado. Enviamos un nuevo código a tu correo.',
newPassword: 'Debe tener mínimo 8 caracteres.',
password: 'Contraseña incorrecta. Vuelve a intentarlo o haz click en “¿Olvidaste tu contraseña?”',
verify: 'Código de verificación erróneo.'
};
var _ref6 = /*#__PURE__*/React.createElement(VisibilityIcon, {
color: "inherit",
fontSize: "inherit"
});
var _ref7 = /*#__PURE__*/React.createElement(VisibilityOffIcon, {
color: "inherit",
fontSize: "inherit"
});
var _ref8 = /*#__PURE__*/React.createElement(GoogleButton, null);
var _ref9 = /*#__PURE__*/React.createElement(MicrosoftButton, null);
var _ref10 = /*#__PURE__*/React.createElement(CircularProgress, {
disableShrink: true,
size: 18
});
var KrowdyOneTap = forwardRef(function (_ref, ref) {
var _ref$onChangeUserLogi = _ref.onChangeUserLogin,
onChangeUserLogin = _ref$onChangeUserLogi === void 0 ? function () {} : _ref$onChangeUserLogi,
typeView = _ref.typeView,
currentUser = _ref.currentUser;
var _useAuth = useAuth(),
verifyAccount = _useAuth.verifyAccount,
loginByPassword = _useAuth.loginByPassword,
loginByCode = _useAuth.loginByCode,
typeCode = _useAuth.typeCode,
onSuccessLogin = _useAuth.onSuccessLogin,
updateAccount = _useAuth.updateAccount,
loading = _useAuth.loading,
loginWith = _useAuth.loginWith,
onUpdatePassword = _useAuth.onUpdatePassword,
onUpdateState = _useAuth.onUpdateState,
onChangeView = _useAuth.onChangeView,
onError = _useAuth.onError,
logout = _useAuth.logout;
var classes = useStyles();
var _useState = useState(null),
_useState2 = _slicedToArray(_useState, 2),
loginkey = _useState2[0],
setLoginKey = _useState2[1];
var _useState3 = useState(typeView === ViewType.Login ? currentUser : ''),
_useState4 = _slicedToArray(_useState3, 2),
valueInput = _useState4[0],
setValueInput = _useState4[1];
var _useState5 = useState(''),
_useState6 = _slicedToArray(_useState5, 2),
passwordValue = _useState6[0],
setPasswordValue = _useState6[1];
var _useState7 = useState(false),
_useState8 = _slicedToArray(_useState7, 2),
isErrorLogin = _useState8[0],
setErrorLogin = _useState8[1];
var _useState9 = useState(false),
_useState10 = _slicedToArray(_useState9, 2),
isCodeValidationExpired = _useState10[0],
setIsCodeValidationExpired = _useState10[1];
var _useState11 = useState(false),
_useState12 = _slicedToArray(_useState11, 2),
showPassword = _useState12[0],
setShowPassword = _useState12[1];
var _useState13 = useState(true),
_useState14 = _slicedToArray(_useState13, 2),
keepSession = _useState14[0],
setKeepSession = _useState14[1];
var _useState15 = useState({}),
_useState16 = _slicedToArray(_useState15, 2),
register = _useState16[0],
setRegister = _useState16[1];
var isNextDisabled = useMemo(function () {
switch (typeView) {
case ViewType.NewPassword:
return passwordValue.length < 8;
case ViewType.Register:
{
var firstName = register.firstName,
lastName = register.lastName;
return !(firstName && lastName);
}
case ViewType.Login:
if (loginWith === 'only-email') {
var emailRegex = /^[-\w.%+]{1,64}@(?:[A-Z0-9-]{1,63}\.){1,125}[A-Z]{2,63}$/i;
return !valueInput || !emailRegex.test(valueInput);
} else {
return !valueInput;
}
case ViewType.Password:
case ViewType.Recovery:
return !passwordValue;
default:
return false;
}
}, [typeView, valueInput, register, loginWith, passwordValue]);
var _handleChangeInput = useCallback(function (_ref2) {
var _ref2$target = _ref2.target,
value = _ref2$target.value,
name = _ref2$target.name;
setValueInput(value);
if (name === 'login' && value) {
var res = value.split(new RegExp('[ @ | . ]'));
var domain = res ? res[res.length - 2] : null;
if (domain && 'gmail'.indexOf(domain) !== -1) setLoginKey('google');else if (domain && ('outlook'.indexOf(domain) !== -1 || 'hotmail'.indexOf(domain) !== -1)) setLoginKey('microsoft');else setLoginKey(null);
}
}, []);
var _handleChangePassword = useCallback(function (_ref3) {
var value = _ref3.target.value;
setPasswordValue(value);
}, []);
var _handleChangeRegister = useCallback(function (_ref4) {
var _ref4$target = _ref4.target,
value = _ref4$target.value,
name = _ref4$target.name;
setRegister(function (prev) {
return _extends({}, prev, _defineProperty({}, name, value));
});
}, []);
var _handleSubmitSetEmail = useCallback(function _callee(valueInput, nextView) {
var _await$verifyAccount, hasPassword, success, value, type;
return _regeneratorRuntime.async(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
if (!(nextView && ![ViewType.Password, ViewType.Verify].includes(nextView))) {
_context.next = 2;
break;
}
throw new Error('nextView is no valid');
case 2:
_context.next = 4;
return _regeneratorRuntime.awrap(verifyAccount(valueInput, Boolean(nextView)));
case 4:
_await$verifyAccount = _context.sent;
hasPassword = _await$verifyAccount.hasPassword;
success = _await$verifyAccount.success;
value = _await$verifyAccount.value;
type = _await$verifyAccount.type;
setErrorLogin(!success);
if (success) {
onChangeUserLogin(type === 'phone' ? value : valueInput);
onChangeView(nextView !== null && nextView !== void 0 ? nextView : hasPassword ? ViewType.Password : ViewType.Verify);
setLoginKey(null);
}
case 11:
case "end":
return _context.stop();
}
}
}, null, null, null, Promise);
}, [onChangeUserLogin, onChangeView, verifyAccount]);
var _handleNext = useCallback(function _callee2(e) {
var _await$loginByPasswor, isPasswordValid, _await$loginByCode, isCodeValid, isFirstTime, error, _ref5, successRegister, _await$onUpdatePasswo, successPasswword, _await$loginByCode2, isRecoveryValid;
return _regeneratorRuntime.async(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
if (!(e.charCode && e.charCode !== 13 || isNextDisabled || loading)) {
_context2.next = 2;
break;
}
return _context2.abrupt("return");
case 2:
setIsCodeValidationExpired(false);
_context2.prev = 3;
_context2.t0 = typeView;
_context2.next = _context2.t0 === ViewType.Login ? 7 : _context2.t0 === ViewType.Password ? 9 : _context2.t0 === ViewType.Verify ? 15 : _context2.t0 === ViewType.Register ? 25 : _context2.t0 === ViewType.NewPassword ? 34 : _context2.t0 === ViewType.Recovery ? 40 : 47;
break;
case 7:
_handleSubmitSetEmail(valueInput);
return _context2.abrupt("break", 48);
case 9:
_context2.next = 11;
return _regeneratorRuntime.awrap(loginByPassword({
email: currentUser,
keepSession: keepSession,
password: passwordValue
}));
case 11:
_await$loginByPasswor = _context2.sent;
isPasswordValid = _await$loginByPasswor.success;
setErrorLogin(!isPasswordValid);
return _context2.abrupt("break", 48);
case 15:
_context2.next = 17;
return _regeneratorRuntime.awrap(loginByCode({
code: passwordValue,
keepSession: keepSession,
type: typeCode,
value: currentUser
}));
case 17:
_await$loginByCode = _context2.sent;
isCodeValid = _await$loginByCode.success;
isFirstTime = _await$loginByCode.isNew;
error = _await$loginByCode.error;
setErrorLogin(!isCodeValid);
if (error === 'Validation code expired') setIsCodeValidationExpired(!isCodeValid);
if (isCodeValid) if (isFirstTime) onChangeView(ViewType.Register);else onSuccessLogin(true);
return _context2.abrupt("break", 48);
case 25:
_context2.next = 27;
return _regeneratorRuntime.awrap(updateAccount(register));
case 27:
_context2.t1 = _context2.sent;
if (_context2.t1) {
_context2.next = 30;
break;
}
_context2.t1 = {};
case 30:
_ref5 = _context2.t1;
successRegister = _ref5.success;
if (successRegister) {
setValueInput('');
setPasswordValue('');
}
return _context2.abrupt("break", 48);
case 34:
_context2.next = 36;
return _regeneratorRuntime.awrap(onUpdatePassword(passwordValue));
case 36:
_await$onUpdatePasswo = _context2.sent;
successPasswword = _await$onUpdatePasswo.success;
if (!successPasswword) setErrorLogin(true);
return _context2.abrupt("break", 48);
case 40:
_context2.next = 42;
return _regeneratorRuntime.awrap(loginByCode({
code: passwordValue,
keepSession: keepSession,
type: typeCode,
value: currentUser
}));
case 42:
_await$loginByCode2 = _context2.sent;
isRecoveryValid = _await$loginByCode2.success;
setErrorLogin(!isRecoveryValid);
if (isRecoveryValid) {
setPasswordValue('');
onChangeView(ViewType.NewPassword);
}
return _context2.abrupt("break", 48);
case 47:
return _context2.abrupt("break", 48);
case 48:
_context2.next = 53;
break;
case 50:
_context2.prev = 50;
_context2.t2 = _context2["catch"](3);
onError(_context2.t2, typeView);
case 53:
case "end":
return _context2.stop();
}
}
}, null, null, [[3, 50]], Promise);
}, [isNextDisabled, loading, typeView, _handleSubmitSetEmail, valueInput, loginByPassword, currentUser, keepSession, passwordValue, loginByCode, typeCode, onChangeView, onSuccessLogin, updateAccount, register, onUpdatePassword, onError]);
var _handleClickShowPassword = useCallback(function () {
setShowPassword(function (prev) {
return !prev;
});
}, []);
var _handleKeepSession = useCallback(function () {
setKeepSession(function (prev) {
onUpdateState({
keepSession: !prev
});
return !prev;
});
}, [onUpdateState]);
var _handleResendPassword = useCallback(function _callee3() {
var _await$verifyAccount2, success;
return _regeneratorRuntime.async(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
_context3.next = 2;
return _regeneratorRuntime.awrap(verifyAccount(currentUser, true));
case 2:
_await$verifyAccount2 = _context3.sent;
success = _await$verifyAccount2.success;
if (success) setErrorLogin(false);
case 5:
case "end":
return _context3.stop();
}
}
}, null, null, null, Promise);
}, [currentUser, verifyAccount]);
var _handleForgotPassword = useCallback(function () {
setPasswordValue('');
onChangeView(ViewType.Recovery);
verifyAccount(valueInput, true); // eslint-disable-next-line react-hooks/exhaustive-deps
}, [verifyAccount, valueInput]);
useImperativeHandle(ref, function () {
return {
submitEmail: function submitEmail(email, nextView) {
logout();
_handleChangeInput({
target: {
name: 'email',
value: email
}
});
_handleSubmitSetEmail(email, nextView);
}
};
});
return /*#__PURE__*/React.createElement(React.Fragment, null, [ViewType.Password, ViewType.Verify, ViewType.Recovery, ViewType.NewPassword].includes(typeView) && /*#__PURE__*/React.createElement(TextField, {
autoFocus: true,
className: clsx(classes.labelOutlined),
error: isErrorLogin || isCodeValidationExpired,
FormHelperTextProps: {
classes: {
contained: classes.helperText
}
},
fullWidth: true,
helperText: isCodeValidationExpired ? errorMessages.newCode : (isErrorLogin || [ViewType.Recovery, ViewType.NewPassword].includes(typeView)) && errorMessages[typeView],
InputProps: {
className: classes.inputStyle,
classes: {
input: classes.emailInput,
root: clsx(isErrorLogin && classes.colorError)
},
endAdornment: [ViewType.Password, ViewType.NewPassword].includes(typeView) && /*#__PURE__*/React.createElement(IconButton, {
className: classes.iconShowPassword,
onClick: _handleClickShowPassword,
size: "small"
}, showPassword ? _ref6 : _ref7)
},
label: [ViewType.Verify, ViewType.Recovery].includes(typeView) ? 'Código de verificación' : inputLabels[typeView],
onChange: _handleChangePassword,
onKeyPress: _handleNext,
required: true,
type: showPassword || [ViewType.Verify, ViewType.Recovery].includes(typeView) ? 'text' : 'password',
value: passwordValue,
variant: "outlined"
}), typeView === ViewType.Login && /*#__PURE__*/React.createElement(TextField, {
autoFocus: true,
className: clsx(classes.fieldEmail, classes.labelOutlined),
error: isErrorLogin,
fullWidth: true,
helperText: isErrorLogin && errorMessages[typeView],
InputProps: {
classes: {
input: classes.emailInput,
root: classes.textfield
}
},
label: inputLabels[loginWith],
name: "login",
onChange: _handleChangeInput,
onKeyPress: _handleNext,
type: "email",
value: valueInput,
variant: "outlined"
}), typeView === ViewType.Register && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(TextField, {
autoFocus: true,
className: clsx(classes.labelOutlined),
fullWidth: true // InputLabelProps={{
// classes: {
// root: classes.labelOutlined
// }
// }}
,
InputProps: {
classes: {
input: classes.emailInput,
root: classes.textfield
}
},
label: "Nombres",
name: "firstName",
onChange: _handleChangeRegister,
required: true,
value: register.firstName || '',
variant: "outlined"
}), /*#__PURE__*/React.createElement(TextField, {
className: clsx(classes.fieldEmail, classes.labelOutlined),
fullWidth: true // InputLabelProps={{
// classes: {
// root: classes.labelOutlined
// }
// }}
,
InputProps: {
classes: {
input: classes.emailInput,
root: classes.textfield
}
},
label: "Apellidos",
name: "lastName",
onChange: _handleChangeRegister,
required: true,
value: register.lastName || '',
variant: "outlined"
}), /*#__PURE__*/React.createElement(TextField, {
className: clsx(classes.fieldEmail, classes.labelOutlined),
fullWidth: true // InputLabelProps={{
// classes: {
// root: classes.labelOutlined
// }
// }}
,
InputProps: {
classes: {
input: classes.emailInput,
root: classes.textfield
}
},
label: currentUser.indexOf('@') !== -1 ? 'Celular (opcional)' : 'Correo electrónico (opcional)',
name: currentUser.indexOf('@') !== -1 ? 'phone' : 'email',
onChange: _handleChangeRegister,
value: register[currentUser.indexOf('@') !== -1 ? 'phone' : 'email'] || '',
variant: "outlined"
})), loginkey && /*#__PURE__*/React.createElement("div", {
className: classes.margintop
}, loginkey === 'google' && _ref8, loginkey === 'microsoft' && _ref9), [ViewType.Password, ViewType.Verify, ViewType.NewPassword].includes(typeView) && /*#__PURE__*/React.createElement(FormControlLabel, {
className: classes.labelCheckbox,
control: /*#__PURE__*/React.createElement(Checkbox, {
checked: keepSession,
color: "primary",
onChange: _handleKeepSession
}),
label: "Mantener mi sesi\xF3n abierta"
}), typeView === ViewType.NewPassword && /*#__PURE__*/React.createElement(Typography, {
align: "center",
className: clsx(classes.textfield, classes.textEnd, classes.nextButton2),
color: "disabled"
}, "No olvides revisar tu contrase\xF1a antes de establecerla para evitar cualquier inconveniente m\xE1s adelante."), /*#__PURE__*/React.createElement(Button, {
className: clsx(classes.nextButton, loginkey && classes.nextButton2),
color: "primary",
disabled: isNextDisabled || loading,
fullWidth: true,
onClick: _handleNext,
startIcon: loading && _ref10,
variant: "contained"
}, "Continuar"), [ViewType.Password, ViewType.Verify, ViewType.Recovery].includes(typeView) && /*#__PURE__*/React.createElement("div", {
className: classes.endContent
}, typeView === ViewType.Password ? /*#__PURE__*/React.createElement(Button, {
color: "primary",
onClick: _handleForgotPassword,
size: "small"
}, "\xBFOlvidaste tu contrase\xF1a?") : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Typography, {
className: clsx(classes.textfield, classes.textEnd),
color: "disabled"
}, "\xBFNo lo encuentras?"), /*#__PURE__*/React.createElement(Button, {
className: classes.capitalizeText,
color: "primary",
onClick: _handleResendPassword,
size: "small"
}, "Reenviar"))));
});
var useStyles = makeStyles(function (_ref11) {
var spacing = _ref11.spacing,
palette = _ref11.palette;
return {
capitalizeText: {
textTransform: 'capitalize'
},
colorError: {
color: palette.error.main
},
emailInput: {
color: palette.common.black,
// fontSize: 14,
padding: spacing(1.5)
},
endContent: {
alignItems: 'center',
display: 'flex',
justifyContent: 'center',
marginTop: spacing(3)
},
fieldEmail: {
marginTop: spacing(1.5)
},
helperText: {
marginLeft: 0
},
inputStyle: {
fontSize: 14
},
labelCheckbox: {
'& > span': {
fontSize: 14,
padding: spacing(1, 1, 1, 0)
},
margin: spacing(2, 0, 0, 0)
},
labelOutlined: {
'& .MuiInputLabel-outlined': {
transform: 'translate(8px, 13px) scale(1)'
},
'& .MuiInputLabel-outlined.MuiInputLabel-shrink': {
transform: 'translate(8px, -5px) scale(0.9)'
}
},
margintop: {
marginTop: spacing(4)
},
nextButton: {
marginTop: spacing(4)
},
nextButton2: {
marginTop: spacing(2)
},
outlinedLabel: {
top: -8
},
textEnd: {
color: palette.grey[600]
},
textfield: {
fontSize: 14
}
};
}, {
name: 'KrowdyOneTap'
});
export default React.memo(KrowdyOneTap);