LoginPage.vue 2.16 KB
<script setup>
import { ref } from 'vue'
import { useI18n } from 'vue-i18n'
import { useRoute, useRouter } from 'vue-router'
import { Button, Card, Input } from '@drama/ui'

import { api, setToken } from '../api.js'

const { t, locale } = useI18n()
const router = useRouter()
const route = useRoute()
const mode = ref('login')
const email = ref('')
const password = ref('')
const code = ref('')
const message = ref('')

async function sendCode() {
  await api('POST', '/api/voko/auth/send-code', { email: email.value, locale: locale.value })
  message.value = t('login.codeSent')
}

async function submit() {
  try {
    const session = mode.value === 'login'
      ? await api('POST', '/api/voko/auth/login', { method: 'password', email: email.value, password: password.value })
      : await api('POST', '/api/voko/auth/register', { email: email.value, password: password.value, verification_code: code.value, locale: locale.value })
    setToken(session.access_token)
    // 只接受站内路径(认领链接登录后回到认领页)。
    const next = typeof route.query.next === 'string' && route.query.next.startsWith('/') && !route.query.next.startsWith('//') ? route.query.next : '/'
    await router.push(next)
  } catch (err) {
    message.value = err instanceof Error ? err.message : String(err)
  }
}
</script>

<template>
  <Card>
    <h1>{{ mode === 'login' ? t('login.title') : t('login.registerTitle') }}</h1>
    <label class="voko-field">{{ t('login.email') }}<Input v-model="email" type="email" /></label>
    <label class="voko-field">{{ t('login.password') }}<Input v-model="password" type="password" /></label>
    <template v-if="mode === 'register'">
      <label class="voko-field">{{ t('login.code') }}<Input v-model="code" /></label>
      <Button variant="secondary" @click="sendCode">{{ t('login.sendCode') }}</Button>
    </template>
    <p v-if="message">{{ message }}</p>
    <Button @click="submit">{{ mode === 'login' ? t('login.submit') : t('login.register') }}</Button>
    <Button variant="ghost" @click="mode = mode === 'login' ? 'register' : 'login'">
      {{ mode === 'login' ? t('login.toRegister') : t('login.toLogin') }}
    </Button>
  </Card>
</template>