Files
InsightReply/web/src/views/Login.vue
zs c686d81d30
All checks were successful
Web Console Deploy (Vue 3 + Vite) / deploy (push) Successful in 1m10s
Backend Deploy (Go + Docker) / deploy (push) Successful in 1m44s
feat: 前端登录跳转问题
2026-03-03 01:33:12 +08:00

69 lines
3.2 KiB
Vue

<script setup lang="ts">
import { ref } from 'vue'
import { useRouter } from 'vue-router'
import { Activity } from 'lucide-vue-next'
const router = useRouter()
const email = ref('')
const password = ref('')
const errorMsg = ref('')
const loading = ref(false)
const handleLogin = async () => {
errorMsg.value = ''
loading.value = true
const apiBase = import.meta.env.VITE_API_BASE_URL || 'http://localhost:8080/api/v1'
try {
const res = await fetch(`${apiBase}/auth/login`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email: email.value, password: password.value })
})
if (!res.ok) throw new Error('Invalid credentials')
const data = await res.json()
if (data.data && data.data.token) {
localStorage.setItem('jwt_token', data.data.token)
router.push('/dashboard')
} else {
throw new Error(data.message || 'Login failed')
}
} catch (err: any) {
errorMsg.value = err.message || 'Login failed'
} finally {
loading.value = false
}
}
</script>
<template>
<div class="h-screen w-full flex items-center justify-center relative bg-[#0B1120]">
<div class="glass-panel w-full max-w-sm p-8 z-10 flex flex-col items-center">
<div class="w-12 h-12 rounded-xl bg-gradient-to-br from-brand-primary to-blue-600 flex items-center justify-center mb-6">
<Activity color="white" :size="24" />
</div>
<h2 class="text-2xl font-bold text-white mb-2">Welcome Back</h2>
<p class="text-zinc-400 text-sm text-center mb-8">Sign in to orchestrate your AI reply strategy.</p>
<form @submit.prevent="handleLogin" class="w-full space-y-4">
<div v-if="errorMsg" class="bg-red-500/10 text-red-400 p-3 rounded-lg text-sm text-center">
{{ errorMsg }}
</div>
<div>
<label class="text-xs font-semibold text-zinc-500 uppercase tracking-widest block mb-2">Email</label>
<input v-model="email" type="email" required placeholder="founder@startup.com" class="w-full bg-black/20 border border-white/10 rounded-lg px-4 py-3 text-white placeholder-zinc-600 focus:outline-none focus:border-brand-primary/50 focus:ring-1 focus:ring-brand-primary/50 transition-all cursor-text pointer-events-auto" style="pointer-events: auto;" />
</div>
<div>
<label class="text-xs font-semibold text-zinc-500 uppercase tracking-widest block mb-2">Password</label>
<input v-model="password" type="password" required placeholder="••••••••" class="w-full bg-black/20 border border-white/10 rounded-lg px-4 py-3 text-white placeholder-zinc-600 focus:outline-none focus:border-brand-primary/50 focus:ring-1 focus:ring-brand-primary/50 transition-all cursor-text pointer-events-auto" style="pointer-events: auto;" />
</div>
<button type="submit" :disabled="loading" class="w-full bg-brand-primary hover:bg-blue-500 disabled:opacity-50 text-white font-medium rounded-lg px-4 py-3 mt-4 transition-all hover:shadow-[0_0_20px_rgba(59,130,246,0.3)] duration-300">
{{ loading ? 'Signing In...' : 'Sign In' }}
</button>
</form>
</div>
</div>
</template>