monacousa-portal/components/PhoneInputDemo.vue

165 lines
5.8 KiB
Vue

<template>
<div class="demo-container">
<v-card class="pa-6" elevation="2">
<v-card-title class="text-h5 mb-4">
📱 Professional Phone Input - Desktop & Mobile Optimized
</v-card-title>
<v-row>
<v-col cols="12" md="6">
<PhoneInputWrapper
v-model="phoneNumber"
label="Phone Number"
placeholder="Enter your phone number"
help-text="Clean Vuetify design with advanced mobile optimization"
@phone-data="handlePhoneData"
@country-changed="handleCountryChange"
/>
<div class="mt-4">
<v-btn
color="primary"
@click="testUSNumber"
variant="outlined"
size="small"
class="mr-2 mb-2"
>
Test: (917) 932-4061
</v-btn>
<v-btn
color="secondary"
@click="testMonacoNumber"
variant="outlined"
size="small"
class="mr-2 mb-2"
>
Test: Monaco +377
</v-btn>
<v-btn
color="accent"
@click="testFrenchNumber"
variant="outlined"
size="small"
class="mr-2 mb-2"
>
Test: France +33
</v-btn>
</div>
</v-col>
<v-col cols="12" md="6">
<v-card variant="outlined" class="pa-4">
<v-card-title class="text-subtitle-1">Live Phone Data:</v-card-title>
<div class="mt-2">
<p><strong>Number:</strong> <code>{{ phoneNumber }}</code></p>
<p><strong>Valid:</strong> {{ phoneData?.isValid ? '✅ Valid' : '❌ Invalid' }}</p>
<p><strong>Country:</strong> {{ phoneData?.country?.name }} ({{ phoneData?.country?.iso2 }})</p>
<p><strong>Dial Code:</strong> {{ phoneData?.country?.dialCode }}</p>
<p><strong>Device:</strong> {{ isMobile ? '📱 Mobile' : '🖥️ Desktop' }}</p>
</div>
</v-card>
</v-col>
</v-row>
<v-alert type="success" variant="tonal" class="mt-6">
<template #title>🎯 Perfect Desktop Implementation:</template>
<ul class="mt-2">
<li><strong>Clean Design:</strong> Exactly like your screenshot - Vuetify text field with flag inside</li>
<li><strong>Compact Dropdown:</strong> Max 240px height, not oversized</li>
<li><strong>Real Flags:</strong> High-quality country flags from flagcdn.com</li>
<li><strong>Monaco Priority:</strong> 🇲🇨 Monaco and 🇫🇷 France appear first</li>
<li><strong>Smart Formatting:</strong> Uses libphonenumber-js for proper formatting</li>
<li><strong>Search Functionality:</strong> Type to find countries quickly</li>
</ul>
</v-alert>
<v-alert type="info" variant="tonal" class="mt-4">
<template #title>📱 Advanced Mobile Optimization:</template>
<ul class="mt-2">
<li><strong>Mobile Detection:</strong> Automatic device detection with resize handling</li>
<li><strong>Full-Screen Modal:</strong> Mobile dropdown opens as centered modal with overlay</li>
<li><strong>Touch-Friendly:</strong> All elements sized for proper touch targets (44px+)</li>
<li><strong>iOS Safari Fixes:</strong> Prevents zoom on focus, proper appearance handling</li>
<li><strong>Android Material:</strong> Material Design touch targets and interactions</li>
<li><strong>Accessibility:</strong> Reduced motion, high contrast, screen reader support</li>
<li><strong>Safe Areas:</strong> Handles notched devices with proper padding</li>
<li><strong>Landscape Support:</strong> Optimized layout for landscape orientation</li>
<li><strong>Backdrop Blur:</strong> Modern glass morphism effects on supported devices</li>
<li><strong>Smooth Scrolling:</strong> Native touch scrolling with momentum</li>
</ul>
</v-alert>
<v-alert type="warning" variant="tonal" class="mt-4">
<template #title>🧪 Test Mobile Features:</template>
<p class="mt-2 mb-2">To test mobile features, try:</p>
<ul>
<li><strong>Resize Window:</strong> Make browser window narrow (< 768px)</li>
<li><strong>Developer Tools:</strong> Toggle device emulation in Chrome DevTools</li>
<li><strong>Touch Device:</strong> Test on actual phone/tablet for best experience</li>
</ul>
</v-alert>
</v-card>
</div>
</template>
<script setup lang="ts">
import PhoneInputWrapper from './PhoneInputWrapper.vue';
const phoneNumber = ref('');
const phoneData = ref<any>(null);
const isMobile = ref(false);
// Mobile detection
onMounted(() => {
const checkMobile = () => {
isMobile.value = window.innerWidth <= 768 || 'ontouchstart' in window;
};
checkMobile();
window.addEventListener('resize', checkMobile);
onUnmounted(() => {
window.removeEventListener('resize', checkMobile);
});
});
const handlePhoneData = (data: any) => {
phoneData.value = data;
console.log('Phone data:', data);
};
const handleCountryChange = (country: any) => {
console.log('Country changed:', country);
};
const testUSNumber = () => {
phoneNumber.value = '+19179324061';
};
const testMonacoNumber = () => {
phoneNumber.value = '+37799123456';
};
const testFrenchNumber = () => {
phoneNumber.value = '+33123456789';
};
</script>
<style scoped>
.demo-container {
max-width: 1000px;
margin: 0 auto;
padding: 20px;
}
code {
background: rgba(var(--v-theme-primary), 0.1);
padding: 2px 6px;
border-radius: 4px;
font-family: 'Roboto Mono', monospace;
font-size: 0.875rem;
}
</style>