149 lines
5.4 KiB
PHP
149 lines
5.4 KiB
PHP
@extends('web.layouts.auth')
|
|
|
|
@section('title', '이메일 인증 필요 | PIN FOR YOU')
|
|
@section('meta_description', 'PIN FOR YOU 이메일 인증 안내 페이지입니다.')
|
|
@section('canonical', url('/auth/email-required'))
|
|
|
|
@section('h1', '이메일 인증이 필요합니다')
|
|
@section('desc', '인증 후 사이트 이용이 가능합니다. 등록된 이메일로 인증 메일을 보내드릴게요.')
|
|
@section('card_aria', '이메일 인증 안내')
|
|
@section('show_cs_links', true)
|
|
|
|
@section('auth_content')
|
|
<form method="POST" action="{{ route('web.auth.email.send_verify') }}">
|
|
@csrf
|
|
{{-- HERO 이미지 (아이디 찾기와 동일 스타일) --}}
|
|
<img
|
|
class="reg-step0-hero__img"
|
|
src="{{ asset('assets/images/web/member/idpwfind.webp') }}"
|
|
alt=""
|
|
loading="lazy"
|
|
onerror="this.style.display='none';"
|
|
/>
|
|
|
|
<div class="auth-panel is-active" data-step="1">
|
|
<div class="auth-field">
|
|
<label class="auth-label">인증 메일 수신 주소</label>
|
|
|
|
<input
|
|
class="auth-input"
|
|
type="text"
|
|
value="{{ $email }}"
|
|
readonly
|
|
aria-readonly="true"
|
|
/>
|
|
|
|
<div class="auth-help">
|
|
위 이메일 주소로 인증 링크를 발송합니다. 링크는 <b>30분</b> 동안만 유효합니다.
|
|
</div>
|
|
</div>
|
|
|
|
<div class="auth-actions">
|
|
{{-- ✅ id 추가 (JS가 찾을 수 있게) --}}
|
|
<button id="btnSendVerify" class="auth-btn auth-btn--primary" type="submit">
|
|
인증메일 발송
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
@endsection
|
|
|
|
@section('auth_bottom')
|
|
{{-- 필요 시 하단 문구 --}}
|
|
@endsection
|
|
|
|
@push('scripts')
|
|
<script>
|
|
(function () {
|
|
const form = document.querySelector('form[action="{{ route('web.auth.email.send_verify') }}"]');
|
|
const btn = document.getElementById('btnSendVerify');
|
|
if (!form || !btn) return;
|
|
|
|
const csrf = () => document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || '';
|
|
|
|
let animTimer = null;
|
|
|
|
// ✅ 발송중 + 점 애니메이션
|
|
const setBusy = (busy) => {
|
|
btn.disabled = !!busy;
|
|
|
|
if (busy) {
|
|
// 원래 문구 저장(최초 1회)
|
|
btn.dataset.prevText = btn.dataset.prevText || btn.textContent.trim();
|
|
|
|
btn.setAttribute('aria-busy', 'true');
|
|
|
|
let dots = 0;
|
|
btn.textContent = '발송중';
|
|
|
|
animTimer = setInterval(() => {
|
|
dots = (dots + 1) % 4; // 0~3
|
|
btn.textContent = '발송중' + '.'.repeat(dots);
|
|
}, 320);
|
|
} else {
|
|
btn.removeAttribute('aria-busy');
|
|
|
|
if (animTimer) {
|
|
clearInterval(animTimer);
|
|
animTimer = null;
|
|
}
|
|
}
|
|
};
|
|
|
|
// ✅ 성공/실패 후 버튼 문구를 "이메일 다시발송"으로 고정
|
|
const setResendLabel = () => {
|
|
btn.dataset.prevText = '이메일 다시발송';
|
|
btn.textContent = '이메일 다시발송';
|
|
};
|
|
|
|
// ✅ submit(기본 폼 전송) 막고 AJAX만 수행
|
|
form.addEventListener('submit', async (e) => {
|
|
e.preventDefault();
|
|
if (btn.disabled) return;
|
|
|
|
setBusy(true);
|
|
|
|
try {
|
|
const res = await fetch(@json(route('web.auth.email.send_verify')), {
|
|
method: 'POST',
|
|
credentials: 'same-origin',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-CSRF-TOKEN': csrf(),
|
|
'X-Requested-With': 'XMLHttpRequest',
|
|
'Accept': 'application/json',
|
|
},
|
|
body: JSON.stringify({})
|
|
});
|
|
|
|
const ct = res.headers.get('content-type') || '';
|
|
const raw = await res.text();
|
|
|
|
let json = null;
|
|
if (ct.includes('application/json')) {
|
|
try { json = JSON.parse(raw); } catch (e) {}
|
|
}
|
|
|
|
if (!res.ok) {
|
|
const msg = json?.message || `요청 실패 (${res.status})`;
|
|
alert(msg);
|
|
setResendLabel();
|
|
return;
|
|
}
|
|
|
|
alert(json?.message || '인증메일을 발송했습니다. 메일함을 확인해 주세요.');
|
|
setResendLabel();
|
|
|
|
} catch (e) {
|
|
alert('인증메일 발송 중 오류가 발생했습니다.');
|
|
setResendLabel();
|
|
} finally {
|
|
setBusy(false);
|
|
// busy 해제 후에도 문구는 유지
|
|
if (!btn.textContent.includes('다시발송')) setResendLabel();
|
|
}
|
|
});
|
|
})();
|
|
</script>
|
|
@endpush
|