Add Mobile Safari optimizations and fixes to signup page
All checks were successful
Build And Push Image / docker (push) Successful in 3m10s

- Implement device detection and performance optimization flags
- Add dynamic CSS classes based on device capabilities
- Create mobile safari utility functions and client plugin
- Optimize backdrop filters and hardware acceleration for iOS
- Fix viewport height issues with mobile Safari fallbacks
- Update membership fee config and add IBAN payment details
- Prevent horizontal scrolling and improve mobile UX
This commit is contained in:
2025-08-09 18:36:10 +02:00
parent 358e9c0ad1
commit 44cdc988ee
3 changed files with 270 additions and 8 deletions

View File

@@ -1,9 +1,9 @@
<template>
<div class="signup-container">
<div :class="containerClasses">
<v-container fluid class="fill-height">
<v-row class="fill-height" justify="center" align="center">
<v-col cols="12" sm="10" md="8" lg="6" xl="5">
<v-card class="signup-card" elevation="24" :loading="loading">
<v-card :class="cardClasses" elevation="24" :loading="loading">
<v-card-text class="pa-8">
<!-- Logo and Welcome -->
<div class="text-center mb-6">
@@ -209,6 +209,14 @@
<script setup lang="ts">
import type { RegistrationFormData, RecaptchaConfig, RegistrationConfig } from '~/utils/types';
import {
getDeviceInfo,
needsPerformanceOptimization,
shouldDisableBackdropFilter,
getOptimizedClasses,
applyMobileSafariFixes,
debounce
} from '~/utils/mobile-safari-utils';
// Declare global grecaptcha interface for TypeScript
declare global {
@@ -225,12 +233,17 @@ definePageMeta({
layout: false
});
// Configs - need to be declared first
// Mobile Safari optimization flags
const deviceInfo = ref(getDeviceInfo());
const performanceMode = ref(needsPerformanceOptimization());
const disableBackdropFilter = ref(shouldDisableBackdropFilter());
// Configs with fallback defaults
const recaptchaConfig = ref<RecaptchaConfig>({ siteKey: '', secretKey: '' });
const registrationConfig = ref<RegistrationConfig>({
membershipFee: 50,
iban: '',
accountHolder: ''
membershipFee: 150,
iban: 'MC58 1756 9000 0104 0050 1001 860',
accountHolder: 'ASSOCIATION MONACO USA'
});
// Reactive data - Using individual refs to prevent Vue reactivity corruption
@@ -258,6 +271,7 @@ const loading = ref(false);
const recaptchaToken = ref('');
const successMessage = ref('');
const errorMessage = ref('');
const configsLoaded = ref(false);
// Success dialog state
const showSuccessDialog = ref(false);
@@ -268,10 +282,23 @@ useHead({
title: 'Register - MonacoUSA Portal',
meta: [
{ name: 'description', content: 'Register to become a member of MonacoUSA Association' },
{ name: 'robots', content: 'noindex, nofollow' }
{ name: 'robots', content: 'noindex, nofollow' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no' }
]
});
// Dynamic CSS classes based on device
const containerClasses = computed(() => [
'signup-container',
...getOptimizedClasses()
].join(' '));
const cardClasses = computed(() => [
'signup-card',
performanceMode.value ? 'performance-optimized' : '',
disableBackdropFilter.value ? 'no-backdrop-filter' : ''
].filter(Boolean).join(' '));
// Form validation rules
const nameRules = [
(v: string) => !!v || 'Name is required',
@@ -465,9 +492,10 @@ onMounted(async () => {
</script>
<style scoped>
/* Base container styles */
.signup-container {
min-height: 100vh;
min-height: 100dvh; /* Dynamic viewport height for mobile */
min-height: calc(var(--vh, 1vh) * 100); /* Mobile Safari fallback */
background: linear-gradient(rgba(163, 21, 21, 0.7), rgba(0, 0, 0, 0.5)),
url('/monaco_high_res.jpg');
background-size: cover;
@@ -476,6 +504,19 @@ onMounted(async () => {
background-attachment: scroll;
padding: 20px 0;
position: relative;
overflow-x: hidden; /* Prevent horizontal scroll on mobile */
}
/* Mobile Safari optimizations */
.signup-container.is-mobile-safari {
min-height: 100vh;
min-height: -webkit-fill-available;
background-attachment: scroll !important; /* Force scroll attachment */
}
.signup-container.performance-mode {
will-change: auto; /* Reduce repainting */
transform: translateZ(0); /* Force hardware acceleration but lighter */
}
/* Ensure background covers full content */
@@ -496,6 +537,13 @@ onMounted(async () => {
min-height: 100%;
}
/* Performance mode background - simpler for mobile */
.signup-container.performance-mode::before {
background: linear-gradient(rgba(163, 21, 21, 0.8), rgba(0, 0, 0, 0.6));
/* Remove background image on low-performance devices */
}
/* Default card styles */
.signup-card {
backdrop-filter: blur(15px);
background: rgba(255, 255, 255, 0.95) !important;
@@ -507,10 +555,30 @@ onMounted(async () => {
width: 100%;
}
/* Performance optimized card */
.signup-card.performance-optimized {
backdrop-filter: none; /* Remove expensive filter */
background: rgba(255, 255, 255, 0.98) !important;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2) !important; /* Lighter shadow */
transition: none; /* Remove animations for better performance */
}
/* No backdrop filter fallback */
.signup-card.no-backdrop-filter {
backdrop-filter: none;
background: rgba(255, 255, 255, 0.98) !important;
}
.signup-card:hover {
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.4) !important;
}
/* Disable hover effects on performance mode */
.signup-card.performance-optimized:hover {
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2) !important;
transform: none;
}
.payment-info {
background: rgba(163, 21, 21, 0.05);
border-radius: 12px;