Refactor mobile detection to use built-in Nuxt device module
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:
2025-08-10 14:38:02 +02:00
parent fd08c38ade
commit 2eaf9cda95
10 changed files with 532 additions and 462 deletions

View File

@@ -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');