WillemVH commited on
Commit
56262e9
·
verified ·
1 Parent(s): 3855f90

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +15 -728
app.py CHANGED
@@ -1,732 +1,19 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>ShopEasy - One Page E-Commerce</title>
7
- <!-- Bootstrap 5 CSS -->
8
- <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
9
- <!-- Font Awesome for icons -->
10
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
11
- <style>
12
- .section {
13
- display: none;
14
- animation: fadeIn 0.5s;
15
- }
16
- .active-section {
17
- display: block;
18
- }
19
- .nav-item {
20
- cursor: pointer;
21
- }
22
- .nav-link.active {
23
- background-color: #0d6efd;
24
- color: white !important;
25
- }
26
- .card {
27
- transition: transform 0.3s;
28
- height: 100%;
29
- }
30
- .card:hover {
31
- transform: translateY(-5px);
32
- box-shadow: 0 5px 15px rgba(0,0,0,0.1);
33
- }
34
- .cart-item {
35
- border-bottom: 1px solid #eee;
36
- padding: 10px 0;
37
- }
38
- .quantity-control {
39
- display: flex;
40
- align-items: center;
41
- gap: 10px;
42
- }
43
- .product-img {
44
- height: 200px;
45
- object-fit: cover;
46
- width: 100%;
47
- }
48
- .badge-notification {
49
- position: absolute;
50
- top: -5px;
51
- right: -5px;
52
- }
53
- @keyframes fadeIn {
54
- from { opacity: 0; }
55
- to { opacity: 1; }
56
- }
57
- .checkout-step {
58
- display: none;
59
- }
60
- .checkout-step.active {
61
- display: block;
62
- }
63
- .order-summary {
64
- background-color: #f8f9fa;
65
- border-radius: 10px;
66
- padding: 20px;
67
- }
68
- </style>
69
- </head>
70
- <body>
71
- <!-- Navigation -->
72
- <nav class="navbar navbar-expand-lg navbar-dark bg-primary sticky-top">
73
- <div class="container">
74
- <a class="navbar-brand" href="#" onclick="showSection('home')">
75
- <i class="fas fa-shopping-bag me-2"></i>ShopEasy
76
- </a>
77
- <div class="d-flex align-items-center">
78
- <!-- Cart Icon with Badge -->
79
- <div class="position-relative me-3" onclick="showSection('cart')" style="cursor: pointer;">
80
- <i class="fas fa-shopping-cart fa-lg text-white"></i>
81
- <span id="cartBadge" class="badge bg-danger badge-notification">0</span>
82
- </div>
83
- <!-- Navigation Tabs -->
84
- <ul class="navbar-nav">
85
- <li class="nav-item">
86
- <a class="nav-link" onclick="showSection('home')">Home</a>
87
- </li>
88
- <li class="nav-item">
89
- <a class="nav-link" onclick="showSection('products')">Products</a>
90
- </li>
91
- <li class="nav-item">
92
- <a class="nav-link" onclick="showSection('cart')">Cart</a>
93
- </li>
94
- <li class="nav-item">
95
- <a class="nav-link" onclick="showSection('checkout')">Checkout</a>
96
- </li>
97
- </ul>
98
- </div>
99
- </div>
100
- </nav>
101
 
