Added change password form on login page

This commit is contained in:
bourquecharles
2021-07-17 13:10:41 -04:00
parent 7830023db3
commit 235f9d6a98
4 changed files with 198 additions and 51 deletions

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "ucentral-libs",
"version": "0.8.13",
"version": "0.8.14",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "ucentral-libs",
"version": "0.8.13",
"version": "0.8.14",
"devDependencies": {
"@babel/core": "^7.14.6",
"@babel/plugin-proposal-class-properties": "^7.14.5",

View File

@@ -1,6 +1,6 @@
{
"name": "ucentral-libs",
"version": "0.8.13",
"version": "0.8.14",
"main": "dist/index.js",
"source": "src/index.js",
"engines": {

View File

@@ -0,0 +1,118 @@
import React from 'react';
import {
CButton,
CCol,
CForm,
CInput,
CInputGroup,
CInputGroupPrepend,
CInputGroupText,
CRow,
CSpinner,
CPopover,
CAlert,
CInvalidFeedback,
} from '@coreui/react';
import PropTypes from 'prop-types';
import CIcon from '@coreui/icons-react';
import { cilLockLocked } from '@coreui/icons';
import LanguageSwitcher from '../LanguageSwitcher';
import styles from './index.module.scss';
const ChangePasswordForm = ({
t,
i18n,
onKeyDown,
signIn,
loading,
fields,
updateField,
changePasswordResponse,
cancelPasswordChange,
}) => (
<CForm onKeyDown={(e) => onKeyDown(e, signIn)}>
<h1>
{t('login.change_password')}
<div className={styles.languageSwitcher}>
<LanguageSwitcher i18n={i18n} />
</div>
</h1>
<p className="text-muted">{t('login.change_password_instructions')}</p>
<CInputGroup className="mb-4">
<CPopover content={t('login.password')}>
<CInputGroupPrepend>
<CInputGroupText>
<CIcon name="cilLockLocked" content={cilLockLocked} />
</CInputGroupText>
</CInputGroupPrepend>
</CPopover>
<CInput
id="newpassword"
invalid={fields.newpassword.error}
autoFocus
required
type="password"
placeholder={t(fields.newpassword.placeholder)}
autoComplete="username"
onChange={updateField}
/>
<CInvalidFeedback className="help-block">{t('login.please_enter_username')}</CInvalidFeedback>
</CInputGroup>
<CInputGroup className="mb-4">
<CPopover content={t('login.password')}>
<CInputGroupPrepend>
<CInputGroupText>
<CIcon content={cilLockLocked} />
</CInputGroupText>
</CInputGroupPrepend>
</CPopover>
<CInput
id="confirmpassword"
invalid={fields.confirmpassword.error}
required
type="password"
placeholder={t(fields.confirmpassword.placeholder)}
autoComplete="current-password"
onChange={updateField}
/>
<CInvalidFeedback className="help-block">{t('login.different_passwords')}</CInvalidFeedback>
</CInputGroup>
<CRow>
<CCol>
<CAlert
show={changePasswordResponse.tried}
color={!changePasswordResponse.error ? 'success' : 'danger'}
>
{changePasswordResponse.text}
</CAlert>
</CCol>
</CRow>
<CRow>
<CCol xs="6">
<CButton color="primary" className="px-4" onClick={() => signIn(true)} disabled={loading}>
{loading ? t('login.changing_password') : t('login.change_password')}
<CSpinner hidden={!loading} color="light" component="span" size="sm" />
</CButton>
</CCol>
<CCol xs="6" className={styles.forgotPassword}>
<CButton variant="ghost" color="primary" onClick={cancelPasswordChange}>
{t('common.cancel')}
</CButton>
</CCol>
</CRow>
</CForm>
);
ChangePasswordForm.propTypes = {
t: PropTypes.func.isRequired,
i18n: PropTypes.instanceOf(Object).isRequired,
onKeyDown: PropTypes.func.isRequired,
signIn: PropTypes.func.isRequired,
loading: PropTypes.bool.isRequired,
fields: PropTypes.instanceOf(Object).isRequired,
updateField: PropTypes.func.isRequired,
changePasswordResponse: PropTypes.instanceOf(Object).isRequired,
cancelPasswordChange: PropTypes.func.isRequired,
};
export default ChangePasswordForm;

View File

@@ -4,6 +4,7 @@ import PropTypes from 'prop-types';
import styles from './index.module.scss';
import LoginForm from './LoginForm';
import ForgotPasswordForm from './ForgotPasswordForm';
import ChangePasswordForm from './ChangePasswordForm';
const LoginPage = ({
t,
@@ -15,56 +16,81 @@ const LoginPage = ({
fields,
updateField,
isLogin,
isPasswordChange,
toggleForgotPassword,
onKeyDown,
sendForgotPasswordEmail,
}) => (
<div className="c-app c-default-layout flex-row align-items-center">
<CContainer>
<CRow className="justify-content-center">
<CCol md="8">
<img
className={[styles.logo, 'c-sidebar-brand-full'].join(' ')}
src="assets/OpenWiFi_LogoLockup_DarkGreyColour.svg"
alt="OpenWifi"
/>
<CCardGroup>
<CCard className="p-4">
<CCardBody>
{isLogin ? (
<LoginForm
t={t}
i18n={i18n}
onKeyDown={onKeyDown}
signIn={signIn}
loading={loading}
fields={fields}
updateField={updateField}
loginResponse={loginResponse}
toggleForgotPassword={toggleForgotPassword}
/>
) : (
<ForgotPasswordForm
t={t}
i18n={i18n}
onKeyDown={onKeyDown}
signIn={signIn}
loading={loading}
fields={fields}
updateField={updateField}
forgotResponse={forgotResponse}
toggleForgotPassword={toggleForgotPassword}
sendForgotPasswordEmail={sendForgotPasswordEmail}
/>
)}
</CCardBody>
</CCard>
</CCardGroup>
</CCol>
</CRow>
</CContainer>
</div>
);
changePasswordResponse,
cancelPasswordChange,
}) => {
const getForm = () => {
if (!isLogin) {
return (
<ForgotPasswordForm
t={t}
i18n={i18n}
onKeyDown={onKeyDown}
signIn={signIn}
loading={loading}
fields={fields}
updateField={updateField}
forgotResponse={forgotResponse}
toggleForgotPassword={toggleForgotPassword}
sendForgotPasswordEmail={sendForgotPasswordEmail}
/>
);
}
if (isPasswordChange) {
return (
<ChangePasswordForm
t={t}
i18n={i18n}
onKeyDown={onKeyDown}
signIn={signIn}
loading={loading}
fields={fields}
updateField={updateField}
changePasswordResponse={changePasswordResponse}
cancelPasswordChange={cancelPasswordChange}
/>
);
}
return (
<LoginForm
t={t}
i18n={i18n}
onKeyDown={onKeyDown}
signIn={signIn}
loading={loading}
fields={fields}
updateField={updateField}
loginResponse={loginResponse}
toggleForgotPassword={toggleForgotPassword}
/>
);
};
return (
<div className="c-app c-default-layout flex-row align-items-center">
<CContainer>
<CRow className="justify-content-center">
<CCol md="8">
<img
className={[styles.logo, 'c-sidebar-brand-full'].join(' ')}
src="assets/OpenWiFi_LogoLockup_DarkGreyColour.svg"
alt="OpenWifi"
/>
<CCardGroup>
<CCard className="p-4">
<CCardBody>{getForm()}</CCardBody>
</CCard>
</CCardGroup>
</CCol>
</CRow>
</CContainer>
</div>
);
};
LoginPage.propTypes = {
t: PropTypes.func.isRequired,
@@ -75,10 +101,13 @@ LoginPage.propTypes = {
forgotResponse: PropTypes.instanceOf(Object).isRequired,
fields: PropTypes.instanceOf(Object).isRequired,
updateField: PropTypes.func.isRequired,
isLogin: PropTypes.func.isRequired,
isLogin: PropTypes.bool.isRequired,
isPasswordChange: PropTypes.bool.isRequired,
toggleForgotPassword: PropTypes.func.isRequired,
onKeyDown: PropTypes.func.isRequired,
sendForgotPasswordEmail: PropTypes.func.isRequired,
changePasswordResponse: PropTypes.instanceOf(Object).isRequired,
cancelPasswordChange: PropTypes.func.isRequired,
};
export default React.memo(LoginPage);