web/satellite: SelectInput, RegistrationSuccess components migrated to use composition api
Change-Id: Ic2d0e152d48e7b5b57780712905d51ab1139a77d
This commit is contained in:
parent
0b790070a3
commit
ad9fbe2953
@ -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();
|
||||
}
|
||||
const userEmail = computed((): string => {
|
||||
return props.email || route.query.email.toString();
|
||||
});
|
||||
|
||||
/**
|
||||
* Lifecycle hook before component destroying.
|
||||
* Resets interval.
|
||||
*/
|
||||
public beforeDestroy(): void {
|
||||
if (this.intervalID) {
|
||||
clearInterval(this.intervalID);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Checks if page is inside iframe.
|
||||
*/
|
||||
const isInsideIframe = computed((): boolean => {
|
||||
return window.self !== window.top;
|
||||
});
|
||||
|
||||
/**
|
||||
* Gets email (either passed in as prop or via query param).
|
||||
*/
|
||||
public get userEmail(): string {
|
||||
return this.email || this.$route.query.email.toString();
|
||||
}
|
||||
/**
|
||||
* Returns the time left until the Resend Email button is enabled in mm:ss form.
|
||||
*/
|
||||
const timeToEnableResendEmailButton = computed((): string => {
|
||||
return `${Math.floor(secondsToWait.value / 60).toString().padStart(2, '0')}:${(secondsToWait.value % 60).toString().padStart(2, '0')}`;
|
||||
});
|
||||
|
||||
/**
|
||||
* Reloads page.
|
||||
*/
|
||||
public onLogoClick(): void {
|
||||
location.replace(RouteConfig.Register.path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if page is inside iframe.
|
||||
*/
|
||||
public get isInsideIframe(): 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')}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resend email if interval timer is expired.
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets timer blocking email resend button spamming.
|
||||
*/
|
||||
private startResendEmailCountdown(): void {
|
||||
this.secondsToWait = 30;
|
||||
|
||||
this.intervalID = setInterval(() => {
|
||||
if (--this.secondsToWait <= 0) {
|
||||
clearInterval(this.intervalID);
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
/**
|
||||
* Reloads page.
|
||||
*/
|
||||
function onLogoClick(): void {
|
||||
location.replace(RouteConfig.Register.path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets timer blocking email resend button spamming.
|
||||
*/
|
||||
function startResendEmailCountdown(): void {
|
||||
secondsToWait.value = 30;
|
||||
|
||||
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">
|
||||
|
@ -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[];
|
||||
const value = ref<string>('');
|
||||
|
||||
@Prop({ default: false })
|
||||
private readonly isWhite: boolean;
|
||||
/**
|
||||
* Returns style objects depends on props.
|
||||
*/
|
||||
const style = computed((): Record<string, unknown> => {
|
||||
return {
|
||||
inputStyle: {
|
||||
width: props.width,
|
||||
height: props.height,
|
||||
},
|
||||
labelStyle: {
|
||||
color: props.isWhite ? 'white' : '#354049',
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns style objects depends on props.
|
||||
*/
|
||||
protected get style(): Record<string, unknown> {
|
||||
return {
|
||||
inputStyle: {
|
||||
width: this.width,
|
||||
height: this.height,
|
||||
},
|
||||
labelStyle: {
|
||||
color: this.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">
|
||||
|
Loading…
Reference in New Issue
Block a user