puwanath commited on
Commit
b0b757e
·
verified ·
1 Parent(s): 759b890

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +483 -696
index.html CHANGED
@@ -1,377 +1,236 @@
1
  <!DOCTYPE html>
2
  <html lang="th">
3
-
4
  <head>
5
  <meta charset="UTF-8">
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
- <title>Smart POS - Modern Store</title>
8
- <link rel="preconnect" href="https://fonts.googleapis.com">
9
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
10
- <link href="https://fonts.googleapis.com/css2?family=Kanit:wght@300;400;600;800&display=swap" rel="stylesheet">
11
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
12
 
13
  <style>
14
  :root {
15
- --primary-gradient: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
16
- --primary-color: #667eea;
17
- --secondary-color: #764ba2;
18
- --accent-color: #20e3b2;
19
- --danger-color: #ff4757;
20
- --bg-color: #f0f2f5;
21
- --card-bg: rgba(255, 255, 255, 0.95);
22
- --text-dark: #2d3436;
23
- --text-light: #636e72;
24
- --shadow: 0 10px 30px rgba(0,0,0,0.1);
25
- --radius: 16px;
 
 
26
  }
27
 
28
  * {
29
  box-sizing: border-box;
30
  margin: 0;
31
  padding: 0;
32
- font-family: 'Kanit', sans-serif;
33
  }
34
 
35
  body {
36
  background-color: var(--bg-color);
37
- background-image:
38
- radial-gradient(circle at 10% 20%, rgba(102, 126, 234, 0.1) 0%, transparent 20%),
39
- radial-gradient(circle at 90% 80%, rgba(118, 75, 162, 0.1) 0%, transparent 20%);
40
- color: var(--text-dark);
41
  height: 100vh;
42
  display: flex;
43
  flex-direction: column;
44
- overflow: hidden;
45
  }
46
 
47
- /* --- Header --- */
48
  header {
49
- background: var(--card-bg);
50
  padding: 1rem 2rem;
51
  display: flex;
52
  justify-content: space-between;
53
  align-items: center;
54
- box-shadow: 0 4px 20px rgba(0,0,0,0.05);
55
- z-index: 100;
56
- backdrop-filter: blur(10px);
57
  }
58
 
59
  .brand {
60
  display: flex;
61
  align-items: center;
62
- gap: 15px;
63
- font-size: 1.8rem;
64
- font-weight: 800;
65
  color: var(--primary-color);
66
- letter-spacing: 1px;
67
- }
68
-
69
- .brand i { color: var(--secondary-color); }
70
-
71
- .header-info {
72
- display: flex;
73
- align-items: center;
74
- gap: 25px;
75
- }
76
-
77
- .user-badge {
78
- display: flex;
79
- align-items: center;
80
- gap: 10px;
81
- background: #f8f9fa;
82
- padding: 8px 16px;
83
- border-radius: 50px;
84
- color: var(--text-light);
85
- font-weight: 600;
86
- border: 1px solid #e9ecef;
87
- }
88
-
89
- .user-avatar {
90
- width: 35px;
91
- height: 35px;
92
- border-radius: 50%;
93
- background: var(--primary-gradient);
94
- color: white;
95
- display: flex;
96
- align-items: center;
97
- justify-content: center;
98
- font-size: 1.2rem;
99
  }
100
 
101
- .btn-logout {
102
- background: var(--danger-color);
103
- color: white;
104
  border: none;
105
- padding: 10px 20px;
106
- border-radius: 50px;
107
  cursor: pointer;
108
- font-weight: 600;
109
- transition: all 0.3s ease;
110
- box-shadow: 0 4px 15px rgba(255, 71, 87, 0.3);
111
  }
112
 
113
- .btn-logout:hover {
114
- transform: translateY(-2px);
115
- box-shadow: 0 6px 20px rgba(255, 71, 87, 0.4);
116
  }
117
 
118
- /* --- Main Layout --- */
119
  main {
120
- display: grid;
121
- grid-template-columns: 280px 1fr 380px;
122
  flex: 1;
123
  overflow: hidden;
124
  gap: 20px;
125
  padding: 20px;
126
  }
127
 
128
- /* Left Panel: Categories */
129
- .categories-panel {
130
- background: var(--card-bg);
131
- border-radius: var(--radius);
132
- padding: 20px;
133
- box-shadow: var(--shadow);
134
  display: flex;
135
  flex-direction: column;
136
- overflow-y: auto;
137
- height: 100%;
138
- border-top: 4px solid var(--primary-color);
139
- }
140
-
141
- .panel-title {
142
- font-size: 1.4rem;
143
- font-weight: 800;
144
- margin-bottom: 20px;
145
- color: var(--text-dark);
146
- display: flex;
147
- align-items: center;
148
- gap: 10px;
149
- }
150
-
151
- .category-list {
152
- display: flex;
153
- flex-direction: column;
154
- gap: 10px;
155
- }
156
-
157
- .cat-btn {
158
- padding: 15px;
159
- text-align: left;
160
- background: white;
161
- border: 2px solid #e0e0e0;
162
- border-radius: 12px;
163
- cursor: pointer;
164
- transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
165
- display: flex;
166
- align-items: center;
167
  gap: 15px;
168
- font-size: 1.1rem;
169
- color: var(--text-light);
170
- font-weight: 600;
171
- }
172
-
173
- .cat-btn:hover {
174
- border-color: var(--primary-color);
175
- background: #f8f9ff;
176
- transform: translateX(5px);
177
- }
178
-
179
- .cat-btn.active {
180
- background: var(--primary-gradient);
181
- color: white;
182
- border-color: var(--primary-color);
183
- box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
184
- }
185
-
186
- .cat-btn i { font-size: 1.4rem; width: 30px; text-align: center; }
187
-
188
- /* Center Panel: Products */
189
- .products-panel {
190
- background: #f8f9fa;
191
- border-radius: var(--radius);
192
- padding: 25px;
193
- box-shadow: var(--shadow);
194
- display: flex;
195
- flex-direction: column;
196
- overflow: hidden;
197
  }
198
 
 
199
  .search-container {
200
  position: relative;
201
- margin-bottom: 25px;
202
  }
203
 
204
  .search-input {
205
  width: 100%;
206
- padding: 15px 20px 15px 55px;
207
- border-radius: 50px;
208
- border: none;
209
- background: white;
210
- font-size: 1.1rem;
211
- box-shadow: 0 4px 15px rgba(0,0,0,0.05);
212
- transition: all 0.3s;
213
- outline: none;
214
  }
215
 
216
  .search-input:focus {
217
- box-shadow: 0 8px 25px rgba(102, 126, 234, 0.2);
218
- transform: scale(1.01);
 
219
  }
220
 
221
  .search-icon {
222
  position: absolute;
223
- left: 20px;
224
  top: 50%;
225
  transform: translateY(-50%);
226
- color: var(--primary-color);
227
- font-size: 1.3rem;
228
  }
229
 
230
- .products-grid {
 
231
  display: grid;
232
- grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
233
- gap: 25px;
234
- overflow-y: auto;
235
- padding-right: 5px;
236
- height: 100%;
237
  padding-bottom: 20px;
238
  }
239
 
240
  .product-card {
241
- background: white;
242
- border-radius: 20px;
243
- padding: 20px;
244
- box-shadow: 0 5px 15px rgba(0,0,0,0.05);
245
- transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
246
  cursor: pointer;
 
 
247
  position: relative;
248
- overflow: hidden;
249
  }
250
 
251
  .product-card:hover {
252
- transform: translateY(-10px);
253
- box-shadow: 0 15px 30px rgba(102, 126, 234, 0.2);
254
- }
255
-
256
- .product-img-container {
257
- width: 100%;
258
- height: 140px;
259
- border-radius: 15px;
260
- overflow: hidden;
261
- margin-bottom: 15px;
262
- background: #f0f0f0;
263
- position: relative;
264
  }
265
 
266
  .product-img {
267
  width: 100%;
268
- height: 100%;
269
  object-fit: cover;
270
- transition: transform 0.5s ease;
271
  }
272
 
273
- .product-card:hover .product-img {
274
- transform: scale(1.1);
 
 
 
275
  }
276
 
