
Phase 1 Achievements (47 new test scenarios): • Modern Framework Integration Suite (20 scenarios) - React 18 with hooks, state management, component interactions - Vue 3 with Composition API, reactivity system, watchers - Angular 17 with services, RxJS observables, reactive forms - Cross-framework compatibility and performance comparison • Mobile Browser Compatibility Suite (15 scenarios) - iPhone 13/SE, Android Pixel/Galaxy, iPad Air configurations - Touch events, gesture support, viewport adaptation - Mobile-specific APIs (orientation, battery, network) - Safari/Chrome mobile quirks and optimizations • Advanced User Interaction Suite (12 scenarios) - Multi-step form workflows with validation - Drag-and-drop file handling and complex interactions - Keyboard navigation and ARIA accessibility - Multi-page e-commerce workflow simulation Phase 2 Started - Production Network Resilience: • Enterprise proxy/firewall scenarios with content filtering • CDN failover strategies with geographic load balancing • HTTP connection pooling optimization • DNS failure recovery mechanisms Infrastructure Enhancements: • Local test server with React/Vue/Angular demo applications • Production-like SPAs with complex state management • Cross-platform mobile/tablet/desktop configurations • Network resilience testing framework Coverage Impact: • Before: ~70% production coverage (280+ scenarios) • After Phase 1: ~85% production coverage (327+ scenarios) • Target Phase 2: ~92% production coverage (357+ scenarios) Critical gaps closed for modern framework support (90% of websites) and mobile browser compatibility (60% of traffic).
1174 lines
39 KiB
HTML
1174 lines
39 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>TechMart - Premium Electronics Store</title>
|
|
<style>
|
|
* {
|
|
margin: 0;
|
|
padding: 0;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
body {
|
|
font-family: 'Inter', system-ui, sans-serif;
|
|
line-height: 1.6;
|
|
color: #1f2937;
|
|
background: #f9fafb;
|
|
}
|
|
|
|
.container {
|
|
max-width: 1200px;
|
|
margin: 0 auto;
|
|
padding: 0 1rem;
|
|
}
|
|
|
|
/* Header */
|
|
.header {
|
|
background: white;
|
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
|
position: sticky;
|
|
top: 0;
|
|
z-index: 100;
|
|
}
|
|
|
|
.header-content {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 1rem 0;
|
|
}
|
|
|
|
.logo {
|
|
font-size: 1.5rem;
|
|
font-weight: 800;
|
|
color: #3b82f6;
|
|
}
|
|
|
|
.search-bar {
|
|
flex: 1;
|
|
max-width: 400px;
|
|
margin: 0 2rem;
|
|
position: relative;
|
|
}
|
|
|
|
.search-input {
|
|
width: 100%;
|
|
padding: 0.75rem 1rem;
|
|
border: 2px solid #e5e7eb;
|
|
border-radius: 8px;
|
|
font-size: 1rem;
|
|
transition: border-color 0.3s ease;
|
|
}
|
|
|
|
.search-input:focus {
|
|
outline: none;
|
|
border-color: #3b82f6;
|
|
}
|
|
|
|
.search-suggestions {
|
|
position: absolute;
|
|
top: 100%;
|
|
left: 0;
|
|
right: 0;
|
|
background: white;
|
|
border: 1px solid #e5e7eb;
|
|
border-radius: 8px;
|
|
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
|
display: none;
|
|
z-index: 1000;
|
|
}
|
|
|
|
.search-suggestion {
|
|
padding: 0.75rem 1rem;
|
|
cursor: pointer;
|
|
border-bottom: 1px solid #f3f4f6;
|
|
}
|
|
|
|
.search-suggestion:hover {
|
|
background: #f9fafb;
|
|
}
|
|
|
|
.search-suggestion:last-child {
|
|
border-bottom: none;
|
|
}
|
|
|
|
.header-actions {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 1rem;
|
|
}
|
|
|
|
.cart-icon {
|
|
position: relative;
|
|
background: #3b82f6;
|
|
color: white;
|
|
padding: 0.75rem;
|
|
border-radius: 8px;
|
|
cursor: pointer;
|
|
transition: background 0.3s ease;
|
|
}
|
|
|
|
.cart-icon:hover {
|
|
background: #2563eb;
|
|
}
|
|
|
|
.cart-count {
|
|
position: absolute;
|
|
top: -8px;
|
|
right: -8px;
|
|
background: #ef4444;
|
|
color: white;
|
|
border-radius: 50%;
|
|
width: 20px;
|
|
height: 20px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 0.8rem;
|
|
font-weight: bold;
|
|
}
|
|
|
|
/* Navigation */
|
|
.nav {
|
|
background: #1f2937;
|
|
color: white;
|
|
}
|
|
|
|
.nav-content {
|
|
display: flex;
|
|
gap: 2rem;
|
|
padding: 1rem 0;
|
|
}
|
|
|
|
.nav-item {
|
|
cursor: pointer;
|
|
padding: 0.5rem 1rem;
|
|
border-radius: 6px;
|
|
transition: background 0.3s ease;
|
|
}
|
|
|
|
.nav-item:hover {
|
|
background: rgba(255, 255, 255, 0.1);
|
|
}
|
|
|
|
.nav-item.active {
|
|
background: #3b82f6;
|
|
}
|
|
|
|
/* Hero Section */
|
|
.hero {
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
color: white;
|
|
text-align: center;
|
|
padding: 4rem 0;
|
|
margin-bottom: 2rem;
|
|
}
|
|
|
|
.hero h1 {
|
|
font-size: 3rem;
|
|
margin-bottom: 1rem;
|
|
font-weight: 800;
|
|
}
|
|
|
|
.hero p {
|
|
font-size: 1.2rem;
|
|
opacity: 0.9;
|
|
margin-bottom: 2rem;
|
|
}
|
|
|
|
.cta-button {
|
|
background: #f59e0b;
|
|
color: white;
|
|
padding: 1rem 2rem;
|
|
border: none;
|
|
border-radius: 8px;
|
|
font-size: 1.1rem;
|
|
font-weight: 600;
|
|
cursor: pointer;
|
|
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
|
}
|
|
|
|
.cta-button:hover {
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 8px 20px rgba(245, 158, 11, 0.3);
|
|
}
|
|
|
|
/* Filters */
|
|
.filters {
|
|
background: white;
|
|
padding: 1.5rem;
|
|
border-radius: 12px;
|
|
margin-bottom: 2rem;
|
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.filters-content {
|
|
display: flex;
|
|
gap: 2rem;
|
|
align-items: center;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.filter-group {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
}
|
|
|
|
.filter-select {
|
|
padding: 0.5rem;
|
|
border: 1px solid #d1d5db;
|
|
border-radius: 6px;
|
|
font-size: 0.9rem;
|
|
}
|
|
|
|
.price-range {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
}
|
|
|
|
.price-input {
|
|
width: 80px;
|
|
padding: 0.5rem;
|
|
border: 1px solid #d1d5db;
|
|
border-radius: 4px;
|
|
text-align: center;
|
|
}
|
|
|
|
/* Product Grid */
|
|
.products {
|
|
margin-bottom: 3rem;
|
|
}
|
|
|
|
.section-title {
|
|
font-size: 2rem;
|
|
font-weight: 700;
|
|
margin-bottom: 1.5rem;
|
|
color: #1f2937;
|
|
}
|
|
|
|
.product-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
|
gap: 1.5rem;
|
|
}
|
|
|
|
.product-card {
|
|
background: white;
|
|
border-radius: 12px;
|
|
overflow: hidden;
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.product-card:hover {
|
|
transform: translateY(-4px);
|
|
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
|
|
}
|
|
|
|
.product-image {
|
|
height: 200px;
|
|
background: linear-gradient(45deg, #f3f4f6, #e5e7eb);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
color: #6b7280;
|
|
font-size: 3rem;
|
|
position: relative;
|
|
}
|
|
|
|
.product-badge {
|
|
position: absolute;
|
|
top: 1rem;
|
|
right: 1rem;
|
|
background: #ef4444;
|
|
color: white;
|
|
padding: 0.25rem 0.5rem;
|
|
border-radius: 4px;
|
|
font-size: 0.8rem;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.product-info {
|
|
padding: 1.5rem;
|
|
}
|
|
|
|
.product-category {
|
|
color: #6b7280;
|
|
font-size: 0.8rem;
|
|
text-transform: uppercase;
|
|
font-weight: 500;
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
|
|
.product-title {
|
|
font-size: 1.1rem;
|
|
font-weight: 600;
|
|
margin-bottom: 0.5rem;
|
|
color: #1f2937;
|
|
}
|
|
|
|
.product-description {
|
|
color: #6b7280;
|
|
font-size: 0.9rem;
|
|
margin-bottom: 1rem;
|
|
line-height: 1.4;
|
|
}
|
|
|
|
.product-price {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
margin-bottom: 1rem;
|
|
}
|
|
|
|
.current-price {
|
|
font-size: 1.3rem;
|
|
font-weight: 700;
|
|
color: #059669;
|
|
}
|
|
|
|
.original-price {
|
|
font-size: 1rem;
|
|
color: #6b7280;
|
|
text-decoration: line-through;
|
|
}
|
|
|
|
.discount {
|
|
background: #fef2f2;
|
|
color: #dc2626;
|
|
padding: 0.25rem 0.5rem;
|
|
border-radius: 4px;
|
|
font-size: 0.8rem;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.product-rating {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
margin-bottom: 1rem;
|
|
}
|
|
|
|
.stars {
|
|
color: #f59e0b;
|
|
}
|
|
|
|
.rating-text {
|
|
color: #6b7280;
|
|
font-size: 0.9rem;
|
|
}
|
|
|
|
.product-actions {
|
|
display: flex;
|
|
gap: 0.5rem;
|
|
}
|
|
|
|
.btn {
|
|
padding: 0.75rem 1rem;
|
|
border: none;
|
|
border-radius: 6px;
|
|
font-weight: 500;
|
|
cursor: pointer;
|
|
transition: all 0.3s ease;
|
|
flex: 1;
|
|
text-align: center;
|
|
}
|
|
|
|
.btn-primary {
|
|
background: #3b82f6;
|
|
color: white;
|
|
}
|
|
|
|
.btn-primary:hover {
|
|
background: #2563eb;
|
|
}
|
|
|
|
.btn-secondary {
|
|
background: #f3f4f6;
|
|
color: #374151;
|
|
border: 1px solid #d1d5db;
|
|
}
|
|
|
|
.btn-secondary:hover {
|
|
background: #e5e7eb;
|
|
}
|
|
|
|
/* Loading states */
|
|
.loading {
|
|
text-align: center;
|
|
padding: 2rem;
|
|
color: #6b7280;
|
|
}
|
|
|
|
.spinner {
|
|
width: 40px;
|
|
height: 40px;
|
|
border: 4px solid #f3f4f6;
|
|
border-top: 4px solid #3b82f6;
|
|
border-radius: 50%;
|
|
animation: spin 1s linear infinite;
|
|
margin: 0 auto 1rem;
|
|
}
|
|
|
|
@keyframes spin {
|
|
0% { transform: rotate(0deg); }
|
|
100% { transform: rotate(360deg); }
|
|
}
|
|
|
|
/* Cart sidebar */
|
|
.cart-sidebar {
|
|
position: fixed;
|
|
top: 0;
|
|
right: -400px;
|
|
width: 400px;
|
|
height: 100vh;
|
|
background: white;
|
|
box-shadow: -4px 0 8px rgba(0, 0, 0, 0.1);
|
|
transition: right 0.3s ease;
|
|
z-index: 1000;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.cart-sidebar.open {
|
|
right: 0;
|
|
}
|
|
|
|
.cart-header {
|
|
padding: 1.5rem;
|
|
border-bottom: 1px solid #e5e7eb;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
}
|
|
|
|
.cart-title {
|
|
font-size: 1.3rem;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.cart-close {
|
|
background: none;
|
|
border: none;
|
|
font-size: 1.5rem;
|
|
cursor: pointer;
|
|
color: #6b7280;
|
|
}
|
|
|
|
.cart-items {
|
|
flex: 1;
|
|
overflow-y: auto;
|
|
padding: 1rem;
|
|
}
|
|
|
|
.cart-item {
|
|
display: flex;
|
|
gap: 1rem;
|
|
padding: 1rem;
|
|
border-bottom: 1px solid #f3f4f6;
|
|
}
|
|
|
|
.cart-item-image {
|
|
width: 60px;
|
|
height: 60px;
|
|
background: #f3f4f6;
|
|
border-radius: 8px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
color: #6b7280;
|
|
}
|
|
|
|
.cart-item-info {
|
|
flex: 1;
|
|
}
|
|
|
|
.cart-item-title {
|
|
font-weight: 500;
|
|
margin-bottom: 0.25rem;
|
|
}
|
|
|
|
.cart-item-price {
|
|
color: #059669;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.cart-item-quantity {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
margin-top: 0.5rem;
|
|
}
|
|
|
|
.quantity-btn {
|
|
width: 30px;
|
|
height: 30px;
|
|
border: 1px solid #d1d5db;
|
|
background: white;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.cart-footer {
|
|
padding: 1.5rem;
|
|
border-top: 1px solid #e5e7eb;
|
|
}
|
|
|
|
.cart-total {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
font-size: 1.3rem;
|
|
font-weight: 600;
|
|
margin-bottom: 1rem;
|
|
}
|
|
|
|
.checkout-btn {
|
|
width: 100%;
|
|
background: #059669;
|
|
color: white;
|
|
padding: 1rem;
|
|
border: none;
|
|
border-radius: 8px;
|
|
font-size: 1.1rem;
|
|
font-weight: 600;
|
|
cursor: pointer;
|
|
transition: background 0.3s ease;
|
|
}
|
|
|
|
.checkout-btn:hover {
|
|
background: #047857;
|
|
}
|
|
|
|
/* Responsive */
|
|
@media (max-width: 768px) {
|
|
.header-content {
|
|
flex-wrap: wrap;
|
|
gap: 1rem;
|
|
}
|
|
|
|
.search-bar {
|
|
order: 3;
|
|
flex-basis: 100%;
|
|
margin: 0;
|
|
}
|
|
|
|
.hero h1 {
|
|
font-size: 2rem;
|
|
}
|
|
|
|
.filters-content {
|
|
flex-direction: column;
|
|
align-items: stretch;
|
|
}
|
|
|
|
.nav-content {
|
|
flex-wrap: wrap;
|
|
gap: 1rem;
|
|
}
|
|
|
|
.cart-sidebar {
|
|
width: 100%;
|
|
right: -100%;
|
|
}
|
|
}
|
|
|
|
/* Notification */
|
|
.notification {
|
|
position: fixed;
|
|
top: 100px;
|
|
right: 20px;
|
|
background: #10b981;
|
|
color: white;
|
|
padding: 1rem 1.5rem;
|
|
border-radius: 8px;
|
|
box-shadow: 0 4px 12px rgba(16, 185, 129, 0.3);
|
|
transform: translateX(400px);
|
|
transition: transform 0.3s ease;
|
|
z-index: 1001;
|
|
}
|
|
|
|
.notification.show {
|
|
transform: translateX(0);
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<!-- Header -->
|
|
<header class="header">
|
|
<div class="container">
|
|
<div class="header-content">
|
|
<div class="logo">TechMart</div>
|
|
|
|
<div class="search-bar">
|
|
<input type="text" class="search-input" placeholder="Search products..." id="search-input">
|
|
<div class="search-suggestions" id="search-suggestions"></div>
|
|
</div>
|
|
|
|
<div class="header-actions">
|
|
<div class="cart-icon" onclick="toggleCart()">
|
|
🛒
|
|
<span class="cart-count" id="cart-count">0</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
<!-- Navigation -->
|
|
<nav class="nav">
|
|
<div class="container">
|
|
<div class="nav-content">
|
|
<div class="nav-item active" data-category="all">All Products</div>
|
|
<div class="nav-item" data-category="smartphones">Smartphones</div>
|
|
<div class="nav-item" data-category="laptops">Laptops</div>
|
|
<div class="nav-item" data-category="headphones">Headphones</div>
|
|
<div class="nav-item" data-category="tablets">Tablets</div>
|
|
<div class="nav-item" data-category="accessories">Accessories</div>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
|
|
<!-- Hero Section -->
|
|
<section class="hero">
|
|
<div class="container">
|
|
<h1>Premium Electronics Store</h1>
|
|
<p>Discover the latest technology with unbeatable prices and fast shipping</p>
|
|
<button class="cta-button" onclick="scrollToProducts()">Shop Now</button>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Main Content -->
|
|
<main class="container">
|
|
<!-- Filters -->
|
|
<section class="filters">
|
|
<div class="filters-content">
|
|
<div class="filter-group">
|
|
<label>Sort by:</label>
|
|
<select class="filter-select" id="sort-select">
|
|
<option value="featured">Featured</option>
|
|
<option value="price-low">Price: Low to High</option>
|
|
<option value="price-high">Price: High to Low</option>
|
|
<option value="rating">Customer Rating</option>
|
|
<option value="newest">Newest First</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="filter-group">
|
|
<label>Brand:</label>
|
|
<select class="filter-select" id="brand-select">
|
|
<option value="all">All Brands</option>
|
|
<option value="apple">Apple</option>
|
|
<option value="samsung">Samsung</option>
|
|
<option value="sony">Sony</option>
|
|
<option value="microsoft">Microsoft</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="price-range">
|
|
<label>Price:</label>
|
|
<input type="number" class="price-input" placeholder="Min" id="price-min">
|
|
<span>-</span>
|
|
<input type="number" class="price-input" placeholder="Max" id="price-max">
|
|
</div>
|
|
|
|
<button class="btn btn-primary" onclick="applyFilters()">Apply Filters</button>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Products -->
|
|
<section class="products">
|
|
<h2 class="section-title">Featured Products</h2>
|
|
|
|
<div id="products-container">
|
|
<div class="loading">
|
|
<div class="spinner"></div>
|
|
Loading products...
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</main>
|
|
|
|
<!-- Cart Sidebar -->
|
|
<div class="cart-sidebar" id="cart-sidebar">
|
|
<div class="cart-header">
|
|
<h3 class="cart-title">Shopping Cart</h3>
|
|
<button class="cart-close" onclick="toggleCart()">×</button>
|
|
</div>
|
|
|
|
<div class="cart-items" id="cart-items">
|
|
<!-- Cart items will be populated dynamically -->
|
|
</div>
|
|
|
|
<div class="cart-footer">
|
|
<div class="cart-total">
|
|
<span>Total:</span>
|
|
<span id="cart-total">$0.00</span>
|
|
</div>
|
|
<button class="checkout-btn" onclick="checkout()">Proceed to Checkout</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Notification -->
|
|
<div class="notification" id="notification"></div>
|
|
|
|
<script>
|
|
// E-commerce Application
|
|
class TechMartStore {
|
|
constructor() {
|
|
this.products = [
|
|
{
|
|
id: 1,
|
|
title: "iPhone 15 Pro Max",
|
|
category: "smartphones",
|
|
brand: "apple",
|
|
price: 1199,
|
|
originalPrice: 1299,
|
|
description: "Latest iPhone with A17 Pro chip and titanium design",
|
|
rating: 4.8,
|
|
reviews: 2341,
|
|
image: "📱",
|
|
inStock: true,
|
|
isNew: true
|
|
},
|
|
{
|
|
id: 2,
|
|
title: "MacBook Pro 16-inch",
|
|
category: "laptops",
|
|
brand: "apple",
|
|
price: 2499,
|
|
originalPrice: 2699,
|
|
description: "Powerful laptop with M3 Max chip for professionals",
|
|
rating: 4.9,
|
|
reviews: 1876,
|
|
image: "💻",
|
|
inStock: true,
|
|
isSale: true
|
|
},
|
|
{
|
|
id: 3,
|
|
title: "Sony WH-1000XM5",
|
|
category: "headphones",
|
|
brand: "sony",
|
|
price: 399,
|
|
originalPrice: 449,
|
|
description: "Industry-leading noise canceling headphones",
|
|
rating: 4.7,
|
|
reviews: 5432,
|
|
image: "🎧",
|
|
inStock: true,
|
|
isSale: true
|
|
},
|
|
{
|
|
id: 4,
|
|
title: "iPad Air 5th Gen",
|
|
category: "tablets",
|
|
brand: "apple",
|
|
price: 599,
|
|
originalPrice: 649,
|
|
description: "Versatile tablet with M1 chip and stunning display",
|
|
rating: 4.6,
|
|
reviews: 3210,
|
|
image: "📱",
|
|
inStock: true
|
|
},
|
|
{
|
|
id: 5,
|
|
title: "Samsung Galaxy S24 Ultra",
|
|
category: "smartphones",
|
|
brand: "samsung",
|
|
price: 1299,
|
|
originalPrice: 1399,
|
|
description: "Premium Android phone with S Pen and AI features",
|
|
rating: 4.5,
|
|
reviews: 1987,
|
|
image: "📱",
|
|
inStock: false,
|
|
isNew: true
|
|
},
|
|
{
|
|
id: 6,
|
|
title: "AirPods Pro 2nd Gen",
|
|
category: "accessories",
|
|
brand: "apple",
|
|
price: 249,
|
|
originalPrice: 279,
|
|
description: "Wireless earbuds with active noise cancellation",
|
|
rating: 4.4,
|
|
reviews: 8765,
|
|
image: "🎧",
|
|
inStock: true,
|
|
isSale: true
|
|
}
|
|
];
|
|
|
|
this.cart = [];
|
|
this.currentCategory = 'all';
|
|
this.currentSort = 'featured';
|
|
this.filters = {
|
|
brand: 'all',
|
|
priceMin: null,
|
|
priceMax: null
|
|
};
|
|
|
|
this.init();
|
|
}
|
|
|
|
init() {
|
|
this.setupEventListeners();
|
|
this.renderProducts();
|
|
this.setupSearch();
|
|
this.simulateDynamicPricing();
|
|
|
|
// Simulate real-time inventory updates
|
|
setInterval(() => this.updateInventory(), 10000);
|
|
|
|
// Simulate price changes
|
|
setInterval(() => this.updatePrices(), 30000);
|
|
}
|
|
|
|
setupEventListeners() {
|
|
// Navigation
|
|
document.querySelectorAll('.nav-item').forEach(item => {
|
|
item.addEventListener('click', (e) => {
|
|
document.querySelector('.nav-item.active').classList.remove('active');
|
|
e.target.classList.add('active');
|
|
this.currentCategory = e.target.dataset.category;
|
|
this.renderProducts();
|
|
});
|
|
});
|
|
|
|
// Sort and filter
|
|
document.getElementById('sort-select').addEventListener('change', (e) => {
|
|
this.currentSort = e.target.value;
|
|
this.renderProducts();
|
|
});
|
|
|
|
document.getElementById('brand-select').addEventListener('change', (e) => {
|
|
this.filters.brand = e.target.value;
|
|
this.renderProducts();
|
|
});
|
|
}
|
|
|
|
setupSearch() {
|
|
const searchInput = document.getElementById('search-input');
|
|
const suggestions = document.getElementById('search-suggestions');
|
|
|
|
searchInput.addEventListener('input', (e) => {
|
|
const query = e.target.value.toLowerCase();
|
|
|
|
if (query.length > 1) {
|
|
const matches = this.products.filter(p =>
|
|
p.title.toLowerCase().includes(query) ||
|
|
p.category.toLowerCase().includes(query) ||
|
|
p.brand.toLowerCase().includes(query)
|
|
).slice(0, 5);
|
|
|
|
if (matches.length > 0) {
|
|
suggestions.innerHTML = matches.map(p => `
|
|
<div class="search-suggestion" onclick="store.selectProduct(${p.id})">
|
|
${p.image} ${p.title} - $${p.price}
|
|
</div>
|
|
`).join('');
|
|
suggestions.style.display = 'block';
|
|
} else {
|
|
suggestions.style.display = 'none';
|
|
}
|
|
} else {
|
|
suggestions.style.display = 'none';
|
|
}
|
|
});
|
|
|
|
// Hide suggestions when clicking outside
|
|
document.addEventListener('click', (e) => {
|
|
if (!e.target.closest('.search-bar')) {
|
|
suggestions.style.display = 'none';
|
|
}
|
|
});
|
|
}
|
|
|
|
selectProduct(id) {
|
|
const product = this.products.find(p => p.id === id);
|
|
if (product) {
|
|
document.getElementById('search-suggestions').style.display = 'none';
|
|
this.showProductDetails(product);
|
|
}
|
|
}
|
|
|
|
showProductDetails(product) {
|
|
alert(`${product.title}\n\nPrice: $${product.price}\nRating: ${product.rating}/5\n\n${product.description}`);
|
|
}
|
|
|
|
renderProducts() {
|
|
const container = document.getElementById('products-container');
|
|
let filteredProducts = this.getFilteredProducts();
|
|
|
|
if (filteredProducts.length === 0) {
|
|
container.innerHTML = `
|
|
<div class="loading">
|
|
<p>No products found matching your criteria.</p>
|
|
</div>
|
|
`;
|
|
return;
|
|
}
|
|
|
|
container.innerHTML = `
|
|
<div class="product-grid">
|
|
${filteredProducts.map(product => this.renderProduct(product)).join('')}
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
getFilteredProducts() {
|
|
let filtered = this.products;
|
|
|
|
// Filter by category
|
|
if (this.currentCategory !== 'all') {
|
|
filtered = filtered.filter(p => p.category === this.currentCategory);
|
|
}
|
|
|
|
// Filter by brand
|
|
if (this.filters.brand !== 'all') {
|
|
filtered = filtered.filter(p => p.brand === this.filters.brand);
|
|
}
|
|
|
|
// Filter by price range
|
|
if (this.filters.priceMin) {
|
|
filtered = filtered.filter(p => p.price >= this.filters.priceMin);
|
|
}
|
|
if (this.filters.priceMax) {
|
|
filtered = filtered.filter(p => p.price <= this.filters.priceMax);
|
|
}
|
|
|
|
// Sort products
|
|
return this.sortProducts(filtered);
|
|
}
|
|
|
|
sortProducts(products) {
|
|
switch (this.currentSort) {
|
|
case 'price-low':
|
|
return products.sort((a, b) => a.price - b.price);
|
|
case 'price-high':
|
|
return products.sort((a, b) => b.price - a.price);
|
|
case 'rating':
|
|
return products.sort((a, b) => b.rating - a.rating);
|
|
case 'newest':
|
|
return products.sort((a, b) => b.isNew - a.isNew);
|
|
default:
|
|
return products;
|
|
}
|
|
}
|
|
|
|
renderProduct(product) {
|
|
const discount = product.originalPrice ?
|
|
Math.round(((product.originalPrice - product.price) / product.originalPrice) * 100) : 0;
|
|
|
|
return `
|
|
<div class="product-card" onclick="store.selectProduct(${product.id})">
|
|
<div class="product-image">
|
|
${product.image}
|
|
${product.isNew ? '<div class="product-badge">NEW</div>' : ''}
|
|
${product.isSale ? '<div class="product-badge">SALE</div>' : ''}
|
|
</div>
|
|
|
|
<div class="product-info">
|
|
<div class="product-category">${product.category}</div>
|
|
<h3 class="product-title">${product.title}</h3>
|
|
<p class="product-description">${product.description}</p>
|
|
|
|
<div class="product-price">
|
|
<span class="current-price">$${product.price}</span>
|
|
${product.originalPrice ? `
|
|
<span class="original-price">$${product.originalPrice}</span>
|
|
<span class="discount">${discount}% OFF</span>
|
|
` : ''}
|
|
</div>
|
|
|
|
<div class="product-rating">
|
|
<span class="stars">${'★'.repeat(Math.floor(product.rating))}${'☆'.repeat(5-Math.floor(product.rating))}</span>
|
|
<span class="rating-text">${product.rating}/5 (${product.reviews})</span>
|
|
</div>
|
|
|
|
<div class="product-actions">
|
|
<button class="btn ${product.inStock ? 'btn-primary' : 'btn-secondary'}"
|
|
onclick="event.stopPropagation(); store.addToCart(${product.id})"
|
|
${!product.inStock ? 'disabled' : ''}>
|
|
${product.inStock ? 'Add to Cart' : 'Out of Stock'}
|
|
</button>
|
|
<button class="btn btn-secondary" onclick="event.stopPropagation(); store.addToWishlist(${product.id})">
|
|
❤️
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
addToCart(productId) {
|
|
const product = this.products.find(p => p.id === productId);
|
|
if (!product || !product.inStock) return;
|
|
|
|
const existingItem = this.cart.find(item => item.id === productId);
|
|
if (existingItem) {
|
|
existingItem.quantity += 1;
|
|
} else {
|
|
this.cart.push({ ...product, quantity: 1 });
|
|
}
|
|
|
|
this.updateCartDisplay();
|
|
this.showNotification(`${product.title} added to cart!`);
|
|
}
|
|
|
|
addToWishlist(productId) {
|
|
const product = this.products.find(p => p.id === productId);
|
|
this.showNotification(`${product.title} added to wishlist!`);
|
|
}
|
|
|
|
updateCartDisplay() {
|
|
const cartCount = document.getElementById('cart-count');
|
|
const cartItems = document.getElementById('cart-items');
|
|
const cartTotal = document.getElementById('cart-total');
|
|
|
|
const totalItems = this.cart.reduce((sum, item) => sum + item.quantity, 0);
|
|
const totalPrice = this.cart.reduce((sum, item) => sum + (item.price * item.quantity), 0);
|
|
|
|
cartCount.textContent = totalItems;
|
|
cartTotal.textContent = `$${totalPrice.toFixed(2)}`;
|
|
|
|
if (this.cart.length === 0) {
|
|
cartItems.innerHTML = '<div style="text-align: center; padding: 2rem; color: #6b7280;">Your cart is empty</div>';
|
|
} else {
|
|
cartItems.innerHTML = this.cart.map(item => `
|
|
<div class="cart-item">
|
|
<div class="cart-item-image">${item.image}</div>
|
|
<div class="cart-item-info">
|
|
<div class="cart-item-title">${item.title}</div>
|
|
<div class="cart-item-price">$${item.price}</div>
|
|
<div class="cart-item-quantity">
|
|
<button class="quantity-btn" onclick="store.updateQuantity(${item.id}, -1)">-</button>
|
|
<span>${item.quantity}</span>
|
|
<button class="quantity-btn" onclick="store.updateQuantity(${item.id}, 1)">+</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`).join('');
|
|
}
|
|
}
|
|
|
|
updateQuantity(productId, change) {
|
|
const item = this.cart.find(item => item.id === productId);
|
|
if (!item) return;
|
|
|
|
item.quantity += change;
|
|
if (item.quantity <= 0) {
|
|
this.cart = this.cart.filter(item => item.id !== productId);
|
|
}
|
|
|
|
this.updateCartDisplay();
|
|
}
|
|
|
|
applyFilters() {
|
|
this.filters.priceMin = parseFloat(document.getElementById('price-min').value) || null;
|
|
this.filters.priceMax = parseFloat(document.getElementById('price-max').value) || null;
|
|
this.renderProducts();
|
|
}
|
|
|
|
simulateDynamicPricing() {
|
|
// Simulate flash sales and price changes
|
|
setInterval(() => {
|
|
const randomProduct = this.products[Math.floor(Math.random() * this.products.length)];
|
|
const originalPrice = randomProduct.originalPrice || randomProduct.price;
|
|
const discount = Math.random() * 0.3; // Up to 30% discount
|
|
|
|
randomProduct.price = Math.round(originalPrice * (1 - discount));
|
|
randomProduct.originalPrice = originalPrice;
|
|
randomProduct.isSale = discount > 0.1;
|
|
|
|
this.renderProducts();
|
|
}, 15000);
|
|
}
|
|
|
|
updateInventory() {
|
|
// Simulate inventory changes
|
|
this.products.forEach(product => {
|
|
if (Math.random() < 0.1) { // 10% chance
|
|
product.inStock = !product.inStock;
|
|
}
|
|
});
|
|
this.renderProducts();
|
|
}
|
|
|
|
updatePrices() {
|
|
// Simulate price fluctuations
|
|
this.products.forEach(product => {
|
|
if (Math.random() < 0.2) { // 20% chance
|
|
const variation = (Math.random() - 0.5) * 0.1; // ±5%
|
|
product.price = Math.round(product.price * (1 + variation));
|
|
}
|
|
});
|
|
this.renderProducts();
|
|
}
|
|
|
|
showNotification(message) {
|
|
const notification = document.getElementById('notification');
|
|
notification.textContent = message;
|
|
notification.classList.add('show');
|
|
|
|
setTimeout(() => {
|
|
notification.classList.remove('show');
|
|
}, 3000);
|
|
}
|
|
}
|
|
|
|
// Global functions
|
|
function toggleCart() {
|
|
document.getElementById('cart-sidebar').classList.toggle('open');
|
|
}
|
|
|
|
function scrollToProducts() {
|
|
document.querySelector('.products').scrollIntoView({ behavior: 'smooth' });
|
|
}
|
|
|
|
function checkout() {
|
|
if (store.cart.length === 0) {
|
|
alert('Your cart is empty!');
|
|
return;
|
|
}
|
|
|
|
const total = store.cart.reduce((sum, item) => sum + (item.price * item.quantity), 0);
|
|
alert(`Proceeding to checkout\n\nTotal: $${total.toFixed(2)}\nItems: ${store.cart.length}`);
|
|
}
|
|
|
|
// Initialize store
|
|
const store = new TechMartStore();
|
|
|
|
// Global test data
|
|
window.testData = {
|
|
storeName: 'TechMart',
|
|
version: '3.2.1',
|
|
totalProducts: () => store.products.length,
|
|
inStockProducts: () => store.products.filter(p => p.inStock).length,
|
|
cartItems: () => store.cart.length,
|
|
cartTotal: () => store.cart.reduce((sum, item) => sum + (item.price * item.quantity), 0),
|
|
currentCategory: () => store.currentCategory,
|
|
currentSort: () => store.currentSort,
|
|
searchProduct: (query) => store.products.filter(p =>
|
|
p.title.toLowerCase().includes(query.toLowerCase())
|
|
),
|
|
getProductById: (id) => store.products.find(p => p.id === id),
|
|
getCartContents: () => store.cart,
|
|
generateTimestamp: () => new Date().toISOString()
|
|
};
|
|
|
|
console.log('TechMart E-commerce initialized');
|
|
console.log('Test data available at window.testData');
|
|
</script>
|
|
</body>
|
|
</html> |