Files
hnh-map/frontend-nuxt/pages/login.vue
Nikolay Tatarinov adfdfd01c4 Update frontend components for accessibility and functionality improvements
- Modified docker-compose.dev.yml to conditionally run npm install based on the presence of package-lock.json.
- Upgraded Nuxt version in package-lock.json from 3.21.1 to 4.3.1 for enhanced features.
- Enhanced ConfirmModal component with aria-modal attribute for better accessibility.
- Updated MapErrorBoundary component's error message for clarity.
- Added role and aria-label attributes to MapView and MapSearch components for improved screen reader support.
- Refactored various components to manage focus behavior on modal close, enhancing user experience.
- Improved ToastContainer styling for better responsiveness and visibility.
- Updated layout components to include skip navigation links for improved accessibility.
2026-03-04 01:00:56 +03:00

76 lines
2.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<AuthCard>
<h1 class="card-title justify-center text-2xl">HnH Map</h1>
<p class="text-center text-base-content/70 text-sm">Log in to continue</p>
<div v-if="(oauthProviders ?? []).length" class="flex flex-col gap-2">
<a
v-for="p in (oauthProviders ?? [])"
:key="p"
:href="api.oauthLoginUrl(p, redirect || undefined)"
class="btn btn-outline gap-2"
>
<span v-if="p === 'google'">Login with Google</span>
<span v-else>Login with {{ p }}</span>
</a>
<div class="divider text-sm">or</div>
</div>
<form @submit.prevent="submit" class="flex flex-col gap-4">
<fieldset class="fieldset">
<label class="label" for="user">User</label>
<input
ref="userInputRef"
id="user"
v-model="user"
type="text"
class="input min-h-11 touch-manipulation"
required
autocomplete="username"
/>
</fieldset>
<PasswordInput
v-model="pass"
label="Password"
required
autocomplete="current-password"
/>
<p v-if="error" class="text-error text-sm">{{ error }}</p>
<button type="submit" class="btn btn-primary min-h-11 touch-manipulation" :disabled="loading">
<span v-if="loading" class="loading loading-spinner loading-sm" />
<span v-else>Log in</span>
</button>
</form>
</AuthCard>
</template>
<script setup lang="ts">
// No auth required; auth.global skips this path
useHead({ title: 'Login HnH Map' })
const user = ref('')
const pass = ref('')
const oauthProviders = ref<string[]>([])
const router = useRouter()
const route = useRoute()
const api = useMapApi()
const { loading, error, run } = useFormSubmit('Login failed')
const redirect = computed(() => (route.query.redirect as string) || '')
const userInputRef = ref<HTMLInputElement | null>(null)
onMounted(async () => {
oauthProviders.value = await api.oauthProviders()
if (import.meta.client && window.matchMedia('(pointer: fine)').matches) {
nextTick(() => userInputRef.value?.focus())
}
})
async function submit() {
await run(async () => {
await api.login(user.value, pass.value)
await router.push(redirect.value || '/')
})
}
</script>