277
  .product-name {
278
- font-weight: 700;
279
- font-size: 1.2rem;
280
- margin-bottom: 8px;
281
- white-space: nowrap;
282
- overflow: hidden;
283
- text-overflow: ellipsis;
284
- }
285
-
286
- .product-footer {
287
- display: flex;
288
- justify-content: space-between;
289
- align-items: center;
290
- margin-top: auto;
291
  }
292
 
293
  .product-price {
 
294
  color: var(--primary-color);
295
- font-size: 1.4rem;
296
- font-weight: 800;
297
  }
298
 
299
  .add-btn {
300
- background: var(--primary-gradient);
 
 
 
301
  color: white;
302
- width: 35px;
303
- height: 35px;
304
- border-radius: 50%;
305
- display: flex;
306
- align-items: center;
307
- justify-content: center;
308
- transition: 0.2s;
309
- box-shadow: 0 4px 10px rgba(102, 126, 234, 0.3);
310
  }
311
 
312
  .add-btn:hover {
313
- transform: scale(1.1);
314
- box-shadow: 0 6px 15px rgba(102, 126, 234, 0.4);
315
  }
316
 
317
- /* Right Panel: Cart */
318
- .cart-panel {
319
- background: white;
 
320
  border-radius: var(--radius);
321
- box-shadow: var(--shadow);
322
  display: flex;
323
  flex-direction: column;
324
  overflow: hidden;
325
- border: 1px solid #e0e0e0;
326
  }
327
 
328
  .cart-header {
329
  padding: 20px;
330
- background: var(--primary-gradient);
331
- color: white;
332
  display: flex;
333
  justify-content: space-between;
334
  align-items: center;
335
  }
336
 
337
- .cart-title h2 {
338
- font-size: 1.5rem;
339
- margin-bottom: 5px;
340
- }
341
-
342
- .cart-count-badge {
343
- background: rgba(255,255,255,0.2);
344
- padding: 5px 12px;
345
- border-radius: 20px;
346
- font-weight: 800;
347
- font-size: 1rem;
348
  }
349
 
350
  .cart-items {
351
  flex: 1;
352
  overflow-y: auto;
353
- padding: 20px;
354
- background: #fafafa;
355
- }
356
-
357
- .cart-items-empty {
358
- display: flex;
359
- flex-direction: column;
360
- align-items: center;
361
- justify-content: center;
362
- height: 100%;
363
- color: var(--text-light);
364
- opacity: 0.6;
365
  }
366
 
367
  .cart-item {
368
- background: white;
369
- padding: 15px;
370
- border-radius: 12px;
371
- margin-bottom: 15px;
372
  display: flex;
 
373
  align-items: center;
374
- box-shadow: 0 2px 8px rgba(0,0,0,0.05);
 
375
  animation: slideIn 0.3s ease;
376
  }
377
 
@@ -380,642 +239,570 @@
380
  to { opacity: 1; transform: translateX(0); }
381
  }
382
 
383
- .cart-item-img {
384
- width: 60px;
385
- height: 60px;
386
- border-radius: 10px;
387
- object-fit: cover;
388
- margin-right: 15px;
389
- }
390
-
391
- .cart-item-details {
392
  flex: 1;
393
  }
394
 
395
  .cart-item-name {
396
- font-weight: 700;
397
- font-size: 1.1rem;
398
- margin-bottom: 5px;
399
  }
400
 
401
  .cart-item-price {
402
- color: var(--primary-color);
403
- font-weight: 600;
404
  }
405
 
406
- .cart-actions {
407
  display: flex;
408
  align-items: center;
409
  gap: 10px;
410
- background: #f0f2f5;
411
- padding: 5px;
412
- border-radius: 10px;
413
  }
414
 
415
  .qty-btn {
416
  width: 28px;
417
  height: 28px;
418
- border: none;
 
419
  background: white;
420
- border-radius: 6px;
421
  cursor: pointer;
422
- color: var(--text-light);
423
- font-weight: 700;
424
- transition: 0.2s;
425
- box-shadow: 0 2px 5px rgba(0,0,0,0.05);
 
 
 
 
 
 
 
 
 
 
 
 
426
  }
427
 
428
- .qty-btn:hover { color: var(--primary-color); }
429
- .qty-btn.minus:hover { color: var(--danger-color); }
 
 
 
 
 
 
 
 
430
 
431
  .cart-footer {
432
- padding: 25px;
433
- background: #f9fafb;
434
- border-top: 1px solid #e0e0e0;
435
  }
436
 
437
  .summary-row {
438
  display: flex;
439
  justify-content: space-between;
440
- margin-bottom: 12px;
441
- font-size: 1.1rem;
442
- color: var(--text-light);
443
  }
444
 
445
  .summary-row.total {
446
- font-size: 1.8rem;
447
- font-weight: 800;
448
- color: var(--text-dark);
449
- border-top: 2px dashed #dfe6e9;
450
- padding-top: 20px;
451
- margin-top: 10px;
452
- }
453
-
454
- .action-buttons {
455
- display: grid;
456
- grid-template-columns: 1fr 1fr;
457
- gap: 15px;
458
- margin-top: 20px;
459
  }
460
 
461
- .btn {
462
- padding: 16px;
463
- border-radius: 12px;
 
 
 
 
464
  font-size: 1.1rem;
465
- font-weight: 700;
 
466
  cursor: pointer;
467
- transition: all 0.3s ease;
468
  display: flex;
469
- align-items: center;
470
  justify-content: center;
 
471
  gap: 10px;
472
- border: none;
473
- font-family: 'Kanit', sans-serif;
474
  }
475
 
476
- .btn-clear {
477
- background: #f1f2f6;
478
- color: var(--text-light);
479
  }
480
- .btn-clear:hover { background: #dfe6e9; }
481
 
482
- .btn-checkout {
483
- background: var(--primary-gradient);
484
- color: white;
485
- box-shadow: 0 10px 20px rgba(102, 126, 234, 0.4);
486
- font-size: 1.3rem;
487
- padding: 18px;
488
- }
489
- .btn-checkout:hover {
490
- transform: translateY(-3px);
491
- box-shadow: 0 15px 25px rgba(102, 126, 234, 0.5);
492
  }
493
 
494
- /* --- Modal (Receipt) --- */
495
  .modal-overlay {
496
  position: fixed;
497
  top: 0;
498
  left: 0;
499
  width: 100%;
500
  height: 100%;
501
- background: rgba(0,0,0,0.6);
502
- backdrop-filter: blur(5px);
503
- z-index: 1000;
504
  display: flex;
505
  justify-content: center;
506
  align-items: center;
 
507
  opacity: 0;
508
- pointer-events: none;
509
- transition: opacity 0.3s ease;
510
  }
511
 
512
  .modal-overlay.active {
513
  opacity: 1;
514
- pointer-events: all;
515
  }
516
 
517
  .modal {
518
  background: white;
 
 
519
  width: 90%;
520
- max-width: 500px;
521
- border-radius: 20px;
522
- padding: 40px;
523
- box-shadow: 0 25px 50px rgba(0,0,0,0.25);
524
  text-align: center;
525
- transform: scale(0.8);
526
- transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
527
  }
528
 
529
  .modal-overlay.active .modal {
530
  transform: scale(1);
531
  }
532
 
533
- .receipt-paper {
534
- background: #f8f9fa;
535
- padding: 30px;
536
- border-radius: 10px;
537
- margin: 30px 0;
538
- border: 2px dashed #dfe6e9;
539
- position: relative;
540
  }
541
 
542
- .receipt-paper::before {
543
- content: "Receipt";
544
- position: absolute;
545
- top: -15px;
546
- left: 50%;
547
- transform: translateX(-50%);
548
- background: white;
549
- padding: 0 10px;
550
- color: var(--text-light);
551
- font-weight: 700;
552
- font-size: 0.9rem;
553
  }
554
 
555
- .receipt-header h3 {
556
- color: var(--primary-color);
557
- font-size: 2rem;
558
- margin-bottom: 5px;
559
- }
560
- .receipt-meta {
561
- color: var(--text-light);
562
- font-size: 0.9rem;
563
  margin-bottom: 20px;
564
- border-bottom: 1px solid #e0e0e0;
565
- padding-bottom: 15px;
566
  }
567
 
568
- .receipt-item-row {
569
  display: flex;
570
- justify-content: space-between;
571
- margin-bottom: 10px;
572
- font-size: 1.1rem;
573
- color: var(--text-dark);
574
  }
575
- .receipt-item-sub {
576
- font-size: 0.9rem;
577
- color: var(--text-light);
 
 
 
 
 
578
  }
579
 
580
- .receipt-total-row {
581
- display: flex;
582
- justify-content: space-between;
583
- font-size: 1.5rem;
584
- font-weight: 800;
585
- color: var(--primary-color);
586
- margin-top: 20px;
587
- padding-top: 15px;
588
- border-top: 2px solid #dfe6e9;
589
  }
590
 
591
- .modal-actions {
592
- display: flex;
593
- gap: 15px;
594
- margin-top: 30px;
595
  }
596
 
597
- /* Responsive Design */
598
- @media (max-width: 1024px) {
599
- main { grid-template-columns: 250px 1fr 350px; }
600
  }
601
 
 
602
  @media (max-width: 768px) {
603
  main {
604
- grid-template-columns: 1fr;
605
- grid-template-rows: auto auto 1fr 250px;
606
- overflow-y: auto;
607
  padding: 10px;
 
608
  }
609
-
610
- .categories-panel { order: 1; }
611
- .products-panel { order: 2; min-height: 500px; }
612
- .cart-panel { order: 3; }
613
-
614
- .brand span { display: none; }
615
- .header-info { display: none; }
616
- }
617
-
618
- @media (max-width: 480px) {
619
- .products-grid { grid-template-columns: repeat(2, 1fr); }
620
- .brand { font-size: 1.4rem; }
621
- .cart-footer { padding: 15px; }
622
- .btn-checkout { font-size: 1rem; }
623
- }
624
-
625
- /* Print Styles */
626
- @media print {
627
- body * { visibility: hidden; }
628
- #receiptContent, #receiptContent * { visibility: visible; }
629
- #receiptContent {
630
- position: absolute;
631
- left: 0;
632
- top: 0;
633
- width: 100%;
634
- background: white;
635
- box-shadow: none;
636
- border: none;
637
  }
638
- .no-print { display: none !important; }
639
  }
