v0.0.54: 사용자 인증 화면 UX 보정
회원가입/로그인 공개 화면의 모바일 가독성과 입력 피드백을 다듬고, 비밀번호 보기 토글과 상태 메시지 분리로 인증 전환 흐름을 명확히 했다. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -7,6 +7,7 @@ const currentStep = ref(1)
|
||||
const resendCooldown = ref(0)
|
||||
const isSubmitting = ref(false)
|
||||
const signupCompleted = ref(false)
|
||||
const statusMessage = ref('')
|
||||
const { data: siteSettings } = await useFetch('/api/site-settings', {
|
||||
default: () => ({
|
||||
title: 'AFFiNE',
|
||||
@@ -29,8 +30,8 @@ const errors = reactive({
|
||||
})
|
||||
|
||||
const canResend = computed(() => resendCooldown.value <= 0)
|
||||
const welcomeTitle = computed(() => `Welcome to ${siteSettings.value.title || 'AFFiNE'}`)
|
||||
const welcomeDescription = computed(() => siteSettings.value.description || 'Configure your Self Host AFFiNE with a few simple settings.')
|
||||
const welcomeTitle = computed(() => `Welcome to ${siteSettings.value?.title || 'AFFiNE'}`)
|
||||
const welcomeDescription = computed(() => siteSettings.value?.description || 'Configure your Self Host AFFiNE with a few simple settings.')
|
||||
|
||||
/**
|
||||
* 필드 에러 메시지를 초기화한다.
|
||||
@@ -88,6 +89,8 @@ const validateStepTwo = () => {
|
||||
* @returns {void}
|
||||
*/
|
||||
const goNextStep = () => {
|
||||
statusMessage.value = ''
|
||||
|
||||
if (currentStep.value === 1) {
|
||||
currentStep.value = 2
|
||||
return
|
||||
@@ -110,6 +113,7 @@ const goNextStep = () => {
|
||||
const goPreviousStep = () => {
|
||||
if (currentStep.value > 1 && !isSubmitting.value) {
|
||||
currentStep.value -= 1
|
||||
statusMessage.value = ''
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,6 +130,7 @@ const resendVerificationEmail = async () => {
|
||||
await new Promise((resolve) => setTimeout(resolve, 500))
|
||||
isSubmitting.value = false
|
||||
resendCooldown.value = 30
|
||||
statusMessage.value = '인증 메일을 다시 보냈습니다. 메일함을 확인해 주세요.'
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -137,6 +142,7 @@ const completeSignup = async () => {
|
||||
await new Promise((resolve) => setTimeout(resolve, 600))
|
||||
isSubmitting.value = false
|
||||
signupCompleted.value = true
|
||||
statusMessage.value = '이메일 인증이 완료되었습니다. 로그인 페이지로 이동할 수 있습니다.'
|
||||
}
|
||||
|
||||
const countdownTimer = ref(/** @type {ReturnType<typeof setInterval> | null} */ (null))
|
||||
@@ -158,11 +164,11 @@ onBeforeUnmount(() => {
|
||||
|
||||
<template>
|
||||
<section class="auth-signup min-h-screen bg-[#0a0b0d] text-[#f5f7fa]">
|
||||
<div class="mx-auto flex min-h-screen w-full max-w-[1280px] items-start px-8 py-24 sm:px-16">
|
||||
<div class="flex min-h-[calc(100vh-12rem)] w-full max-w-[430px] flex-col">
|
||||
<div class="mx-auto flex min-h-screen w-full max-w-[1280px] items-start px-5 py-12 sm:px-10 sm:py-16 lg:px-16 lg:py-24">
|
||||
<div class="flex min-h-[calc(100vh-6rem)] w-full max-w-[430px] flex-col rounded-2xl border border-[#1a212a] bg-[#0d1116] p-5 sm:min-h-[calc(100vh-8rem)] sm:p-8 lg:min-h-[calc(100vh-12rem)]">
|
||||
<div>
|
||||
<template v-if="currentStep === 1">
|
||||
<p class="text-[40px] font-semibold leading-tight">
|
||||
<p class="text-[32px] font-semibold leading-tight sm:text-[40px]">
|
||||
{{ welcomeTitle }}
|
||||
</p>
|
||||
<p class="mt-2 text-sm text-[#9ba3af]">
|
||||
@@ -240,6 +246,14 @@ onBeforeUnmount(() => {
|
||||
비밀번호는 8~32자로 설정해 주세요.<br>
|
||||
권장사항: 대문자, 소문자, 숫자, 기호 2개를 포함해 주세요.
|
||||
</p>
|
||||
|
||||
<p class="mt-4 text-xs text-[#9ba3af]">
|
||||
이미 계정이 있다면
|
||||
<NuxtLink class="text-[#7eb8ff] hover:opacity-80" to="/signin">
|
||||
로그인
|
||||
</NuxtLink>
|
||||
하세요.
|
||||
</p>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
@@ -265,14 +279,14 @@ onBeforeUnmount(() => {
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<p v-if="signupCompleted" class="mt-4 text-sm text-[#7ccf90]">
|
||||
이메일 인증이 완료되었습니다. 로그인 화면으로 이동해 주세요.
|
||||
<p v-if="statusMessage" class="mt-4 text-sm text-[#7ccf90]" aria-live="polite">
|
||||
{{ statusMessage }}
|
||||
</p>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<div class="mt-auto pt-10">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="flex flex-wrap items-center gap-3">
|
||||
<button
|
||||
class="h-9 rounded-[8px] border border-[#1a212a] px-4 text-xs text-[#d8dee6] transition-opacity hover:opacity-75 disabled:cursor-not-allowed disabled:opacity-40"
|
||||
type="button"
|
||||
@@ -284,8 +298,9 @@ onBeforeUnmount(() => {
|
||||
|
||||
<button
|
||||
v-if="currentStep < 3"
|
||||
class="h-9 rounded-[8px] bg-[#2f6feb] px-8 text-xs font-medium text-white transition-opacity hover:opacity-90"
|
||||
class="h-9 rounded-[8px] bg-[#2f6feb] px-8 text-xs font-medium text-white transition-opacity hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-60"
|
||||
type="button"
|
||||
:disabled="isSubmitting"
|
||||
@click="goNextStep"
|
||||
>
|
||||
다음으로
|
||||
@@ -304,7 +319,7 @@ onBeforeUnmount(() => {
|
||||
<NuxtLink
|
||||
v-else
|
||||
class="inline-flex h-9 items-center rounded-[8px] bg-[#2f6feb] px-8 text-xs font-medium text-white transition-opacity hover:opacity-90"
|
||||
to="/signin/"
|
||||
to="/signin"
|
||||
>
|
||||
로그인으로 이동
|
||||
</NuxtLink>
|
||||
|
||||
Reference in New Issue
Block a user