web/satellite: migrate ForgotPassword component to use SFC composition api

Change-Id: I9a69e95183efa79aa13b469091c452b6074b4d69
This commit is contained in:
Vitalii 2023-04-04 17:58:52 +03:00 committed by Egon Elbre
parent 3336a24c5d
commit 7cf840ee98

View File

@ -38,7 +38,7 @@
<SelectedCheckIcon /> <SelectedCheckIcon />
<span class="forgot-area__expand__dropdown__item__name">{{ satelliteName }}</span> <span class="forgot-area__expand__dropdown__item__name">{{ satelliteName }}</span>
</li> </li>
<li v-for="sat in partneredSatellites" :key="sat.id"> <li v-for="sat in partneredSatellites" :key="sat.name">
<a class="forgot-area__expand__dropdown__item" :href="sat.address + '/forgot-password'"> <a class="forgot-area__expand__dropdown__item" :href="sat.address + '/forgot-password'">
{{ sat.name }} {{ sat.name }}
</a> </a>
@ -94,8 +94,8 @@
</div> </div>
</template> </template>
<script lang="ts"> <script setup lang="ts">
import { Component, Vue } from 'vue-property-decorator'; import { computed, onMounted, reactive, ref } from 'vue';
import VueRecaptcha from 'vue-recaptcha'; import VueRecaptcha from 'vue-recaptcha';
import VueHcaptcha from '@hcaptcha/vue-hcaptcha'; import VueHcaptcha from '@hcaptcha/vue-hcaptcha';
@ -105,6 +105,7 @@ import { PartneredSatellite } from '@/types/common';
import { Validator } from '@/utils/validation'; import { Validator } from '@/utils/validation';
import { MetaUtils } from '@/utils/meta'; import { MetaUtils } from '@/utils/meta';
import { AnalyticsHttpApi } from '@/api/analytics'; import { AnalyticsHttpApi } from '@/api/analytics';
import { useNotify, useRouter, useStore } from '@/utils/hooks';
import VInput from '@/components/common/VInput.vue'; import VInput from '@/components/common/VInput.vue';
import VButton from '@/components/common/VButton.vue'; import VButton from '@/components/common/VButton.vue';
@ -115,173 +116,145 @@ import CloseIcon from '@/../static/images/notifications/closeSmall.svg';
import SelectedCheckIcon from '@/../static/images/common/selectedCheck.svg'; import SelectedCheckIcon from '@/../static/images/common/selectedCheck.svg';
import BottomArrowIcon from '@/../static/images/common/lightBottomArrow.svg'; import BottomArrowIcon from '@/../static/images/common/lightBottomArrow.svg';
// @vue/component const store = useStore();
@Component({ const notify = useNotify();
components: { const nativeRouter = useRouter();
VInput, const router = reactive(nativeRouter);
VButton,
BottomArrowIcon,
SelectedCheckIcon,
LogoIcon,
InfoIcon,
CloseIcon,
VueRecaptcha,
VueHcaptcha,
},
})
export default class ForgotPassword extends Vue {
private email = '';
private emailError = '';
private captchaResponseToken = '';
private isLoading = false;
private isPasswordResetExpired = false;
private isMessageShowing = true;
private readonly recaptchaEnabled: boolean = MetaUtils.getMetaContent('login-recaptcha-enabled') === 'true'; const recaptchaEnabled: boolean = MetaUtils.getMetaContent('login-recaptcha-enabled') === 'true';
private readonly recaptchaSiteKey: string = MetaUtils.getMetaContent('login-recaptcha-site-key'); const recaptchaSiteKey: string = MetaUtils.getMetaContent('login-recaptcha-site-key');
private readonly hcaptchaEnabled: boolean = MetaUtils.getMetaContent('login-hcaptcha-enabled') === 'true'; const hcaptchaEnabled: boolean = MetaUtils.getMetaContent('login-hcaptcha-enabled') === 'true';
private readonly hcaptchaSiteKey: string = MetaUtils.getMetaContent('login-hcaptcha-site-key'); const hcaptchaSiteKey: string = MetaUtils.getMetaContent('login-hcaptcha-site-key');
const auth: AuthHttpApi = new AuthHttpApi();
const analytics: AnalyticsHttpApi = new AnalyticsHttpApi();
const loginPath: string = RouteConfig.Login.path;
private readonly auth: AuthHttpApi = new AuthHttpApi(); const email = ref<string>('');
const emailError = ref<string>('');
const captchaResponseToken = ref<string>('');
const isLoading = ref<boolean>(false);
const isPasswordResetExpired = ref<boolean>(false);
const isMessageShowing = ref<boolean>(true);
const isDropdownShown = ref<boolean>(false);
const captcha = ref<VueRecaptcha | VueHcaptcha>();
public readonly analytics: AnalyticsHttpApi = new AnalyticsHttpApi(); /**
* Name of the current satellite.
*/
const satelliteName = computed((): string => {
return store.state.appStateModule.satelliteName;
});
// tardigrade logic /**
public isDropdownShown = false; * Information about partnered satellites, including name and signup link.
*/
const partneredSatellites = computed((): PartneredSatellite[] => {
return store.state.appStateModule.partneredSatellites;
});
public readonly loginPath: string = RouteConfig.Login.path; /**
* Close the expiry message banner.
public $refs!: { */
captcha: VueRecaptcha | VueHcaptcha; function closeMessage() {
}; isMessageShowing.value = false;
public mounted(): void {
this.isPasswordResetExpired = this.$route.query.expired === 'true';
}
/**
* Close the expiry message banner.
*/
public closeMessage() {
this.isMessageShowing = false;
}
/**
* Sets the email field to the given value.
*/
public setEmail(value: string): void {
this.email = value.trim();
this.emailError = '';
}
/**
* Name of the current satellite.
*/
public get satelliteName(): string {
return this.$store.state.appStateModule.satelliteName;
}
/**
* Information about partnered satellites, including name and signup link.
*/
public get partneredSatellites(): PartneredSatellite[] {
return this.$store.state.appStateModule.partneredSatellites;
}
/**
* Toggles satellite selection dropdown visibility (Tardigrade).
*/
public toggleDropdown(): void {
this.isDropdownShown = !this.isDropdownShown;
}
/**
* Closes satellite selection dropdown (Tardigrade).
*/
public closeDropdown(): void {
this.isDropdownShown = false;
}
/**
* Handles captcha verification response.
*/
public onCaptchaVerified(response: string): void {
this.captchaResponseToken = response;
this.onSendConfigurations();
}
/**
* Handles captcha error.
*/
public onCaptchaError(): void {
this.captchaResponseToken = '';
this.$notify.error('The captcha encountered an error. Please try again.', null);
}
/**
* Sends recovery password email.
*/
public async onSendConfigurations(): Promise<void> {
let activeElement = document.activeElement;
if (activeElement && activeElement.id === 'resetDropdown') return;
if (this.isLoading || !this.validateFields()) {
return;
}
if (this.$refs.captcha && !this.captchaResponseToken) {
this.$refs.captcha.execute();
return;
}
if (this.isDropdownShown) {
this.isDropdownShown = false;
return;
}
this.isLoading = true;
try {
await this.auth.forgotPassword(this.email, this.captchaResponseToken);
await this.$notify.success('Please look for instructions in your email');
} catch (error) {
await this.$notify.error(error.message, null);
}
this.$refs.captcha?.reset();
this.captchaResponseToken = '';
this.isLoading = false;
}
/**
* Changes location to Login route.
*/
public onBackToLoginClick(): void {
this.analytics.pageVisit(RouteConfig.Login.path);
this.$router.push(RouteConfig.Login.path);
}
/**
* Redirects to storj.io homepage.
*/
public onLogoClick(): void {
const homepageURL = MetaUtils.getMetaContent('homepage-url');
window.location.href = homepageURL;
}
/**
* Returns whether the email address is properly structured.
*/
private validateFields(): boolean {
const isEmailValid = Validator.email(this.email);
if (!isEmailValid) {
this.emailError = 'Invalid Email';
}
return isEmailValid;
}
} }
/**
* Sets the email field to the given value.
*/
function setEmail(value: string): void {
email.value = value.trim();
emailError.value = '';
}
/**
* Toggles satellite selection dropdown visibility (Partnered).
*/
function toggleDropdown(): void {
isDropdownShown.value = !isDropdownShown.value;
}
/**
* Closes satellite selection dropdown (Partnered).
*/
function closeDropdown(): void {
isDropdownShown.value = false;
}
/**
* Handles captcha verification response.
*/
function onCaptchaVerified(response: string): void {
captchaResponseToken.value = response;
onSendConfigurations();
}
/**
* Handles captcha error.
*/
function onCaptchaError(): void {
captchaResponseToken.value = '';
notify.error('The captcha encountered an error. Please try again.', null);
}
/**
* Sends recovery password email.
*/
async function onSendConfigurations(): Promise<void> {
let activeElement = document.activeElement;
if (activeElement && activeElement.id === 'resetDropdown') return;
if (isLoading.value || !validateFields()) {
return;
}
if (captcha.value && !captchaResponseToken.value) {
captcha.value.execute();
return;
}
if (isDropdownShown.value) {
closeDropdown();
return;
}
isLoading.value = true;
try {
await auth.forgotPassword(email.value, captchaResponseToken.value);
await notify.success('Please look for instructions in your email');
} catch (error) {
await notify.error(error.message, null);
}
captcha.value?.reset();
captchaResponseToken.value = '';
isLoading.value = false;
}
/**
* Redirects to storj.io homepage.
*/
function onLogoClick(): void {
window.location.href = MetaUtils.getMetaContent('homepage-url');
}
/**
* Returns whether the email address is properly structured.
*/
function validateFields(): boolean {
const isEmailValid = Validator.email(email.value);
if (!isEmailValid) {
emailError.value = 'Invalid Email';
}
return isEmailValid;
}
onMounted((): void => {
isPasswordResetExpired.value = router.currentRoute.query.expired === 'true';
});
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">