640
  </style>
641
  </head>
642
-
643
  <body>
644
 
645
  <!-- Header -->
646
- <header class="no-print">
647
  <div class="brand">
648
  <i class="fa-solid fa-cash-register"></i>
649
- <span>Smart<span style="color:var(--secondary-color)">POS</span></span>
650
  </div>
651
- <div class="header-info">
652
- <div class="user-badge">
653
- <div class="user-avatar"><i class="fa-solid fa-user"></i></div>
654
- <div>
655
- <div style="font-size: 0.8rem; opacity: 0.8;">พนักงาน</div>
656
- <div style="font-weight: 700;">ปกรณ์ ปกรณ์</div>
657
- </div>
658
- </div>
659
- <button class="btn-logout" onclick="logout()">
660
- <i class="fa-solid fa-right-from-bracket"></i> ออกจากระบบ
661
  </button>
662
  </div>
663
  </header>
664
 
665
  <!-- Main Content -->
666
  <main>
667
- <!-- Left: Categories -->
668
- <aside class="categories-panel no-print">
669
- <div class="panel-title">
670
- <i class="fa-solid fa-list-ul"></i> หมวดหมู่สินค้า
671
- </div>
672
- <div class="category-list" id="categoryList">
673
- <!-- Categories injected by JS -->
674
- </div>
675
- </aside>
676
-
677
- <!-- Center: Products -->
678
- <section class="products-panel no-print">
679
  <div class="search-container">
680
- <i class="fa-solid fa-search search-icon"></i>
681
- <input type="text" id="searchInput" class="search-input" placeholder="ค้นหาสินค้า (เช่น กาแฟ, พิซซ่า)...">
682
  </div>
683
- <div class="products-grid" id="productsGrid">
684
- <!-- Products injected by JS -->
685
  </div>
686
  </section>
687
 
688
- <!-- Right: Cart -->
689
- <aside class="cart-panel no-print">
690
  <div class="cart-header">
691
- <div class="cart-title">
692
- <h2>ตะกสินค้า</h2>
693
- <span style="font-size: 0.9rem; opacity: 0.9;">เลือกสินค้าเพื่อชำระเงิน</span>
694
- </div>
695
- <div class="cart-count-badge" id="cartCount">0 ชิ้น</div>
696
  </div>
697
-
698
- <div class="cart-items" id="cartItems">
699
- <!-- Cart Items injected by JS -->
700
- <div class="cart-items-empty">
701
- <i class="fa-solid fa-shopping-cart" style="font-size: 4rem; margin-bottom: 20px; opacity: 0.3;"></i>
702
  <p>ยังไม่มีสินค้าในตะกร้า</p>
703
  </div>
704
  </div>
705
-
706
  <div class="cart-footer">
707
  <div class="summary-row">
708
- <span><i class="fa-solid fa-calculator"></i> จำนนชน</span>
709
- <span id="summaryQty" style="font-weight: 700;">0</span>
710
  </div>
711
  <div class="summary-row">
712
- <span><i class="fa-solid fa-percentage"></i> ส่วนลด</span>
713
- <span style="color: var(--accent-color);">0.00 บาท</span>
714
  </div>
715
  <div class="summary-row total">
716
- <span>รวมทั้งสิ้น</span>
717
- <span id="summaryTotal">0.00 บาท</span>
718
- </div>
719
-
720
- <div class="action-buttons">
721
- <button class="btn btn-clear" onclick="clearCart()">
722
- <i class="fa-solid fa-rotate-left"></i> ยกเลิก
723
- </button>
724
- <button class="btn btn-checkout" onclick="checkout()">
725
- <i class="fa-solid fa-credit-card"></i> ชำระเงิน
726
- </button>
727
  </div>
 
 
 
728
  </div>
729
- </aside>
730
  </main>
731
 
732
- <!-- Checkout Modal -->
733
- <div class="modal-overlay" id="checkoutModal">
734
  <div class="modal">
735
- <i class="fa-solid fa-check-circle" style="font-size: 4rem; color: var(--accent-color); margin-bottom: 20px;"></i>
736
- <h2 style="color: var(--text-dark); margin-bottom: 10px;">ชำระเงินสำเร็จ!</h2>
737
- <p style="color: var(--text-light);">ขอบคุณที่ใช้บริการ Smart POS</p>
738
-
739
- <div class="receipt-paper" id="receiptContent">
740
- <div class="receipt-header">
741
- <h3>Smart POS</h3>
742
- <p>123 ถนนสุขุมวิท แขวคลองตัน</p>
743
- <p>เขคลองเต็ง กุงทพฯ 10110</p>
744
- <p style="font-size: 0.8rem; color: #999;">Tel: 02-123-4567</p>
745
- </div>
746
- <div class="receipt-meta">
747
- <div id="receiptDate">วันที่: -</div>
748
- <div id="receiptTime">เวลา: -</div>
749
- <div id="receiptCashier">Cashier: ปกรณ์ ปกรณ์</div>
750
- </div>
751
-
752
- <div id="receiptItemsContainer">
753
- <!-- Items injected here -->
754
- </div>
755
 
756
- <div class="receipt-total-row">
757
- <span>ยอดรมสุทธิ</span>
758
- <span id="receiptTotalAmount">0.00 บาท</span>
759
- </div>
 
 
 
 
760
  </div>
761
 
762
  <div class="modal-actions">
763
- <button class="btn btn-clear" onclick="closeModal()">
764
- <i class="fa-solid fa-print"></i> พิมพ์ใบเสร็จ
765
- </button>
766
- <button class="btn btn-checkout" onclick="resetAndClose()">
767
- <i class="fa-solid fa-cart-shopping"></i> ทำรายการต่อไป
768
- </button>
769
  </div>
770
  </div>
771
  </div>
772
 
