web/satellite: SelectInput, RegistrationSuccess components migrated to use composition api

Change-Id: Ic2d0e152d48e7b5b57780712905d51ab1139a77d
This commit is contained in:
NickolaiYurchenko 2022-12-21 18:09:24 +02:00 committed by Nikolay Yurchenko
parent 0b790070a3
commit ad9fbe2953
2 changed files with 126 additions and 141 deletions

View File

@ -50,115 +50,106 @@
</div>
</template>
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
<script setup lang="ts">
import { computed, onBeforeUnmount, onMounted, ref } from 'vue';
import { AuthHttpApi } from '@/api/auth';
import { RouteConfig } from '@/router';
import { useNotify, useRoute } from '@/utils/hooks';
import VButton from '@/components/common/VButton.vue';
import LogoIcon from '@/../static/images/logo.svg';
import MailIcon from '@/../static/images/register/mail.svg';
// @vue/component
@Component({
components: {
VButton,
LogoIcon,
MailIcon,
},
})
export default class RegistrationSuccess extends Vue {
@Prop({ default: '' })
private readonly email: string;
@Prop({ default: true })
private readonly showManualActivationMsg: boolean;
const props = withDefaults(defineProps<{
email: string;
showManualActivationMsg: boolean;
}>(), {
email: '',
showManualActivationMsg: true,
});
private secondsToWait = 30;
private intervalID: ReturnType<typeof setInterval>;
const route = useRoute();
const notify = useNotify();
private readonly auth: AuthHttpApi = new AuthHttpApi();
const auth: AuthHttpApi = new AuthHttpApi();
const loginPath: string = RouteConfig.Login.path;
public readonly loginPath: string = RouteConfig.Login.path;
const secondsToWait = ref<number>(30);
const intervalId = ref<ReturnType<typeof setInterval>>();
/**
* Lifecycle hook after initial render.
* Starts resend email button availability countdown.
*/
public mounted(): void {
this.startResendEmailCountdown();
}
/**
* Lifecycle hook before component destroying.
* Resets interval.
*/
public beforeDestroy(): void {
if (this.intervalID) {
clearInterval(this.intervalID);
}
}
/**
* Gets email (either passed in as prop or via query param).
*/
public get userEmail(): string {
return this.email || this.$route.query.email.toString();
}
/**
* Reloads page.
*/
public onLogoClick(): void {
location.replace(RouteConfig.Register.path);
}
const userEmail = computed((): string => {
return props.email || route.query.email.toString();
});
/**
* Checks if page is inside iframe.
*/
public get isInsideIframe(): boolean {
const isInsideIframe = computed((): boolean => {
return window.self !== window.top;
}
});
/**
* Returns the time left until the Resend Email button is enabled in mm:ss form.
*/
public get timeToEnableResendEmailButton(): string {
return `${Math.floor(this.secondsToWait / 60).toString().padStart(2, '0')}:${(this.secondsToWait % 60).toString().padStart(2, '0')}`;
}
const timeToEnableResendEmailButton = computed((): string => {
return `${Math.floor(secondsToWait.value / 60).toString().padStart(2, '0')}:${(secondsToWait.value % 60).toString().padStart(2, '0')}`;
});
/**
* Resend email if interval timer is expired.
* Reloads page.
*/
public async onResendEmailButtonClick(): Promise<void> {
const email = this.userEmail;
if (this.secondsToWait != 0 || !email) {
return;
}
try {
await this.auth.resendEmail(email);
} catch (error) {
await this.$notify.error(error.message, null);
}
this.startResendEmailCountdown();
function onLogoClick(): void {
location.replace(RouteConfig.Register.path);
}
/**
* Resets timer blocking email resend button spamming.
*/
private startResendEmailCountdown(): void {
this.secondsToWait = 30;
function startResendEmailCountdown(): void {
secondsToWait.value = 30;
this.intervalID = setInterval(() => {
if (--this.secondsToWait <= 0) {
clearInterval(this.intervalID);
intervalId.value = setInterval(() => {
if (--secondsToWait.value <= 0) {
clearInterval(intervalId.value);
}
}, 1000);
}
/**
* Resend email if interval timer is expired.
*/
async function onResendEmailButtonClick(): Promise<void> {
const email = userEmail.value;
if (secondsToWait.value != 0 || !email) {
return;
}
try {
await auth.resendEmail(email);
} catch (error) {
await notify.error(error.message, null);
}
startResendEmailCountdown();
}
/**
* Lifecycle hook after initial render.
* Starts resend email button availability countdown.
*/
onMounted(() => {
startResendEmailCountdown();
});
/**
* Lifecycle hook before component destroying.
* Resets interval.
*/
onBeforeUnmount(() => {
clearInterval(intervalId.value);
});
</script>
<style scoped lang="scss">

View File

@ -6,7 +6,7 @@
<div class="label-container">
<p v-if="label" class="label-container__label" :style="style.labelStyle">{{ label }}</p>
</div>
<InputCaret v-if="optionsList.length > 0" class="select-input__caret" />
<input-caret v-if="optionsList.length > 0" class="select-input__caret" />
<select
v-model="value"
:style="style.inputStyle"
@ -25,62 +25,56 @@
</div>
</template>
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
<script setup lang="ts">
import { computed, onBeforeMount, ref } from 'vue';
import InputCaret from '@/../static/images/common/caret.svg';
// Custom input component for login page
// @vue/component
@Component({
components: {
InputCaret,
},
})
export default class SelectInput extends Vue {
const props = withDefaults(defineProps<{
label?: string;
height?: string;
width?: string;
optionsList?: string[];
isWhite?: boolean;
}>(), {
label: '',
height: '48px',
width: '100%',
optionsList: () => [],
isWhite: false,
});
protected value = '';
const emit = defineEmits(['setData']);
@Prop({ default: '' })
protected readonly label: string;
@Prop({ default: '48px' })
protected readonly height: string;
@Prop({ default: '100%' })
protected readonly width: string;
@Prop({ default: () => [] })
protected readonly optionsList: string[];
@Prop({ default: false })
private readonly isWhite: boolean;
public created() {
this.value = this.optionsList ? this.optionsList[0] : '';
this.$emit('setData', this.value);
}
/**
* triggers on input.
*/
public onInput(event: Event): void {
const target = event.target as HTMLSelectElement;
this.$emit('setData', target.value);
}
const value = ref<string>('');
/**
* Returns style objects depends on props.
*/
protected get style(): Record<string, unknown> {
const style = computed((): Record<string, unknown> => {
return {
inputStyle: {
width: this.width,
height: this.height,
width: props.width,
height: props.height,
},
labelStyle: {
color: this.isWhite ? 'white' : '#354049',
color: props.isWhite ? 'white' : '#354049',
},
};
});
/**
* triggers on input.
*/
function onInput(event: Event): void {
const target = event.target as HTMLSelectElement;
emit('setData', target.value);
}
}
onBeforeMount(() => {
value.value = props.optionsList ? props.optionsList[0] : '';
emit('setData', value.value);
});
</script>
<style scoped lang="scss">