monacousa-portal/pages/auth/verify-success.vue

266 lines
7.1 KiB
Vue

<template>
<div :class="containerClasses">
<v-container class="fill-height" fluid>
<v-row align="center" justify="center">
<v-col cols="12" sm="8" md="6" lg="4">
<v-card class="elevation-12 rounded-lg">
<v-card-text class="text-center pa-8">
<div class="mb-6">
<v-icon
color="success"
size="80"
class="mb-4"
>
mdi-check-circle
</v-icon>
<h1 class="text-h4 font-weight-bold text-success mb-3">
Email Verified Successfully!
</h1>
<p class="text-body-1 text-medium-emphasis mb-2" v-if="email">
Your email address <strong>{{ email }}</strong> has been verified.
</p>
<p class="text-body-1 text-medium-emphasis mb-6">
Your MonacoUSA Portal account is now active and ready to use.
You can now log in to access your dashboard and member features.
</p>
<!-- Warning message for partial verification -->
<v-alert
v-if="partialWarning"
type="warning"
variant="tonal"
class="mb-4 text-start"
icon="mdi-information"
>
<div class="text-body-2">
<strong>Note:</strong> Your email has been verified, but there may have been
a minor issue updating your account status. If you experience any login
problems, please contact support.
</div>
</v-alert>
</div>
<div class="d-flex flex-column gap-3">
<v-btn
color="primary"
size="large"
variant="elevated"
block
@click="goToPasswordSetup"
class="text-none"
>
<v-icon start>mdi-lock-plus</v-icon>
Set Your Password
</v-btn>
<v-btn
color="outline"
size="small"
variant="text"
block
to="/"
class="text-none"
>
<v-icon start>mdi-home</v-icon>
Return to Home
</v-btn>
</div>
<!-- Additional help -->
<div class="mt-6 pt-4 border-t">
<p class="text-caption text-medium-emphasis mb-2">
Need help? Contact support at:
</p>
<v-chip
size="small"
variant="outlined"
prepend-icon="mdi-email"
>
support@monacousa.org
</v-chip>
</div>
</v-card-text>
</v-card>
</v-col>
</v-row>
</v-container>
</div>
</template>
<script setup lang="ts">
definePageMeta({
layout: false,
middleware: 'guest'
});
// Get query parameters
const route = useRoute();
const email = ref((route.query.email as string) || '');
const partialWarning = ref(route.query.warning === 'partial');
// Simple device detection
const isMobile = ref(false);
const isMobileSafari = ref(false);
// Initialize device detection on mount
onMounted(() => {
if (process.client) {
const userAgent = navigator.userAgent;
isMobile.value = /Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent) || window.innerWidth <= 768;
isMobileSafari.value = /iPhone|iPad|iPod/i.test(userAgent) && /Safari/i.test(userAgent);
}
});
// CSS classes based on device detection
const containerClasses = computed(() => {
const classes = ['verification-success'];
if (isMobile.value) classes.push('is-mobile');
if (isMobileSafari.value) classes.push('is-mobile-safari');
return classes.join(' ');
});
// Set page title with mobile viewport optimization
useHead({
title: 'Email Verified - MonacoUSA Portal',
meta: [
{
name: 'description',
content: 'Your email has been successfully verified. You can now log in to the MonacoUSA Portal.'
},
{
name: 'viewport',
content: 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover'
}
]
});
// Go to password setup page
const goToPasswordSetup = () => {
navigateTo({
path: '/auth/setup-password',
query: {
email: email.value
}
});
};
// Track verification
onMounted(() => {
console.log('[verify-success] Email verification completed', {
email: email.value,
partialWarning: partialWarning.value
});
});
</script>
<style scoped>
.verification-success {
min-height: 100vh;
min-height: calc(var(--vh, 1vh) * 100); /* Mobile Safari fallback */
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
overflow-x: hidden; /* Prevent horizontal scroll on mobile */
}
/* Mobile Safari optimizations */
.verification-success.is-mobile-safari {
min-height: 100vh;
min-height: -webkit-fill-available;
}
.verification-success.performance-mode {
will-change: auto;
transform: translateZ(0); /* Lighter hardware acceleration */
}
.fill-height {
min-height: 100vh;
min-height: calc(var(--vh, 1vh) * 100); /* Mobile Safari fallback */
}
/* Mobile Safari fill-height optimization */
.is-mobile-safari .fill-height {
min-height: -webkit-fill-available;
}
.border-t {
border-top: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
}
.gap-3 {
gap: 12px;
}
/* Animation for the success icon - reduced for performance mode */
.v-icon {
animation: bounce 0.6s ease-in-out;
}
.performance-mode .v-icon {
animation: none; /* Disable animations on performance mode */
}
@keyframes bounce {
0%, 20%, 53%, 80%, 100% {
transform: translate3d(0, 0, 0);
}
40%, 43% {
transform: translate3d(0, -8px, 0);
}
70% {
transform: translate3d(0, -4px, 0);
}
90% {
transform: translate3d(0, -2px, 0);
}
}
/* Custom scrollbar for mobile */
::-webkit-scrollbar {
width: 4px;
}
::-webkit-scrollbar-track {
background: rgba(255, 255, 255, 0.1);
}
::-webkit-scrollbar-thumb {
background: rgba(163, 21, 21, 0.5);
border-radius: 2px;
}
/* Responsive adjustments */
@media (max-width: 600px) {
.verification-success {
padding: 16px;
}
.v-card {
margin: 0;
}
/* Optimize button spacing on mobile */
.gap-3 {
gap: 8px;
}
}
/* Improve touch targets on mobile */
@media (hover: none) and (pointer: coarse) {
.v-btn {
min-height: 48px; /* Ensure touch-friendly button size */
}
}
/* Performance mode optimizations */
.performance-mode .v-card {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1) !important; /* Lighter shadow */
}
.performance-mode .v-btn {
transition: none; /* Remove button transitions for better performance */
}
</style>