773
- <script>
774
- // --- Data & State ---
775
- const categories = [
776
- { id: 'all', name: 'ทั้งหมด', icon: 'fa-layer-group' },
777
- { id: 'beverage', name: 'เคื่อดื่ม', icon: 'fa-mug-hot' },
778
- { id: 'snack', name: 'ของว่าง', icon: 'fa-cookie-bite' },
779
- { id: 'meal', name: 'มื้อหลัก', icon: 'fa-utensils' },
780
- { id: 'dessert', name: 'ของหวาน', icon: 'fa-ice-cream' }
781
- ];
 
 
 
 
 
 
782
 
 
 
 
 
 
 
 
 
 
 
 
 
 
783
  const products = [
784
- { id: 1, name: 'กาแฟดำ', price: 45, category: 'beverage', img: 'https://placehold.co/300x200/3e2723/FFF?text=Black+Coffee&font=roboto' },
785
- { id: 2, name: 'ชาขีว', price: 55, category: 'beverage', img: 'https://placehold.co/300x200/1b5e20/FFF?text=Green+Tea&font=roboto' },
786
- { id: 3, name: 'น้ำส้คั้สด', price: 60, category: 'beverage', img: 'https://placehold.co/300x200/e65100/FFF?text=Orange+Juice&font=roboto' },
787
- { id: 4, name: 'โซดาตรอว์เบอร์รี่', price: 40, category: 'beverage', img: 'https://placehold.co/300x200/f44336/FFF?text=Strawberry+Soda&font=roboto' },
788
- { id: 5, name: 'พิซซ่ื้อับ', price: 199, category: 'meal', img: 'https://placehold.co/300x200/d32f2f/FFF?text=Pizza&font=roboto' },
789
- { id: 6, name: 'ขาวหมูแด', price: 85, category: 'meal', img: 'https://placehold.co/300x200/b71c1c/FFF?text=Pork+Rice&font=roboto' },
790
- { id: 7, name: 'สปาเกตตี้มิลล์', price: 150, category: 'meal', img: 'https://placehold.co/300x200/ff6f00/FFF?text=Pasta&font=roboto' },
791
- { id: 8, name: 'ไก่ทอดกรอบ', price: 120, category: 'meal', img: 'https://placehold.co/300x200/fbc02d/FFF?text=Fried+Chicken&font=roboto' },
792
- { id: 9, name: 'เค้กช็อกโกแล', price: 95, category: 'dessert', img: 'https://placehold.co/300x200/3e2723/FFF?text=Chocolate+Cake&font=roboto' },
793
- { id: 10, name: 'ไศครีมวาิลลา', price: 50, category: 'dessert', img: 'https://placehold.co/300x200/9e9e9e/FFF?text=Vanilla+IceCream&font=roboto' },
794
- { id: 11, name: 'คุกกีช็อกชิป', price: 45, category: 'snack', img: 'https://placehold.co/300x200/5d4037/FFF?text=Chips+Cookie&font=roboto' },
795
- { id: 12, name: 'มันฝรั่งทอ', price: 40, category: 'snack', img: 'https://placehold.co/300x200/fbc02d/FFF?text=Chips&font=roboto' }
796
  ];
797
 
798
  let cart = [];
799
- let currentCategory = 'all';
800
- let searchQuery = '';
801
-
802
- // --- DOM Elements ---
803
- const productsGrid = document.getElementById('productsGrid');
804
- const categoryList = document.getElementById('categoryList');
805
- const cartItems = document.getElementById('cartItems');
806
- const cartCount = document.getElementById('cartCount');
807
- const summaryQty = document.getElementById('summaryQty');
808
- const summaryTotal = document.getElementById('summaryTotal');
809
- const searchInput = document.getElementById('searchInput');
810
- const checkoutModal = document.getElementById('checkoutModal');
811
- const receiptContent = document.getElementById('receiptContent');
812
-
813
- // --- Initialization ---
814
- function init() {
815
- renderCategories();
816
- renderProducts();
817
- updateCartUI();
818
- }
 
 
 
819
 
820
  // --- Render Functions ---
821
- function renderCategories() {
822
- categoryList.innerHTML = categories.map(cat => `
823
- <button class="cat-btn ${currentCategory === cat.id ? 'active' : ''}"
824
- onclick="filterByCategory('${cat.id}')">
825
- <i class="${cat.icon}"></i>
826
- ${cat.name}
827
- </button>
828
- `).join('');
 
 
 
 
 
 
 
 
 
 
829
  }
830
 
831
- function renderProducts() {
832
- const filteredProducts = products.filter(product => {
833
- const matchCategory = currentCategory === 'all' || product.category === currentCategory;
834
- const matchSearch = product.name.toLowerCase().includes(searchQuery.toLowerCase());
835
- return matchCategory && matchSearch;
836
- });
837
 
838
- if (filteredProducts.length === 0) {
839
- productsGrid.innerHTML = `
840
- <div style="grid-column: 1/-1; text-align: center; padding: 50px; color: #999;">
841
- <i class="fa-solid fa-box-open" style="font-size: 3rem; margin-bottom: 20px; opacity: 0.5;"></i>
842
- <h3>ไม่พบสินค้า</h3>
843
- <p>ลองเปลี่ยนคำค้นหาหรือหมวดหมู่</p>
 
844
  </div>`;
 
 
 
845
  return;
846
  }
847
 
848
- productsGrid.innerHTML = filteredProducts.map(product => `
849
- <div class="product-card" onclick="addToCart(${product.id})">
850
- <div class="product-img-container">
851
- <img src="${product.img}" alt="${product.name}" class="product-img" loading="lazy">
 
 
 
 
 
 
852
  </div>
853
- <div class="product-name">${product.name}</div>
854
- <div class="product-footer">
855
- <div class="product-price">${product.price.toFixed(2)} บาท</div>
856
- <div class="add-btn">
857
- <i class="fa-solid fa-plus"></i>
858
- </div>
859
  </div>
860
- </div>
861
- `).join('');
 
 
 
 
 
862
  }
863
 
864
- // --- Cart Logic ---
865
- function addToCart(productId) {
866
- const product = products.find(p => p.id === productId);
867
- if (!product) return;
868
 
869
- const existingItem = cart.find(item => item.id === productId);
 
 
870
 
871
- if (existingItem) {
872
- existingItem.qty++;
 
 
 
 
 
 
 
 
873
  } else {
874
  cart.push({ ...product, qty: 1 });
875
  }
876
-
877
- // Animation effect on cart
878
- cartItems.style.opacity = '0';
879
- setTimeout(() => {
880
- updateCartUI();
881
- cartItems.style.opacity = '1';
882
- }, 200);
883
  }
884
 
885
- function updateCartUI() {
886
- cartCount.innerText = cart.reduce((acc, item) => acc + item.qty, 0) + " ชิ้น";
887
-
888
- let totalQty = 0;
889
- let totalPrice = 0;
890
 
891
- if (cart.length === 0) {
892
- cartItems.innerHTML = `
893
- <div class="cart-items-empty">
894
- <i class="fa-solid fa-shopping-cart" style="font-size: 4rem; margin-bottom: 20px; opacity: 0.3;"></i>
895
- <p>ยังไม่มีสินค้าในตะกร��า</p>
896
- </div>`;
897
  } else {
898
- cartItems.innerHTML = cart.map(item => `
899
- <div class="cart-item">
900
- <img src="${item.img}" alt="${item.name}" class="cart-item-img">
901
- <div class="cart-item-details">
902
- <div class="cart-item-name">${item.name}</div>
903
- <div class="cart-item-price">${item.price.toFixed(2)} บาท</div>
904
- </div>
905
- <div class="cart-actions">
906
- <button class="qty-btn minus" onclick="changeQty(${item.id}, -1)">-</button>
907
- <span style="font-weight: 700; width: 30px; text-align: center;">${item.qty}</span>
908
- <button class="qty-btn plus" onclick="changeQty(${item.id}, 1)">+</button>
909
- </div>
910
- </div>
911
- `).join('');
912
  }
913
-
914
- cart.forEach(item => {
915
- totalQty += item.qty;
916
- totalPrice += item.price * item.qty;
917
- });
918
-
919
- summaryQty.innerText = totalQty;
920
- summaryTotal.innerText = totalPrice.toFixed(2) + ' บาท';
921
  }
922
 
923
- function changeQty(id, change) {
924
- const itemIndex = cart.findIndex(item => item.id === id);
925
- if (itemIndex > -1) {
926
- cart[itemIndex].qty += change;
927
- if (cart[itemIndex].qty <= 0) {
928
- cart.splice(itemIndex, 1);
929
- }
930
- updateCartUI();
931
- }
932
  }
933
 
934
- function clearCart() {
935
- if (cart.length === 0) return;
936
- if (confirm('ต้องการยกเลิกรายการทั้งหมดหรือไม่?')) {
937
  cart = [];
938
- updateCartUI();
939
  }
940
  }
