- 방송 플랫폼 예시를 "유튜브, SOOP, 치지직"으로 변경 - 트위치, 아프리카TV 제거 (국내 주요 플랫폼으로 정리) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
376 lines
12 KiB
JavaScript
376 lines
12 KiB
JavaScript
// ========================================
|
|
// Partner 페이지 전용 JavaScript
|
|
// ========================================
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
initCopyButton();
|
|
initEmailLinkCopy();
|
|
});
|
|
|
|
// 복사 버튼 초기화
|
|
function initCopyButton() {
|
|
const copyBtn = document.getElementById('copyTemplateBtn');
|
|
|
|
if (copyBtn) {
|
|
copyBtn.addEventListener('click', function() {
|
|
copyApplicationTemplate();
|
|
});
|
|
}
|
|
}
|
|
|
|
// 지원서 양식 복사 함수
|
|
function copyApplicationTemplate() {
|
|
const templateText = `밍글스튜디오 파트너 스트리머 지원서
|
|
|
|
[ 기본 정보 ]
|
|
1. 현재 데뷔하여 활동하고 계신가요?
|
|
답변: (예 / 아니오)
|
|
|
|
2. 활동하고 계시다면, 활동명은 무엇인가요?
|
|
답변:
|
|
|
|
3. 어떤 방송 플랫폼에서 방송을 하고 계신가요?
|
|
답변: (예: 유튜브, SOOP, 치지직 등)
|
|
|
|
4. MCN 또는 기업 소속이신가요?
|
|
답변: (예 / 아니오)
|
|
※ 소속된 경우, 소속 회사명을 함께 기재해주세요
|
|
|
|
[ 지원 동기 및 계획 ]
|
|
5. 지원하게 된 계기가 무엇인가요?
|
|
답변:
|
|
|
|
6. 파트너 스트리머가 된다면 어떤 콘텐츠를 진행해보고 싶으신가요?
|
|
답변:
|
|
|
|
[ 경험 및 환경 ]
|
|
7. 모션 캡처를 경험해보신 적이 있으신가요?
|
|
답변: (예 / 아니오)
|
|
|
|
8. 스튜디오 방문에 어려움이 있으신가요?
|
|
※ 스튜디오는 인천광역시 부평구에 위치하고 있습니다
|
|
답변: (어려움 없음 / 다소 어렵지만 가능 / 어려움 있음)
|
|
|
|
9. 본인만의 특기가 있다면?
|
|
답변: (방송이나 유튜브 영상 링크 첨부로 대체 가능)
|
|
|
|
[ 연락처 정보 ]
|
|
• 이름:
|
|
• 이메일:
|
|
• 디스코드 아이디: `;
|
|
|
|
// 클립보드에 복사
|
|
navigator.clipboard.writeText(templateText).then(function() {
|
|
// 성공 피드백
|
|
const copyBtn = document.getElementById('copyTemplateBtn');
|
|
const originalText = copyBtn.querySelector('.copy-text').textContent;
|
|
|
|
copyBtn.classList.add('copied');
|
|
copyBtn.querySelector('.copy-text').textContent = '복사 완료!';
|
|
|
|
// 2초 후 원래대로 복원
|
|
setTimeout(function() {
|
|
copyBtn.classList.remove('copied');
|
|
copyBtn.querySelector('.copy-text').textContent = originalText;
|
|
}, 2000);
|
|
|
|
// 알림 표시 (commonUtils 사용 가능한 경우)
|
|
if (window.commonUtils && window.commonUtils.showNotification) {
|
|
window.commonUtils.showNotification('양식이 클립보드에 복사되었습니다!', 'success');
|
|
}
|
|
}).catch(function(err) {
|
|
console.error('복사 실패:', err);
|
|
if (window.commonUtils && window.commonUtils.showNotification) {
|
|
window.commonUtils.showNotification('복사에 실패했습니다. 다시 시도해주세요.', 'error');
|
|
} else {
|
|
alert('복사에 실패했습니다. 다시 시도해주세요.');
|
|
}
|
|
});
|
|
}
|
|
|
|
// 이메일 링크 클릭 시 복사
|
|
function initEmailLinkCopy() {
|
|
const emailLink = document.getElementById('emailLink');
|
|
|
|
if (emailLink) {
|
|
emailLink.addEventListener('click', function(e) {
|
|
e.preventDefault();
|
|
const email = this.textContent.trim();
|
|
|
|
navigator.clipboard.writeText(email).then(function() {
|
|
// 성공 알림
|
|
if (window.commonUtils && window.commonUtils.showNotification) {
|
|
window.commonUtils.showNotification('이메일 주소가 복사되었습니다!', 'success');
|
|
}
|
|
|
|
// 링크 시각적 피드백
|
|
emailLink.style.color = '#4CAF50';
|
|
setTimeout(function() {
|
|
emailLink.style.color = '';
|
|
}, 1000);
|
|
}).catch(function(err) {
|
|
console.error('이메일 복사 실패:', err);
|
|
if (window.commonUtils && window.commonUtils.showNotification) {
|
|
window.commonUtils.showNotification('복사에 실패했습니다.', 'error');
|
|
}
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
// 파트너 지원 폼 초기화 (사용하지 않음 - 삭제 가능)
|
|
function initPartnerForm() {
|
|
const form = document.getElementById('partnerApplicationForm');
|
|
|
|
if (form) {
|
|
form.addEventListener('submit', handleFormSubmit);
|
|
|
|
// 실시간 유효성 검사
|
|
const inputs = form.querySelectorAll('input, textarea');
|
|
inputs.forEach(input => {
|
|
if (input.type !== 'radio' && input.type !== 'checkbox') {
|
|
input.addEventListener('blur', validateField);
|
|
}
|
|
});
|
|
|
|
// 전화번호 자동 포맷팅
|
|
const phoneInput = document.getElementById('phone');
|
|
if (phoneInput) {
|
|
phoneInput.addEventListener('input', formatPhoneNumber);
|
|
}
|
|
}
|
|
}
|
|
|
|
// 조건부 필드 초기화
|
|
function initConditionalFields() {
|
|
// MCN/기업 소속 여부에 따라 소속명 입력란 표시
|
|
const affiliationRadios = document.querySelectorAll('input[name="hasAffiliation"]');
|
|
const affiliationNameInput = document.getElementById('affiliationName');
|
|
|
|
affiliationRadios.forEach(radio => {
|
|
radio.addEventListener('change', function() {
|
|
if (this.value === 'yes') {
|
|
affiliationNameInput.style.display = 'block';
|
|
affiliationNameInput.required = true;
|
|
} else {
|
|
affiliationNameInput.style.display = 'none';
|
|
affiliationNameInput.required = false;
|
|
affiliationNameInput.value = '';
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
// 폼 제출 처리
|
|
async function handleFormSubmit(e) {
|
|
e.preventDefault();
|
|
|
|
const form = e.target;
|
|
const submitBtn = form.querySelector('button[type="submit"]');
|
|
|
|
// 유효성 검사
|
|
if (!validateForm(form)) {
|
|
if (window.commonUtils && window.commonUtils.showNotification) {
|
|
window.commonUtils.showNotification('모든 필수 항목을 입력해 주세요.', 'error');
|
|
} else {
|
|
alert('모든 필수 항목을 입력해 주세요.');
|
|
}
|
|
return;
|
|
}
|
|
|
|
// 개인정보 동의 확인
|
|
const privacyAgree = document.getElementById('privacyAgree');
|
|
if (!privacyAgree.checked) {
|
|
if (window.commonUtils && window.commonUtils.showNotification) {
|
|
window.commonUtils.showNotification('개인정보 수집 및 이용에 동의해 주세요.', 'warning');
|
|
} else {
|
|
alert('개인정보 수집 및 이용에 동의해 주세요.');
|
|
}
|
|
return;
|
|
}
|
|
|
|
// 제출 버튼 비활성화
|
|
const originalText = submitBtn.textContent;
|
|
submitBtn.textContent = '제출 중...';
|
|
submitBtn.disabled = true;
|
|
|
|
try {
|
|
// 폼 데이터 수집
|
|
const formData = new FormData(form);
|
|
const data = Object.fromEntries(formData);
|
|
|
|
// 서버로 전송 (실제 구현 필요)
|
|
await submitApplicationForm(data);
|
|
|
|
// 성공 메시지
|
|
if (window.commonUtils && window.commonUtils.showNotification) {
|
|
window.commonUtils.showNotification('지원서가 성공적으로 제출되었습니다. 검토 후 연락드리겠습니다!', 'success');
|
|
} else {
|
|
alert('지원서가 성공적으로 제출되었습니다. 검토 후 연락드리겠습니다!');
|
|
}
|
|
|
|
// 폼 초기화
|
|
form.reset();
|
|
|
|
// 조건부 필드 숨기기
|
|
const affiliationNameInput = document.getElementById('affiliationName');
|
|
if (affiliationNameInput) {
|
|
affiliationNameInput.style.display = 'none';
|
|
affiliationNameInput.required = false;
|
|
}
|
|
|
|
} catch (error) {
|
|
console.error('Form submission error:', error);
|
|
if (window.commonUtils && window.commonUtils.showNotification) {
|
|
window.commonUtils.showNotification('전송 중 오류가 발생했습니다. 다시 시도해 주세요.', 'error');
|
|
} else {
|
|
alert('전송 중 오류가 발생했습니다. 다시 시도해 주세요.');
|
|
}
|
|
} finally {
|
|
// 버튼 복원
|
|
submitBtn.textContent = originalText;
|
|
submitBtn.disabled = false;
|
|
}
|
|
}
|
|
|
|
// 서버 전송 시뮬레이션 (실제 구현 필요)
|
|
async function submitApplicationForm(data) {
|
|
// 실제 서버 API 엔드포인트로 전송
|
|
// 예: await fetch('/api/partner-application', { method: 'POST', body: JSON.stringify(data) })
|
|
|
|
// 시뮬레이션을 위한 딜레이
|
|
return new Promise((resolve) => {
|
|
setTimeout(() => {
|
|
console.log('Application data:', data);
|
|
resolve({ success: true });
|
|
}, 1500);
|
|
});
|
|
}
|
|
|
|
// 폼 유효성 검사
|
|
function validateForm(form) {
|
|
let isValid = true;
|
|
|
|
// 모든 필수 입력 필드 검사
|
|
const requiredInputs = form.querySelectorAll('input[required], textarea[required]');
|
|
requiredInputs.forEach(input => {
|
|
if (!validateField({ target: input })) {
|
|
isValid = false;
|
|
}
|
|
});
|
|
|
|
// 라디오 버튼 그룹 검사
|
|
const requiredRadioGroups = ['isActive', 'hasAffiliation', 'hasMocapExperience', 'canVisit'];
|
|
requiredRadioGroups.forEach(groupName => {
|
|
const radios = form.querySelectorAll(`input[name="${groupName}"]`);
|
|
const checked = Array.from(radios).some(radio => radio.checked);
|
|
if (!checked) {
|
|
isValid = false;
|
|
// 라디오 그룹 에러 표시
|
|
const radioGroup = radios[0]?.closest('.form-group');
|
|
if (radioGroup) {
|
|
radioGroup.style.borderLeft = '4px solid #e74c3c';
|
|
}
|
|
} else {
|
|
const radioGroup = radios[0]?.closest('.form-group');
|
|
if (radioGroup) {
|
|
radioGroup.style.borderLeft = 'none';
|
|
}
|
|
}
|
|
});
|
|
|
|
return isValid;
|
|
}
|
|
|
|
// 개별 필드 유효성 검사
|
|
function validateField(e) {
|
|
const field = e.target;
|
|
const value = field.value.trim();
|
|
let isValid = true;
|
|
let errorMessage = '';
|
|
|
|
// 필수 필드 확인
|
|
if (field.required && !value) {
|
|
isValid = false;
|
|
errorMessage = '이 항목은 필수입니다.';
|
|
}
|
|
|
|
// 이메일 검사
|
|
if (field.type === 'email' && value) {
|
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
if (!emailRegex.test(value)) {
|
|
isValid = false;
|
|
errorMessage = '올바른 이메일 형식이 아닙니다.';
|
|
}
|
|
}
|
|
|
|
// 전화번호 검사
|
|
if (field.type === 'tel' && value) {
|
|
const phoneRegex = /^[0-9-]+$/;
|
|
if (!phoneRegex.test(value)) {
|
|
isValid = false;
|
|
errorMessage = '올바른 전화번호 형식이 아닙니다.';
|
|
}
|
|
}
|
|
|
|
// 에러 표시
|
|
if (!isValid) {
|
|
showFieldError(field, errorMessage);
|
|
} else {
|
|
clearFieldError(field);
|
|
}
|
|
|
|
return isValid;
|
|
}
|
|
|
|
// 필드 에러 표시
|
|
function showFieldError(field, message) {
|
|
field.style.borderColor = '#e74c3c';
|
|
|
|
// 기존 에러 메시지 제거
|
|
const existingError = field.parentElement.querySelector('.error-message');
|
|
if (existingError) {
|
|
existingError.remove();
|
|
}
|
|
|
|
// 새 에러 메시지 추가
|
|
const errorDiv = document.createElement('div');
|
|
errorDiv.className = 'error-message';
|
|
errorDiv.style.color = '#e74c3c';
|
|
errorDiv.style.fontSize = '0.875rem';
|
|
errorDiv.style.marginTop = '0.5rem';
|
|
errorDiv.textContent = message;
|
|
field.parentElement.appendChild(errorDiv);
|
|
}
|
|
|
|
// 필드 에러 제거
|
|
function clearFieldError(field) {
|
|
if (field instanceof Event) {
|
|
field = field.target;
|
|
}
|
|
|
|
field.style.borderColor = '';
|
|
|
|
const errorMessage = field.parentElement.querySelector('.error-message');
|
|
if (errorMessage) {
|
|
errorMessage.remove();
|
|
}
|
|
}
|
|
|
|
// 전화번호 자동 포맷팅
|
|
function formatPhoneNumber(e) {
|
|
const input = e.target;
|
|
let value = input.value.replace(/[^0-9]/g, '');
|
|
|
|
// 자동 하이픈 추가
|
|
if (value.length <= 3) {
|
|
input.value = value;
|
|
} else if (value.length <= 7) {
|
|
input.value = value.slice(0, 3) + '-' + value.slice(3);
|
|
} else if (value.length <= 11) {
|
|
input.value = value.slice(0, 3) + '-' + value.slice(3, 7) + '-' + value.slice(7);
|
|
} else {
|
|
input.value = value.slice(0, 3) + '-' + value.slice(3, 7) + '-' + value.slice(7, 11);
|
|
}
|
|
}
|