Initial AI-generated site
This commit is contained in:
@@ -0,0 +1,289 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
// Set current year in footer
|
||||
const yearEl = document.getElementById('currentYear');
|
||||
if (yearEl) {
|
||||
yearEl.textContent = new Date().getFullYear();
|
||||
}
|
||||
|
||||
// Check for reduced motion preference
|
||||
const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
||||
|
||||
// Mobile Navigation
|
||||
const navToggle = document.querySelector('.nav-toggle');
|
||||
const navMenu = document.querySelector('.nav-menu');
|
||||
|
||||
if (navToggle && navMenu) {
|
||||
navToggle.addEventListener('click', () => {
|
||||
const isExpanded = navToggle.getAttribute('aria-expanded') === 'true';
|
||||
navToggle.setAttribute('aria-expanded', !isExpanded);
|
||||
navToggle.setAttribute('aria-label', isExpanded ? 'פתיחת תפריט ניווט' : 'סגירת תפריט ניווט');
|
||||
navMenu.classList.toggle('active');
|
||||
});
|
||||
|
||||
// Close menu when clicking a link
|
||||
navMenu.querySelectorAll('a').forEach(link => {
|
||||
link.addEventListener('click', () => {
|
||||
navToggle.setAttribute('aria-expanded', 'false');
|
||||
navToggle.setAttribute('aria-label', 'פתיחת תפריט ניווט');
|
||||
navMenu.classList.remove('active');
|
||||
});
|
||||
});
|
||||
|
||||
// Close menu on escape key
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Escape' && navMenu.classList.contains('active')) {
|
||||
navToggle.setAttribute('aria-expanded', 'false');
|
||||
navToggle.setAttribute('aria-label', 'פתיחת תפריט ניווט');
|
||||
navMenu.classList.remove('active');
|
||||
navToggle.focus();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Smooth scroll for anchor links
|
||||
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
||||
anchor.addEventListener('click', function(e) {
|
||||
const href = this.getAttribute('href');
|
||||
if (href === '#') return;
|
||||
|
||||
const target = document.querySelector(href);
|
||||
if (target) {
|
||||
e.preventDefault();
|
||||
target.scrollIntoView({
|
||||
behavior: prefersReducedMotion ? 'auto' : 'smooth',
|
||||
block: 'start'
|
||||
});
|
||||
// Set focus to target for accessibility
|
||||
target.setAttribute('tabindex', '-1');
|
||||
target.focus({ preventScroll: true });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Toast notification
|
||||
function showToast(message, type = 'success') {
|
||||
const toast = document.getElementById('toast');
|
||||
if (!toast) return;
|
||||
|
||||
toast.textContent = message;
|
||||
toast.className = 'toast show ' + type;
|
||||
|
||||
setTimeout(() => {
|
||||
toast.classList.remove('show');
|
||||
}, 4000);
|
||||
}
|
||||
|
||||
// Form validation helpers
|
||||
function showError(inputId, message) {
|
||||
const input = document.getElementById(inputId);
|
||||
const errorEl = document.getElementById(inputId + '-error');
|
||||
if (input) {
|
||||
input.classList.add('error');
|
||||
input.setAttribute('aria-invalid', 'true');
|
||||
input.setAttribute('aria-describedby', inputId + '-error');
|
||||
}
|
||||
if (errorEl) {
|
||||
errorEl.textContent = message;
|
||||
}
|
||||
}
|
||||
|
||||
function clearError(inputId) {
|
||||
const input = document.getElementById(inputId);
|
||||
const errorEl = document.getElementById(inputId + '-error');
|
||||
if (input) {
|
||||
input.classList.remove('error');
|
||||
input.removeAttribute('aria-invalid');
|
||||
input.removeAttribute('aria-describedby');
|
||||
}
|
||||
if (errorEl) {
|
||||
errorEl.textContent = '';
|
||||
}
|
||||
}
|
||||
|
||||
function clearAllErrors(form) {
|
||||
form.querySelectorAll('.error').forEach(el => el.classList.remove('error'));
|
||||
form.querySelectorAll('.error-message').forEach(el => el.textContent = '');
|
||||
form.querySelectorAll('[aria-invalid]').forEach(el => {
|
||||
el.removeAttribute('aria-invalid');
|
||||
el.removeAttribute('aria-describedby');
|
||||
});
|
||||
}
|
||||
|
||||
// Set minimum date for booking
|
||||
const dateInput = document.getElementById('date');
|
||||
if (dateInput) {
|
||||
const today = new Date();
|
||||
const tomorrow = new Date(today);
|
||||
tomorrow.setDate(tomorrow.getDate() + 1);
|
||||
|
||||
const year = tomorrow.getFullYear();
|
||||
const month = String(tomorrow.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(tomorrow.getDate()).padStart(2, '0');
|
||||
|
||||
dateInput.setAttribute('min', `${year}-${month}-${day}`);
|
||||
|
||||
// Set max date to 3 months from now
|
||||
const maxDate = new Date(today);
|
||||
maxDate.setMonth(maxDate.getMonth() + 3);
|
||||
const maxYear = maxDate.getFullYear();
|
||||
const maxMonth = String(maxDate.getMonth() + 1).padStart(2, '0');
|
||||
const maxDay = String(maxDate.getDate()).padStart(2, '0');
|
||||
dateInput.setAttribute('max', `${maxYear}-${maxMonth}-${maxDay}`);
|
||||
}
|
||||
|
||||
// Phone validation (Israeli format)
|
||||
function isValidPhone(phone) {
|
||||
const cleaned = phone.replace(/[\s\-]/g, '');
|
||||
return /^0[2-9]\d{7,8}$/.test(cleaned);
|
||||
}
|
||||
|
||||
// Booking Form
|
||||
const bookingForm = document.getElementById('bookingForm');
|
||||
if (bookingForm) {
|
||||
bookingForm.addEventListener('submit', function(e) {
|
||||
e.preventDefault();
|
||||
clearAllErrors(this);
|
||||
|
||||
const formData = new FormData(this);
|
||||
const data = Object.fromEntries(formData.entries());
|
||||
let hasError = false;
|
||||
|
||||
// Validate required fields
|
||||
if (!data.name.trim()) {
|
||||
showError('name', 'נא להזין שם');
|
||||
hasError = true;
|
||||
}
|
||||
|
||||
if (!data.phone.trim()) {
|
||||
showError('phone', 'נא להזין טלפון');
|
||||
hasError = true;
|
||||
} else if (!isValidPhone(data.phone)) {
|
||||
showError('phone', 'נא להזין מספר טלפון תקין');
|
||||
hasError = true;
|
||||
}
|
||||
|
||||
if (!data.service) {
|
||||
showError('service', 'נא לבחור שירות');
|
||||
hasError = true;
|
||||
}
|
||||
|
||||
if (!data.date) {
|
||||
showError('date', 'נא לבחור תאריך');
|
||||
hasError = true;
|
||||
}
|
||||
|
||||
if (!data.time) {
|
||||
showError('time', 'נא לבחור שעה');
|
||||
hasError = true;
|
||||
}
|
||||
|
||||
if (hasError) {
|
||||
showToast('נא לתקן את השגיאות בטופס', 'error');
|
||||
// Focus first error
|
||||
const firstError = this.querySelector('.error');
|
||||
if (firstError) firstError.focus();
|
||||
return;
|
||||
}
|
||||
|
||||
// Simulate form submission
|
||||
const submitBtn = this.querySelector('button[type="submit"]');
|
||||
const originalText = submitBtn.textContent;
|
||||
submitBtn.textContent = 'שולח...';
|
||||
submitBtn.disabled = true;
|
||||
|
||||
setTimeout(() => {
|
||||
showToast('הבקשה נשלחה! נחזור אליכם תוך 3 שעות.', 'success');
|
||||
this.reset();
|
||||
submitBtn.textContent = originalText;
|
||||
submitBtn.disabled = false;
|
||||
}, 1200);
|
||||
});
|
||||
|
||||
// Clear errors on input
|
||||
bookingForm.querySelectorAll('input, select, textarea').forEach(input => {
|
||||
input.addEventListener('input', () => {
|
||||
clearError(input.id);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Contact Form
|
||||
const contactForm = document.getElementById('contactForm');
|
||||
if (contactForm) {
|
||||
contactForm.addEventListener('submit', function(e) {
|
||||
e.preventDefault();
|
||||
clearAllErrors(this);
|
||||
|
||||
const formData = new FormData(this);
|
||||
const data = Object.fromEntries(formData.entries());
|
||||
let hasError = false;
|
||||
|
||||
if (!data.name.trim()) {
|
||||
showError('contactName', 'נא להזין שם');
|
||||
hasError = true;
|
||||
}
|
||||
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
if (!data.email.trim()) {
|
||||
showError('contactEmail', 'נא להזין אימייל');
|
||||
hasError = true;
|
||||
} else if (!emailRegex.test(data.email)) {
|
||||
showError('contactEmail', 'נא להזין אימייל תקין');
|
||||
hasError = true;
|
||||
}
|
||||
|
||||
if (!data.message.trim()) {
|
||||
showError('contactMessage', 'נא להזין הודעה');
|
||||
hasError = true;
|
||||
}
|
||||
|
||||
if (hasError) {
|
||||
showToast('נא לתקן את השגיאות בטופס', 'error');
|
||||
const firstError = this.querySelector('.error');
|
||||
if (firstError) firstError.focus();
|
||||
return;
|
||||
}
|
||||
|
||||
// Simulate form submission
|
||||
const submitBtn = this.querySelector('button[type="submit"]');
|
||||
const originalText = submitBtn.textContent;
|
||||
submitBtn.textContent = 'שולח...';
|
||||
submitBtn.disabled = true;
|
||||
|
||||
setTimeout(() => {
|
||||
showToast('ההודעה נשלחה! תודה על פנייתכם.', 'success');
|
||||
this.reset();
|
||||
submitBtn.textContent = originalText;
|
||||
submitBtn.disabled = false;
|
||||
}, 1200);
|
||||
});
|
||||
|
||||
// Clear errors on input
|
||||
contactForm.querySelectorAll('input, textarea').forEach(input => {
|
||||
input.addEventListener('input', () => {
|
||||
clearError(input.id);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Header background on scroll
|
||||
const header = document.querySelector('.site-header');
|
||||
let ticking = false;
|
||||
|
||||
window.addEventListener('scroll', () => {
|
||||
if (!ticking) {
|
||||
window.requestAnimationFrame(() => {
|
||||
if (window.pageYOffset > 50) {
|
||||
header.style.background = 'rgba(15, 15, 15, 0.98)';
|
||||
} else {
|
||||
header.style.background = 'rgba(15, 15, 15, 0.92)';
|
||||
}
|
||||
ticking = false;
|
||||
});
|
||||
ticking = true;
|
||||
}
|
||||
}, { passive: true });
|
||||
|
||||
})();
|
||||
Reference in New Issue
Block a user