941
 
942
- // --- Checkout Logic ---
943
- function checkout() {
944
- if (cart.length === 0) {
945
- alert('กรุณาเลือกสินค้าก่อนชำระเงิน');
946
- return;
947
- }
948
-
949
- const totalAmount = cart.reduce((sum, item) => sum + (item.price * item.qty), 0);
950
 
951
- // Populate Receipt
952
- const date = new Date();
953
- const dateOptions = { year: 'numeric', month: 'long', day: 'numeric', hour: '2-digit', minute: '2-digit' };
954
-
955
- document.getElementById('receiptDate').innerText = 'วันที่: ' + date.toLocaleDateString('th-TH', {year: 'numeric', month: 'long', day: 'numeric'});
956
- document.getElementById('receiptTime').innerText = 'เวลา: ' + date.toLocaleTimeString('th-TH', {hour: '2-digit', minute: '2-digit'});
957
- document.getElementById('receiptCashier').innerText = 'Cashier: ปกรณ์ ปกรณ์';
958
-
959
- const itemsContainer = document.getElementById('receiptItemsContainer');
960
- itemsContainer.innerHTML = cart.map(item => `
961
- <div class="receipt-item-row">
962
- <div>
963
- <span>${item.name} x ${item.qty}</span>
964
- <div class="receipt-item-sub">${item.price.toFixed(2)} บาท</div>
965
- </div>
966
- <span>${(item.price * item.qty).toFixed(2)} บาท</span>
967
- </div>
968
- `).join('');
969
 
970
- document.getElementById('receiptTotalAmount').innerText = totalAmount.toFixed(2) + ' บาท';
 
 
 
971
 
972
- checkoutModal.classList.add('active');
 
 
 
 
 
 
973
  }
974
 
975
- function closeModal() {
976
- window.print();
977
- }
 
 
 
 
 
 
 
 
978
 
979
- function resetAndClose() {
980
- checkoutModal.classList.remove('active');
 
 
 
 
 
 
 
 
981
  cart = [];
982
- updateCartUI();
 
 
983
  }
984
 
985
- function logout() {
986
- if(confirm('คุณต้องการออกจากระบบใช่หรือไม่?')) {
987
- alert('กำลังออกจากระบบ...');
988
- // In a real app, this would redirect to login
989
- window.location.href = "#";
990
- }
991
  }
992
 
993
- // --- Event Listeners ---
994
- searchInput.addEventListener('input', (e) => {
995
- searchQuery = e.target.value.toLowerCase();
996
- renderProducts();
997
- });
998
-
999
- function filterByCategory(catId) {
1000
- currentCategory = catId;
1001
- renderCategories();
1002
- renderProducts();
1003
  }
1004
 
1005
- // Start the app
1006
- init();
1007
-
1008
- // Built with anycoder link
1009
- const footerLink = document.createElement('div');
1010
- footerLink.style.position = 'fixed';
1011
- footerLink.style.bottom = '10px';
1012
- footerLink.style.right = '10px';
1013
- footerLink.style.zIndex = '9999';
1014
- footerLink.style.fontSize = '0.8rem';
1015
- footerLink.innerHTML = 'Built with <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" style="color: var(--primary-color); text-decoration: none;">anycoder</a>';
1016
- document.body.appendChild(footerLink);
1017
 
 
 
 
 
 
 
1018
  </script>
1019
  </body>
1020
-
1021
  </html>
 
1
  <!DOCTYPE html>
2
  <html lang="th">
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Smart POS System - ระบบขายปลีกอัจฉริยะ</title>
7
+ <!-- Google Fonts: Sarabun เพื่อความสวยงามและอ่านง่ายภาษาไทย -->
8
+ <link href="https://fonts.googleapis.com/css2?family=Sarabun:wght@300;400;500;600;700&display=swap" rel="stylesheet">
9
+ <!-- FontAwesome for Icons -->
10
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
11
 
12
  <style>
13
  :root {
14
+ --primary-color: #2563eb;
15
+ --secondary-color: #1e40af;
16
+ --accent-color: #f59e0b;
17
+ --bg-color: #f3f4f6;
18
+ --card-bg: #ffffff;
19
+ --text-main: #1f2937;
20
+ --text-muted: #6b7280;
21
+ --border-color: #e5e7eb;
22
+ --danger-color: #ef4444;
23
+ --success-color: #10b981;
24
+ --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
25
+ --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
26
+ --radius: 12px;
27
  }
28
 
29
  * {
30
  box-sizing: border-box;
31
  margin: 0;
32
  padding: 0;
33
+ font-family: 'Sarabun', sans-serif;
34
  }
35
 
36
  body {
37
  background-color: var(--bg-color);
38
+ color: var(--text-main);
 
 
 
39
  height: 100vh;
40
  display: flex;
41
  flex-direction: column;
42
+ overflow: hidden; /* ป้องกันการเลื่อนหน้าจร้างเกิน */
43
  }
44
 
45
+ /* Header */
46
  header {
47
+ background-color: var(--card-bg);
48
  padding: 1rem 2rem;
49
  display: flex;
50
  justify-content: space-between;
51
  align-items: center;
52
+ box-shadow: var(--shadow-sm);
53
+ z-index: 10;
 
54
  }
55
 
56
  .brand {
57
  display: flex;
58
  align-items: center;
59
+ gap: 12px;
60
+ font-size: 1.5rem;
61
+ font-weight: 700;
62
  color: var(--primary-color);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  }
64
 
65
+ .header-actions button {
66
+ background: none;
 
67
  border: none;
68
+ font-size: 1.2rem;
69
+ color: var(--text-muted);
70
  cursor: pointer;
71
+ transition: color 0.3s;
 
 
72
  }
73
 
74
+ .header-actions button:hover {
75
+ color: var(--primary-color);
 
76
  }
77
 
78
+ /* Main Layout */
79
  main {
80
+ display: flex;
 
81
  flex: 1;
82
  overflow: hidden;
83
  gap: 20px;
84
  padding: 20px;
85
  }
86
 
87
+ /* Left Side: Product Grid */
88
+ .product-section {
89
+ flex: 2;
 
 
 
90
  display: flex;
91
  flex-direction: column;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  gap: 15px;
93
+ overflow-y: auto;
94
+ padding-right: 5px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
  }
96
 
97
+ /* Search Bar */
98
  .search-container {
99
  position: relative;
100
+ margin-bottom: 10px;
101
  }
102
 
103
  .search-input {
104
  width: 100%;
105
+ padding: 12px 20px 12px 45px;
106
+ border: 1px solid var(--border-color);
107
+ border-radius: var(--radius);
108
+ font-size: 1rem;
109
+ background-color: var(--card-bg);
110
+ box-shadow: var(--shadow-sm);
111
+ transition: all 0.3s ease;
 
112
  }
113
 
114
  .search-input:focus {
115
+ outline: none;
116
+ border-color: var(--primary-color);
117
+ box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);
118
  }
119
 
120
  .search-icon {
121
  position: absolute;
122
+ left: 15px;
123
  top: 50%;
124
  transform: translateY(-50%);
125
+ color: var(--text-muted);
 
126
  }
127
 
128
+ /* Product Grid */
129
+ .product-grid {
130
  display: grid;
131
+ grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
132
+ gap: 15px;
 
 
 
133
  padding-bottom: 20px;
134
  }
135
 
136
  .product-card {
137
+ background: var(--card-bg);
138
+ border-radius: var(--radius);
139
+ overflow: hidden;
140
+ box-shadow: var(--shadow-sm);
141
+ transition: transform 0.2s, box-shadow 0.2s;
142
  cursor: pointer;
143
+ display: flex;
144
+ flex-direction: column;
145
  position: relative;
 
146
  }
147
 
148
  .product-card:hover {
149
+ transform: translateY(-4px);
150
+ box-shadow: var(--shadow-md);
 
 
 
 
 
 
 
 
 
 
151
  }
152
 
153
  .product-img {
154
  width: 100%;
155
+ height: 120px;
156
  object-fit: cover;
157
+ background-color: #e5e7eb;
158
  }
159
 
160
+ .product-info {
161
+ padding: 12px;
162
+ flex: 1;
163
+ display: flex;
164
+ flex-direction: column;
165
  }
