메일송신 mailJS , 영/한 전환 적용ㅁ
This commit is contained in:
@@ -1,123 +1,89 @@
|
||||
// Header scroll effect
|
||||
// ============================================================
|
||||
// ★ EmailJS 설정 - 아래 3가지 값을 본인 계정으로 교체하세요 ★
|
||||
// ============================================================
|
||||
const EMAILJS_PUBLIC_KEY = 'HO6i369gX6X5HEXtJ';
|
||||
const EMAILJS_SERVICE_ID = 'service_4ur5lqd';
|
||||
const EMAILJS_TEMPLATE_ID = 'template_jp0v5qv';
|
||||
// ============================================================
|
||||
|
||||
emailjs.init(EMAILJS_PUBLIC_KEY);
|
||||
|
||||
// ── Contact Form ─────────────────────────────────────────────
|
||||
document.getElementById('contact-submit').addEventListener('click', function () {
|
||||
const name = document.getElementById('contact-name').value.trim();
|
||||
const email = document.getElementById('contact-email').value.trim();
|
||||
const company = document.getElementById('contact-company').value.trim();
|
||||
const message = document.getElementById('contact-message').value.trim();
|
||||
const btn = document.getElementById('contact-submit');
|
||||
|
||||
if (!name || !email || !message) {
|
||||
showStatus('error', t('contact.error.required')); return;
|
||||
}
|
||||
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
|
||||
showStatus('error', t('contact.error.email')); return;
|
||||
}
|
||||
|
||||
btn.disabled = true;
|
||||
btn.textContent = t('contact.sending');
|
||||
|
||||
const templateParams = {
|
||||
name : name,
|
||||
message : 'Email : ' + email + '\nCompany : ' + (company || 'N/A') + '\n\n' + message,
|
||||
reply_to : email
|
||||
};
|
||||
|
||||
emailjs.send(EMAILJS_SERVICE_ID, EMAILJS_TEMPLATE_ID, templateParams)
|
||||
.then(function () {
|
||||
showStatus('success', t('contact.success'));
|
||||
document.getElementById('contact-name').value = '';
|
||||
document.getElementById('contact-email').value = '';
|
||||
document.getElementById('contact-company').value = '';
|
||||
document.getElementById('contact-message').value = '';
|
||||
})
|
||||
.catch(function (error) {
|
||||
console.error('EmailJS error:', error);
|
||||
showStatus('error', t('contact.error.fail'));
|
||||
})
|
||||
.finally(function () {
|
||||
btn.disabled = false;
|
||||
btn.textContent = t('contact.btn');
|
||||
});
|
||||
});
|
||||
|
||||
function showStatus(type, msg) {
|
||||
const status = document.getElementById('contact-status');
|
||||
status.classList.remove('hidden', 'bg-green-500/20', 'text-green-400', 'bg-red-500/20', 'text-red-400');
|
||||
status.classList.add(type === 'success' ? 'bg-green-500/20' : 'bg-red-500/20',
|
||||
type === 'success' ? 'text-green-400' : 'text-red-400');
|
||||
status.textContent = msg;
|
||||
}
|
||||
|
||||
// ── Header scroll ────────────────────────────────────────────
|
||||
const mainHeader = document.getElementById('main-header');
|
||||
const brandName = document.getElementById('brand-name');
|
||||
const navLinks = document.querySelectorAll('.nav-link');
|
||||
const brandName = document.getElementById('brand-name');
|
||||
const navLinks = document.querySelectorAll('.nav-link');
|
||||
|
||||
window.addEventListener('scroll', () => {
|
||||
if (window.scrollY > 50) {
|
||||
mainHeader.classList.add('glass-effect', 'py-3');
|
||||
mainHeader.classList.remove('py-6');
|
||||
if (brandName) brandName.classList.replace('text-white', 'text-slate-900');
|
||||
navLinks.forEach(link => {
|
||||
link.classList.replace('text-slate-100', 'text-slate-700');
|
||||
});
|
||||
navLinks.forEach(link => link.classList.replace('text-slate-100', 'text-slate-700'));
|
||||
} else {
|
||||
mainHeader.classList.remove('glass-effect', 'py-3');
|
||||
mainHeader.classList.add('py-6');
|
||||
if (brandName) brandName.classList.replace('text-slate-900', 'text-white');
|
||||
navLinks.forEach(link => {
|
||||
link.classList.replace('text-slate-700', 'text-slate-100');
|
||||
});
|
||||
navLinks.forEach(link => link.classList.replace('text-slate-700', 'text-slate-100'));
|
||||
}
|
||||
});
|
||||
|
||||
// Mobile menu open
|
||||
// ── Mobile menu ───────────────────────────────────────────────
|
||||
const mobileMenuBtn = document.getElementById('mobile-menu-btn');
|
||||
const mobileMenu = document.getElementById('mobile-menu');
|
||||
const closeMenuBtn = document.getElementById('close-menu-btn');
|
||||
const mobileMenu = document.getElementById('mobile-menu');
|
||||
const closeMenuBtn = document.getElementById('close-menu-btn');
|
||||
|
||||
if (mobileMenuBtn) {
|
||||
mobileMenuBtn.addEventListener('click', () => {
|
||||
mobileMenu.classList.remove('translate-x-full');
|
||||
});
|
||||
}
|
||||
if (mobileMenuBtn) mobileMenuBtn.addEventListener('click', () => mobileMenu.classList.remove('translate-x-full'));
|
||||
if (closeMenuBtn) closeMenuBtn.addEventListener('click', () => mobileMenu.classList.add('translate-x-full'));
|
||||
|
||||
// Mobile menu close
|
||||
if (closeMenuBtn) {
|
||||
closeMenuBtn.addEventListener('click', () => {
|
||||
mobileMenu.classList.add('translate-x-full');
|
||||
});
|
||||
}
|
||||
|
||||
// Close on nav link click
|
||||
const mobileNavLinks = mobileMenu ? mobileMenu.querySelectorAll('a') : [];
|
||||
mobileNavLinks.forEach(link => {
|
||||
link.addEventListener('click', () => {
|
||||
mobileMenu.classList.add('translate-x-full');
|
||||
});
|
||||
});
|
||||
|
||||
// Contact form handler
|
||||
const contactSubmitBtn = document.getElementById('contact-submit');
|
||||
const contactForm = {
|
||||
name: document.getElementById('contact-name'),
|
||||
email: document.getElementById('contact-email'),
|
||||
company: document.getElementById('contact-company'),
|
||||
message: document.getElementById('contact-message')
|
||||
};
|
||||
const contactStatus = document.getElementById('contact-status');
|
||||
|
||||
if (contactSubmitBtn) {
|
||||
contactSubmitBtn.addEventListener('click', async (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
// 폼 데이터 수집
|
||||
const formData = {
|
||||
name: contactForm.name.value,
|
||||
email: contactForm.email.value,
|
||||
company: contactForm.company.value,
|
||||
message: contactForm.message.value
|
||||
};
|
||||
|
||||
// 로딩 상태 표시
|
||||
contactSubmitBtn.disabled = true;
|
||||
contactSubmitBtn.textContent = 'Sending...';
|
||||
contactStatus.classList.add('hidden');
|
||||
|
||||
try {
|
||||
// FastAPI 엔드포인트로 요청 (nginx 프록시를 통함)
|
||||
const response = await fetch('/api/contact', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(formData),
|
||||
mode: 'cors',
|
||||
credentials: 'omit'
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
// 응답 처리
|
||||
contactStatus.classList.remove('hidden');
|
||||
|
||||
if (response.ok && result.success !== false) {
|
||||
// 성공 메시지
|
||||
contactStatus.classList.remove('bg-red-900/50', 'text-red-200');
|
||||
contactStatus.classList.add('bg-green-900/50', 'text-green-200');
|
||||
contactStatus.textContent = result.message;
|
||||
|
||||
// 폼 초기화
|
||||
contactForm.name.value = '';
|
||||
contactForm.email.value = '';
|
||||
contactForm.company.value = '';
|
||||
contactForm.message.value = '';
|
||||
} else {
|
||||
// 오류 메시지
|
||||
contactStatus.classList.remove('bg-green-900/50', 'text-green-200');
|
||||
contactStatus.classList.add('bg-red-900/50', 'text-red-200');
|
||||
contactStatus.textContent = result.detail || result.message || 'Failed to send message';
|
||||
}
|
||||
} catch (error) {
|
||||
// 네트워크 오류
|
||||
contactStatus.classList.remove('hidden', 'bg-green-900/50', 'text-green-200');
|
||||
contactStatus.classList.add('bg-red-900/50', 'text-red-200');
|
||||
contactStatus.textContent = 'Error: Could not send message. Please try again later.';
|
||||
console.error('Contact form error:', error);
|
||||
} finally {
|
||||
// 버튼 상태 복구
|
||||
contactSubmitBtn.disabled = false;
|
||||
contactSubmitBtn.textContent = 'Send Message';
|
||||
}
|
||||
});
|
||||
}
|
||||
mobileNavLinks.forEach(link => link.addEventListener('click', () => mobileMenu.classList.add('translate-x-full')));
|
||||
|
||||
Reference in New Issue
Block a user