web/satellite: PasswordStrength, NewBillingAddCouponCodeInput components migrated to use composition api
Change-Id: I1b878a7bce574c34ec424e7c8b94077c65fa9529
This commit is contained in:
parent
af238e2ef9
commit
b683f83994
@ -28,58 +28,54 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Vue } from 'vue-property-decorator';
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
|
||||
import { PAYMENTS_ACTIONS } from '@/store/modules/payments';
|
||||
import { AnalyticsHttpApi } from '@/api/analytics';
|
||||
import { AnalyticsErrorEventSource } from '@/utils/constants/analyticsEventNames';
|
||||
import { useNotify, useStore } from '@/utils/hooks';
|
||||
|
||||
import VInput from '@/components/common/VInput.vue';
|
||||
import ValidationMessage from '@/components/common/ValidationMessage.vue';
|
||||
import VButton from '@/components/common/VButton.vue';
|
||||
|
||||
// @vue/component
|
||||
@Component({
|
||||
components: {
|
||||
VButton,
|
||||
VInput,
|
||||
ValidationMessage,
|
||||
},
|
||||
})
|
||||
export default class NewBillingAddCouponCodeInput extends Vue {
|
||||
private showValidationMessage = false;
|
||||
private isCodeValid = false;
|
||||
private errorMessage = '';
|
||||
private couponCode = '';
|
||||
private isLoading = false;
|
||||
const store = useStore();
|
||||
const notify = useNotify();
|
||||
|
||||
private readonly analytics = new AnalyticsHttpApi();
|
||||
const emit = defineEmits(['close']);
|
||||
|
||||
public setCouponCode(value: string): void {
|
||||
this.couponCode = value;
|
||||
}
|
||||
const showValidationMessage = ref<boolean>(false);
|
||||
const isCodeValid = ref<boolean>(false);
|
||||
const errorMessage = ref<string>('');
|
||||
const couponCode = ref<string>('');
|
||||
const isLoading = ref<boolean>(false);
|
||||
|
||||
/**
|
||||
* Check if coupon code is valid
|
||||
*/
|
||||
public async applyCouponCode(): Promise<void> {
|
||||
if (this.isLoading) return;
|
||||
const analytics = new AnalyticsHttpApi();
|
||||
|
||||
this.isLoading = true;
|
||||
function setCouponCode(value: string): void {
|
||||
couponCode.value = value;
|
||||
}
|
||||
|
||||
try {
|
||||
await this.$store.dispatch(PAYMENTS_ACTIONS.APPLY_COUPON_CODE, this.couponCode);
|
||||
await this.$notify.success('Coupon Added!');
|
||||
this.$emit('close');
|
||||
} catch (error) {
|
||||
this.errorMessage = error.message;
|
||||
this.isCodeValid = false;
|
||||
this.showValidationMessage = true;
|
||||
this.analytics.errorEventTriggered(AnalyticsErrorEventSource.BILLING_APPLY_COUPON_CODE_INPUT);
|
||||
} finally {
|
||||
this.isLoading = false;
|
||||
}
|
||||
/**
|
||||
* Check if coupon code is valid
|
||||
*/
|
||||
async function applyCouponCode(): Promise<void> {
|
||||
if (isLoading.value) return;
|
||||
|
||||
isLoading.value = true;
|
||||
|
||||
try {
|
||||
await store.dispatch(PAYMENTS_ACTIONS.APPLY_COUPON_CODE, couponCode.value);
|
||||
await notify.success('Coupon Added!');
|
||||
emit('close');
|
||||
} catch (error) {
|
||||
errorMessage.value = error.message;
|
||||
isCodeValid.value = false;
|
||||
showValidationMessage.value = true;
|
||||
await analytics.errorEventTriggered(AnalyticsErrorEventSource.BILLING_APPLY_COUPON_CODE_INPUT);
|
||||
} finally {
|
||||
isLoading.value = false;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -34,8 +34,8 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Prop, Vue } from 'vue-property-decorator';
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { Validator } from '@/utils/validation';
|
||||
|
||||
@ -54,141 +54,124 @@ class BarFillStyle {
|
||||
}
|
||||
}
|
||||
|
||||
const PASSWORD_STRENGTH = {
|
||||
veryStrong: 'Very Strong',
|
||||
strong: 'Strong',
|
||||
good: 'Good',
|
||||
weak: 'Weak',
|
||||
};
|
||||
|
||||
const PASSWORD_STRENGTH_COLORS = {
|
||||
[PASSWORD_STRENGTH.good]: '#ffff00',
|
||||
[PASSWORD_STRENGTH.strong]: '#bfff00',
|
||||
[PASSWORD_STRENGTH.veryStrong]: '#00ff40',
|
||||
default: '#e16c58',
|
||||
};
|
||||
|
||||
const BAR_WIDTH = {
|
||||
[PASSWORD_STRENGTH.weak]: '25%',
|
||||
[PASSWORD_STRENGTH.good]: '50%',
|
||||
[PASSWORD_STRENGTH.strong]: '75%',
|
||||
[PASSWORD_STRENGTH.veryStrong]: '100%',
|
||||
default: '0px',
|
||||
};
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
passwordString?: string;
|
||||
isShown?: boolean;
|
||||
}>(), {
|
||||
passwordString: '',
|
||||
isShown: false,
|
||||
});
|
||||
|
||||
const isPasswordLengthAcceptable = computed((): boolean => {
|
||||
return Validator.password(props.passwordString);
|
||||
});
|
||||
|
||||
/**
|
||||
* StrengthLabelColor class holds info for StrengthLabelColor entity.
|
||||
* Returns password strength label depends on score.
|
||||
*/
|
||||
class StrengthLabelColor {
|
||||
color: string;
|
||||
|
||||
public constructor(color: string) {
|
||||
this.color = color;
|
||||
}
|
||||
}
|
||||
|
||||
// @vue/component
|
||||
@Component({
|
||||
components: {
|
||||
VectorIcon,
|
||||
},
|
||||
})
|
||||
export default class PasswordStrength extends Vue {
|
||||
@Prop({ default: '' })
|
||||
private readonly passwordString: string;
|
||||
/**
|
||||
* Indicates if component should be rendered.
|
||||
*/
|
||||
@Prop({ default: false })
|
||||
private readonly isShown: boolean;
|
||||
|
||||
public get isPasswordLengthAcceptable(): boolean {
|
||||
return Validator.password(this.passwordString);
|
||||
const passwordStrength = computed((): string => {
|
||||
if (props.passwordString.length < Validator.PASS_MIN_LENGTH) {
|
||||
return `Use ${Validator.PASS_MIN_LENGTH} or more characters`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns password strength label depends on score.
|
||||
*/
|
||||
public get passwordStrength(): string {
|
||||
if (this.passwordString.length < Validator.PASS_MIN_LENGTH) {
|
||||
return `Use ${Validator.PASS_MIN_LENGTH} or more characters`;
|
||||
}
|
||||
|
||||
if (this.passwordString.length > Validator.PASS_MAX_LENGTH) {
|
||||
return `Use ${Validator.PASS_MAX_LENGTH} or fewer characters`;
|
||||
}
|
||||
|
||||
const score = this.scorePassword();
|
||||
if (score > 90) {
|
||||
return 'Very Strong';
|
||||
}
|
||||
if (score > 70) {
|
||||
return 'Strong';
|
||||
}
|
||||
if (score > 45) {
|
||||
return 'Good';
|
||||
}
|
||||
|
||||
return 'Weak';
|
||||
if (props.passwordString.length > Validator.PASS_MAX_LENGTH) {
|
||||
return `Use ${Validator.PASS_MAX_LENGTH} or fewer characters`;
|
||||
}
|
||||
|
||||
public get barFillStyle(): BarFillStyle {
|
||||
return new BarFillStyle(this.passwordStrengthColor, this.barWidth);
|
||||
const score = scorePassword();
|
||||
if (score > 90) {
|
||||
return PASSWORD_STRENGTH.veryStrong;
|
||||
}
|
||||
if (score > 70) {
|
||||
return PASSWORD_STRENGTH.strong;
|
||||
}
|
||||
if (score > 45) {
|
||||
return PASSWORD_STRENGTH.good;
|
||||
}
|
||||
|
||||
public get strengthLabelColor(): StrengthLabelColor {
|
||||
return new StrengthLabelColor(this.passwordStrengthColor);
|
||||
return PASSWORD_STRENGTH.weak;
|
||||
});
|
||||
|
||||
/**
|
||||
* Color for indicator between red as weak and green as strong password.
|
||||
*/
|
||||
const passwordStrengthColor = computed((): string => {
|
||||
return PASSWORD_STRENGTH_COLORS[passwordStrength.value] || PASSWORD_STRENGTH_COLORS.default;
|
||||
});
|
||||
|
||||
/**
|
||||
* Fills password strength indicator bar.
|
||||
*/
|
||||
const barWidth = computed((): string => {
|
||||
return BAR_WIDTH[passwordStrength.value] || BAR_WIDTH.default;
|
||||
});
|
||||
|
||||
const strengthLabelColor = computed((): { color: string } => {
|
||||
return { color: passwordStrengthColor.value };
|
||||
});
|
||||
|
||||
const hasLowerAndUpperCaseLetters = computed((): boolean => {
|
||||
return /[a-z]/.test(props.passwordString) && /[A-Z]/.test(props.passwordString);
|
||||
});
|
||||
|
||||
const hasSpecialCharacter = computed((): boolean => {
|
||||
return /\W/.test(props.passwordString);
|
||||
});
|
||||
|
||||
const barFillStyle = computed((): BarFillStyle => {
|
||||
return new BarFillStyle(passwordStrengthColor.value, barWidth.value);
|
||||
});
|
||||
|
||||
/**
|
||||
* Returns password strength score depends on length, case variations and special characters.
|
||||
*/
|
||||
function scorePassword(): number {
|
||||
const password: string = props.passwordString;
|
||||
let score = 0;
|
||||
|
||||
const letters: number[] = [];
|
||||
for (let i = 0; i < password.length; i++) {
|
||||
letters[password[i]] = (letters[password[i]] || 0) + 1;
|
||||
score += 5 / letters[password[i]];
|
||||
}
|
||||
|
||||
public get hasLowerAndUpperCaseLetters(): boolean {
|
||||
return /[a-z]/.test(this.passwordString) && /[A-Z]/.test(this.passwordString);
|
||||
}
|
||||
const variations: boolean[] = [
|
||||
/\d/.test(password),
|
||||
/[a-z]/.test(password),
|
||||
/[A-Z]/.test(password),
|
||||
/\W/.test(password),
|
||||
];
|
||||
|
||||
public get hasSpecialCharacter(): boolean {
|
||||
return /\W/.test(this.passwordString);
|
||||
}
|
||||
let variationCount = 0;
|
||||
variations.forEach((check) => {
|
||||
variationCount += check ? 1 : 0;
|
||||
});
|
||||
|
||||
/**
|
||||
* Returns password strength score depends on length, case variations and special characters.
|
||||
*/
|
||||
private scorePassword(): number {
|
||||
const password: string = this.passwordString;
|
||||
let score = 0;
|
||||
score += variationCount * 10;
|
||||
|
||||
const letters: number[] = [];
|
||||
for (let i = 0; i < password.length; i++) {
|
||||
letters[password[i]] = (letters[password[i]] || 0) + 1;
|
||||
score += 5 / letters[password[i]];
|
||||
}
|
||||
|
||||
const variations: boolean[] = [
|
||||
/\d/.test(password),
|
||||
/[a-z]/.test(password),
|
||||
/[A-Z]/.test(password),
|
||||
/\W/.test(password),
|
||||
];
|
||||
|
||||
let variationCount = 0;
|
||||
variations.forEach((check) => {
|
||||
variationCount += check ? 1 : 0;
|
||||
});
|
||||
|
||||
score += variationCount * 10;
|
||||
|
||||
return score;
|
||||
}
|
||||
|
||||
/**
|
||||
* Color for indicator between red as weak and green as strong password.
|
||||
*/
|
||||
private get passwordStrengthColor(): string {
|
||||
switch (this.passwordStrength) {
|
||||
case 'Good':
|
||||
return '#ffff00';
|
||||
case 'Strong':
|
||||
return '#bfff00';
|
||||
case 'Very Strong':
|
||||
return '#00ff40';
|
||||
}
|
||||
|
||||
return '#e16c58';
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills password strength indicator bar.
|
||||
*/
|
||||
private get barWidth(): string {
|
||||
switch (this.passwordStrength) {
|
||||
case 'Weak':
|
||||
return '25%';
|
||||
case 'Good':
|
||||
return '50%';
|
||||
case 'Strong':
|
||||
return '75%';
|
||||
case 'Very Strong':
|
||||
return '100%';
|
||||
}
|
||||
|
||||
return '0px';
|
||||
}
|
||||
return score;
|
||||
}
|
||||
</script>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user