feat: add LoginPage component

This commit is contained in:
2026-06-16 00:26:46 -06:00
parent 405fcbc0a3
commit 2503bf83fd

View File

@@ -0,0 +1,128 @@
<script setup lang="ts">
import { ref } from 'vue'
import { useAuth } from '../composables/useAuth'
const emit = defineEmits<{ success: [] }>()
const { login } = useAuth()
const username = ref('')
const password = ref('')
const error = ref('')
const loading = ref(false)
async function handleSubmit(): Promise<void> {
if (!username.value.trim() || !password.value) return
error.value = ''
loading.value = true
try {
await login(username.value.trim(), password.value)
emit('success')
} catch (e) {
error.value = e instanceof Error ? e.message : '登录失败'
} finally {
loading.value = false
}
}
</script>
<template>
<div class="login-wrapper">
<form class="login-form" @submit.prevent="handleSubmit">
<h1>教学设计</h1>
<div class="field">
<label for="username">用户名</label>
<input
id="username"
v-model="username"
type="text"
autocomplete="username"
:disabled="loading"
/>
</div>
<div class="field">
<label for="password">密码</label>
<input
id="password"
v-model="password"
type="password"
autocomplete="current-password"
:disabled="loading"
/>
</div>
<p v-if="error" class="error">{{ error }}</p>
<button type="submit" :disabled="loading || !username || !password">
{{ loading ? '登录中…' : '登录' }}
</button>
</form>
</div>
</template>
<style scoped>
.login-wrapper {
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
background: #f5f5f5;
}
.login-form {
background: white;
padding: 2rem;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
width: 320px;
display: flex;
flex-direction: column;
gap: 1rem;
}
.login-form h1 {
margin: 0;
font-size: 1.5rem;
text-align: center;
}
.field {
display: flex;
flex-direction: column;
gap: 0.25rem;
}
.field label {
font-size: 0.875rem;
color: #555;
}
.field input {
padding: 0.5rem;
border: 1px solid #ccc;
border-radius: 4px;
font-size: 1rem;
}
.field input:disabled {
background: #f5f5f5;
}
.error {
color: #c0392b;
font-size: 0.875rem;
margin: 0;
}
button[type='submit'] {
padding: 0.6rem;
background: #2c3e50;
color: white;
border: none;
border-radius: 4px;
font-size: 1rem;
cursor: pointer;
}
button[type='submit']:disabled {
opacity: 0.5;
cursor: not-allowed;
}
</style>