| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- <template>
- <main class="user--main">
- <div class="join--container">
- <div class="title--wrap">
- <h1>{{ activeTab === 'id' ? '아이디 찾기' : '비밀번호 재설정' }}</h1>
- </div>
- <div class="find--tab--wrap mt--14">
- <button type="button" :class="{ active: activeTab === 'id' }" @click="setTab('id')">아이디 찾기</button>
- <button type="button" :class="{ active: activeTab === 'pw' }" @click="setTab('pw')">비밀번호 찾기</button>
- </div>
- <!-- 아이디 찾기 -->
- <div v-if="activeTab === 'id'" class="login--wrap mt--20">
- <form @submit.prevent="handleFindId">
- <p class="mb--15 desc--p">가입 시 등록한 이름과 핸드폰 번호로 아이디를 찾을 수 있습니다.</p>
- <div class="input--wrap">
- <label for="findId--name">이름</label>
- <input id="findId--name" v-model="idForm.name" type="text" placeholder="이름을 입력해 주세요" maxlength="50">
- </div>
- <div class="input--wrap mt--18">
- <label for="findId--phone1">핸드폰 <span class="required">*</span></label>
- <div class="input--inner--wrap gap--4">
- <input id="findId--phone1" v-model="idForm.phoneFront" type="text" maxlength="3">
- <span>-</span>
- <input v-model="idForm.phoneMiddle" type="text" maxlength="4" inputmode="numeric">
- <span>-</span>
- <input v-model="idForm.phoneLast" type="text" maxlength="4" inputmode="numeric">
- </div>
- </div>
- </form>
- </div>
- <!-- 비밀번호 재설정 (본인확인) -->
- <div v-else class="login--wrap mt--20">
- <form @submit.prevent="handleVerifyForReset">
- <p class="mb--15 desc--p">아이디와 본인인증으로 비밀번호를 재설정할 수 있습니다.</p>
- <div class="input--wrap">
- <label for="findPw--id">아이디</label>
- <input id="findPw--id" v-model="pwForm.username" type="text" placeholder="아이디를 입력해 주세요" maxlength="20">
- </div>
- <!-- 소셜 가입자 안내 -->
- <div v-if="socialNotice" class="mt--20 find--social--box">
- <span>💬 소셜 가입 회원 안내</span>
- <p>{{ socialNotice }}</p>
- </div>
- <p class="label--p mt--28">본인인증 (이름ㆍ핸드폰)</p>
- <div class="input--wrap mt--18">
- <label for="findPw--name">이름</label>
- <input id="findPw--name" v-model="pwForm.name" type="text" placeholder="이름을 입력해 주세요" maxlength="50">
- </div>
- <div class="input--wrap mt--18">
- <label for="findPw--phone1">핸드폰 <span class="required">*</span></label>
- <div class="input--inner--wrap gap--4">
- <input id="findPw--phone1" v-model="pwForm.phoneFront" type="text" maxlength="3">
- <span>-</span>
- <input v-model="pwForm.phoneMiddle" type="text" maxlength="4" inputmode="numeric">
- <span>-</span>
- <input v-model="pwForm.phoneLast" type="text" maxlength="4" inputmode="numeric">
- </div>
- </div>
- </form>
- </div>
- </div>
- <div class="float--btn--wrap">
- <a
- href="#"
- :class="{ disabled: submitting }"
- @click.prevent="submit"
- >{{ submitting ? '처리 중...' : '다음' }}</a>
- </div>
- <AppAlertModal
- v-model="modal.show"
- :icon-type="modal.iconType"
- :title="modal.title"
- :message="modal.message"
- />
- </main>
- </template>
- <script setup>
- import { ref, reactive, onMounted } from 'vue'
- import { useRoute, useRouter } from 'vue-router'
- import AppAlertModal from '~/components/AppAlertModal.vue'
- const route = useRoute()
- const router = useRouter()
- const { post } = useApi()
- const activeTab = ref('id') // 'id' | 'pw'
- // 쿼리스트링 ?tab=pw 로 진입하면 비밀번호 탭 자동 활성
- onMounted(() => {
- if (route.query.tab === 'pw') activeTab.value = 'pw'
- })
- const submitting = ref(false)
- const socialNotice = ref('')
- const idForm = reactive({
- name: '',
- phoneFront: '010',
- phoneMiddle: '',
- phoneLast: '',
- })
- const pwForm = reactive({
- username: '',
- name: '',
- phoneFront: '010',
- phoneMiddle: '',
- phoneLast: '',
- })
- const modal = reactive({ show: false, iconType: 'error', title: '', message: '' })
- const showAlert = (title, message, iconType = 'error') => {
- modal.title = title
- modal.message = message
- modal.iconType = iconType
- modal.show = true
- }
- const setTab = (t) => {
- activeTab.value = t
- socialNotice.value = ''
- }
- const submit = () => {
- if (activeTab.value === 'id') handleFindId()
- else handleVerifyForReset()
- }
- // 아이디 찾기
- const handleFindId = async () => {
- if (submitting.value) return
- if (!idForm.name.trim()) return showAlert('입력 확인', '이름을 입력해 주세요.')
- if (!idForm.phoneMiddle || !idForm.phoneLast) {
- return showAlert('입력 확인', '핸드폰 번호를 입력해 주세요.')
- }
- submitting.value = true
- try {
- const phone = `${idForm.phoneFront}-${idForm.phoneMiddle}-${idForm.phoneLast}`
- const { data, error } = await post('/users/find-id', {
- name: idForm.name.trim(),
- phone,
- })
- if (error || !data?.success) {
- return showAlert('조회 실패', error?.message || data?.message || '일치하는 회원 정보가 없습니다.')
- }
- sessionStorage.setItem('find_id_result', JSON.stringify(data.data))
- router.push('/login/findIdComplete')
- } catch (e) {
- console.error(e)
- showAlert('오류', '서버 오류가 발생했습니다.')
- } finally {
- submitting.value = false
- }
- }
- // 비밀번호 재설정 본인확인
- const handleVerifyForReset = async () => {
- if (submitting.value) return
- socialNotice.value = ''
- if (!pwForm.username.trim()) return showAlert('입력 확인', '아이디를 입력해 주세요.')
- if (!pwForm.name.trim()) return showAlert('입력 확인', '이름을 입력해 주세요.')
- if (!pwForm.phoneMiddle || !pwForm.phoneLast) {
- return showAlert('입력 확인', '핸드폰 번호를 입력해 주세요.')
- }
- submitting.value = true
- try {
- const phone = `${pwForm.phoneFront}-${pwForm.phoneMiddle}-${pwForm.phoneLast}`
- const { data, error } = await post('/users/verify-for-reset', {
- username: pwForm.username.trim(),
- name: pwForm.name.trim(),
- phone,
- })
- if (error || !data?.success) {
- const msg = error?.message || data?.message || '일치하는 회원 정보가 없습니다.'
- // 소셜 가입자 안내 (백엔드가 "소셜 가입 회원입니다. (kakao)" 류로 응답)
- if (msg.includes('소셜')) {
- socialNotice.value = msg + ' 비밀번호 없이 소셜 로그인을 이용해 주세요.'
- return
- }
- return showAlert('인증 실패', msg)
- }
- sessionStorage.setItem('reset_token', data.data.reset_token)
- sessionStorage.setItem('reset_username', pwForm.username.trim())
- router.push('/login/findPw')
- } catch (e) {
- console.error(e)
- showAlert('오류', '서버 오류가 발생했습니다.')
- } finally {
- submitting.value = false
- }
- }
- </script>
|