Files
mws.frontend.vue/src/views/auth/LoginView.vue
T
2026-08-11 23:17:04 +07:00

75 lines
2.3 KiB
Vue

<template>
<div class="flex min-h-screen items-center justify-center bg-slate-100 p-4 dark:bg-slate-900">
<Button
:icon="theme.isDark.value ? 'pi pi-sun' : 'pi pi-moon'"
rounded
text
style="position: fixed; right: 1rem; top: 1rem; z-index: 10"
:aria-label="theme.isDark.value ? 'Switch to light mode' : 'Switch to dark mode'"
@click="theme.toggle"
/>
<Card class="w-full max-w-[380px]">
<template #title>
<div class="flex items-center gap-2">
<i class="pi pi-briefcase" style="color: #3b82f6"></i>
MWS My Workspace
</div>
</template>
<template #content>
<form @submit.prevent="submit">
<div class="field">
<label for="username">Username</label>
<InputText id="username" v-model.trim="username" class="w-full" autocomplete="username" />
</div>
<div class="field">
<label for="password">Password</label>
<InputText
id="password"
v-model="password"
type="password"
class="w-full"
autocomplete="current-password"
/>
</div>
<Message v-if="error" severity="error" variant="simple" class="mb-2 w-full">{{ error }}</Message>
<Button type="submit" label="Sign in" class="w-full" :loading="loading" />
</form>
</template>
</Card>
</div>
</template>
<script setup lang="ts">
import { useAuthStore } from '../../stores/auth'
import { errorMessage } from '../../services/api'
import { useTheme } from '../../composables/useTheme'
const auth = useAuthStore()
const theme = useTheme()
const router = useRouter()
const route = useRoute()
const username = ref('')
const password = ref('')
const loading = ref(false)
const error = ref('')
async function submit() {
error.value = ''
if (!username.value || !password.value) {
error.value = 'Username and password are required'
return
}
loading.value = true
try {
await auth.login(username.value, password.value)
const redirect = typeof route.query.redirect === 'string' ? route.query.redirect : '/projects'
router.push(redirect)
} catch (e) {
error.value = errorMessage(e)
} finally {
loading.value = false
}
}
</script>