Files
headless-login-demo/public/app.js

117 lines
4.8 KiB
JavaScript

const identifierInput = document.getElementById('identifier');
const passwordField = document.getElementById('password-field');
const passwordInput = document.getElementById('password');
const inputHint = document.getElementById('input-hint');
const submitButton = document.getElementById('submit-button');
const loginForm = document.getElementById('login-form');
const statusText = document.getElementById('status-text');
const statusDisplay = document.getElementById('status-display');
const successPanel = document.getElementById('success-panel');
const successTitle = document.getElementById('success-title');
const successDescription = document.getElementById('success-description');
let currentMode = 'unknown'; // 'unknown', 'phone', 'employee'
function classifyInput(value) {
const trimmed = value.trim();
if (!trimmed) return 'unknown';
// Check if it's strictly numeric (ignoring spaces or dashes for phone)
const numericOnly = trimmed.replace(/[\s-]/g, '');
if (/^\d+$/.test(numericOnly)) {
return 'phone';
}
return 'employee';
}
function formatPhoneNumber(value) {
const digits = value.replace(/\D/g, '').slice(0, 11);
if (digits.length <= 3) return digits;
if (digits.length <= 7) return `${digits.slice(0, 3)}-${digits.slice(3)}`;
return `${digits.slice(0, 3)}-${digits.slice(3, 7)}-${digits.slice(7)}`;
}
function updateUI() {
const value = identifierInput.value;
const mode = classifyInput(value);
currentMode = mode;
if (mode === 'phone') {
const formatted = formatPhoneNumber(value);
if (identifierInput.value !== formatted) {
identifierInput.value = formatted;
}
passwordField.classList.add('hidden');
inputHint.textContent = '전화번호가 확인되었습니다. 인증링크 발송 흐름을 사용할 수 있습니다.';
submitButton.textContent = '인증링크 발송';
submitButton.disabled = value.replace(/\D/g, '').length < 10;
statusText.textContent = '인증링크 발송 단계를 준비했습니다.';
} else if (mode === 'employee') {
passwordField.classList.remove('hidden');
inputHint.textContent = 'ID 입력이 확인되었습니다. 비밀번호를 입력해 로그인하세요.';
submitButton.textContent = '로그인';
submitButton.disabled = passwordInput.value.trim().length === 0;
statusText.textContent = '비밀번호 입력 단계를 노출했습니다.';
} else {
passwordField.classList.add('hidden');
inputHint.textContent = '입력값에 따라 적절한 로그인 방식이 자동으로 선택됩니다.';
submitButton.textContent = '로그인';
submitButton.disabled = true;
statusText.textContent = '입력값을 기다리는 초기 상태입니다.';
}
}
identifierInput.addEventListener('input', updateUI);
passwordInput.addEventListener('input', updateUI);
loginForm.addEventListener('submit', async (e) => {
e.preventDefault();
const identifier = identifierInput.value;
const password = passwordInput.value;
submitButton.disabled = true;
const originalBtnText = submitButton.textContent;
submitButton.textContent = '처리 중...';
try {
let response;
if (currentMode === 'phone') {
response = await fetch('/api/send-link', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ phoneNumber: identifier.replace(/\D/g, '') })
});
} else {
response = await fetch('/api/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ loginId: identifier, password: password })
});
}
const result = await response.json();
if (response.ok) {
loginForm.classList.add('hidden');
statusDisplay.classList.add('hidden');
successPanel.classList.remove('hidden');
successTitle.textContent = currentMode === 'phone' ? '인증링크 발송 완료' : '로그인 성공';
successDescription.textContent = currentMode === 'phone'
? `${identifier} 번호로 인증 링크를 보냈습니다.`
: `${identifier} 계정으로 접속되었습니다.`;
} else {
alert(result.message || '오류가 발생했습니다.');
submitButton.disabled = false;
submitButton.textContent = originalBtnText;
}
} catch (error) {
console.error('Request failed', error);
alert('서버 통신에 실패했습니다.');
submitButton.disabled = false;
submitButton.textContent = originalBtnText;
}
});