102
- <!-- Main Content -->
103
- <div class="container mt-4">
104
-
105
- <!-- Home Section -->
106
- <div id="home" class="section active-section">
107
- <div class="jumbotron bg-light p-5 rounded">
108
- <h1 class="display-4">Welcome to ShopEasy!</h1>
109
- <p class="lead">Your one-stop shop for all your needs. Browse our products, add them to cart, and checkout securely.</p>
110
- <hr class="my-4">
111
- <p>We offer high-quality products with fast delivery and excellent customer service.</p>
112
- <button class="btn btn-primary btn-lg" onclick="showSection('products')">
113
- Start Shopping <i class="fas fa-arrow-right ms-2"></i>
114
- </button>
115
- </div>
116
-
117
- <div class="row mt-5">
118
- <div class="col-md-4">
119
- <div class="card text-center">
120
- <div class="card-body">
121
- <i class="fas fa-shipping-fast fa-3x text-primary mb-3"></i>
122
- <h5 class="card-title">Fast Delivery</h5>
123
- <p class="card-text">Get your orders delivered within 2-3 business days.</p>
124
- </div>
125
- </div>
126
- </div>
127
- <div class="col-md-4">
128
- <div class="card text-center">
129
- <div class="card-body">
130
- <i class="fas fa-shield-alt fa-3x text-success mb-3"></i>
131
- <h5 class="card-title">Secure Payment</h5>
132
- <p class="card-text">100% secure payment processing with encryption.</p>
133
- </div>
134
- </div>
135
- </div>
136
- <div class="col-md-4">
137
- <div class="card text-center">
138
- <div class="card-body">
139
- <i class="fas fa-headset fa-3x text-warning mb-3"></i>
140
- <h5 class="card-title">24/7 Support</h5>
141
- <p class="card-text">Our support team is always ready to help you.</p>
142
- </div>
143
- </div>
144
- </div>
145
- </div>
146
- </div>
147
 
148
- <!-- Products Section -->
149
- <div id="products" class="section">
150
- <h2 class="mb-4">Our Products</h2>
151
- <div class="row" id="productsGrid">
152
- <!-- Products will be loaded here -->
153
- </div>
154
- </div>
155
 
156
- <!-- Cart Section -->
157
- <div id="cart" class="section">
158
- <h2 class="mb-4">Your Shopping Cart</h2>
159
- <div class="row">
160
- <div class="col-md-8">
161
- <div id="cartItems">
162
- <!-- Cart items will be loaded here -->
163
- <p class="text-muted" id="emptyCartMessage">Your cart is empty. <a href="#" onclick="showSection('products')">Browse products</a></p>
164
- </div>
165
- </div>
166
- <div class="col-md-4">
167
- <div class="order-summary">
168
- <h5>Order Summary</h5>
169
- <table class="table">
170
- <tr>
171
- <td>Subtotal:</td>
172
- <td class="text-end">$<span id="subtotal">0.00</span></td>
173
- </tr>
174
- <tr>
175
- <td>Shipping:</td>
176
- <td class="text-end">$<span id="shipping">5.00</span></td>
177
- </tr>
178
- <tr>
179
- <td>Tax:</td>
180
- <td class="text-end">$<span id="tax">0.00</span></td>
181
- </tr>
182
- <tr class="table-active">
183
- <th>Total:</th>
184
- <th class="text-end">$<span id="total">5.00</span></th>
185
- </tr>
186
- </table>
187
- <button class="btn btn-primary w-100" onclick="showSection('checkout')" id="checkoutBtn" disabled>
188
- Proceed to Checkout
189
- </button>
190
- <button class="btn btn-outline-secondary w-100 mt-2" onclick="clearCart()">
191
- Clear Cart
192
- </button>
193
- </div>
194
- </div>
195
- </div>
196
- </div>
197
 
