103 lines
3.5 KiB
Vue
103 lines
3.5 KiB
Vue
<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>
|