499 Zeilen
14 KiB
JavaScript
499 Zeilen
14 KiB
JavaScript
/**
|
|
* UI Components module for IntelSight website
|
|
* Contains all interactive UI component logic
|
|
*/
|
|
|
|
// Language Toggle Component
|
|
const LanguageToggle = {
|
|
element: null,
|
|
|
|
/**
|
|
* Initialize language toggle
|
|
*/
|
|
init() {
|
|
this.element = document.querySelector(SELECTORS.LANG_TOGGLE);
|
|
if (!this.element) return;
|
|
|
|
this.element.addEventListener('click', (e) => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
this.toggle();
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Toggle between languages
|
|
*/
|
|
toggle() {
|
|
const newLanguage = getCurrentLanguage() === 'de' ? 'en' : 'de';
|
|
switchLanguage(newLanguage);
|
|
|
|
// Update expand button text after language change
|
|
ProductShowcase.updateExpandButtonText();
|
|
}
|
|
};
|
|
|
|
// Navigation Component
|
|
const Navigation = {
|
|
navbar: null,
|
|
|
|
/**
|
|
* Initialize navigation component
|
|
*/
|
|
init() {
|
|
this.navbar = document.querySelector(SELECTORS.NAVBAR);
|
|
this.setupSmoothScrolling();
|
|
this.setupMobileMenu();
|
|
},
|
|
|
|
/**
|
|
* Setup smooth scrolling for anchor links
|
|
*/
|
|
setupSmoothScrolling() {
|
|
document.querySelectorAll(SELECTORS.SMOOTH_LINKS).forEach(anchor => {
|
|
anchor.addEventListener('click', function(e) {
|
|
e.preventDefault();
|
|
const targetId = this.getAttribute('href');
|
|
const target = document.querySelector(targetId);
|
|
|
|
if (target) {
|
|
target.scrollIntoView({
|
|
behavior: 'smooth',
|
|
block: 'start'
|
|
});
|
|
}
|
|
});
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Setup mobile menu functionality
|
|
*/
|
|
setupMobileMenu() {
|
|
// Mobile menu logic would go here if needed
|
|
// Currently not implemented as per YAGNI principle
|
|
}
|
|
};
|
|
|
|
// About Section Tabs
|
|
const AboutTabs = {
|
|
tabs: null,
|
|
panels: null,
|
|
|
|
/**
|
|
* Initialize about section tabs
|
|
*/
|
|
init() {
|
|
this.tabs = document.querySelectorAll(SELECTORS.ABOUT_TABS);
|
|
this.panels = document.querySelectorAll(SELECTORS.ABOUT_PANELS);
|
|
|
|
if (!this.tabs.length) return;
|
|
|
|
this.tabs.forEach(tab => {
|
|
tab.addEventListener('click', () => this.switchTab(tab));
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Switch to selected tab
|
|
* @param {HTMLElement} selectedTab - Tab element that was clicked
|
|
*/
|
|
switchTab(selectedTab) {
|
|
const targetPanelId = selectedTab.getAttribute(DATA_ATTRS.TAB);
|
|
|
|
// Remove active class from all tabs and panels
|
|
this.tabs.forEach(tab => tab.classList.remove(CLASSES.ACTIVE));
|
|
this.panels.forEach(panel => panel.classList.remove(CLASSES.ACTIVE));
|
|
|
|
// Add active class to selected tab and corresponding panel
|
|
selectedTab.classList.add(CLASSES.ACTIVE);
|
|
const targetPanel = document.getElementById(targetPanelId);
|
|
if (targetPanel) {
|
|
targetPanel.classList.add(CLASSES.ACTIVE);
|
|
}
|
|
}
|
|
};
|
|
|
|
// Product Showcase Component
|
|
const ProductShowcase = {
|
|
expandButton: null,
|
|
toolsGrid: null,
|
|
|
|
/**
|
|
* Initialize product showcase
|
|
*/
|
|
init() {
|
|
this.expandButton = document.querySelector(SELECTORS.EXPAND_BUTTON);
|
|
this.toolsGrid = document.querySelector(SELECTORS.TOOLS_GRID);
|
|
|
|
if (!this.expandButton || !this.toolsGrid) return;
|
|
|
|
this.expandButton.addEventListener('click', () => this.toggleExpand());
|
|
},
|
|
|
|
/**
|
|
* Toggle expand/collapse state
|
|
*/
|
|
toggleExpand() {
|
|
const isExpanded = this.expandButton.getAttribute(DATA_ATTRS.EXPANDED) === 'true';
|
|
|
|
if (isExpanded) {
|
|
this.collapse();
|
|
} else {
|
|
this.expand();
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Expand the tools grid
|
|
*/
|
|
expand() {
|
|
this.toolsGrid.classList.remove(CLASSES.COLLAPSED);
|
|
this.expandButton.setAttribute(DATA_ATTRS.EXPANDED, 'true');
|
|
this.updateExpandButtonText();
|
|
},
|
|
|
|
/**
|
|
* Collapse the tools grid
|
|
*/
|
|
collapse() {
|
|
this.toolsGrid.classList.add(CLASSES.COLLAPSED);
|
|
this.expandButton.setAttribute(DATA_ATTRS.EXPANDED, 'false');
|
|
this.updateExpandButtonText();
|
|
},
|
|
|
|
/**
|
|
* Update expand button text based on state
|
|
*/
|
|
updateExpandButtonText() {
|
|
const expandText = this.expandButton?.querySelector('.expand-text');
|
|
if (!expandText) return;
|
|
|
|
const isExpanded = this.expandButton.getAttribute(DATA_ATTRS.EXPANDED) === 'true';
|
|
expandText.textContent = getTranslation(isExpanded ? 'hideDetails' : 'expandDetails');
|
|
}
|
|
};
|
|
|
|
// Login Modal Component
|
|
const LoginModal = {
|
|
modalElement: null,
|
|
modalStyles: null,
|
|
|
|
/**
|
|
* Show login modal
|
|
*/
|
|
show() {
|
|
this.createModal();
|
|
this.attachEventListeners();
|
|
},
|
|
|
|
/**
|
|
* Create modal HTML and styles
|
|
*/
|
|
createModal() {
|
|
// Create modal element
|
|
this.modalElement = document.createElement('div');
|
|
this.modalElement.className = 'login-modal';
|
|
this.modalElement.innerHTML = this.getModalHTML();
|
|
document.body.appendChild(this.modalElement);
|
|
|
|
// Add modal styles if not already added
|
|
if (!this.modalStyles) {
|
|
this.addModalStyles();
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Get modal HTML content
|
|
* @returns {string} Modal HTML
|
|
*/
|
|
getModalHTML() {
|
|
const t = getTranslation;
|
|
return `
|
|
<div class="modal-content">
|
|
<button class="modal-close">×</button>
|
|
<div class="modal-header">
|
|
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" class="lock-icon">
|
|
<rect x="5" y="11" width="14" height="10" rx="2" stroke="currentColor" stroke-width="2"/>
|
|
<path d="M7 11V7C7 4.23858 9.23858 2 12 2C14.7614 2 17 4.23858 17 7V11" stroke="currentColor" stroke-width="2"/>
|
|
<circle cx="12" cy="16" r="1" fill="currentColor"/>
|
|
</svg>
|
|
<h3>${t('authRequired')}</h3>
|
|
</div>
|
|
<p>${t('authDescription')}</p>
|
|
<form id="loginForm">
|
|
<div class="form-group">
|
|
<label for="auth-password">${t('accessCode')}</label>
|
|
<input type="password" id="auth-password" placeholder="${t('accessCodePlaceholder')}" required autofocus>
|
|
</div>
|
|
<button type="submit" class="primary-button">${t('grantAccess')}</button>
|
|
</form>
|
|
<p class="auth-note">${t('noAccess')} <a href="mailto:info@intelsight.de">${t('contactUs')}</a></p>
|
|
</div>
|
|
`;
|
|
},
|
|
|
|
/**
|
|
* Add modal styles to document
|
|
*/
|
|
addModalStyles() {
|
|
this.modalStyles = document.createElement('style');
|
|
this.modalStyles.textContent = `
|
|
.login-modal {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
background: rgba(0, 0, 0, 0.7);
|
|
backdrop-filter: blur(10px);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
z-index: 10000;
|
|
animation: fadeIn 0.3s ease;
|
|
}
|
|
.modal-content {
|
|
background: #ffffff;
|
|
border-radius: 12px;
|
|
padding: 2.5rem;
|
|
max-width: 400px;
|
|
width: 90%;
|
|
position: relative;
|
|
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
|
|
}
|
|
.modal-header {
|
|
text-align: center;
|
|
margin-bottom: 1.5rem;
|
|
}
|
|
.modal-header .lock-icon {
|
|
width: 48px;
|
|
height: 48px;
|
|
color: #0066cc;
|
|
margin-bottom: 1rem;
|
|
}
|
|
.modal-close {
|
|
position: absolute;
|
|
top: 1rem;
|
|
right: 1rem;
|
|
background: none;
|
|
border: none;
|
|
color: #666;
|
|
font-size: 2rem;
|
|
cursor: pointer;
|
|
transition: all 0.3s ease;
|
|
width: 32px;
|
|
height: 32px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
border-radius: 50%;
|
|
}
|
|
.modal-close:hover {
|
|
background: #f0f0f0;
|
|
color: #333;
|
|
}
|
|
.modal-content h3 {
|
|
color: #1a1a1a;
|
|
margin-bottom: 0.5rem;
|
|
font-size: 1.5rem;
|
|
font-weight: 600;
|
|
}
|
|
.modal-content p {
|
|
color: #666;
|
|
margin-bottom: 2rem;
|
|
text-align: center;
|
|
}
|
|
.modal-content .form-group {
|
|
margin-bottom: 1.5rem;
|
|
}
|
|
.modal-content label {
|
|
display: block;
|
|
color: #333;
|
|
margin-bottom: 0.5rem;
|
|
font-weight: 500;
|
|
}
|
|
.modal-content input {
|
|
width: 100%;
|
|
padding: 0.875rem;
|
|
background: #f8f8f8;
|
|
border: 2px solid #e0e0e0;
|
|
border-radius: 8px;
|
|
color: #333;
|
|
font-size: 1rem;
|
|
transition: all 0.3s ease;
|
|
}
|
|
.modal-content input:focus {
|
|
outline: none;
|
|
border-color: #0066cc;
|
|
background: #fff;
|
|
}
|
|
.modal-content input::placeholder {
|
|
color: #999;
|
|
}
|
|
.modal-content .primary-button {
|
|
width: 100%;
|
|
padding: 0.875rem;
|
|
background: #0066cc;
|
|
color: white;
|
|
border: none;
|
|
border-radius: 8px;
|
|
font-size: 1rem;
|
|
font-weight: 600;
|
|
cursor: pointer;
|
|
transition: all 0.3s ease;
|
|
}
|
|
.modal-content .primary-button:hover {
|
|
background: #0052a3;
|
|
transform: translateY(-1px);
|
|
box-shadow: 0 4px 12px rgba(0, 102, 204, 0.3);
|
|
}
|
|
.auth-note {
|
|
text-align: center;
|
|
margin-top: 1.5rem;
|
|
font-size: 0.9rem;
|
|
color: #666;
|
|
}
|
|
.auth-note a {
|
|
color: #0066cc;
|
|
text-decoration: none;
|
|
}
|
|
.auth-note a:hover {
|
|
text-decoration: underline;
|
|
}
|
|
`;
|
|
document.head.appendChild(this.modalStyles);
|
|
},
|
|
|
|
/**
|
|
* Attach event listeners to modal
|
|
*/
|
|
attachEventListeners() {
|
|
// Close button
|
|
const closeBtn = this.modalElement.querySelector('.modal-close');
|
|
closeBtn.addEventListener('click', () => this.close());
|
|
|
|
// Form submission
|
|
const form = this.modalElement.querySelector('#loginForm');
|
|
form.addEventListener('submit', (e) => this.handleSubmit(e));
|
|
|
|
// Click outside to close
|
|
this.modalElement.addEventListener('click', (e) => {
|
|
if (e.target === this.modalElement) {
|
|
this.close();
|
|
}
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Handle form submission
|
|
* @param {Event} e - Submit event
|
|
*/
|
|
handleSubmit(e) {
|
|
e.preventDefault();
|
|
const password = document.getElementById('auth-password').value;
|
|
|
|
// Check password (temporarily hardcoded as requested)
|
|
if (password === '123456') {
|
|
sessionStorage.setItem(CONFIG.AUTH.SESSION_KEY, 'true');
|
|
this.close();
|
|
window.location.href = CONFIG.AUTH.REDIRECT_PAGE;
|
|
} else {
|
|
alert(getTranslation('wrongCode'));
|
|
document.getElementById('auth-password').value = '';
|
|
document.getElementById('auth-password').focus();
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Close and remove modal
|
|
*/
|
|
close() {
|
|
if (this.modalElement) {
|
|
this.modalElement.remove();
|
|
this.modalElement = null;
|
|
}
|
|
}
|
|
};
|
|
|
|
// Contact Form Component
|
|
const ContactForm = {
|
|
form: null,
|
|
|
|
/**
|
|
* Initialize contact form
|
|
*/
|
|
init() {
|
|
this.form = document.querySelector(SELECTORS.CONTACT_FORM);
|
|
if (!this.form) return;
|
|
|
|
this.form.addEventListener('submit', (e) => this.handleSubmit(e));
|
|
},
|
|
|
|
/**
|
|
* Handle form submission
|
|
* @param {Event} e - Submit event
|
|
*/
|
|
handleSubmit(e) {
|
|
e.preventDefault();
|
|
|
|
// Get form data
|
|
const formData = new FormData(this.form);
|
|
const data = Object.fromEntries(formData.entries());
|
|
|
|
// In production, this would send data to server
|
|
console.log('Form submission:', data);
|
|
|
|
// Show success message
|
|
alert(getTranslation('contactFormSuccess'));
|
|
this.form.reset();
|
|
}
|
|
};
|
|
|
|
// Demo Request Handler
|
|
const DemoRequest = {
|
|
/**
|
|
* Initialize demo request buttons
|
|
*/
|
|
init() {
|
|
document.querySelectorAll('.primary-button, .secondary-button, .cta-button').forEach(button => {
|
|
if (button.textContent.toLowerCase().includes('demo')) {
|
|
button.addEventListener('click', (e) => this.handleDemoRequest(e));
|
|
}
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Handle demo request
|
|
* @param {Event} e - Click event
|
|
*/
|
|
handleDemoRequest(e) {
|
|
e.preventDefault();
|
|
alert(getTranslation('demoRequestAlert'));
|
|
}
|
|
};
|
|
|
|
// Initialize all components
|
|
const Components = {
|
|
/**
|
|
* Initialize all UI components
|
|
*/
|
|
init() {
|
|
LanguageToggle.init();
|
|
Navigation.init();
|
|
AboutTabs.init();
|
|
ProductShowcase.init();
|
|
ContactForm.init();
|
|
DemoRequest.init();
|
|
}
|
|
};
|
|
|
|
// Make showLoginModal globally available for onclick attribute
|
|
window.showLoginModal = function() {
|
|
LoginModal.show();
|
|
};
|
|
|
|
// Make closeLoginModal globally available for onclick attribute
|
|
window.closeLoginModal = function() {
|
|
LoginModal.close();
|
|
}; |