198
- <!-- Checkout Section -->
199
- <div id="checkout" class="section">
200
- <h2 class="mb-4">Checkout</h2>
201
- <div class="row">
202
- <div class="col-md-8">
203
- <div id="checkoutSteps">
204
- <!-- Step 1: Shipping Info -->
205
- <div id="step1" class="checkout-step active">
206
- <h4>Shipping Information</h4>
207
- <form id="shippingForm">
208
- <div class="row mb-3">
209
- <div class="col-md-6">
210
- <label class="form-label">First Name *</label>
211
- <input type="text" class="form-control" required>
212
- </div>
213
- <div class="col-md-6">
214
- <label class="form-label">Last Name *</label>
215
- <input type="text" class="form-control" required>
216
- </div>
217
- </div>
218
- <div class="mb-3">
219
- <label class="form-label">Address *</label>
220
- <input type="text" class="form-control" required>
221
- </div>
222
- <div class="row mb-3">
223
- <div class="col-md-6">
224
- <label class="form-label">City *</label>
225
- <input type="text" class="form-control" required>
226
- </div>
227
- <div class="col-md-6">
228
- <label class="form-label">ZIP Code *</label>
229
- <input type="text" class="form-control" required>
230
- </div>
231
- </div>
232
- <div class="mb-3">
233
- <label class="form-label">Email *</label>
234
- <input type="email" class="form-control" required>
235
- </div>
236
- <button type="button" class="btn btn-primary" onclick="nextStep(2)">Continue to Payment</button>
237
- </form>
238
- </div>
239
-
240
- <!-- Step 2: Payment Info -->
241
- <div id="step2" class="checkout-step">
242
- <h4>Payment Information</h4>
243
- <form id="paymentForm">
244
- <div class="mb-3">
245
- <label class="form-label">Card Number *</label>
246
- <input type="text" class="form-control" placeholder="1234 5678 9012 3456" required>
247
- </div>
248
- <div class="row mb-3">
249
- <div class="col-md-6">
250
- <label class="form-label">Expiry Date *</label>
251
- <input type="text" class="form-control" placeholder="MM/YY" required>
252
- </div>
253
- <div class="col-md-6">
254
- <label class="form-label">CVV *</label>
255
- <input type="text" class="form-control" required>
256
- </div>
257
- </div>
258
- <div class="mb-3">
259
- <label class="form-label">Name on Card *</label>
260
- <input type="text" class="form-control" required>
261
- </div>
262
- <button type="button" class="btn btn-secondary" onclick="prevStep(1)">Back</button>
263
- <button type="button" class="btn btn-primary" onclick="nextStep(3)">Review Order</button>
264
- </form>
265
- </div>
266
-
267
- <!-- Step 3: Review Order -->
268
- <div id="step3" class="checkout-step">
269
- <h4>Review Your Order</h4>
270
- <div id="reviewOrderItems" class="mb-4">
271
- <!-- Order items will be shown here -->
272
- </div>
273
- <div class="order-summary mb-4">
274
- <h5>Order Total: $<span id="reviewTotal">0.00</span></h5>
275
- </div>
276
- <div class="mb-3">
277
- <h5>Shipping Address:</h5>
278
- <p id="reviewAddress">Not provided yet</p>
279
- </div>
280
- <button type="button" class="btn btn-secondary" onclick="prevStep(2)">Back</button>
281
- <button type="button" class="btn btn-success" onclick="placeOrder()">
282
- <i class="fas fa-lock me-2"></i>Place Order
283
- </button>
284
- </div>
285
-
286
- <!-- Step 4: Confirmation -->
287
- <div id="step4" class="checkout-step">
288
- <div class="text-center py-5">
289
- <i class="fas fa-check-circle fa-5x text-success mb-4"></i>
290
- <h3>Order Confirmed!</h3>
291
- <p class="lead">Thank you for your purchase.</p>
292
- <p>Your order number is: <strong>ORD-<span id="orderNumber">0000</span></strong></p>
293
- <p>You will receive a confirmation email shortly.</p>
294
- <button class="btn btn-primary" onclick="showSection('home')">
295
- Return to Home
296
- </button>
297
- </div>
298
- </div>
299
- </div>
300
- </div>
301
-
302
- <div class="col-md-4">
303
- <div class="order-summary">
304
- <h5>Order Summary</h5>
305
- <div id="checkoutCartItems">
306
- <!-- Checkout cart items -->
307
- </div>
308
- <table class="table">
309
- <tr>
310
- <td>Subtotal:</td>
311
- <td class="text-end">$<span id="checkoutSubtotal">0.00</span></td>
312
- </tr>
313
- <tr>
314
- <td>Shipping:</td>
315
- <td class="text-end">$<span id="checkoutShipping">5.00</span></td>
316
- </tr>
317
- <tr>
318
- <td>Tax:</td>
319
- <td class="text-end">$<span id="checkoutTax">0.00</span></td>
320
- </tr>
321
- <tr class="table-active">
322
- <th>Total:</th>
323
- <th class="text-end">$<span id="checkoutTotal">5.00</span></th>
324
- </tr>
325
- </table>
326
- </div>
327
- </div>
328
- </div>
329
- </div>
330
- </div>
331
-
332
- <!-- Footer -->
333
- <footer class="bg-dark text-white mt-5 py-4">
334
- <div class="container text-center">
335
- <p>&copy; 2024 ShopEasy. All rights reserved.</p>
336
- <p class="mb-0">
337
- <a href="#" onclick="showSection('home')" class="text-white me-3">Home</a> |
338
- <a href="#" onclick="showSection('products')" class="text-white me-3">Products</a> |
339
- <a href="#" onclick="showSection('cart')" class="text-white me-3">Cart</a> |
340
- <a href="#" onclick="showSection('checkout')" class="text-white">Checkout</a>
341
- </p>
342
- </div>
343
- </footer>
344
-
345
- <!-- JavaScript -->
346
- <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
347
- <script>
348
- // Sample product data
349
- const products = [
350
- { id: 1, name: "Wireless Headphones", price: 99.99, image: "https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=400&h=300&fit=crop", category: "Electronics" },
351
- { id: 2, name: "Smart Watch", price: 199.99, image: "https://images.unsplash.com/photo-1523275335684-37898b6baf30?w=400&h=300&fit=crop", category: "Electronics" },
352
- { id: 3, name: "Running Shoes", price: 89.99, image: "https://images.unsplash.com/photo-1542291026-7eec264c27ff?w=400&h=300&fit=crop", category: "Fashion" },
353
- { id: 4, name: "Coffee Maker", price: 49.99, image: "https://images.unsplash.com/photo-1495474472287-4d71bcdd2085?w=400&h=300&fit=crop", category: "Home" },
354
- { id: 5, name: "Backpack", price: 39.99, image: "https://images.unsplash.com/photo-1553062407-98eeb64c6a62?w=400&h=300&fit=crop", category: "Fashion" },
355
- { id: 6, name: "Desk Lamp", price: 29.99, image: "https://images.unsplash.com/photo-1507473885765-e6ed057f782c?w=400&h=300&fit=crop", category: "Home" }
356
- ];
357
-
358
- // Cart state
359
- let cart = JSON.parse(localStorage.getItem('cart')) || [];
360
- let currentStep = 1;
361
-
362
- // Initialize the page
363
- document.addEventListener('DOMContentLoaded', function() {
364
- loadProducts();
365
- updateCartBadge();
366
- updateNav();
367
- });
368
-
369
- // Navigation functions
370
- function showSection(sectionId) {
371
- // Hide all sections
372
- document.querySelectorAll('.section').forEach(section => {
373
- section.classList.remove('active-section');
374
- });
375
-
376
- // Show selected section
377
- document.getElementById(sectionId).classList.add('active-section');
378
-
379
- // Update navigation highlighting
380
- updateNav();
381
-
382
- // Special handling for each section
383
- if (sectionId === 'products') {
384
- loadProducts();
385
- } else if (sectionId === 'cart') {
386
- updateCartDisplay(); // FIXED: Only update cart display when on cart section
387
- } else if (sectionId === 'checkout') {
388
- resetCheckoutSteps();
389
- updateCheckoutDisplay(); // FIXED: Use checkout-specific update function
390
- }
391
- }
392
-
393
- function updateNav() {
394
- const navLinks = document.querySelectorAll('.nav-link');
395
- navLinks.forEach(link => link.classList.remove('active'));
396
-
397
- const activeSection = document.querySelector('.section.active-section');
398
- if (activeSection) {
399
- const sectionId = activeSection.id;
400
- const activeLink = document.querySelector(`.nav-link[onclick="showSection('${sectionId}')"]`);
401
- if (activeLink) {
402
- activeLink.classList.add('active');
403
- }
404
- }
405
- }
406
-
407
- // Product functions
408
- function loadProducts() {
409
- const productsGrid = document.getElementById('productsGrid');
410
- productsGrid.innerHTML = '';
411
-
412
- products.forEach(product => {
413
- const productCard = `
414
- <div class="col-md-4 col-lg-4 mb-4">
415
- <div class="card">
416
- <img src="${product.image}" class="card-img-top product-img" alt="${product.name}">
417
- <div class="card-body">
418
- <h5 class="card-title">${product.name}</h5>
419
- <p class="card-text">${product.category}</p>
420
- <p class="card-text"><strong>$${product.price.toFixed(2)}</strong></p>
421
- <button class="btn btn-primary" onclick="addToCart(${product.id})">
422
- <i class="fas fa-cart-plus me-2"></i>Add to Cart
423
- </button>
424
- </div>
425
- </div>
426
- </div>
427
- `;
428
- productsGrid.innerHTML += productCard;
429
- });
430
- }
431
-
432
- // Cart functions
433
- function addToCart(productId) {
434
- const product = products.find(p => p.id === productId);
435
- const existingItem = cart.find(item => item.id === productId);
436
-
437
- if (existingItem) {
438
- existingItem.quantity += 1;
439
- } else {
440
- cart.push({
441
- id: product.id,
442
- name: product.name,
443
- price: product.price,
444
- image: product.image,
445
- quantity: 1
446
- });
447
- }
448
-
449
- saveCart();
450
- updateCartBadge();
451
- showToast(`${product.name} added to cart!`);
452
-
453
- // Update cart display only if we're on the cart page
454
- if (document.getElementById('cart').classList.contains('active-section')) {
455
- updateCartDisplay();
456
- }
457
- }
458
-
459
- function removeFromCart(productId) {
460
- cart = cart.filter(item => item.id !== productId);
461
- saveCart();
462
- updateCartBadge();
463
- updateCartDisplay();
464
- }
465
-
466
- function updateQuantity(productId, change) {
467
- const item = cart.find(item => item.id === productId);
468
- if (item) {
469
- item.quantity += change;
470
- if (item.quantity <= 0) {
471
- removeFromCart(productId);
472
- } else {
473
- saveCart();
474
- updateCartBadge();
475
- updateCartDisplay();
476
- }
477
- }
478
- }
479
-
480
- function clearCart() {
481
- cart = [];
482
- saveCart();
483
- updateCartBadge();
484
-
485
- // Update cart display if on cart page
486
- if (document.getElementById('cart').classList.contains('active-section')) {
487
- updateCartDisplay();
488
- }
489
-
490
- // Update checkout display if on checkout page
491
- if (document.getElementById('checkout').classList.contains('active-section')) {
492
- updateCheckoutDisplay();
493
- }
494
-
495
- showToast('Cart cleared!');
496
- }
497
-
498
- function saveCart() {
499
- localStorage.setItem('cart', JSON.stringify(cart));
500
- updateCartBadge();
501
- }
502
-
503
- function updateCartBadge() {
504
- const totalItems = cart.reduce((sum, item) => sum + item.quantity, 0);
505
- document.getElementById('cartBadge').textContent = totalItems;
506
-
507
- // Update checkout button state
508
- const checkoutBtn = document.getElementById('checkoutBtn');
509
- if (checkoutBtn) {
510
- checkoutBtn.disabled = totalItems === 0;
511
- }
512
- }
513
-
514
- function updateCartDisplay() {
515
- const cartItemsDiv = document.getElementById('cartItems');
516
- const emptyCartMessage = document.getElementById('emptyCartMessage');
517
-
518
- // FIXED: Check if elements exist before using them
519
- if (!cartItemsDiv || !emptyCartMessage) return;
520
-
521
- if (cart.length === 0) {
522
- cartItemsDiv.innerHTML = '<p class="text-muted">Your cart is empty. <a href="#" onclick="showSection(\'products\')">Browse products</a></p>';
523
- emptyCartMessage.style.display = 'block';
524
- } else {
525
- emptyCartMessage.style.display = 'none';
526
-
527
- let cartHTML = '';
528
- let subtotal = 0;
529
-
530
- cart.forEach(item => {
531
- const itemTotal = item.price * item.quantity;
532
- subtotal += itemTotal;
533
-
534
- cartHTML += `
535
- <div class="cart-item">
536
- <div class="row align-items-center">
537
- <div class="col-2">
538
- <img src="${item.image}" class="img-fluid rounded" alt="${item.name}">
539
- </div>
540
- <div class="col-4">
541
- <h6 class="mb-0">${item.name}</h6>
542
- <p class="mb-0 text-muted">$${item.price.toFixed(2)}</p>
543
- </div>
544
- <div class="col-4">
545
- <div class="quantity-control">
546
- <button class="btn btn-sm btn-outline-secondary" onclick="updateQuantity(${item.id}, -1)">-</button>
547
- <span class="mx-2">${item.quantity}</span>
548
- <button class="btn btn-sm btn-outline-secondary" onclick="updateQuantity(${item.id}, 1)">+</button>
549
- </div>
550
- </div>
551
- <div class="col-2 text-end">
552
- <h6 class="mb-0">$${itemTotal.toFixed(2)}</h6>
553
- <button class="btn btn-sm btn-danger mt-1" onclick="removeFromCart(${item.id})">
554
- <i class="fas fa-trash"></i>
555
- </button>
556
- </div>
557
- </div>
558
- </div>
559
- `;
560
- });
561
-
562
- cartItemsDiv.innerHTML = cartHTML;
563
-
564
- const shipping = 5.00;
565
- const tax = subtotal * 0.08; // 8% tax
566
- const total = subtotal + shipping + tax;
567
-
568
- // FIXED: Check if elements exist before updating
569
- const subtotalEl = document.getElementById('subtotal');
570
- const taxEl = document.getElementById('tax');
571
- const totalEl = document.getElementById('total');
572
-
573
- if (subtotalEl) subtotalEl.textContent = subtotal.toFixed(2);
574
- if (taxEl) taxEl.textContent = tax.toFixed(2);
575
- if (totalEl) totalEl.textContent = total.toFixed(2);
576
- }
577
- }
578
-
579
- // Checkout functions
580
- function resetCheckoutSteps() {
581
- currentStep = 1;
582
- document.querySelectorAll('.checkout-step').forEach(step => {
583
- step.classList.remove('active');
584
- });
585
- document.getElementById('step1').classList.add('active');
586
- }
587
-
588
- function nextStep(stepNumber) {
589
- if (stepNumber === 2) {
590
- // Validate shipping form
591
- const shippingForm = document.getElementById('shippingForm');
592
- if (!shippingForm.checkValidity()) {
593
- shippingForm.reportValidity();
594
- return;
595
- }
596
- } else if (stepNumber === 3) {
597
- // Validate payment form
598
- const paymentForm = document.getElementById('paymentForm');
599
- if (!paymentForm.checkValidity()) {
600
- paymentForm.reportValidity();
601
- return;
602
- }
603
- updateReviewSection();
604
- }
605
-
606
- currentStep = stepNumber;
607
- document.querySelectorAll('.checkout-step').forEach(step => {
608
- step.classList.remove('active');
609
- });
610
- document.getElementById(`step${stepNumber}`).classList.add('active');
611
- }
612
-
613
- function prevStep(stepNumber) {
614
- currentStep = stepNumber;
615
- document.querySelectorAll('.checkout-step').forEach(step => {
616
- step.classList.remove('active');
617
- });
618
- document.getElementById(`step${stepNumber}`).classList.add('active');
619
- }
620
-
621
- function updateCheckoutDisplay() {
622
- const checkoutCartItems = document.getElementById('checkoutCartItems');
623
- if (!checkoutCartItems) return;
624
-
625
- let itemsHTML = '';
626
- let subtotal = 0;
627
-
628
- cart.forEach(item => {
629
- const itemTotal = item.price * item.quantity;
630
- subtotal += itemTotal;
631
-
632
- itemsHTML += `
633
- <div class="d-flex justify-content-between mb-2">
634
- <div>
635
- <span>${item.name} x ${item.quantity}</span>
636
- </div>
637
- <div>$${itemTotal.toFixed(2)}</div>
638
- </div>
639
- `;
640
- });
641
-
642
- checkoutCartItems.innerHTML = itemsHTML || '<p class="text-muted">No items in cart</p>';
643
-
644
- const shipping = 5.00;
645
- const tax = subtotal * 0.08;
646
- const total = subtotal + shipping + tax;
647
-
648
- // FIXED: Update checkout summary
649
- document.getElementById('checkoutSubtotal').textContent = subtotal.toFixed(2);
650
- document.getElementById('checkoutTax').textContent = tax.toFixed(2);
651
- document.getElementById('checkoutTotal').textContent = total.toFixed(2);
652
- document.getElementById('reviewTotal').textContent = total.toFixed(2);
653
- }
654
-
655
- function updateReviewSection() {
656
- const reviewOrderItems = document.getElementById('reviewOrderItems');
657
- if (!reviewOrderItems) return;
658
-
659
- let itemsHTML = '<h5>Items:</h5>';
660
-
661
- cart.forEach(item => {
662
- itemsHTML += `
663
- <div class="d-flex justify-content-between mb-2">
664
- <div>
665
- <span>${item.name} x ${item.quantity}</span>
666
- </div>
667
- <div>$${(item.price * item.quantity).toFixed(2)}</div>
668
- </div>
669
- `;
670
- });
671
-
672
- reviewOrderItems.innerHTML = itemsHTML;
673
-
674
- // Get shipping address from form (simplified)
675
- const addressInput = document.querySelector('#shippingForm input[type="text"]');
676
- const address = addressInput ? addressInput.value : '';
677
- document.getElementById('reviewAddress').textContent = address || "Not provided";
678
- }
679
-
680
- function placeOrder() {
681
- if (cart.length === 0) {
682
- showToast('Your cart is empty!');
683
- return;
684
- }
685
-
686
- // Generate random order number
687
- const orderNumber = Math.floor(1000 + Math.random() * 9000);
688
- document.getElementById('orderNumber').textContent = orderNumber;
689
-
690
- // Clear cart
691
- cart = [];
692
- saveCart();
693
- updateCartBadge();
694
-
695
- // Show confirmation
696
- nextStep(4);
697
-
698
- // In a real app, you would send order to server here
699
- console.log('Order placed:', orderNumber);
700
- showToast('Order placed successfully!');
701
- }
702
-
703
- // Utility function
704
- function showToast(message) {
705
- // Create toast element
706
- const toast = document.createElement('div');
707
- toast.className = 'position-fixed bottom-0 end-0 p-3';
708
- toast.style.zIndex = '1050';
709
- toast.innerHTML = `
710
- <div class="toast show" role="alert">
711
- <div class="toast-header">
712
- <strong class="me-auto">ShopEasy</strong>
713
- <button type="button" class="btn-close" onclick="this.parentElement.parentElement.parentElement.remove()"></button>
714
- </div>
715
- <div class="toast-body">
716
- ${message}
717
- </div>
718
- </div>
719
- `;
720
-
721
- document.body.appendChild(toast);
722
-
723
- // Auto-remove after 3 seconds
724
- setTimeout(() => {
725
- if (toast.parentNode) {
726
- toast.parentNode.removeChild(toast);
727
- }
728
- }, 3000);
729
- }
730
- </script>
731
- </body>
732
- </html>
 
1
+ from flask import Flask, render_template, request, jsonify
2
+ import os
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
 
4
+ app = Flask(__name__)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
+ # Home route
7
+ @app.route('/')
8
+ def home():
9
+ return render_template('index.html')
 
 
 
10
 
11
+ # API example
12
+ @app.route('/api/hello', methods=['GET'])
13
+ def hello():
14
+ name = request.args.get('name', 'World')
15
+ return jsonify({'message': f'Hello {name}!'})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
 
17
+ # For Hugging Face Spaces
18
+ if __name__ == '__main__':
19
+ app.run(debug=True, host='0.0.0.0', port=7860)