166 lines
6.8 KiB
PHP
166 lines
6.8 KiB
PHP
@extends('web.layouts.auth')
|
|
|
|
@section('title', '로그인 | PIN FOR YOU')
|
|
@section('meta_description', 'PIN FOR YOU 로그인 페이지입니다.')
|
|
@section('canonical', url('/auth/login'))
|
|
|
|
@section('h1', '로그인')
|
|
@section('desc', '안전한 거래를 위해 로그인해 주세요.')
|
|
@section('headline', '안전한 핀 발송/거래')
|
|
@section('subheadline', '로그인 후 구매/문의 내역을 빠르게 확인할 수 있어요.')
|
|
@section('card_aria', '로그인 폼')
|
|
|
|
{{-- ✅ reCAPTCHA 스크립트/공통함수는 이 페이지에서만 로드 --}}
|
|
@push('recaptcha')
|
|
<script>window.__recaptchaSiteKey = @json(config('services.recaptcha.site_key'));</script>
|
|
<script src="https://www.google.com/recaptcha/api.js?render={{ config('services.recaptcha.site_key') }}"></script>
|
|
<script src="{{ asset('assets/js/recaptcha-v3.js') }}"></script>
|
|
@endpush
|
|
|
|
@section('auth_content')
|
|
<form class="auth-form" method="post" action="{{ route('web.auth.login.prc') }}" id="loginForm">
|
|
@csrf
|
|
|
|
<input type="hidden" name="return_url" value="{{ request('return_url', '/') }}">
|
|
<input type="hidden" name="g-recaptcha-response" id="g-recaptcha-response" value="">
|
|
|
|
<img
|
|
class="reg-step0-hero__img"
|
|
src="{{ asset('assets/images/web/member/login.webp') }}"
|
|
alt=""
|
|
loading="lazy"
|
|
onerror="this.style.display='none';"
|
|
/>
|
|
|
|
<div class="auth-field">
|
|
<label class="auth-label" for="login_id">아이디(이메일)</label>
|
|
<input class="auth-input" id="login_id" name="mem_email" type="email"
|
|
placeholder="example@domain.com" autocomplete="username"
|
|
value="{{ old('mem_email') }}">
|
|
</div>
|
|
|
|
<div class="auth-field">
|
|
<label class="auth-label" for="login_pw">비밀번호</label>
|
|
<input class="auth-input" id="login_pw" name="mem_pw" type="password"
|
|
placeholder="비밀번호" autocomplete="current-password">
|
|
</div>
|
|
<div class="auth-row">
|
|
<label class="auth-check">
|
|
{{-- <input type="checkbox" name="auto_login" value="1">--}}
|
|
{{-- 자동 로그인--}}
|
|
</label>
|
|
<div class="auth-links-inline">
|
|
<a class="auth-link" href="{{ route('web.auth.find_id') }}">아이디 찾기</a>
|
|
<span class="auth-dot">·</span>
|
|
<a class="auth-link" href="{{ route('web.auth.find_password') }}">비밀번호 찾기</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="auth-actions">
|
|
<button class="auth-btn auth-btn--primary" type="submit">로그인</button>
|
|
<a class="auth-btn auth-btn--ghost" href="{{ route('web.auth.register') }}">회원가입</a>
|
|
</div>
|
|
</form>
|
|
@endsection
|
|
|
|
@section('auth_bottom')
|
|
<div class="auth-links">
|
|
<a class="auth-link" href="{{ route('web.cs.faq.index') }}">FAQ</a>
|
|
<span class="auth-dot">·</span>
|
|
<a class="auth-link" href="{{ route('web.cs.qna.index') }}">1:1 문의</a>
|
|
<span class="auth-dot">·</span>
|
|
<a class="auth-link" href="{{ route('web.cs.kakao.index') }}">카카오 상담</a>
|
|
</div>
|
|
@endsection
|
|
|
|
@push('scripts')
|
|
@push('scripts')
|
|
<script>
|
|
(function(){
|
|
const form = document.getElementById('loginForm');
|
|
if (!form) return;
|
|
|
|
const emailEl = document.getElementById('login_id');
|
|
const pwEl = document.getElementById('login_pw');
|
|
const btn = form.querySelector('button[type="submit"]');
|
|
|
|
// showMsg / clearMsg 가 공통으로 있으면 그대로 활용
|
|
async function alertMsg(msg) {
|
|
if (typeof showMsg === 'function') {
|
|
await showMsg(msg, { type: 'alert', title: '입력오류' });
|
|
} else {
|
|
alert(msg);
|
|
}
|
|
}
|
|
|
|
function isEmail(v){
|
|
// 너무 빡세게 잡지 말고 기본만
|
|
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v);
|
|
}
|
|
|
|
form.addEventListener('submit', async function (e) {
|
|
e.preventDefault();
|
|
|
|
if (typeof clearMsg === 'function') clearMsg();
|
|
|
|
const email = (emailEl?.value || '').trim();
|
|
const pw = (pwEl?.value || '');
|
|
|
|
if (!email) {
|
|
await alertMsg('아이디(이메일)를 입력해 주세요.');
|
|
emailEl?.focus();
|
|
return;
|
|
}
|
|
if (!isEmail(email)) {
|
|
await alertMsg('아이디는 이메일 형식이어야 합니다.');
|
|
emailEl?.focus();
|
|
return;
|
|
}
|
|
if (!pw) {
|
|
await alertMsg('비밀번호를 입력해 주세요.');
|
|
pwEl?.focus();
|
|
return;
|
|
}
|
|
|
|
// 버튼 잠금
|
|
if (btn) btn.disabled = true;
|
|
|
|
try {
|
|
// ✅ 운영에서만 recaptcha 토큰 넣기 (서버도 동일 정책)
|
|
@if(app()->environment('production') && config('services.recaptcha.site_key'))
|
|
const hidden = document.getElementById('g-recaptcha-response');
|
|
try {
|
|
// recaptcha-v3.js 에 recaptchaV3Exec(action) 있다고 가정
|
|
const token = await window.recaptchaV3Exec('login');
|
|
if (hidden) hidden.value = token || '';
|
|
} catch (err) {
|
|
if (hidden) hidden.value = '';
|
|
}
|
|
@endif
|
|
|
|
form.submit(); // 실제 전송
|
|
} finally {
|
|
// submit() 호출 후 페이지 이동하므로 보통 의미 없지만
|
|
// 혹시 ajax로 바꾸면 필요함
|
|
// if (btn) btn.disabled = false;
|
|
}
|
|
});
|
|
})();
|
|
|
|
document.addEventListener('DOMContentLoaded', async () => {
|
|
const msg = @json($errors->first('login'));
|
|
if (msg) {
|
|
if (typeof showMsg === 'function') {
|
|
await showMsg(msg, { type: 'alert', title: '로그인 실패' });
|
|
} else if (typeof showAlert === 'function') {
|
|
await showAlert(msg, '로그인 실패');
|
|
} else {
|
|
alert(msg);
|
|
}
|
|
}
|
|
});
|
|
</script>
|
|
@endpush
|
|
|
|
@endpush
|