Compare commits

...

2 Commits

Author SHA1 Message Date
Sami b7d4d6d1ee FAQ fixed 2025-09-12 16:08:22 +00:00
Sami 1b0cdedc14 code optimized 2025-09-12 15:14:31 +00:00
4 changed files with 281 additions and 292 deletions
+100 -15
View File
@@ -125,64 +125,147 @@
<!-- FAQ Section -->
<section class="faq-section" aria-labelledby="faq-heading">
<h2 id="faq-heading">Frequently Asked Questions</h2>
<div class="faq-item">
<div class="faq-question" role="button" aria-expanded="false" aria-controls="faq-answer-1">
<div
class="faq-question"
role="button"
aria-expanded="false"
aria-controls="faq-answer-1"
>
<h4>What makes your teas different from supermarket teas?</h4>
<span class="faq-toggle">+</span>
</div>
<div id="faq-answer-1" class="faq-answer">
<p>Our teas are sourced directly from traditional tea gardens and artisan farmers around the world. Unlike supermarket teas that may sit in warehouses for months, our teas are freshly harvested, properly stored, and shipped directly to you. We work closely with tea masters who have perfected their craft over generations, ensuring you receive authentic, premium-quality teas with exceptional flavor profiles.</p>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat
nulla pariatur. Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
</div>
</div>
<div class="faq-item">
<div class="faq-question" role="button" aria-expanded="false" aria-controls="faq-answer-2">
<div
class="faq-question"
role="button"
aria-expanded="false"
aria-controls="faq-answer-2"
>
<h4>How should I store my tea to maintain freshness?</h4>
<span class="faq-toggle">+</span>
</div>
<div id="faq-answer-2" class="faq-answer">
<p>To maintain optimal freshness, store your tea in an airtight container away from light, heat, and moisture. We recommend keeping tea in a cool, dark place like a pantry or cupboard. Avoid storing tea near strong odors, as tea can absorb surrounding scents. Properly stored, most teas will maintain their quality for 6-12 months, while pu-erh teas can actually improve with age when stored correctly.</p>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat
nulla pariatur. Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
</div>
</div>
<div class="faq-item">
<div class="faq-question" role="button" aria-expanded="false" aria-controls="faq-answer-3">
<h4>What is the best water temperature for brewing different types of tea?</h4>
<div
class="faq-question"
role="button"
aria-expanded="false"
aria-controls="faq-answer-3"
>
<h4>
What is the best water temperature for brewing different types of
tea?
</h4>
<span class="faq-toggle">+</span>
</div>
<div id="faq-answer-3" class="faq-answer">
<p>Water temperature is crucial for optimal tea brewing. Here's our guide: Green teas: 160-180°F (71-82°C), White teas: 175-185°F (79-85°C), Oolong teas: 185-205°F (85-96°C), Black teas: 200-212°F (93-100°C), Pu-erh teas: 200-212°F (93-100°C), Herbal infusions: 200-212°F (93-100°C). Using water that's too hot can burn delicate teas, while water that's too cool won't extract the full flavor profile.</p>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat
nulla pariatur. Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
</div>
</div>
<div class="faq-item">
<div class="faq-question" role="button" aria-expanded="false" aria-controls="faq-answer-4">
<div
class="faq-question"
role="button"
aria-expanded="false"
aria-controls="faq-answer-4"
>
<h4>Do you offer organic teas?</h4>
<span class="faq-toggle">+</span>
</div>
<div id="faq-answer-4" class="faq-answer">
<p>Yes! Many of our teas are certified organic, and we work with farms that practice sustainable, chemical-free cultivation methods. Look for the organic certification label on our product pages. Even our non-certified teas are sourced from farms that prioritize environmental stewardship and sustainable farming practices, as we believe great tea starts with healthy soil and happy plants.</p>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat
nulla pariatur. Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
</div>
</div>
<div class="faq-item">
<div class="faq-question" role="button" aria-expanded="false" aria-controls="faq-answer-5">
<h4>How long does shipping take, and do you ship internationally?</h4>
<div
class="faq-question"
role="button"
aria-expanded="false"
aria-controls="faq-answer-5"
>
<h4>
How long does shipping take, and do you ship internationally?
</h4>
<span class="faq-toggle">+</span>
</div>
<div id="faq-answer-5" class="faq-answer">
<p>We offer fast shipping throughout the United States, with most orders arriving within 3-5 business days. We also ship internationally to many countries, though delivery times vary by destination (typically 7-14 business days). All orders include tracking information, and we carefully package our teas to ensure they arrive in perfect condition. Free shipping is available on orders over $50 within the US.</p>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat
nulla pariatur. Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
</div>
</div>
<div class="faq-item">
<div class="faq-question" role="button" aria-expanded="false" aria-controls="faq-answer-6">
<div
class="faq-question"
role="button"
aria-expanded="false"
aria-controls="faq-answer-6"
>
<h4>Can I return or exchange tea if I'm not satisfied?</h4>
<span class="faq-toggle">+</span>
</div>
<div id="faq-answer-6" class="faq-answer">
<p>Your satisfaction is our top priority. If you're not completely happy with your tea, please contact us within 30 days of purchase. While we cannot accept returns of opened tea due to food safety regulations, we'll work with you to find a solution - whether that's a replacement, store credit, or refund depending on the circumstances. We want every cup of tea you brew to bring you joy!</p>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat
nulla pariatur. Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
</div>
</div>
</section>
@@ -195,5 +278,7 @@
tea experts.
</p>
</footer>
<script src="script.js"></script>
</body>
</html>
+1
View File
@@ -4,6 +4,7 @@
<meta charset="UTF-8" />
<title>Contact Us - Global Tea Emporium</title>
<link rel="stylesheet" href="styles.css" />
<script src="script.js"></script>
</head>
<body>
<header>
+1
View File
@@ -4,6 +4,7 @@
<meta charset="UTF-8" />
<title>Global Tea Emporium - Premium Authentic Teas Worldwide</title>
<link rel="stylesheet" href="styles.css" />
<script src="script.js"></script>
</head>
<body>
<!-- Skip to main content link for screen readers -->
+179 -277
View File
@@ -1,295 +1,197 @@
// Global Tea Emporium - JavaScript Functionality
// Global Tea Emporium - Optimized JavaScript
// Image Gallery Functionality
document.addEventListener('DOMContentLoaded', function() {
console.log('Gallery script loading...');
const galleryImages = [
{
src: 'images/green-tea-leaves.webp',
alt: 'Premium Green Tea Leaves',
caption: 'Premium Green Tea Leaves - Hand-picked from our finest gardens'
},
{
src: 'images/Indian Black Teas.webp',
alt: 'Indian Black Tea Selection',
caption: 'Authentic Indian Black Teas - Rich and robust flavors from Assam and Darjeeling'
},
{
src: 'images/Oolong Selections.jpg',
alt: 'Oolong Tea Collection',
caption: 'Traditional Oolong Selections - Complex flavors from Taiwan and China'
document.addEventListener("DOMContentLoaded", function () {
// ===== FAQ ACCORDION =====
const faqQuestions = document.querySelectorAll(".faq-question");
faqQuestions.forEach((question) => {
question.addEventListener("click", function () {
const answer = this.nextElementSibling;
const toggle = this.querySelector(".faq-toggle");
const isExpanded = this.getAttribute("aria-expanded") === "true";
// Close all other FAQ items
faqQuestions.forEach((otherQuestion) => {
if (otherQuestion !== this) {
const otherAnswer = otherQuestion.nextElementSibling;
const otherToggle = otherQuestion.querySelector(".faq-toggle");
otherQuestion.setAttribute("aria-expanded", "false");
otherAnswer.classList.remove("active");
otherToggle.classList.remove("active");
}
];
});
let currentImageIndex = 0;
const galleryImage = document.getElementById('gallery-image');
const galleryCaption = document.getElementById('gallery-caption');
const prevBtn = document.getElementById('prev-btn');
const nextBtn = document.getElementById('next-btn');
const thumbnails = document.querySelectorAll('.thumbnail');
// Check if gallery elements exist
if (!galleryImage || !galleryCaption) {
console.log('Gallery image or caption not found');
return;
}
console.log('Gallery elements found:', {
image: !!galleryImage,
caption: !!galleryCaption,
prevBtn: !!prevBtn,
nextBtn: !!nextBtn,
thumbnails: thumbnails.length
// Toggle current FAQ item
this.setAttribute("aria-expanded", !isExpanded);
answer.classList.toggle("active");
toggle.classList.toggle("active");
});
function updateGallery(index) {
console.log('Updating gallery to index:', index);
currentImageIndex = index;
galleryImage.src = galleryImages[index].src;
galleryImage.alt = galleryImages[index].alt;
galleryCaption.textContent = galleryImages[index].caption;
// Update active thumbnail
thumbnails.forEach((thumb, i) => {
thumb.classList.toggle('active', i === index);
});
}
function nextImage() {
console.log('Next image clicked');
const newIndex = (currentImageIndex + 1) % galleryImages.length;
updateGallery(newIndex);
}
function prevImage() {
console.log('Previous image clicked');
const newIndex = (currentImageIndex - 1 + galleryImages.length) % galleryImages.length;
updateGallery(newIndex);
}
// Event listeners for gallery controls
if (prevBtn) {
console.log('Adding prev button listener');
prevBtn.addEventListener('click', prevImage);
} else {
console.log('Prev button not found');
}
if (nextBtn) {
console.log('Adding next button listener');
nextBtn.addEventListener('click', nextImage);
} else {
console.log('Next button not found');
}
// Thumbnail click events
thumbnails.forEach((thumbnail) => {
thumbnail.addEventListener('click', () => {
const index = parseInt(thumbnail.getAttribute('data-index'));
console.log('Thumbnail clicked, index:', index);
if (!isNaN(index)) {
updateGallery(index);
}
});
// Add keyboard navigation
question.addEventListener("keydown", function (e) {
if (e.key === "Enter" || e.key === " ") {
e.preventDefault();
this.click();
}
});
});
// Auto-advance gallery every 5 seconds
setInterval(nextImage, 5000);
console.log('Gallery initialized successfully');
}); // End of DOMContentLoaded for gallery
// ===== IMAGE GALLERY =====
const galleryImages = [
{
src: "images/green-tea-leaves.webp",
alt: "Premium Green Tea Leaves",
caption: "Premium Green Tea Leaves - Hand-picked from our finest gardens",
},
{
src: "images/Indian Black Teas.webp",
alt: "Indian Black Tea Selection",
caption:
"Authentic Indian Black Teas - Rich and robust flavors from Assam and Darjeeling",
},
{
src: "images/Oolong Selections.jpg",
alt: "Oolong Tea Collection",
caption:
"Traditional Oolong Selections - Complex flavors from Taiwan and China",
},
];
// Enhanced Contact Form Validation
document.addEventListener('DOMContentLoaded', function() {
const contactForm = document.querySelector('.contact-form');
if (contactForm) {
const formGroups = contactForm.querySelectorAll('.form-group');
// Real-time validation function
function validateField(field) {
const formGroup = field.closest('.form-group');
const errorSpan = formGroup.querySelector('.error-message');
let isValid = true;
let errorMessage = '';
const galleryImage = document.getElementById("gallery-image");
const galleryCaption = document.getElementById("gallery-caption");
const thumbnails = document.querySelectorAll(".thumbnail");
let currentIndex = 0;
// Remove previous validation classes
formGroup.classList.remove('error', 'success');
if (!galleryImage || !galleryCaption) return;
// Validate required fields
if (field.hasAttribute('required') && !field.value.trim()) {
isValid = false;
errorMessage = 'This field is required.';
} else if (field.type === 'email' && field.value) {
// Email validation
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(field.value)) {
isValid = false;
errorMessage = 'Please enter a valid email address.';
}
} else if (field.type === 'tel' && field.value) {
// Phone validation (basic)
const phoneRegex = /^[\d\s\-\+\(\)]+$/;
if (!phoneRegex.test(field.value)) {
isValid = false;
errorMessage = 'Please enter a valid phone number.';
}
} else if (field.tagName === 'TEXTAREA' && field.value.length < 10 && field.hasAttribute('required')) {
// Message length validation
isValid = false;
errorMessage = 'Message must be at least 10 characters long.';
}
// Update gallery display
function updateGallery(index) {
currentIndex = index;
const image = galleryImages[index];
galleryImage.src = image.src;
galleryImage.alt = image.alt;
galleryCaption.textContent = image.caption;
// Display validation results
if (errorSpan) {
errorSpan.textContent = errorMessage;
}
if (isValid && field.value.trim()) {
formGroup.classList.add('success');
} else if (!isValid) {
formGroup.classList.add('error');
}
thumbnails.forEach((thumb, i) => {
thumb.classList.toggle("active", i === index);
});
}
return isValid;
// Navigation functions
const nextImage = () =>
updateGallery((currentIndex + 1) % galleryImages.length);
const prevImage = () =>
updateGallery(
(currentIndex - 1 + galleryImages.length) % galleryImages.length
);
// Event listeners
document.getElementById("next-btn")?.addEventListener("click", nextImage);
document.getElementById("prev-btn")?.addEventListener("click", prevImage);
thumbnails.forEach((thumb, index) => {
thumb.addEventListener("click", () => updateGallery(index));
});
// Auto-advance every 10 seconds
setInterval(nextImage, 10000);
// ===== CONTACT FORM =====
const contactForm = document.querySelector(".contact-form");
if (contactForm) {
const validateField = (field) => {
const group = field.closest(".form-group");
const error = group?.querySelector(".error-message");
let isValid = true;
let message = "";
group?.classList.remove("error", "success");
if (field.required && !field.value.trim()) {
isValid = false;
message = "This field is required.";
} else if (
field.type === "email" &&
field.value &&
!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(field.value)
) {
isValid = false;
message = "Please enter a valid email address.";
} else if (
field.type === "tel" &&
field.value &&
!/^[\d\s\-\+\(\)]+$/.test(field.value)
) {
isValid = false;
message = "Please enter a valid phone number.";
}
if (error) error.textContent = message;
group?.classList.add(
isValid && field.value.trim() ? "success" : isValid ? "" : "error"
);
return isValid;
};
contactForm.querySelectorAll("input, textarea").forEach((field) => {
field.addEventListener("blur", () => validateField(field));
field.addEventListener("input", () => {
if (field.closest(".form-group")?.classList.contains("error")) {
validateField(field);
}
});
});
// Add real-time validation to all form fields
formGroups.forEach(group => {
const input = group.querySelector('input, textarea');
if (input) {
input.addEventListener('blur', () => validateField(input));
input.addEventListener('input', () => {
if (group.classList.contains('error')) {
validateField(input);
}
});
}
});
contactForm.addEventListener("submit", (e) => {
e.preventDefault();
const fields = contactForm.querySelectorAll("input, textarea");
const isValid = Array.from(fields).every(validateField);
contactForm.addEventListener('submit', function(e) {
e.preventDefault();
let isFormValid = true;
const formData = new FormData(contactForm);
const data = Object.fromEntries(formData);
// Validate all fields
formGroups.forEach(group => {
const input = group.querySelector('input, textarea');
if (input && !validateField(input)) {
isFormValid = false;
}
});
if (isValid) {
const submitBtn = contactForm.querySelector(".submit-btn");
const originalText = submitBtn.textContent;
submitBtn.textContent = "Sending...";
submitBtn.disabled = true;
if (!isFormValid) {
// Focus on first error field
const firstError = contactForm.querySelector('.form-group.error input, .form-group.error textarea');
if (firstError) {
firstError.focus();
}
return;
}
// Simulate form submission with loading state
const submitBtn = contactForm.querySelector('.submit-btn');
const originalText = submitBtn.textContent;
submitBtn.textContent = 'Sending...';
submitBtn.disabled = true;
setTimeout(() => {
alert(`Thank you for your message, ${data.name}! We'll get back to you soon at ${data.email}.`);
contactForm.reset();
formGroups.forEach(group => group.classList.remove('error', 'success'));
submitBtn.textContent = originalText;
submitBtn.disabled = false;
}, 2000);
});
setTimeout(() => {
const formData = new FormData(contactForm);
const data = Object.fromEntries(formData);
alert(`Thank you, ${data.name}! We'll contact you at ${data.email}.`);
contactForm.reset();
fields.forEach((f) =>
f.closest(".form-group")?.classList.remove("error", "success")
);
submitBtn.textContent = originalText;
submitBtn.disabled = false;
}, 2000);
}
});
}
// ===== HOVER EFFECTS =====
document
.querySelectorAll(".services-list li, .value-item, .timeline-item")
.forEach((item) => {
item.addEventListener("mouseenter", () => {
item.style.transform = "translateY(-2px)";
item.style.transition = "transform 0.3s ease";
});
item.addEventListener("mouseleave", () => {
item.style.transform = "translateY(0)";
});
});
// ===== ACTIVE NAVIGATION =====
const currentPage = location.pathname.split("/").pop();
document.querySelectorAll(".main-nav a").forEach((link) => {
const linkPage = link.getAttribute("href");
if (
linkPage === currentPage ||
(currentPage === "" && linkPage === "index.html")
) {
link.style.backgroundColor = "#daa520";
link.style.color = "#5d4037";
}
});
// FAQ Accordion Functionality
document.addEventListener('DOMContentLoaded', function() {
const faqQuestions = document.querySelectorAll('.faq-question');
faqQuestions.forEach(question => {
question.addEventListener('click', function() {
const answer = this.nextElementSibling;
const toggle = this.querySelector('.faq-toggle');
const isExpanded = this.getAttribute('aria-expanded') === 'true';
// Close all other FAQ items
faqQuestions.forEach(otherQuestion => {
if (otherQuestion !== this) {
const otherAnswer = otherQuestion.nextElementSibling;
const otherToggle = otherQuestion.querySelector('.faq-toggle');
otherQuestion.setAttribute('aria-expanded', 'false');
otherAnswer.classList.remove('active');
otherToggle.classList.remove('active');
}
});
// Toggle current FAQ item
this.setAttribute('aria-expanded', !isExpanded);
answer.classList.toggle('active');
toggle.classList.toggle('active');
});
// Add keyboard navigation
question.addEventListener('keydown', function(e) {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
this.click();
}
});
});
});
// Smooth scrolling for navigation links
document.addEventListener('DOMContentLoaded', function() {
const navLinks = document.querySelectorAll('.main-nav a');
navLinks.forEach(link => {
link.addEventListener('click', function(e) {
// Check if it's an internal link
if (this.hostname === window.location.hostname) {
// Add a subtle animation effect
this.style.transform = 'scale(0.95)';
setTimeout(() => {
this.style.transform = 'scale(1)';
}, 150);
}
});
});
});
// Add hover effects to service items
document.addEventListener('DOMContentLoaded', function() {
const serviceItems = document.querySelectorAll('.services-list li, .value-item, .timeline-item');
serviceItems.forEach(item => {
item.addEventListener('mouseenter', function() {
this.style.transform = 'translateY(-2px)';
this.style.transition = 'transform 0.3s ease';
});
item.addEventListener('mouseleave', function() {
this.style.transform = 'translateY(0)';
});
});
});
// Active navigation highlighting
document.addEventListener('DOMContentLoaded', function() {
const currentPage = window.location.pathname.split('/').pop();
const navLinks = document.querySelectorAll('.main-nav a');
navLinks.forEach(link => {
const linkPage = link.getAttribute('href');
if (linkPage === currentPage || (currentPage === '' && linkPage === 'index.html')) {
link.style.backgroundColor = '#daa520';
link.style.color = '#5d4037';
}
});
});
});