166
 
167
  .product-name {
168
+ font-weight: 600;
169
+ font-size: 1rem;
170
+ margin-bottom: 4px;
171
+ color: var(--text-main);
 
 
 
 
 
 
 
 
 
172
  }
173
 
174
  .product-price {
175
+ font-size: 1.1rem;
176
  color: var(--primary-color);
177
+ font-weight: 700;
178
+ margin-top: auto;
179
  }
180
 
181
  .add-btn {
182
+ margin-top: 10px;
183
+ width: 100%;
184
+ padding: 8px;
185
+ background-color: var(--primary-color);
186
  color: white;
187
+ border: none;
188
+ border-radius: 8px;
189
+ font-weight: 500;
190
+ transition: background 0.2s;
 
 
 
 
191
  }
192
 
193
  .add-btn:hover {
194
+ background-color: var(--secondary-color);
 
195
  }
196
 
197
+ /* Right Side: Cart */
198
+ .cart-section {
199
+ flex: 1;
200
+ background: var(--card-bg);
201
  border-radius: var(--radius);
202
+ box-shadow: var(--shadow-md);
203
  display: flex;
204
  flex-direction: column;
205
  overflow: hidden;
206
+ min-width: 350px;
207
  }
208
 
209
  .cart-header {
210
  padding: 20px;
211
+ border-bottom: 1px solid var(--border-color);
 
212
  display: flex;
213
  justify-content: space-between;
214
  align-items: center;
215
  }
216
 
217
+ .cart-header h2 {
218
+ font-size: 1.25rem;
219
+ color: var(--text-main);
 
 
 
 
 
 
 
 
220
  }
221
 
222
  .cart-items {
223
  flex: 1;
224
  overflow-y: auto;
225
+ padding: 15px;
 
 
 
 
 
 
 
 
 
 
 
226
  }
227
 
228
  .cart-item {
 
 
 
 
229
  display: flex;
230
+ justify-content: space-between;
231
  align-items: center;
232
+ padding: 12px 0;
233
+ border-bottom: 1px solid var(--border-color);
234
  animation: slideIn 0.3s ease;
235
  }
236
 
 
239
  to { opacity: 1; transform: translateX(0); }
240
  }
241
 
242
+ .cart-item-info {
 
 
 
 
 
 
 
 
243
  flex: 1;
244
  }
245
 
246
  .cart-item-name {
247
+ font-weight: 600;
248
+ font-size: 0.95rem;
 
249
  }
250
 
251
  .cart-item-price {
252
+ font-size: 0.85rem;
253
+ color: var(--text-muted);
254
  }
255
 
256
+ .cart-controls {
257
  display: flex;
258
  align-items: center;
259
  gap: 10px;
 
 
 
260
  }
261
 
262
  .qty-btn {
263
  width: 28px;
264
  height: 28px;
265
+ border-radius: 50%;
266
+ border: 1px solid var(--border-color);
267
  background: white;
 
268
  cursor: pointer;
269
+ display: flex;
270
+ align-items: center;
271
+ justify-content: center;
272
+ transition: all 0.2s;
273
+ }
274
+
275
+ .qty-btn:hover {
276
+ background-color: var(--bg-color);
277
+ border-color: var(--primary-color);
278
+ color: var(--primary-color);
279
+ }
280
+
281
+ .qty-value {
282
+ font-weight: 600;
283
+ width: 20px;
284
+ text-align: center;
285
  }
286
 
287
+ .remove-btn {
288
+ color: var(--text-muted);
289
+ cursor: pointer;
290
+ padding: 5px;
291
+ transition: color 0.2s;
292
+ }
293
+
294
+ .remove-btn:hover {
295
+ color: var(--danger-color);
296
+ }
297
 
298
  .cart-footer {
299
+ padding: 20px;
300
+ background-color: #f9fafb;
301
+ border-top: 1px solid var(--border-color);
302
  }
303
 
304
  .summary-row {
305
  display: flex;
306
  justify-content: space-between;
307
+ margin-bottom: 8px;
308
+ font-size: 0.95rem;
309
+ color: var(--text-muted);
310
  }
311
 
312
  .summary-row.total {
313
+ font-size: 1.4rem;
314
+ font-weight: 700;
315
+ color: var(--text-main);
316
+ margin-top: 15px;
317
+ padding-top: 15px;
318
+ border-top: 2px dashed var(--border-color);
 
 
 
 
 
 
 
319
  }
320
 
321
+ .checkout-btn {
322
+ width: 100%;
323
+ padding: 15px;
324
+ background-color: var(--success-color);
325
+ color: white;
326
+ border: none;
327
+ border-radius: var(--radius);
328
  font-size: 1.1rem;
329
+ font-weight: 600;
330
+ margin-top: 15px;
331
  cursor: pointer;
332
+ transition: background 0.3s;
333
  display: flex;
 
334
  justify-content: center;
335
+ align-items: center;
336
  gap: 10px;
 
 
337
  }
338
 
339
+ .checkout-btn:hover {
340
+ background-color: #059669;
 
341
  }
 
342
 
343
+ .checkout-btn:disabled {
344
+ background-color: #9ca3af;
345
+ cursor: not-allowed;
 
 
 
 
 
 
 
346
  }
347
 
348
+ /* Modal / Toast */
349
  .modal-overlay {
350
  position: fixed;
351
  top: 0;
352
  left: 0;
353
  width: 100%;
354
  height: 100%;
355
+ background: rgba(0, 0, 0, 0.5);
 
 
356
  display: flex;
357
  justify-content: center;
358
  align-items: center;
359
+ z-index: 100;
360
  opacity: 0;
361
+ visibility: hidden;
362
+ transition: all 0.3s;
363
  }
364
 
365
  .modal-overlay.active {
366
  opacity: 1;
367
+ visibility: visible;
368
  }
369
 
370
  .modal {
371
  background: white;
372
+ padding: 30px;
373
+ border-radius: var(--radius);
374
  width: 90%;
375
+ max-width: 400px;
 
 
 
376
  text-align: center;
377
+ transform: scale(0.9);
378
+ transition: transform 0.3s;
379
  }
380
 
381
  .modal-overlay.active .modal {
382
  transform: scale(1);
383
  }
384
 
385
+ .modal-icon {
386
+ font-size: 3rem;
387
+ color: var(--success-color);
388
+ margin-bottom: 15px;
 
 
 
389
  }
390
 
391
+ .modal-title {
392
+ font-size: 1.5rem;
393
+ margin-bottom: 10px;
 
 
 
 
 
 
 
 
394
  }
395
 
396
+ .modal-body {
397
+ color: var(--text-muted);
 
 
 
 
 
 
398
  margin-bottom: 20px;
 
 
399
  }
400
 
401
+ .modal-actions {
402
  display: flex;
403
+ gap: 10px;
404
+ justify-content: center;
 
 
405
  }
406
+
407
+ .btn {
408
+ padding: 10px 20px;
409
+ border-radius: 8px;
410
+ border: none;
411
+ cursor: pointer;
412
+ font-weight: 500;
413
+ transition: opacity 0.2s;
414
  }
415
 
416
+ .btn:hover {
417
+ opacity: 0.9;
 
 
 
 
 
 
 
418
  }
419
 
420
+ .btn-primary {
421
+ background-color: var(--primary-color);
422
+ color: white;
 
423
  }
424
 
425
+ .btn-secondary {
426
+ background-color: var(--bg-color);
427
+ color: var(--text-main);
428
  }
429
 
430
+ /* Responsive */
431
  @media (max-width: 768px) {
432
  main {
433
+ flex-direction: column;
 
 
434
  padding: 10px;
435
+ gap: 10px;
436
  }
437
+
438
+ .product-section {
439
+ flex: none;
440
+ height: 60vh;
441
+ }
442
+
443
+ .cart-section {
444
+ flex: none;
445
+ height: 40vh;
446
+ min-width: auto;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
447
  }
 
448
  }
449
  </style>
450
  </head>
 
451
  <body>
452
 
453
  <!-- Header -->
454
+ <header>
455
  <div class="brand">
456
  <i class="fa-solid fa-cash-register"></i>
457
+ Smart POS
458
  </div>
