Refactor mobile detection to use built-in Nuxt device module
Some checks failed
Build And Push Image / docker (push) Failing after 2m27s
Some checks failed
Build And Push Image / docker (push) Failing after 2m27s
Replace custom useMobileDetection composable with Nuxt's useDevice(), removing reactive mobile detection in favor of static detection to prevent reload loops and simplify viewport handling
This commit is contained in:
@@ -157,24 +157,14 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useMobileDetection } from '~/composables/useMobileDetection';
|
||||
|
||||
definePageMeta({
|
||||
layout: false,
|
||||
middleware: 'guest'
|
||||
});
|
||||
|
||||
// Use unified mobile detection
|
||||
const mobileDetection = useMobileDetection();
|
||||
|
||||
// Mobile Safari optimization classes
|
||||
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(' ');
|
||||
});
|
||||
// Static CSS classes based on device (no reactive dependencies)
|
||||
const containerClasses = ref('password-setup-page');
|
||||
|
||||
// Reactive state
|
||||
const loading = ref(false);
|
||||
@@ -252,25 +242,12 @@ useHead({
|
||||
]
|
||||
});
|
||||
|
||||
// Toggle password visibility with debouncing on mobile
|
||||
// Toggle password visibility - simplified for static detection
|
||||
const togglePasswordVisibility = (field: 'password' | 'confirm') => {
|
||||
// Prevent rapid toggling which can cause issues on mobile
|
||||
if (mobileDetection.isMobile) {
|
||||
// Use nextTick to defer the update
|
||||
nextTick(() => {
|
||||
if (field === 'password') {
|
||||
showPassword.value = !showPassword.value;
|
||||
} else {
|
||||
showConfirmPassword.value = !showConfirmPassword.value;
|
||||
}
|
||||
});
|
||||
if (field === 'password') {
|
||||
showPassword.value = !showPassword.value;
|
||||
} else {
|
||||
// Immediate toggle on desktop
|
||||
if (field === 'password') {
|
||||
showPassword.value = !showPassword.value;
|
||||
} else {
|
||||
showConfirmPassword.value = !showConfirmPassword.value;
|
||||
}
|
||||
showConfirmPassword.value = !showConfirmPassword.value;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -333,13 +310,26 @@ const setupPassword = async () => {
|
||||
onMounted(() => {
|
||||
console.log('[setup-password] Password setup page loaded for:', email.value);
|
||||
|
||||
// Static device detection from Nuxt Device Module - no reactive dependencies
|
||||
const { isMobile, isIos, isSafari } = useDevice();
|
||||
|
||||
// Detect mobile Safari specifically
|
||||
const isMobileSafari = isMobile && isIos && isSafari;
|
||||
|
||||
// Apply classes once (static, no reactivity)
|
||||
const containerClassList = ['password-setup-page'];
|
||||
if (isMobile) containerClassList.push('is-mobile');
|
||||
if (isMobileSafari) containerClassList.push('is-mobile-safari');
|
||||
if (isIos) containerClassList.push('is-ios');
|
||||
containerClasses.value = containerClassList.join(' ');
|
||||
|
||||
// Check if we have required parameters
|
||||
if (!email.value) {
|
||||
errorMessage.value = 'No email address provided. Please use the link from your verification email.';
|
||||
}
|
||||
|
||||
// Prevent auto-zoom on iOS when focusing input fields
|
||||
if (mobileDetection.isIOS) {
|
||||
if (isIos) {
|
||||
const metaViewport = document.querySelector('meta[name="viewport"]');
|
||||
if (metaViewport) {
|
||||
metaViewport.setAttribute('content', 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no');
|
||||
|
||||
@@ -209,7 +209,6 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { RegistrationFormData, RecaptchaConfig, RegistrationConfig } from '~/utils/types';
|
||||
import { useMobileDetection } from '~/composables/useMobileDetection';
|
||||
|
||||
// Declare global grecaptcha interface for TypeScript
|
||||
declare global {
|
||||
@@ -226,8 +225,6 @@ definePageMeta({
|
||||
layout: false
|
||||
});
|
||||
|
||||
// Use unified mobile detection
|
||||
const mobileDetection = useMobileDetection();
|
||||
|
||||
// Configs with fallback defaults
|
||||
const recaptchaConfig = ref<RecaptchaConfig>({ siteKey: '', secretKey: '' });
|
||||
@@ -266,7 +263,7 @@ const configsLoaded = ref(false);
|
||||
|
||||
// Success dialog state
|
||||
const showSuccessDialog = ref(false);
|
||||
const registrationResult = ref<{ memberId: string; email: string } | null>(null);
|
||||
const registrationResult = ref<{ memberId: string; email: string } | undefined>(undefined);
|
||||
|
||||
// Head configuration
|
||||
useHead({
|
||||
@@ -278,23 +275,9 @@ useHead({
|
||||
]
|
||||
});
|
||||
|
||||
// Dynamic CSS classes based on device
|
||||
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(() => {
|
||||
const classes = ['signup-card'];
|
||||
if (mobileDetection.isMobileSafari) {
|
||||
classes.push('performance-optimized');
|
||||
classes.push('no-backdrop-filter');
|
||||
}
|
||||
return classes.filter(Boolean).join(' ');
|
||||
});
|
||||
// Static CSS classes based on device (no reactive dependencies)
|
||||
const containerClasses = ref('signup-container');
|
||||
const cardClasses = ref('signup-card');
|
||||
|
||||
// Form validation rules
|
||||
const nameRules = [
|
||||
@@ -451,6 +434,26 @@ onMounted(async () => {
|
||||
// Prevent multiple initializations
|
||||
if (typeof window === 'undefined') return;
|
||||
|
||||
// Static device detection from Nuxt Device Module - no reactive dependencies
|
||||
const { isMobile, isIos, isSafari } = useDevice();
|
||||
|
||||
// Detect mobile Safari specifically
|
||||
const isMobileSafari = isMobile && isIos && isSafari;
|
||||
|
||||
// Apply classes once (static, no reactivity)
|
||||
const containerClassList = ['signup-container'];
|
||||
if (isMobile) containerClassList.push('is-mobile');
|
||||
if (isMobileSafari) containerClassList.push('is-mobile-safari');
|
||||
if (isIos) containerClassList.push('is-ios');
|
||||
containerClasses.value = containerClassList.join(' ');
|
||||
|
||||
const cardClassList = ['signup-card'];
|
||||
if (isMobileSafari) {
|
||||
cardClassList.push('performance-optimized');
|
||||
cardClassList.push('no-backdrop-filter');
|
||||
}
|
||||
cardClasses.value = cardClassList.filter(Boolean).join(' ');
|
||||
|
||||
try {
|
||||
// Load reCAPTCHA config
|
||||
$fetch('/api/recaptcha-config')
|
||||
|
||||
Reference in New Issue
Block a user