Implement compression quota refunds and admin manual subscription
This commit is contained in:
83
frontend/src/pages/ResetPasswordPage.vue
Normal file
83
frontend/src/pages/ResetPasswordPage.vue
Normal file
@@ -0,0 +1,83 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
|
||||
import { resetPassword } from '@/services/api'
|
||||
import { ApiError } from '@/services/http'
|
||||
|
||||
const route = useRoute()
|
||||
const token = computed(() => (typeof route.query.token === 'string' ? route.query.token : ''))
|
||||
|
||||
const newPassword = ref('')
|
||||
const busy = ref(false)
|
||||
const error = ref<string | null>(null)
|
||||
const success = ref<string | null>(null)
|
||||
|
||||
async function submit() {
|
||||
error.value = null
|
||||
success.value = null
|
||||
if (!token.value) {
|
||||
error.value = '缺少 token'
|
||||
return
|
||||
}
|
||||
|
||||
busy.value = true
|
||||
try {
|
||||
const resp = await resetPassword(token.value, newPassword.value)
|
||||
success.value = resp.message
|
||||
} catch (err) {
|
||||
if (err instanceof ApiError) {
|
||||
error.value = `[${err.code}] ${err.message}`
|
||||
} else {
|
||||
error.value = '重置失败,请稍后再试'
|
||||
}
|
||||
} finally {
|
||||
busy.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="mx-auto max-w-md">
|
||||
<div class="rounded-xl border border-slate-200 bg-white p-6">
|
||||
<h1 class="text-xl font-semibold text-slate-900">重置密码</h1>
|
||||
|
||||
<div v-if="error" class="mt-4 rounded-lg border border-rose-200 bg-rose-50 p-3 text-sm text-rose-900">
|
||||
{{ error }}
|
||||
</div>
|
||||
<div
|
||||
v-if="success"
|
||||
class="mt-4 rounded-lg border border-emerald-200 bg-emerald-50 p-3 text-sm text-emerald-900"
|
||||
>
|
||||
{{ success }}
|
||||
</div>
|
||||
|
||||
<form class="mt-5 space-y-4" @submit.prevent="submit">
|
||||
<label class="block space-y-1">
|
||||
<div class="text-xs font-medium text-slate-600">新密码</div>
|
||||
<input
|
||||
v-model="newPassword"
|
||||
type="password"
|
||||
autocomplete="new-password"
|
||||
class="w-full rounded-md border border-slate-200 bg-white px-3 py-2 text-sm text-slate-800"
|
||||
placeholder="至少 8 位"
|
||||
required
|
||||
/>
|
||||
</label>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
class="w-full rounded-md bg-indigo-600 px-3 py-2 text-sm font-medium text-white hover:bg-indigo-700 disabled:opacity-50"
|
||||
:disabled="busy"
|
||||
>
|
||||
{{ busy ? '提交中…' : '重置密码' }}
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div class="mt-4 text-sm text-slate-600">
|
||||
<router-link to="/login" class="text-indigo-600 hover:text-indigo-700">返回登录</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user