459
+ <div class="header-actions">
460
+ <button title="รีเซ็ตระบบ" onclick="resetSystem()">
461
+ <i class="fa-solid fa-rotate-right"></i>
462
+ </button>
463
+ <button title="เกี่ยวกับ" onclick="showAbout()">
464
+ <i class="fa-solid fa-circle-info"></i>
 
 
 
 
465
  </button>
466
  </div>
467
  </header>
468
 
469
  <!-- Main Content -->
470
  <main>
471
+ <!-- Product Section -->
472
+ <section class="product-section">
 
 
 
 
 
 
 
 
 
 
473
  <div class="search-container">
474
+ <i class="fa-solid fa-magnifying-glass search-icon"></i>
475
+ <input type="text" id="searchInput" class="search-input" placeholder="ค้นหาสินค้า (เช่น กาแฟ, ขนม)...">
476
  </div>
477
+ <div id="productGrid" class="product-grid">
478
+ <!-- Products will be injected here via JS -->
479
  </div>
480
  </section>
481
 
482
+ <!-- Cart Section -->
483
+ <section class="cart-section">
484
  <div class="cart-header">
485
+ <h2><i class="fa-solid fa-cart-shopping"></i> ตะกร้าสินค้า</h2>
486
+ <span id="cartCount" style="background: var(--primary-color); color: white; padding: 2px 8px; border-radius: 10px; font-size: 0.8rem;">0 รายก</span>
 
 
 
487
  </div>
488
+ <div id="cartItems" class="cart-items">
489
+ <!-- Cart items will be injected here -->
490
+ <div style="text-align: center; color: var(--text-muted); margin-top: 50px;">
491
+ <i class="fa-solid fa-basket-shopping" style="font-size: 3rem; margin-bottom: 10px; opacity: 0.3;"></i>
 
492
  <p>ยังไม่มีสินค้าในตะกร้า</p>
493
  </div>
494
  </div>
 
495
  <div class="cart-footer">
496
  <div class="summary-row">
497
+ <span>ยอดรมสินค้า</span>
498
+ <span id="subtotalDisplay">฿0.00</span>
499
  </div>
500
  <div class="summary-row">
501
+ <span>ภาษีมูลค่าเพิ่ม (7%)</span>
502
+ <span id="taxDisplay">฿0.00</span>
503
  </div>
504
  <div class="summary-row total">
505
+ <span>ยอดุทธิ</span>
506
+ <span id="totalDisplay">฿0.00</span>
 
 
 
 
 
 
 
 
 
507
  </div>
508
+ <button id="checkoutBtn" class="checkout-btn" onclick="openCheckoutModal()" disabled>
509
+ <i class="fa-solid fa-credit-card"></i> ชำระเงิน
510
+ </button>
511
  </div>
512
+ </section>
513
  </main>
514
 
515
+ <!-- Payment Modal -->
516
+ <div id="paymentModal" class="modal-overlay">
517
  <div class="modal">
518
+ <div class="modal-icon"><i class="fa-solid fa-receipt"></i></div>
519
+ <h3 class="modal-title">ยืนยันการชำระเงิน</h3>
520
+ <p class="modal-body">ยอดชำระทั้งหมด: <strong id="modalTotal" style="color: var(--primary-color);">฿0.00</strong></p>
521
+
522
+ <div style="margin-bottom: 15px;">
523
+ <label style="display: block; margin-bottom: 5px; font-weight: 500;">วิธีการชำระ</label>
524
+ <select id="paymentMethod" class="search-input" style="padding: 10px;">
525
+ <option value="cash">เสด</option>
526
+ <option value="card">บัตรเครดิต</option>
527
+ </select>
528
+ </div>
 
 
 
 
 
 
 
 
 
529
 
530
+ <div id="cashInputGroup" style="margin-bottom: 15px;">
531
+ <label style="display: block; margin-bottom: 5px; font-weight: 500;">จำนนเงนที่รับ</label>
532
+ <input type="number" id="cashReceived" class="search-input" placeholder="0.00" oninput="calculateChange()">
533
+ </div>
534
+
535
+ <div class="summary-row total" style="margin-top: 10px; border-top: none;">
536
+ <span>เงินทอน</span>
537
+ <span id="changeDisplay">฿0.00</span>
538
  </div>
539
 
540
  <div class="modal-actions">
541
+ <button class="btn btn-secondary" onclick="closeModal('paymentModal')">ยกเลิก</button>
542
+ <button class="btn btn-primary" onclick="processPayment()">ยืนยัน</button>
 
 
 
 
543
  </div>
544
  </div>
545
  </div>
546
 
547
+ <!-- Success Modal -->
548
+ <div id="successModal" class="modal-overlay">
549
+ <div class="modal">
550
+ <div class="modal-icon"><i class="fa-solid fa-check-circle"></i></div>
551
+ <h3 class="modal-title">ชำะเินสำเร็จ!</h3>
552
+ <p class="modal-body">ขอบคุณทีใช้บริก Smart POS</p>
553
+ <div style="background: #f3f4f6; padding: 15px; border-radius: 8px; margin-bottom: 20px;">
554
+ <p style="font-size: 0.9rem; margin-bottom: 5px;">รยการสิค้า</p>
555
+ <ul id="receiptList" style="text-align: left; font-size: 0.85rem; color: var(--text-muted); list-style: none;">
556
+ <!-- Receipt items -->
557
+ </ul>
558
+ </div>
559
+ <button class="btn btn-primary" onclick="closeModal('successModal')">ปิดหน้าต่าง</button>
560
+ </div>
561
+ </div>
562
 
563
+ <!-- About Modal -->
564
+ <div id="aboutModal" class="modal-overlay">
565
+ <div class="modal">
566
+ <div class="modal-icon"><i class="fa-solid fa-code"></i></div>
567
+ <h3 class="modal-title">Smart POS System</h3>
568
+ <p class="modal-body">ระบบ POS ระดับมืออาชีพ ที่สร้างด้วย HTML, CSS และ JavaScript แบบ Vanilla</p>
569
+ <p style="font-size: 0.9rem; color: var(--text-muted);">Built with <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" style="color: var(--primary-color); text-decoration: none; font-weight: bold;">anycoder</a></p>
570
+ <button class="btn btn-primary" onclick="closeModal('aboutModal')">เข้าใจแล้ว</button>
571
+ </div>
572
+ </div>
573
+
574
+ <script>
575
+ // --- Data ---
576
  const products = [
577
+ { id: 1, name: "กาแฟโบราณ", price: 45, category: "drink", img: "https://picsum.photos/seed/coffee1/200/200" },
578
+ { id: 2, name: "โกโก้อบ", price: 35, category: "drink", img: "https://picsum.photos/seed/cocoa/200/200" },
579
+ { id: 3, name: "ชาาว", price: 40, category: "drink", img: "https://picsum.photos/seed/tea/200/200" },
580
+ { id: 4, name: "น้ำผลไม้ด", price: 50, category: "drink", img: "https://picsum.photos/seed/juice/200/200" },
581
+ { id: 5, name: "บรี่ชี", price: 90, category: "food", img: "https://picsum.photos/seed/brownie/200/200" },
582
+ { id: 6, name: "เคกท็อปปิ้", price: 85, category: "food", img: "https://picsum.photos/seed/cake/200/200" },
583
+ { id: 7, name: "แซนวชปาทูน่า", price: 110, category: "food", img: "https://picsum.photos/seed/sandwich/200/200" },
584
+ { id: 8, name: "ส้กรอก", price: 120, category: "food", img: "https://picsum.photos/seed/sausage/200/200" },
585
+ { id: 9, name: "บัรอาหาร", price: 5, category: "other", img: "https://picsum.photos/seed/card/200/200" },
586
+ { id: 10, name: "ช้อนทอง", price: 15, category: "other", img: "https://picsum.photos/seed/spoon/200/200" },
587
+ { id: 11, name: "ไข่ตม", price: 20, category: "other", img: "https://picsum.photos/seed/egg/200/200" },
588
+ { id: 12, name: "โซาไฮโดรเจน", price: 25, category: "drink", img: "https://picsum.photos/seed/soda/200/200" },
589
  ];
590
 
591
  let cart = [];
