작업계획서대로 진행
This commit is contained in:
102
frontend/forgot-password.vue
Normal file
102
frontend/forgot-password.vue
Normal file
@@ -0,0 +1,102 @@
|
||||
<template>
|
||||
<div class="login-container">
|
||||
<div class="login-card">
|
||||
<div class="text-center mb-4">
|
||||
<i class="bi bi-key display-1 text-warning"></i>
|
||||
<h2 class="mt-3">비밀번호 찾기</h2>
|
||||
<p class="text-muted">등록된 정보를 입력하시면 임시 비밀번호를 발급해 드립니다.</p>
|
||||
</div>
|
||||
|
||||
<div v-if="!isComplete" class="card">
|
||||
<div class="card-body">
|
||||
<form @submit.prevent="handleSubmit">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">이메일</label>
|
||||
<input type="email" class="form-control" v-model="email" placeholder="example@gmail.com" required />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">이름</label>
|
||||
<input type="text" class="form-control" v-model="name" placeholder="홍길동" required />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">휴대폰 번호 <small class="text-muted">(선택)</small></label>
|
||||
<input type="tel" class="form-control" v-model="phone" placeholder="010-1234-5678" />
|
||||
</div>
|
||||
<button type="submit" class="btn btn-warning w-100" :disabled="isSubmitting">
|
||||
<span v-if="isSubmitting"><span class="spinner-border spinner-border-sm me-2"></span>처리 중...</span>
|
||||
<span v-else><i class="bi bi-envelope me-2"></i>임시 비밀번호 발급</span>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else class="card">
|
||||
<div class="card-body text-center py-4">
|
||||
<i class="bi bi-check-circle display-4 text-success mb-3"></i>
|
||||
<h5>임시 비밀번호가 발송되었습니다</h5>
|
||||
<p class="text-muted">{{ resultMessage }}</p>
|
||||
<NuxtLink to="/login" class="btn btn-primary mt-3">
|
||||
<i class="bi bi-box-arrow-in-right me-2"></i>로그인하기
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-danger mt-3" v-if="errorMessage">
|
||||
<i class="bi bi-exclamation-triangle me-2"></i>{{ errorMessage }}
|
||||
</div>
|
||||
|
||||
<div class="text-center mt-3">
|
||||
<NuxtLink to="/login" class="text-muted"><i class="bi bi-arrow-left me-1"></i>로그인으로 돌아가기</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
definePageMeta({ layout: false })
|
||||
|
||||
const email = ref('')
|
||||
const name = ref('')
|
||||
const phone = ref('')
|
||||
const isSubmitting = ref(false)
|
||||
const errorMessage = ref('')
|
||||
const isComplete = ref(false)
|
||||
const resultMessage = ref('')
|
||||
|
||||
async function handleSubmit() {
|
||||
if (!email.value || !name.value) return
|
||||
isSubmitting.value = true
|
||||
errorMessage.value = ''
|
||||
try {
|
||||
const res = await $fetch<{ message: string }>('/api/auth/reset-password', {
|
||||
method: 'POST',
|
||||
body: { email: email.value, name: name.value, phone: phone.value || undefined }
|
||||
})
|
||||
resultMessage.value = res.message
|
||||
isComplete.value = true
|
||||
} catch (e: any) {
|
||||
errorMessage.value = e.data?.message || e.message || '요청 처리에 실패했습니다.'
|
||||
} finally {
|
||||
isSubmitting.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.login-container {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
|
||||
padding: 2rem;
|
||||
}
|
||||
.login-card {
|
||||
background: white;
|
||||
border-radius: 1rem;
|
||||
padding: 2rem;
|
||||
width: 100%;
|
||||
max-width: 450px;
|
||||
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user