v0.0.54: 사용자 인증 화면 UX 보정

회원가입/로그인 공개 화면의 모바일 가독성과 입력 피드백을 다듬고, 비밀번호 보기 토글과 상태 메시지 분리로 인증 전환 흐름을 명확히 했다.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-05-11 11:29:09 +09:00
parent f3f971ab1b
commit 3916bcb284
6 changed files with 74 additions and 23 deletions

View File

@@ -5,6 +5,8 @@ definePageMeta({
const isSubmitting = ref(false)
const errorMessage = ref('')
const statusMessage = ref('')
const showPassword = ref(false)
const form = reactive({
email: '',
@@ -17,6 +19,7 @@ const form = reactive({
*/
const validateSignIn = () => {
errorMessage.value = ''
statusMessage.value = ''
if (!form.email.trim() || !form.password) {
errorMessage.value = '이메일과 비밀번호를 입력해 주세요.'
@@ -43,14 +46,14 @@ const submitSignIn = async () => {
isSubmitting.value = true
await new Promise((resolve) => setTimeout(resolve, 500))
isSubmitting.value = false
errorMessage.value = '현재 로그인 API 연결 전입니다. 관리자 로그인은 /admin 을 사용해 주세요.'
statusMessage.value = '현재 로그인 API 연결 전입니다. 관리자 로그인은 /admin 을 사용해 주세요.'
}
</script>
<template>
<section class="auth-signin min-h-screen bg-[#0a0b0d] text-[#f5f7fa]">
<div class="mx-auto flex min-h-screen w-full max-w-[1280px] items-center px-8 py-12 sm:px-16">
<div class="w-full max-w-[430px]">
<div class="mx-auto flex min-h-screen w-full max-w-[1280px] items-center px-5 py-12 sm:px-10 lg:px-16">
<div class="w-full max-w-[430px] rounded-2xl border border-[#1a212a] bg-[#0d1116] p-5 sm:p-8">
<p class="text-2xl font-semibold leading-tight">
로그인
</p>
@@ -71,12 +74,21 @@ const submitSignIn = async () => {
<div class="space-y-1.5">
<label class="text-xs text-[#d8dee6]">비밀번호</label>
<input
v-model="form.password"
class="h-10 w-full rounded-[8px] border border-[#1a212a] bg-transparent px-3 text-sm outline-none transition-colors focus:border-[#2f6feb]"
type="password"
autocomplete="current-password"
>
<div class="flex items-center rounded-[8px] border border-[#1a212a] transition-colors focus-within:border-[#2f6feb]">
<input
v-model="form.password"
class="h-10 w-full bg-transparent px-3 text-sm outline-none"
:type="showPassword ? 'text' : 'password'"
autocomplete="current-password"
>
<button
class="px-3 text-xs text-[#9ba3af] transition-opacity hover:opacity-80"
type="button"
@click="showPassword = !showPassword"
>
{{ showPassword ? '숨기기' : '보기' }}
</button>
</div>
</div>
<button
@@ -88,16 +100,22 @@ const submitSignIn = async () => {
</button>
</form>
<p v-if="errorMessage" class="mt-4 text-xs text-[#e5acb1]">
<p v-if="errorMessage" class="mt-4 text-xs text-[#e5acb1]" aria-live="polite">
{{ errorMessage }}
</p>
<p v-if="statusMessage" class="mt-4 text-xs text-[#9fc4ff]" aria-live="polite">
{{ statusMessage }}
</p>
<p class="mt-6 text-sm text-[#9ba3af]">
계정이 없으신가요?
<NuxtLink class="text-[#7eb8ff] hover:opacity-80" to="/signup/">
<NuxtLink class="text-[#7eb8ff] hover:opacity-80" to="/signup">
회원가입
</NuxtLink>
</p>
<NuxtLink class="mt-2 inline-flex text-xs text-[#9ba3af] hover:opacity-80" to="/">
홈으로 돌아가기
</NuxtLink>
</div>
</div>
</section>