chore: bunch of improvements
All checks were successful
JS Unit Tests / test (pull_request) Successful in 33s
Build Test / test (pull_request) Successful in 36s
PHP Unit Tests / test (pull_request) Successful in 1m12s

Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
This commit is contained in:
2026-04-23 22:00:50 -04:00
parent b617234b40
commit 3362afb7ec
28 changed files with 1717 additions and 1297 deletions

View File

@@ -0,0 +1,173 @@
<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>