592
+
593
+ // --- Init ---
594
+ document.addEventListener('DOMContentLoaded', () => {
595
+ renderProducts(products);
596
+
597
+ // Search Listener
598
+ document.getElementById('searchInput').addEventListener('input', (e) => {
599
+ const term = e.target.value.toLowerCase();
600
+ const filtered = products.filter(p => p.name.toLowerCase().includes(term));
601
+ renderProducts(filtered);
602
+ });
603
+
604
+ // Payment Method Listener
605
+ document.getElementById('paymentMethod').addEventListener('change', (e) => {
606
+ const cashGroup = document.getElementById('cashInputGroup');
607
+ if (e.target.value === 'card') {
608
+ cashGroup.style.display = 'none';
609
+ } else {
610
+ cashGroup.style.display = 'block';
611
+ }
612
+ calculateChange();
613
+ });
614
+ });
615
 
616
  // --- Render Functions ---
617
+ function renderProducts(list) {
618
+ const grid = document.getElementById('productGrid');
619
+ grid.innerHTML = '';
620
+
621
+ list.forEach(product => {
622
+ const card = document.createElement('div');
623
+ card.className = 'product-card';
624
+ card.onclick = () => addToCart(product.id);
625
+ card.innerHTML = `
626
+ <img src="${product.img}" alt="${product.name}" class="product-img" loading="lazy">
627
+ <div class="product-info">
628
+ <div class="product-name">${product.name}</div>
629
+ <div class="product-price">฿${product.price.toFixed(2)}</div>
630
+ </div>
631
+ <button class="add-btn"><i class="fa-solid fa-plus"></i> เพิ่ม</button>
632
+ `;
633
+ grid.appendChild(card);
634
+ });
635
  }
636
 
637
+ function renderCart() {
638
+ const container = document.getElementById('cartItems');
639
+ const countBadge = document.getElementById('cartCount');
640
+ const checkoutBtn = document.getElementById('checkoutBtn');
 
 
641
 
642
+ container.innerHTML = '';
643
+
644
+ if (cart.length === 0) {
645
+ container.innerHTML = `
646
+ <div style="text-align: center; color: var(--text-muted); margin-top: 50px;">
647
+ <i class="fa-solid fa-basket-shopping" style="font-size: 3rem; margin-bottom: 10px; opacity: 0.3;"></i>
648
+ <p>ยังไม่มีสินค้าในตะกร้า</p>
649
  </div>`;
650
+ countBadge.textContent = '0 รายการ';
651
+ checkoutBtn.disabled = true;
652
+ updateTotals();
653
  return;
654
  }
655
 
656
+ let totalQty = 0;
657
+
658
+ cart.forEach(item => {
659
+ totalQty += item.qty;
660
+ const el = document.createElement('div');
661
+ el.className = 'cart-item';
662
+ el.innerHTML = `
663
+ <div class="cart-item-info">
664
+ <div class="cart-item-name">${item.name}</div>
665
+ <div class="cart-item-price">฿${item.price.toFixed(2)} x ${item.qty}</div>
666
  </div>
667
+ <div class="cart-controls">
668
+ <button class="qty-btn" onclick="updateQty(${item.id}, -1)">-</button>
669
+ <span class="qty-value">${item.qty}</span>
670
+ <button class="qty-btn" onclick="updateQty(${item.id}, 1)">+</button>
671
+ <i class="fa-solid fa-trash remove-btn" onclick="removeFromCart(${item.id})"></i>
 
672
  </div>
673
+ `;
674
+ container.appendChild(el);
675
+ });
676
+
677
+ countBadge.textContent = `${totalQty} รายการ`;
678
+ checkoutBtn.disabled = false;
679
+ updateTotals();
680
  }
681
 
682
+ function updateTotals() {
683
+ const subtotal = cart.reduce((sum, item) => sum + (item.price * item.qty), 0);
684
+ const tax = subtotal * 0.07;
685
+ const total = subtotal + tax;
686
 
687
+ document.getElementById('subtotalDisplay').textContent = `฿${subtotal.toFixed(2)}`;
688
+ document.getElementById('taxDisplay').textContent = `฿${tax.toFixed(2)}`;
689
+ document.getElementById('totalDisplay').textContent = `฿${total.toFixed(2)}`;
690
 
691
+ return total;
692
+ }
693
+
694
+ // --- Cart Logic ---
695
+ function addToCart(id) {
696
+ const product = products.find(p => p.id === id);
697
+ const existing = cart.find(item => item.id === id);
698
+
699
+ if (existing) {
700
+ existing.qty++;
701
  } else {
702
  cart.push({ ...product, qty: 1 });
703
  }
704
+ renderCart();
 
 
 
 
 
 
705
  }
706
 
707
+ function updateQty(id, change) {
708
+ const item = cart.find(i => i.id === id);
709
+ if (!item) return;
 
 
710
 
711
+ item.qty += change;
712
+
713
+ if (item.qty <= 0) {
714
+ removeFromCart(id);
 
 
715
  } else {
716
+ renderCart();
 
 
 
 
 
 
 
 
 
 
 
 
 
717
  }
 
 
 
 
 
 
 
 
718
  }
719
 
720
+ function removeFromCart(id) {
721
+ cart = cart.filter(item => item.id !== id);
722
+ renderCart();
 
 
 
 
 
 
723
  }
724
 
725
+ function resetSystem() {
726
+ if(confirm('ต้องการรีเซ็ตตะกร้าสินค้าใหม่หรือไม่?')) {
 
727
  cart = [];
728
+ renderCart();
729
  }
730
  }
731
 
732
+ // --- Payment Logic ---
733
+ function openCheckoutModal() {
734
+ const total = updateTotals();
735
+ document.getElementById('modalTotal').textContent = `฿${total.toFixed(2)}`;
736
+ document.getElementById('paymentMethod').value = 'cash';
737
+ document.getElementById('cashInput').value = '';
738
+ document.getElementById('cashInputGroup').style.display = 'block';
739
+ document.getElementById('changeDisplay').textContent = '฿0.00';
740
 
741
+ openModal('paymentModal');
742
+ document.getElementById('cashReceived').focus();
743
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
744
 
745
+ function calculateChange() {
746
+ const method = document.getElementById('paymentMethod').value;
747
+ const total = parseFloat(document.getElementById('modalTotal').textContent.replace('฿', '').replace(',', ''));
748
+ let cash = 0;
749
 
750
+ if (method === 'cash') {
751
+ cash = parseFloat(document.getElementById('cashReceived').value) || 0;
752
+ const change = cash - total;
753
+ document.getElementById('changeDisplay').textContent = `฿${change.toFixed(2)}`;
754
+ } else {
755
+ document.getElementById('changeDisplay').textContent = 'N/A';
756
+ }
757
  }
758
 
759
+ function processPayment() {
760
+ const method = document.getElementById('paymentMethod').value;
761
+ const total = parseFloat(document.getElementById('modalTotal').textContent.replace('฿', '').replace(',', ''));
762
+
763
+ if (method === 'cash') {
764
+ const cash = parseFloat(document.getElementById('cashReceived').value);
765
+ if (isNaN(cash) || cash < total) {
766
+ alert('เงินที่รับไม่เพียงพอ');
767
+ return;
768
+ }
769
+ }
770
 
771
+ // Show Receipt
772
+ const receiptList = document.getElementById('receiptList');
773
+ receiptList.innerHTML = '';
774
+ cart.forEach(item => {
775
+ const li = document.createElement('li');
776
+ li.innerHTML = `<span>${item.name}</span> <span>฿${(item.price * item.qty).toFixed(2)}</span>`;
777
+ receiptList.appendChild(li);
778
+ });
779
+
780
+ // Clear Cart
781
  cart = [];
782
+ renderCart();
783
+ closeModal('paymentModal');
784
+ openModal('successModal');
785
  }
786
 
787
+ // --- UI Utilities ---
788
+ function openModal(id) {
789
+ document.getElementById(id).classList.add('active');
 
 
 
790
  }
791
 
792
+ function closeModal(id) {
793
+ document.getElementById(id).classList.remove('active');
 
 
 
 
 
 
 
 
794
  }
795
 
796
+ function showAbout() {
797
+ openModal('aboutModal');
798
+ }
 
 
 
 
 
 
 
 
 
799
 
800
+ // Close modal on outside click
801
+ window.onclick = function(event) {
802
+ if (event.target.classList.contains('modal-overlay')) {
803
+ event.target.classList.remove('active');
804
+ }
805
+ }
806
  </script>
807
  </body>
 
808
  </html>