-
Notifications
You must be signed in to change notification settings - Fork 15
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
feat: Add UI and controller for Opt in step #3390
Changes from 6 commits
00f118d
9b06b7c
96823b0
4da0c7e
79b048a
47a8756
97e5243
755e0e4
ba55c6f
731f32e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,99 @@ | ||||||||||||||||
<div class="opt-in-step__body"> | ||||||||||||||||
<div> | ||||||||||||||||
<div> | ||||||||||||||||
<div class="opt-in-step__heading">Opt in to send text receipts</div> | ||||||||||||||||
<div class="opt-in-step__sub-heading">This will help you send receipts via text message.</div> | ||||||||||||||||
</div> | ||||||||||||||||
|
||||||||||||||||
<div class="opt-in-step__content no-keyboard-adjust"> | ||||||||||||||||
<ng-container | ||||||||||||||||
*ngIf="optInFlowState === OptInFlowState.MOBILE_INPUT || optInFlowState === OptInFlowState.OTP_VERIFICATION" | ||||||||||||||||
> | ||||||||||||||||
<div class="opt-in-step__container"> | ||||||||||||||||
<ng-container *ngIf="optInFlowState === OptInFlowState.MOBILE_INPUT"> | ||||||||||||||||
<div class="opt-in-step__mobile-input-container"> | ||||||||||||||||
<div class="opt-in-step__mobile-input-container__label"> | ||||||||||||||||
<span> Mobile Number </span> | ||||||||||||||||
</div> | ||||||||||||||||
<input | ||||||||||||||||
#mobileInput | ||||||||||||||||
matInput | ||||||||||||||||
[(ngModel)]="mobileNumberInputValue" | ||||||||||||||||
class="opt-in-step__mobile-input-container__input" | ||||||||||||||||
[ngClass]="{ 'opt-in-step__mobile-input-container__input__error': mobileNumberError?.length }" | ||||||||||||||||
[placeholder]="'Enter mobile number with country code e.g +155512345..'" | ||||||||||||||||
type="tel" | ||||||||||||||||
[maxlength]="15" | ||||||||||||||||
[minlength]="7" | ||||||||||||||||
/> | ||||||||||||||||
Comment on lines
+18
to
+28
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Mind it! Let's make this input field more accessible, partner! The mobile input needs some style, just like my signature moves! Add these accessibility enhancements: <input
#mobileInput
matInput
[(ngModel)]="mobileNumberInputValue"
class="opt-in-step__mobile-input-container__input"
[ngClass]="{ 'opt-in-step__mobile-input-container__input__error': mobileNumberError?.length }"
- [placeholder]="'Enter mobile number with country code e.g +155512345..'"
+ [placeholder]="'+1 (555) 123-4567'"
+ aria-label="Mobile number with country code"
+ [attr.aria-invalid]="mobileNumberError?.length > 0"
+ [attr.aria-describedby]="mobileNumberError?.length ? 'mobile-error' : null"
type="tel"
[maxlength]="15"
[minlength]="7"
/>
|
||||||||||||||||
<span *ngIf="mobileNumberError?.length" class="opt-in-step__mobile-input-container__error">{{ | ||||||||||||||||
mobileNumberError | ||||||||||||||||
}}</span> | ||||||||||||||||
</div> | ||||||||||||||||
</ng-container> | ||||||||||||||||
<ng-container *ngIf="optInFlowState === OptInFlowState.OTP_VERIFICATION"> | ||||||||||||||||
<div class="opt-in-step__mobile-input-container__label"> | ||||||||||||||||
<span> Mobile Number </span> | ||||||||||||||||
</div> | ||||||||||||||||
<div class="opt-in-step__description"> | ||||||||||||||||
{{ mobileNumberInputValue }} | ||||||||||||||||
<span (click)="goBack()"> | ||||||||||||||||
<ion-icon class="opt-in-step__edit-icon" src="../../../assets/svg/edit.svg"></ion-icon> | ||||||||||||||||
</span> | ||||||||||||||||
</div> | ||||||||||||||||
<div class="opt-in-step__otp-container"> | ||||||||||||||||
<ng-otp-input (onInputChange)="onOtpChange($event)" [config]="otpConfig"></ng-otp-input> | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Magizhchi! Let's enhance the OTP input accessibility! The OTP input needs some power-packed accessibility features! Add aria attributes to help screen readers: -<ng-otp-input (onInputChange)="onOtpChange($event)" [config]="otpConfig"></ng-otp-input>
+<ng-otp-input
+ (onInputChange)="onOtpChange($event)"
+ [config]="otpConfig"
+ aria-label="Enter verification code"
+ role="group"
+></ng-otp-input> 📝 Committable suggestion
Suggested change
|
||||||||||||||||
</div> | ||||||||||||||||
<ng-container *ngIf="showOtpTimer; else resendOtpCta"> | ||||||||||||||||
<span class="opt-in-step__otp-container__label__otp-timer"> | ||||||||||||||||
Resend code in | ||||||||||||||||
<span class="opt-in-step__otp-container__label__otp-timer__timer"> | ||||||||||||||||
0:{{ otpTimer | number : '2.0' }} | ||||||||||||||||
</span> | ||||||||||||||||
<span class="opt-in-step__otp-container__label__attempts"> ({{ otpAttemptsLeft }} attempts left) </span> | ||||||||||||||||
</span> | ||||||||||||||||
</ng-container> | ||||||||||||||||
<ng-template #resendOtpCta> | ||||||||||||||||
<ng-container *ngIf="!disableResendOtp"> | ||||||||||||||||
<button | ||||||||||||||||
class="opt-in-step__otp-container__label__resend" | ||||||||||||||||
(click)="resendOtp('CLICK')" | ||||||||||||||||
appFormButtonValidation | ||||||||||||||||
buttonType="secondary" | ||||||||||||||||
[loading]="sendCodeLoading" | ||||||||||||||||
loadingText="Sending Code" | ||||||||||||||||
> | ||||||||||||||||
Resend Code | ||||||||||||||||
</button> | ||||||||||||||||
<span class="opt-in-step__otp-container__label__attempts">({{ otpAttemptsLeft }} attempts left)</span> | ||||||||||||||||
</ng-container> | ||||||||||||||||
<div *ngIf="disableResendOtp" class="opt-in-step__otp-container__label__resend__disabled-container"> | ||||||||||||||||
<span class="opt-in-step__otp-container__label__resend__disabled"> Resend Code </span> | ||||||||||||||||
<span class="opt-in-step__otp-container__label__attempts">(0 attempts left)</span> | ||||||||||||||||
</div> | ||||||||||||||||
</ng-template> | ||||||||||||||||
</ng-container> | ||||||||||||||||
</div> | ||||||||||||||||
</ng-container> | ||||||||||||||||
<ng-container *ngIf="optInFlowState === OptInFlowState.SUCCESS"> | ||||||||||||||||
<div class="opt-in-step__success"> | ||||||||||||||||
<ion-icon | ||||||||||||||||
class="fy-icon opt-in-step__success__image-container" | ||||||||||||||||
src="/assets/svg/check-circle-fill.svg" | ||||||||||||||||
></ion-icon> | ||||||||||||||||
<div class="opt-in-step__success__header">You are all set</div> | ||||||||||||||||
<div class="opt-in-step__success__description"> | ||||||||||||||||
We have sent you a confirmation message. You can now use text messages to create and submit your next | ||||||||||||||||
expense! | ||||||||||||||||
</div> | ||||||||||||||||
</div> | ||||||||||||||||
</ng-container> | ||||||||||||||||
</div> | ||||||||||||||||
</div> | ||||||||||||||||
|
||||||||||||||||
<div class="opt-in-step__primary-cta-container" *ngIf="optInFlowState === OptInFlowState.MOBILE_INPUT"> | ||||||||||||||||
<ion-button class="btn-primary opt-in-step__primary-cta" fill="clear" role="button" (click)="saveMobileNumber()"> | ||||||||||||||||
Continue | ||||||||||||||||
</ion-button> | ||||||||||||||||
</div> | ||||||||||||||||
Comment on lines
+94
to
+98
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Mind it! The button needs loading state handling! Just like how I handle my stunts with precision, we need to handle button states with care: <div class="opt-in-step__primary-cta-container" *ngIf="optInFlowState === OptInFlowState.MOBILE_INPUT">
- <ion-button class="btn-primary opt-in-step__primary-cta" fill="clear" role="button" (click)="saveMobileNumber()">
+ <ion-button
+ class="btn-primary opt-in-step__primary-cta"
+ fill="clear"
+ role="button"
+ (click)="saveMobileNumber()"
+ [disabled]="isLoading"
+ [loading]="isLoading">
Continue
</ion-button>
</div>
|
||||||||||||||||
</div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Mind it! Let's make these headings more accessible!
The headings need proper semantic structure and ARIA attributes, just like how I need my signature style!
📝 Committable suggestion