174 lines
4.6 KiB
Vue
174 lines
4.6 KiB
Vue
<script setup lang="ts">
|
|
import { ref, computed } from 'vue'
|
|
|
|
const props = defineProps<{
|
|
address: string
|
|
secret?: string | null
|
|
hostname?: string | null
|
|
}>()
|
|
|
|
const emit = defineEmits<{
|
|
'update:address': [value: string]
|
|
'update:secret': [value: string | null]
|
|
'update:hostname': [value: string | null]
|
|
'discover': []
|
|
'manual': []
|
|
}>()
|
|
|
|
const localAddress = computed({
|
|
get: () => props.address,
|
|
set: (value) => emit('update:address', value?.trim())
|
|
})
|
|
|
|
const localSecret = computed({
|
|
get: () => props.secret,
|
|
set: (value) => emit('update:secret', value?.trim() || null)
|
|
})
|
|
|
|
const localHostname = computed({
|
|
get: () => props.hostname || '',
|
|
set: (value) => emit('update:hostname', value?.trim() || null)
|
|
})
|
|
|
|
const showSecret = ref(false)
|
|
|
|
const rules = {
|
|
required: (v: string) => !!v || 'Required',
|
|
email: (v: string) => /.+@.+\..+/.test(v) || 'Invalid email address'
|
|
}
|
|
|
|
function handleDiscoverOnEnter() {
|
|
if (!localAddress.value || rules.email(localAddress.value) !== true) {
|
|
return
|
|
}
|
|
|
|
emit('discover')
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="identity-entry-step">
|
|
<h3 class="text-h6 mb-2">Email Account Setup</h3>
|
|
<p class="text-body-2 text-medium-emphasis mb-6">
|
|
Enter your email address to automatically discover your mail server settings.
|
|
</p>
|
|
|
|
<v-text-field
|
|
v-model="localAddress"
|
|
label="Email Address"
|
|
type="email"
|
|
prepend-inner-icon="mdi-email"
|
|
variant="outlined"
|
|
required
|
|
autocomplete="off"
|
|
:rules="[rules.required, rules.email]"
|
|
class="mb-4"
|
|
@keydown.enter.prevent="handleDiscoverOnEnter"
|
|
/>
|
|
|
|
<!-- Advanced Options -->
|
|
<v-expansion-panels variant="accordion" class="mb-6">
|
|
<v-expansion-panel>
|
|
<v-expansion-panel-title>
|
|
<v-icon start>mdi-cog</v-icon>
|
|
Advanced Options (Optional)
|
|
</v-expansion-panel-title>
|
|
<v-expansion-panel-text>
|
|
|
|
<v-text-field
|
|
v-model="localSecret"
|
|
:type="showSecret ? 'text' : 'password'"
|
|
label="Password (Optional)"
|
|
hint="Provide password to validate credentials during discovery"
|
|
persistent-hint
|
|
prepend-inner-icon="mdi-lock"
|
|
variant="outlined"
|
|
autocomplete="new-password"
|
|
class="mb-4"
|
|
>
|
|
<template #append-inner>
|
|
<v-btn
|
|
:icon="showSecret ? 'mdi-eye-off' : 'mdi-eye'"
|
|
variant="text"
|
|
size="small"
|
|
@click="showSecret = !showSecret"
|
|
/>
|
|
</template>
|
|
</v-text-field>
|
|
|
|
<!-- Info -->
|
|
<v-alert
|
|
type="info"
|
|
variant="tonal"
|
|
density="compact"
|
|
class="mt-6"
|
|
>
|
|
<template #prepend>
|
|
<v-icon>mdi-information</v-icon>
|
|
</template>
|
|
<div class="text-caption">
|
|
Your credentials are used only to discover and test server settings.
|
|
They are transmitted securely and not stored during discovery.
|
|
</div>
|
|
</v-alert>
|
|
|
|
<v-text-field
|
|
v-model="localHostname"
|
|
label="Server Hostname"
|
|
hint="If you know your mail server hostname, enter it here to skip DNS lookup (e.g., mail.example.com)"
|
|
persistent-hint
|
|
prepend-inner-icon="mdi-server"
|
|
variant="outlined"
|
|
placeholder="mail.example.com"
|
|
clearable
|
|
/>
|
|
|
|
<v-alert type="info" variant="tonal" density="compact" class="mt-3">
|
|
<template #prepend>
|
|
<v-icon size="small">mdi-information</v-icon>
|
|
</template>
|
|
<div class="text-caption">
|
|
Providing a hostname will skip DNS SRV lookups and test the server directly.
|
|
Leave blank for automatic discovery.
|
|
</div>
|
|
</v-alert>
|
|
</v-expansion-panel-text>
|
|
</v-expansion-panel>
|
|
</v-expansion-panels>
|
|
|
|
<!-- Actions -->
|
|
<div class="d-flex flex-column gap-3">
|
|
<v-btn
|
|
color="primary"
|
|
size="large"
|
|
block
|
|
:disabled="!localAddress || !rules.email(localAddress)"
|
|
@click="$emit('discover')"
|
|
>
|
|
<v-icon start>mdi-magnify</v-icon>
|
|
Discover Settings
|
|
</v-btn>
|
|
|
|
<v-btn
|
|
variant="text"
|
|
block
|
|
class="manual-action-btn"
|
|
prepend-icon="mdi-tune"
|
|
@click="$emit('manual')"
|
|
>
|
|
Manual Configuration
|
|
</v-btn>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.gap-3 {
|
|
gap: 12px;
|
|
}
|
|
|
|
.manual-action-btn {
|
|
background-color: rgba(var(--v-theme-on-surface), 0.06);
|
|
}
|
|
</style>
|