Refactor mobile detection to use unified composable
All checks were successful
Build And Push Image / docker (push) Successful in 2m52s
All checks were successful
Build And Push Image / docker (push) Successful in 2m52s
- Add useMobileDetection composable to centralize device detection logic - Replace direct utility imports with composable usage across components - Update MultipleNationalityInput, PhoneInputWrapper, and auth pages - Simplify mobile-specific styling and behavior handling - Improve code maintainability by consolidating detection logic
This commit is contained in:
@@ -153,21 +153,24 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
getOptimizedClasses,
|
||||
applyMobileSafariFixes
|
||||
} from '~/utils/mobile-safari-utils';
|
||||
import { useMobileDetection } from '~/composables/useMobileDetection';
|
||||
|
||||
definePageMeta({
|
||||
layout: false,
|
||||
middleware: 'guest'
|
||||
});
|
||||
|
||||
// Use unified mobile detection
|
||||
const mobileDetection = useMobileDetection();
|
||||
|
||||
// Mobile Safari optimization classes
|
||||
const containerClasses = computed(() => [
|
||||
'password-setup-page',
|
||||
...getOptimizedClasses()
|
||||
].join(' '));
|
||||
const containerClasses = computed(() => {
|
||||
const classes = ['password-setup-page'];
|
||||
if (mobileDetection.isMobile) classes.push('is-mobile');
|
||||
if (mobileDetection.isMobileSafari) classes.push('is-mobile-safari');
|
||||
if (mobileDetection.isIOS) classes.push('is-ios');
|
||||
return classes.join(' ');
|
||||
});
|
||||
|
||||
// Reactive state
|
||||
const loading = ref(false);
|
||||
@@ -300,13 +303,8 @@ const setupPassword = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
// Apply mobile Safari fixes
|
||||
// Component initialization
|
||||
onMounted(() => {
|
||||
// Apply mobile Safari fixes
|
||||
if (typeof window !== 'undefined') {
|
||||
applyMobileSafariFixes();
|
||||
}
|
||||
|
||||
console.log('[setup-password] Password setup page loaded for:', email.value);
|
||||
|
||||
// Check if we have required parameters
|
||||
|
||||
@@ -91,10 +91,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
getOptimizedClasses,
|
||||
applyMobileSafariFixes
|
||||
} from '~/utils/mobile-safari-utils';
|
||||
import { useMobileDetection } from '~/composables/useMobileDetection';
|
||||
|
||||
definePageMeta({
|
||||
layout: false,
|
||||
@@ -106,11 +103,17 @@ const route = useRoute();
|
||||
const email = computed(() => route.query.email as string || '');
|
||||
const partialWarning = computed(() => route.query.warning === 'partial');
|
||||
|
||||
// Use unified mobile detection
|
||||
const mobileDetection = useMobileDetection();
|
||||
|
||||
// Mobile Safari optimization classes
|
||||
const containerClasses = computed(() => [
|
||||
'verification-success',
|
||||
...getOptimizedClasses()
|
||||
].join(' '));
|
||||
const containerClasses = computed(() => {
|
||||
const classes = ['verification-success'];
|
||||
if (mobileDetection.isMobile) classes.push('is-mobile');
|
||||
if (mobileDetection.isMobileSafari) classes.push('is-mobile-safari');
|
||||
if (mobileDetection.isIOS) classes.push('is-ios');
|
||||
return classes.join(' ');
|
||||
});
|
||||
|
||||
// Setup password URL for Keycloak - Fixed URL structure
|
||||
const setupPasswordUrl = computed(() => {
|
||||
@@ -144,13 +147,8 @@ const goToPasswordSetup = () => {
|
||||
});
|
||||
};
|
||||
|
||||
// Apply mobile Safari fixes and track verification
|
||||
// Track verification
|
||||
onMounted(() => {
|
||||
// Apply mobile Safari fixes
|
||||
if (typeof window !== 'undefined') {
|
||||
applyMobileSafariFixes();
|
||||
}
|
||||
|
||||
console.log('[verify-success] Email verification completed', {
|
||||
email: email.value,
|
||||
partialWarning: partialWarning.value,
|
||||
|
||||
@@ -121,21 +121,24 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
getOptimizedClasses,
|
||||
applyMobileSafariFixes
|
||||
} from '~/utils/mobile-safari-utils';
|
||||
import { useMobileDetection } from '~/composables/useMobileDetection';
|
||||
|
||||
definePageMeta({
|
||||
layout: false,
|
||||
middleware: 'guest'
|
||||
});
|
||||
|
||||
// Use unified mobile detection
|
||||
const mobileDetection = useMobileDetection();
|
||||
|
||||
// Mobile Safari optimization classes
|
||||
const containerClasses = computed(() => [
|
||||
'verification-page',
|
||||
...getOptimizedClasses()
|
||||
].join(' '));
|
||||
const containerClasses = computed(() => {
|
||||
const classes = ['verification-page'];
|
||||
if (mobileDetection.isMobile) classes.push('is-mobile');
|
||||
if (mobileDetection.isMobileSafari) classes.push('is-mobile-safari');
|
||||
if (mobileDetection.isIOS) classes.push('is-ios');
|
||||
return classes.join(' ');
|
||||
});
|
||||
|
||||
// Reactive state
|
||||
const verifying = ref(true);
|
||||
@@ -202,13 +205,8 @@ const retryVerification = () => {
|
||||
verifyEmail();
|
||||
};
|
||||
|
||||
// Apply mobile Safari fixes and start verification
|
||||
// Start verification on mount
|
||||
onMounted(() => {
|
||||
// Apply mobile Safari fixes
|
||||
if (typeof window !== 'undefined') {
|
||||
applyMobileSafariFixes();
|
||||
}
|
||||
|
||||
console.log('[auth/verify] Starting email verification with token:', token.value?.substring(0, 20) + '...');
|
||||
|
||||
// Start verification process
|
||||
|
||||
@@ -209,14 +209,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { RegistrationFormData, RecaptchaConfig, RegistrationConfig } from '~/utils/types';
|
||||
import {
|
||||
getDeviceInfo,
|
||||
needsPerformanceOptimization,
|
||||
shouldDisableBackdropFilter,
|
||||
getOptimizedClasses,
|
||||
applyMobileSafariFixes,
|
||||
debounce
|
||||
} from '~/utils/mobile-safari-utils';
|
||||
import { useMobileDetection } from '~/composables/useMobileDetection';
|
||||
|
||||
// Declare global grecaptcha interface for TypeScript
|
||||
declare global {
|
||||
@@ -233,10 +226,8 @@ definePageMeta({
|
||||
layout: false
|
||||
});
|
||||
|
||||
// Mobile Safari optimization flags
|
||||
const deviceInfo = ref(getDeviceInfo());
|
||||
const performanceMode = ref(needsPerformanceOptimization());
|
||||
const disableBackdropFilter = ref(shouldDisableBackdropFilter());
|
||||
// Use unified mobile detection
|
||||
const mobileDetection = useMobileDetection();
|
||||
|
||||
// Configs with fallback defaults
|
||||
const recaptchaConfig = ref<RecaptchaConfig>({ siteKey: '', secretKey: '' });
|
||||
@@ -288,16 +279,22 @@ useHead({
|
||||
});
|
||||
|
||||
// Dynamic CSS classes based on device
|
||||
const containerClasses = computed(() => [
|
||||
'signup-container',
|
||||
...getOptimizedClasses()
|
||||
].join(' '));
|
||||
const containerClasses = computed(() => {
|
||||
const classes = ['signup-container'];
|
||||
if (mobileDetection.isMobile) classes.push('is-mobile');
|
||||
if (mobileDetection.isMobileSafari) classes.push('is-mobile-safari');
|
||||
if (mobileDetection.isIOS) classes.push('is-ios');
|
||||
return classes.join(' ');
|
||||
});
|
||||
|
||||
const cardClasses = computed(() => [
|
||||
'signup-card',
|
||||
performanceMode.value ? 'performance-optimized' : '',
|
||||
disableBackdropFilter.value ? 'no-backdrop-filter' : ''
|
||||
].filter(Boolean).join(' '));
|
||||
const cardClasses = computed(() => {
|
||||
const classes = ['signup-card'];
|
||||
if (mobileDetection.isMobileSafari) {
|
||||
classes.push('performance-optimized');
|
||||
classes.push('no-backdrop-filter');
|
||||
}
|
||||
return classes.filter(Boolean).join(' ');
|
||||
});
|
||||
|
||||
// Form validation rules
|
||||
const nameRules = [
|
||||
@@ -455,34 +452,35 @@ onMounted(async () => {
|
||||
if (typeof window === 'undefined') return;
|
||||
|
||||
try {
|
||||
// Load configs without complex timeout logic
|
||||
Promise.all([
|
||||
// Load reCAPTCHA config
|
||||
$fetch('/api/recaptcha-config').then((response: any) => {
|
||||
// Load reCAPTCHA config
|
||||
$fetch('/api/recaptcha-config')
|
||||
.then((response: any) => {
|
||||
if (response?.success && response?.data?.siteKey) {
|
||||
recaptchaConfig.value.siteKey = response.data.siteKey;
|
||||
loadRecaptchaScript(response.data.siteKey);
|
||||
}
|
||||
}).catch(() => {
|
||||
})
|
||||
.catch(() => {
|
||||
// Silently fail for reCAPTCHA - not critical
|
||||
}),
|
||||
|
||||
// Load registration config
|
||||
$fetch('/api/registration-config').then((response: any) => {
|
||||
console.debug('reCAPTCHA config not available');
|
||||
});
|
||||
|
||||
// Load registration config
|
||||
$fetch('/api/registration-config')
|
||||
.then((response: any) => {
|
||||
if (response?.success) {
|
||||
registrationConfig.value = response.data;
|
||||
}
|
||||
}).catch(() => {
|
||||
})
|
||||
.catch(() => {
|
||||
// Use defaults if config fails to load
|
||||
console.debug('Using default registration config');
|
||||
registrationConfig.value = {
|
||||
membershipFee: 150,
|
||||
iban: 'MC58 1756 9000 0104 0050 1001 860',
|
||||
accountHolder: 'ASSOCIATION MONACO USA'
|
||||
};
|
||||
})
|
||||
]).catch(() => {
|
||||
// Global fallback - don't let errors cause page reload
|
||||
});
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
// Prevent any errors from bubbling up and causing reload
|
||||
|
||||
Reference in New Issue
Block a user