-
Notifications
You must be signed in to change notification settings - Fork 57
Enhancement: Support email editing on My Account page #3777
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
ankit-mehta07
wants to merge
14
commits into
glific:master
Choose a base branch
from
ankit-mehta07:enhancement/support-email-editing-my-account
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 6 commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
1566ce6
Prefill and validate phone number on reset password form
ankit-mehta07 51ff649
Resolve merge conflict
ankit-mehta07 147674a
Add frontend support for editing email on My Account page
ankit-mehta07 f14ecc0
Update email editing logic as per review feedback
ankit-mehta07 73a6dbb
Fix: Align updateCurrentUser mocks with schema (add key field)
ankit-mehta07 5f957ea
Fix Formik state handling and integration test issues
ankit-mehta07 f1fd0a7
Resolve merge conflict and fix Formik state handling
ankit-mehta07 5e18545
Fix static analysis issues and mock schema mismatch
ankit-mehta07 fce416c
chore: revert out-of-scope changes, keep only email editing support
ankit-mehta07 8d925ee
fix: use existing i18n keys in MyAccount validation schema
ankit-mehta07 cc2b89f
fix: use block body in promise executor to satisfy static analysis
ankit-mehta07 a82c61a
style: fix minor code style issues from static analysis
ankit-mehta07 d74f7bc
fix: decouple profile save from password/OTP flow in MyAccount
ankit-mehta07 53ff048
style: fix import ordering and self-closing Field tag in MyAccount
ankit-mehta07 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,7 +15,7 @@ import setLogs from 'config/logs'; | |
| import { checkOrgStatus } from 'services/AuthService'; | ||
| import { TERMS_OF_USE_LINK } from 'common/constants'; | ||
|
|
||
| import { Promotion } from './Promotion/Promotion'; | ||
| // import { Promotion } from './Promotion/Promotion'; | ||
|
|
||
| export interface AuthProps { | ||
| pageTitle: string; | ||
|
|
@@ -58,29 +58,27 @@ export const Auth = ({ | |
| loading: externalLoading, | ||
| inlineSuccessMessage, | ||
| }: AuthProps) => { | ||
| // handle visibility for the password field | ||
| const [showPassword, setShowPassword] = useState(false); | ||
| const [loading, setLoading] = useState(false); | ||
| const [internalLoading, setInternalLoading] = useState(false); | ||
| const loading = externalLoading !== undefined ? externalLoading : internalLoading; | ||
| const setLoading = setInternalLoading; | ||
| const { t } = useTranslation(); | ||
| const [orgName, setOrgName] = useState('Glific'); | ||
| const [status, setStatus] = useState(''); | ||
|
|
||
| const isLoading = externalLoading !== undefined ? externalLoading : loading; | ||
|
|
||
| useEffect(() => { | ||
| if (mode === 'trialregistration') { | ||
| return; | ||
| } | ||
|
|
||
| axios | ||
| .post(ORGANIZATION_NAME) | ||
| .then(({ data }) => { | ||
| setOrgName(data?.data?.name); | ||
| setStatus(data?.data?.status); | ||
| }) | ||
| .catch((error) => setLogs(`orgName error ${JSON.stringify(error)}`, error)); | ||
| }, [mode]); | ||
| }, []); | ||
|
|
||
| useEffect(() => { | ||
| // Stop loading if any error | ||
| if (loading && errorMessage) { | ||
| setLoading(false); | ||
| } | ||
|
|
@@ -94,7 +92,6 @@ export const Auth = ({ | |
| const boxTitleClass = [styles.BoxTitle]; | ||
| let buttonClass = styles.AuthButton; | ||
| let buttonContainedVariant = true; | ||
|
|
||
| switch (mode) { | ||
| case 'login': | ||
| boxClass.push(styles.LoginBox); | ||
|
|
@@ -106,13 +103,6 @@ export const Auth = ({ | |
| boxTitleClass.push(styles.RegistrationBoxTitle); | ||
| buttonClass = styles.AuthRegistrationButton; | ||
| break; | ||
| case 'trialregistration': | ||
| boxClass.push(styles.RegistrationBox); | ||
| boxClass.push(styles.TrialRegistrationBox); | ||
| boxTitleClass.push(styles.RegistrationBoxTitle); | ||
| buttonClass = styles.AuthButton; | ||
| buttonContainedVariant = true; | ||
| break; | ||
| case 'confirmotp': | ||
| boxClass.push(styles.OTPBox); | ||
| boxTitleClass.push(styles.RegistrationBoxTitle); | ||
|
|
@@ -132,31 +122,33 @@ export const Auth = ({ | |
| } | ||
|
|
||
| const isRegistration = mode === 'registration'; | ||
| const isTrialRegistration = mode === 'trialregistration'; | ||
| const whatsAppIcon = <WhatsAppIcon className={styles.WhatsAppIcon} />; | ||
| const otpMessage = 'You will receive an OTP on your WhatsApp number'; | ||
|
|
||
| let displayErrorMessage: any = null; | ||
| if (errorMessage) { | ||
| displayErrorMessage = <div className={styles.ErrorMessage}>{errorMessage}</div>; | ||
| } | ||
|
|
||
| let displayInlineSuccessMessage: any = null; | ||
| if (inlineSuccessMessage) { | ||
| displayInlineSuccessMessage = <div className={styles.SuccessMessage}>{inlineSuccessMessage}</div>; | ||
| } | ||
|
|
||
| const handlePasswordVisibility = () => { | ||
| setShowPassword(!showPassword); | ||
| }; | ||
|
|
||
| // let's add the additonal password field info to the password field to handle | ||
| // visibility of the field | ||
| const passwordFieldAdditionalInfo = { | ||
| endAdornmentCallback: handlePasswordVisibility, | ||
| togglePassword: showPassword, | ||
| }; | ||
|
|
||
| const handlePhone = | ||
| () => | ||
| (value: string): void => { | ||
| initialFormValues.phone = value; | ||
| }; | ||
|
|
||
|
|
||
| let formElements; | ||
| // we should not render form elements when displaying success message | ||
| if (!successMessage) { | ||
| formElements = ( | ||
| <> | ||
|
|
@@ -169,13 +161,14 @@ export const Auth = ({ | |
|
|
||
| <Formik | ||
| initialValues={initialFormValues} | ||
| enableReinitialize={true} | ||
| validationSchema={validationSchema} | ||
| onSubmit={(item) => { | ||
| setLoading(true); | ||
| saveHandler(item); | ||
| }} | ||
| > | ||
| {({ submitForm, values }) => ( | ||
| {({ submitForm, values, setFieldValue }) => ( | ||
| <div className={styles.CenterBox}> | ||
| <Form className={styles.Form}> | ||
| {formFields.map((field, index) => { | ||
|
|
@@ -184,10 +177,9 @@ export const Auth = ({ | |
| fieldInfo = { ...field, ...passwordFieldAdditionalInfo }; | ||
| } | ||
| if (field.type === 'phone') { | ||
| fieldInfo = { ...field, handlePhone }; | ||
| fieldInfo = { ...field, handlePhone: () => (value: string) => { setFieldValue('phoneNumber', value); } }; | ||
| } | ||
| const key = index; | ||
|
|
||
| return ( | ||
| <div className={field.styles} key={key}> | ||
| {field.label ? ( | ||
|
|
@@ -201,17 +193,11 @@ export const Auth = ({ | |
| </div> | ||
| ); | ||
| })} | ||
|
|
||
| {isTrialRegistration && inlineSuccessMessage && ( | ||
| <div className={styles.SuccessMessageInline}>{inlineSuccessMessage}</div> | ||
| )} | ||
|
|
||
| {linkURL && ( | ||
| <div className={styles.Link}> | ||
| <Link to={`/${linkURL}`}>{linkText}</Link> | ||
| </div> | ||
| )} | ||
|
|
||
| <div className={styles.CenterButton}> | ||
| {isRegistration ? ( | ||
| <Captcha | ||
|
|
@@ -226,7 +212,7 @@ export const Auth = ({ | |
| }} | ||
| className={buttonClass} | ||
| data-testid="SubmitButton" | ||
| loading={isLoading} | ||
| loading={loading} | ||
| action="register" | ||
| > | ||
| {buttonText} | ||
|
|
@@ -239,17 +225,20 @@ export const Auth = ({ | |
| onClick={submitForm} | ||
| className={buttonClass} | ||
| data-testid="SubmitButton" | ||
| loading={isLoading} | ||
| type="button" | ||
| loading={loading} | ||
| > | ||
| {buttonText} | ||
| {!loading && buttonText} | ||
| </Button> | ||
| )} | ||
| </div> | ||
| {isRegistration && <div className={styles.InformationText}>{otpMessage}</div>} | ||
| {/* We neeed to add this submit button to enable form sumbitting when user hits enter | ||
| key. This is an workaround solution till the bug in formik or react is fixed. For | ||
| more info: https://github.com/formium/formik/issues/1418 */} | ||
|
||
| <input className={styles.SubmitAction} type="submit" /> | ||
| </Form> | ||
| {displayErrorMessage} | ||
| {displayInlineSuccessMessage} | ||
| </div> | ||
| )} | ||
| </Formik> | ||
|
|
@@ -260,17 +249,14 @@ export const Auth = ({ | |
| } | ||
|
|
||
| return ( | ||
| <div | ||
| className={`${styles.Container} ${isTrialRegistration ? styles.TrialContainer : ''}`} | ||
| data-testid="AuthContainer" | ||
| > | ||
| <div className={styles.Container} data-testid="AuthContainer"> | ||
| <div className={styles.Auth}> | ||
| <div> | ||
| <img src={GlificLogo} className={styles.GlificLogo} alt="Glific" /> | ||
| </div> | ||
| <hr className={styles.Break} /> | ||
|
|
||
| {!isTrialRegistration && <div className={styles.OrganizationName}>{orgName}</div>} | ||
| <div className={styles.OrganizationName}>{orgName}</div> | ||
|
|
||
| <div className={boxClass.join(' ')}> | ||
| {formElements} | ||
|
|
@@ -297,7 +283,7 @@ export const Auth = ({ | |
| ) : null} | ||
| </div> | ||
|
|
||
| {mode === 'login' && <Promotion />} | ||
| {/* {mode === 'login' && <Promotion />} */} | ||
| </div> | ||
| ); | ||
| }; | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.