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

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +498 -332
index.html CHANGED
@@ -1,33 +1,42 @@
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 - Modern Store</title>
 
 
 
 
 
7
  <style>
8
  :root {
9
- --primary-color: #6366f1;
10
- --primary-hover: #4f46e5;
11
- --secondary-color: #ec4899;
12
- --bg-color: #f3f4f6;
13
- --card-bg: #ffffff;
14
- --text-dark: #1f2937;
15
- --text-light: #6b7280;
16
- --success: #10b981;
17
- --danger: #ef4444;
18
- --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
19
- --radius: 12px;
20
  }
21
 
22
  * {
23
  box-sizing: border-box;
24
  margin: 0;
25
  padding: 0;
26
- font-family: 'Sarabun', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
27
  }
28
 
29
  body {
30
  background-color: var(--bg-color);
 
 
 
31
  color: var(--text-dark);
32
  height: 100vh;
33
  display: flex;
@@ -35,366 +44,469 @@
35
  overflow: hidden;
36
  }
37
 
38
- /* Header */
39
  header {
40
  background: var(--card-bg);
41
  padding: 1rem 2rem;
42
  display: flex;
43
  justify-content: space-between;
44
  align-items: center;
45
- box-shadow: var(--shadow);
46
- z-index: 10;
 
47
  }
48
 
49
  .brand {
50
  display: flex;
51
  align-items: center;
52
- gap: 10px;
53
- font-size: 1.5rem;
54
  font-weight: 800;
55
  color: var(--primary-color);
 
56
  }
57
-
58
- .brand span {
59
- color: var(--text-dark);
60
- }
61
 
62
  .header-info {
63
  display: flex;
64
  align-items: center;
65
- gap: 20px;
66
  }
67
 
68
- .user-info {
69
  display: flex;
70
  align-items: center;
71
  gap: 10px;
72
- font-size: 0.9rem;
 
 
73
  color: var(--text-light);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  }
75
 
76
  .btn-logout {
77
- background: var(--danger);
78
  color: white;
79
  border: none;
80
- padding: 8px 16px;
81
- border-radius: 6px;
82
  cursor: pointer;
83
  font-weight: 600;
84
- transition: 0.2s;
 
85
  }
86
 
87
  .btn-logout:hover {
88
- background: #dc2626;
 
89
  }
90
 
91
- /* Main Layout */
92
  main {
93
  display: grid;
94
- grid-template-columns: 300px 1fr 350px;
95
  flex: 1;
96
  overflow: hidden;
 
 
97
  }
98
 
99
- /* Left: Categories */
100
  .categories-panel {
101
  background: var(--card-bg);
102
- padding: 1.5rem;
103
- border-right: 1px solid #e5e7eb;
 
 
 
104
  overflow-y: auto;
 
 
105
  }
106
 
107
  .panel-title {
108
- font-size: 1.2rem;
109
- font-weight: 700;
110
- margin-bottom: 1rem;
111
  color: var(--text-dark);
 
 
 
112
  }
113
 
114
  .category-list {
115
  display: flex;
116
  flex-direction: column;
117
- gap: 0.5rem;
118
  }
119
 
120
  .cat-btn {
121
- padding: 12px;
122
  text-align: left;
123
- background: transparent;
124
- border: 1px solid #e5e7eb;
125
- border-radius: var(--radius);
126
  cursor: pointer;
127
- transition: all 0.2s;
128
- font-size: 1rem;
 
 
 
129
  color: var(--text-light);
 
130
  }
131
 
132
  .cat-btn:hover {
133
  border-color: var(--primary-color);
134
- color: var(--primary-color);
135
- background: #f9fafb;
136
  }
137
 
138
  .cat-btn.active {
139
- background: var(--primary-color);
140
  color: white;
141
  border-color: var(--primary-color);
142
- box-shadow: 0 2px 4px rgba(99, 102, 241, 0.3);
143
  }
144
 
145
- /* Center: Products Grid */
 
 
146
  .products-panel {
147
- padding: 2rem;
148
- overflow-y: auto;
149
- background: #f9fafb;
 
 
 
 
150
  }
151
 
152
- .search-bar {
153
- margin-bottom: 1.5rem;
154
  position: relative;
 
155
  }
156
 
157
  .search-input {
158
  width: 100%;
159
- padding: 12px 16px 12px 45px;
160
- border-radius: var(--radius);
161
- border: 1px solid #e5e7eb;
162
- font-size: 1rem;
163
  background: white;
164
- box-shadow: var(--shadow);
 
 
 
 
 
 
 
 
165
  }
166
 
167
  .search-icon {
168
  position: absolute;
169
- left: 15px;
170
  top: 50%;
171
  transform: translateY(-50%);
172
- color: var(--text-light);
 
173
  }
174
 
175
  .products-grid {
176
  display: grid;
177
- grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
178
- gap: 1.5rem;
 
 
 
 
179
  }
180
 
181
  .product-card {
182
- background: var(--card-bg);
183
- border-radius: var(--radius);
184
- padding: 1rem;
185
- box-shadow: var(--shadow);
186
- transition: transform 0.2s, box-shadow 0.2s;
187
  cursor: pointer;
188
- border: 1px solid transparent;
189
- display: flex;
190
- flex-direction: column;
191
- align-items: center;
192
- text-align: center;
193
  }
194
 
195
  .product-card:hover {
196
- transform: translateY(-5px);
197
- box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
198
- border-color: var(--primary-color);
 
 
 
 
 
 
 
 
 
199
  }
200
 
201
  .product-img {
202
- width: 100px;
203
- height: 100px;
204
  object-fit: cover;
205
- border-radius: 50%;
206
- margin-bottom: 1rem;
207
- background: #e0e7ff;
 
 
208
  }
209
 
210
  .product-name {
211
- font-weight: 600;
212
- margin-bottom: 0.5rem;
213
- font-size: 1.1rem;
214
  white-space: nowrap;
215
  overflow: hidden;
216
  text-overflow: ellipsis;
217
- width: 100%;
 
 
 
 
 
 
218
  }
219
 
220
  .product-price {
221
- color: var(--success);
 
222
  font-weight: 800;
223
- font-size: 1.25rem;
224
- margin-top: auto;
225
- width: 100%;
226
- text-align: center;
227
  }
228
 
229
- /* Right: Cart & Actions */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
230
  .cart-panel {
231
- background: var(--card-bg);
232
- border-left: 1px solid #e5e7eb;
 
233
  display: flex;
234
  flex-direction: column;
 
 
235
  }
236
 
237
  .cart-header {
238
- padding: 1.5rem;
239
- border-bottom: 1px solid #e5e7eb;
 
240
  display: flex;
241
  justify-content: space-between;
242
  align-items: center;
243
  }
244
 
245
- .cart-title {
246
- font-size: 1.2rem;
247
- font-weight: 700;
248
  }
249
 
250
- .cart-count {
251
- background: var(--primary-color);
252
- color: white;
253
- padding: 2px 8px;
254
  border-radius: 20px;
255
- font-size: 0.8rem;
256
- font-weight: 700;
257
  }
258
 
259
  .cart-items {
260
  flex: 1;
261
  overflow-y: auto;
262
- padding: 1.5rem;
 
 
 
 
 
 
 
 
 
 
 
263
  }
264
 
265
  .cart-item {
 
 
 
 
266
  display: flex;
267
  align-items: center;
268
- margin-bottom: 1rem;
269
- padding-bottom: 1rem;
270
- border-bottom: 1px solid #f3f4f6;
271
  }
272
 
273
- .cart-item-info {
274
- flex: 1;
 
275
  }
276
 
277
- .cart-item-name {
278
- font-size: 0.95rem;
279
- font-weight: 600;
280
- margin-bottom: 4px;
 
 
281
  }
282
 
283
- .cart-item-meta {
284
- font-size: 0.85rem;
285
- color: var(--text-light);
286
  }
287
 
288
- .cart-item-price {
289
  font-weight: 700;
290
- color: var(--text-dark);
291
- margin-left: 10px;
292
  }
293
 
294
- .cart-controls {
 
 
 
 
 
295
  display: flex;
296
  align-items: center;
297
- gap: 8px;
 
 
 
298
  }
299
 
300
  .qty-btn {
301
  width: 28px;
302
  height: 28px;
303
- border: 1px solid #e5e7eb;
304
  background: white;
305
  border-radius: 6px;
306
  cursor: pointer;
307
- display: flex;
308
- align-items: center;
309
- justify-content: center;
310
  color: var(--text-light);
 
311
  transition: 0.2s;
 
312
  }
313
 
314
- .qty-btn:hover {
315
- background: #f3f4f6;
316
- color: var(--primary-color);
317
- }
318
 
319
  .cart-footer {
320
- padding: 1.5rem;
321
  background: #f9fafb;
322
- border-top: 1px solid #e5e7eb;
323
  }
324
 
325
  .summary-row {
326
  display: flex;
327
  justify-content: space-between;
328
- margin-bottom: 0.8rem;
 
329
  color: var(--text-light);
330
- font-size: 0.95rem;
331
  }
332
 
333
  .summary-row.total {
334
- font-size: 1.5rem;
335
  font-weight: 800;
336
  color: var(--text-dark);
337
- margin-top: 1rem;
338
- padding-top: 1rem;
339
- border-top: 2px dashed #e5e7eb;
340
  }
341
 
342
  .action-buttons {
343
  display: grid;
344
  grid-template-columns: 1fr 1fr;
345
- gap: 10px;
346
- margin-top: 1rem;
347
  }
348
 
349
  .btn {
350
- padding: 14px;
351
- border-radius: var(--radius);
352
- font-size: 1rem;
353
  font-weight: 700;
354
  cursor: pointer;
355
- transition: 0.2s;
356
- border: none;
357
  display: flex;
358
  align-items: center;
359
  justify-content: center;
360
- gap: 8px;
 
 
361
  }
362
 
363
  .btn-clear {
364
- background: #f3f4f6;
365
  color: var(--text-light);
366
  }
367
-
368
- .btn-clear:hover {
369
- background: #e5e7eb;
370
- }
371
 
372
  .btn-checkout {
373
- background: var(--primary-color);
374
  color: white;
375
- box-shadow: 0 4px 6px rgba(99, 102, 241, 0.3);
 
 
376
  }
377
-
378
  .btn-checkout:hover {
379
- background: var(--primary-hover);
380
- transform: translateY(-1px);
381
  }
382
 
383
- /* Modal */
384
  .modal-overlay {
385
  position: fixed;
386
  top: 0;
387
  left: 0;
388
  width: 100%;
389
  height: 100%;
390
- background: rgba(0,0,0,0.5);
 
 
391
  display: flex;
392
  justify-content: center;
393
  align-items: center;
394
- z-index: 100;
395
  opacity: 0;
396
  pointer-events: none;
397
- transition: opacity 0.3s;
398
  }
399
 
400
  .modal-overlay.active {
@@ -404,58 +516,87 @@
404
 
405
  .modal {
406
  background: white;
407
- padding: 2rem;
408
- border-radius: var(--radius);
409
  width: 90%;
410
  max-width: 500px;
411
- box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1);
 
 
412
  text-align: center;
 
 
 
 
 
 
413
  }
414
 
415
- .receipt {
416
  background: #f8f9fa;
417
- padding: 2rem;
418
- margin: 20px 0;
419
- border: 1px dashed #d1d5db;
420
- text-align: left;
 
421
  }
422
 
423
- .receipt-header {
424
- text-align: center;
425
- border-bottom: 2px solid #d1d5db;
426
- padding-bottom: 1rem;
427
- margin-bottom: 1rem;
 
 
 
 
 
 
428
  }
429
 
430
- .receipt-item {
 
 
 
 
 
 
 
 
 
 
 
 
 
431
  display: flex;
432
  justify-content: space-between;
433
- margin-bottom: 0.5rem;
 
 
 
 
434
  font-size: 0.9rem;
 
435
  }
436
 
437
- .receipt-total {
438
- border-top: 2px solid #d1d5db;
439
- margin-top: 1rem;
440
- padding-top: 1rem;
441
  display: flex;
442
  justify-content: space-between;
 
443
  font-weight: 800;
444
- font-size: 1.2rem;
 
 
 
445
  }
446
 
447
- .btn-print {
448
- background: var(--success);
449
- color: white;
450
- width: 100%;
451
- margin-top: 10px;
452
  }
453
 
454
  /* Responsive Design */
455
  @media (max-width: 1024px) {
456
- main {
457
- grid-template-columns: 250px 1fr 300px;
458
- }
459
  }
460
 
461
  @media (max-width: 768px) {
@@ -463,67 +604,81 @@
463
  grid-template-columns: 1fr;
464
  grid-template-rows: auto auto 1fr 250px;
465
  overflow-y: auto;
 
466
  }
467
 
468
  .categories-panel { order: 1; }
469
- .products-panel { order: 2; }
470
  .cart-panel { order: 3; }
471
 
472
- .brand { font-size: 1.2rem; }
473
- .header-info { display: none; } /* Hide user info on mobile for space */
474
  }
475
 
476
  @media (max-width: 480px) {
477
- .products-grid {
478
- grid-template-columns: repeat(2, 1fr);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
479
  }
480
- .brand span { display: none; }
481
  }
482
  </style>
483
  </head>
 
484
  <body>
485
 
486
  <!-- Header -->
487
- <header>
488
  <div class="brand">
489
- <svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
490
- <rect x="2" y="7" width="20" height="14" rx="2" ry="2"></rect>
491
- <path d="M16 21V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16"></path>
492
- </svg>
493
- Smart<span>POS</span>
494
  </div>
495
  <div class="header-info">
496
- <div class="user-info">
497
- <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
498
- <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path>
499
- <circle cx="12" cy="7" r="4"></circle>
500
- </svg>
501
- <span>พนักงาน: ปกรณ์ ปกรณ์</span>
502
  </div>
503
- <button class="btn-logout" onclick="logout()">ออกจากระบบ</button>
 
 
504
  </div>
505
  </header>
506
 
507
  <!-- Main Content -->
508
  <main>
509
  <!-- Left: Categories -->
510
- <aside class="categories-panel">
511
- <div class="panel-title">หมวดหมู่สินค้า</div>
 
 
512
  <div class="category-list" id="categoryList">
513
  <!-- Categories injected by JS -->
514
  </div>
515
  </aside>
516
 
517
  <!-- Center: Products -->
518
- <section class="products-panel">
519
- <div class="search-bar">
520
- <span class="search-icon">
521
- <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
522
- <circle cx="11" cy="11" r="8"></circle>
523
- <line x1="21" y1="21" x2="16.65" y2="16.65"></line>
524
- </svg>
525
- </span>
526
- <input type="text" id="searchInput" class="search-input" placeholder="ค้นหาสินค้า (พิมพ์เพื่อค้นหา)...">
527
  </div>
528
  <div class="products-grid" id="productsGrid">
529
  <!-- Products injected by JS -->
@@ -531,39 +686,31 @@
531
  </section>
532
 
533
  <!-- Right: Cart -->
534
- <aside class="cart-panel">
535
  <div class="cart-header">
536
  <div class="cart-title">
537
- ตะกร้าสินค้า <span id="cartCount" class="cart-count">0</span>
 
538
  </div>
539
- <button onclick="clearCart()" style="background:none; border:none; cursor:pointer; color:#ef4444; font-size:0.9rem;">
540
- <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
541
- <polyline points="3 6 5 6 21 6"></polyline>
542
- <path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path>
543
- </svg>
544
- </button>
545
  </div>
546
-
547
  <div class="cart-items" id="cartItems">
548
  <!-- Cart Items injected by JS -->
549
- <div style="text-align: center; color: #9ca3af; margin-top: 3rem;">
550
- <svg width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" style="opacity: 0.5;">
551
- <circle cx="9" cy="21" r="1"></circle>
552
- <circle cx="20" cy="21" r="1"></circle>
553
- <path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"></path>
554
- </svg>
555
- <p style="margin-top: 1rem;">ยังไม่มีสินค้าในตะกร้า</p>
556
  </div>
557
  </div>
558
 
559
  <div class="cart-footer">
560
  <div class="summary-row">
561
- <span>จำนวนชิ้น</span>
562
- <span id="summaryQty">0</span>
563
  </div>
564
  <div class="summary-row">
565
- <span>ส่วนลด</span>
566
- <span>0.00 บาท</span>
567
  </div>
568
  <div class="summary-row total">
569
  <span>รวมทั้งสิ้น</span>
@@ -571,14 +718,11 @@
571
  </div>
572
 
573
  <div class="action-buttons">
574
- <button class="btn btn-clear" onclick="clearCart()">ยกเลิก</button>
 
 
575
  <button class="btn btn-checkout" onclick="checkout()">
576
- <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
577
- <circle cx="9" cy="21" r="1"></circle>
578
- <circle cx="20" cy="21" r="1"></circle>
579
- <path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"></path>
580
- </svg>
581
- ชำระเงิน
582
  </button>
583
  </div>
584
  </div>
@@ -588,60 +732,67 @@
588
  <!-- Checkout Modal -->
589
  <div class="modal-overlay" id="checkoutModal">
590
  <div class="modal">
591
- <h2 style="color: var(--success); margin-bottom: 1rem;">ชำระเงินสำเร็จ!</h2>
592
- <p>ขอบคุณที่ใ้บริการ</p>
593
-
594
- <div class="receipt" id="receiptContent">
 
595
  <div class="receipt-header">
596
- <h3 style="font-size: 1.5rem; color: var(--primary-color);">Smart POS</h3>
597
- <p style="font-size: 0.9rem; color: #6b7280;">123 ถนนสุขุมวิท แขวงคลองตัน เขตคลองเต็ง กรุงเทพฯ</p>
598
- <p style="font-size: 0.9rem;">Tel: 02-123-4567</p>
599
- <hr style="border: 0; border-top: 1px dashed #d1d5db; margin: 10px 0;">
600
- <p style="font-size: 0.85rem;">วันที่: <span id="receiptDate"></span> เวลา: <span id="receiptTime"></span></p>
601
- <p style="font-size: 0.85rem;">Cashier: ปกรณ์ ปกรณ์</p>
 
 
 
602
  </div>
 
603
  <div id="receiptItemsContainer">
604
  <!-- Items injected here -->
605
  </div>
606
- <div class="receipt-total">
607
- <span>ยอดรวม</span>
608
- <span id="receiptTotalAmount">0.00</span>
609
- </div>
610
- <hr style="border: 0; border-top: 1px dashed #d1d5db; margin: 15px 0;">
611
- <div style="text-align: center; font-size: 0.9rem; color: #6b7280;">
612
- <p>Thank you for your business!</p>
613
- <p>กรุณาตรวจสอบเงินทอนให้เรียบร้อย</p>
614
  </div>
615
  </div>
616
 
617
- <button class="btn btn-print" onclick="printReceipt()">พิมพ์ใบเสร็จ</button>
618
- <button class="btn btn-clear" style="margin-top: 10px;" onclick="closeModal()">เริ่มคำสั่งซื้อถัดไป</button>
 
 
 
 
 
 
619
  </div>
620
  </div>
621
 
622
  <script>
623
  // --- Data & State ---
624
  const categories = [
625
- { id: 'all', name: 'ทั้งหมด', icon: 'grid' },
626
- { id: 'beverage', name: 'เครื่องดื่ม', icon: 'coffee' },
627
- { id: 'snack', name: 'ของว่าง', icon: 'cookie' },
628
- { id: 'meal', name: 'มื้อหลัก', icon: 'utensils' },
629
- { id: 'dessert', name: 'ของหวาน', icon: 'ice-cream' }
630
  ];
631
 
632
  const products = [
633
- { id: 1, name: 'กาแฟดำ', price: 45, category: 'beverage', img: 'https://placehold.co/150x150/3e2723/FFF?text=Black+Coffee' },
634
- { id: 2, name: 'ชาเขียว', price: 55, category: 'beverage', img: 'https://placehold.co/150x150/1b5e20/FFF?text=Green+Tea' },
635
- { id: 3, name: 'น้ำส้ม', price: 60, category: 'beverage', img: 'https://placehold.co/150x150/e65100/FFF?text=Orange+Juice' },
636
- { id: 4, name: 'โซดา', price: 35, category: 'beverage', img: 'https://placehold.co/150x150/f44336/FFF?text=Soda' },
637
- { id: 5, name: 'พิซซ่า', price: 199, category: 'meal', img: 'https://placehold.co/150x150/d32f2f/FFF?text=Pizza' },
638
- { id: 6, name: 'ข้าวหมูแดง', price: 85, category: 'meal', img: 'https://placehold.co/150x150/b71c1c/FFF?text=Pork+Rice' },
639
- { id: 7, name: 'สปาเกตตี้', price: 150, category: 'meal', img: 'https://placehold.co/150x150/ff6f00/FFF?text=Pasta' },
640
- { id: 8, name: 'ไก่ทอด', price: 120, category: 'meal', img: 'https://placehold.co/150x150/fbc02d/FFF?text=Fried+Chicken' },
641
- { id: 9, name: 'ชิฟฟ่', price: 75, category: 'dessert', img: 'https://placehold.co/150x150/ec407a/FFF?text=Cake' },
642
- { id: 10, name: 'ไอศครีม', price: 50, category: 'dessert', img: 'https://placehold.co/150x150/9e9e9e/FFF?text=IceCream' },
643
- { id: 11, name: 'คุกกี้ช็อก', price: 45, category: 'snack', img: 'https://placehold.co/150x150/3e2723/FFF?text=Cookies' },
644
- { id: 12, name: 'มันฝรั่งทอด', price: 40, category: 'snack', img: 'https://placehold.co/150x150/fbc02d/FFF?text=Chips' }
645
  ];
646
 
647
  let cart = [];
@@ -671,23 +822,12 @@
671
  categoryList.innerHTML = categories.map(cat => `
672
  <button class="cat-btn ${currentCategory === cat.id ? 'active' : ''}"
673
  onclick="filterByCategory('${cat.id}')">
674
- <span style="margin-right:10px;">${getCategoryIcon(cat.icon)}</span>
675
  ${cat.name}
676
  </button>
677
  `).join('');
678
  }
679
 
680
- function getCategoryIcon(type) {
681
- switch(type) {
682
- case 'grid': return '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="7" height="7"></rect><rect x="14" y="3" width="7" height="7"></rect><rect x="14" y="14" width="7" height="7"></rect><rect x="3" y="14" width="7" height="7"></rect></svg>';
683
- case 'coffee': return '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 8h1a4 4 0 0 1 0 8h-1"></path><path d="M2 8h16v9a4 4 0 0 1-4 4H6a4 4 0 0 1-4-4V8z"></path><line x1="6" y1="1" x2="6" y2="4"></line><line x1="10" y1="1" x2="10" y2="4"></line><line x1="14" y1="1" x2="14" y2="4"></line></svg>';
684
- case 'cookie': return '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"></circle><path d="M8 14s1.5 2 4 2 4-2 4-2"></path><line x1="9" y1="9" x2="9.01" y2="9"></line><line x1="15" y1="9" x2="15.01" y2="9"></line></svg>';
685
- case 'utensils': return '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 2v7c0 1.1.9 2 2 2h4a2 2 0 0 0 2-2V2"></path><path d="M7 2v20"></path><path d="M21 15V2v0a5 5 0 0 0-5 5v6c0 1.1.9 2 2 2h3zm0 0v7"></path></svg>';
686
- case 'ice-cream': return '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M8 2a3 3 0 0 1 3 3v12a3 3 0 0 1-6 0V5a3 3 0 0 1 3-3z"></path><path d="M8 2h8"></path><path d="M12 5v12"></path><path d="M8 22h8"></path></svg>';
687
- default: return '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="9" cy="21" r="1"></circle><circle cx="20" cy="21" r="1"></circle><path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"></path></svg>';
688
- }
689
- }
690
-
691
  function renderProducts() {
692
  const filteredProducts = products.filter(product => {
693
  const matchCategory = currentCategory === 'all' || product.category === currentCategory;
@@ -695,11 +835,28 @@
695
  return matchCategory && matchSearch;
696
  });
697
 
 
 
 
 
 
 
 
 
 
 
698
  productsGrid.innerHTML = filteredProducts.map(product => `
699
  <div class="product-card" onclick="addToCart(${product.id})">
700
- <img src="${product.img}" alt="${product.name}" class="product-img">
 
 
701
  <div class="product-name">${product.name}</div>
702
- <div class="product-price">${product.price.toFixed(2)} บาท</div>
 
 
 
 
 
703
  </div>
704
  `).join('');
705
  }
@@ -716,41 +873,39 @@
716
  } else {
717
  cart.push({ ...product, qty: 1 });
718
  }
719
- updateCartUI();
 
 
 
 
 
 
720
  }
721
 
722
  function updateCartUI() {
723
- cartCount.innerText = cart.length;
 
724
  let totalQty = 0;
725
  let totalPrice = 0;
726
 
727
  if (cart.length === 0) {
728
  cartItems.innerHTML = `
729
- <div style="text-align: center; color: #9ca3af; margin-top: 3rem;">
730
- <svg width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" style="opacity: 0.5;">
731
- <circle cx="9" cy="21" r="1"></circle>
732
- <circle cx="20" cy="21" r="1"></circle>
733
- <path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"></path>
734
- </svg>
735
- <p style="margin-top: 1rem;">ยังไม่มีสินค้าในตะกร้า</p>
736
  </div>`;
737
  } else {
738
  cartItems.innerHTML = cart.map(item => `
739
  <div class="cart-item">
740
- <img src="${item.img}" style="width:50px; height:50px; border-radius:8px; object-fit:cover; margin-right:10px;">
741
- <div class="cart-item-info">
742
  <div class="cart-item-name">${item.name}</div>
743
- <div class="cart-item-meta">
744
- <span style="color:var(--primary-color); font-weight:600;">${item.price.toFixed(2)} บาท</span> x
745
- <span style="margin:0 5px;">${item.qty}</span>
746
- </div>
747
  </div>
748
- <div class="cart-item-price">${(item.price * item.qty).toFixed(2)} บาท</div>
749
-
750
- <div class="cart-controls">
751
- <button class="qty-btn" onclick="changeQty(${item.id}, -1)">-</button>
752
- <span style="font-weight:600; width:20px; text-align:center;">${item.qty}</span>
753
- <button class="qty-btn" onclick="changeQty(${item.id}, 1)">+</button>
754
  </div>
755
  </div>
756
  `).join('');
@@ -763,13 +918,6 @@
763
 
764
  summaryQty.innerText = totalQty;
765
  summaryTotal.innerText = totalPrice.toFixed(2) + ' บาท';
766
-
767
- // Store current total for receipt
768
- document.getElementById('cartTotalValue')?.remove();
769
- const totalSpan = document.createElement('span');
770
- totalSpan.id = 'cartTotalValue';
771
- totalSpan.innerText = totalPrice.toFixed(2);
772
- summaryTotal.appendChild(totalSpan);
773
  }
774
 
775
  function changeQty(id, change) {
@@ -784,6 +932,7 @@
784
  }
785
 
786
  function clearCart() {
 
787
  if (confirm('ต้องการยกเลิกรายการทั้งหมดหรือไม่?')) {
788
  cart = [];
789
  updateCartUI();
@@ -801,13 +950,19 @@
801
 
802
  // Populate Receipt
803
  const date = new Date();
804
- document.getElementById('receiptDate').innerText = date.toLocaleDateString('th-TH');
805
- document.getElementById('receiptTime').innerText = date.toLocaleTimeString('th-TH');
 
 
 
806
 
807
  const itemsContainer = document.getElementById('receiptItemsContainer');
808
  itemsContainer.innerHTML = cart.map(item => `
809
- <div class="receipt-item">
810
- <span>${item.name} x ${item.qty}</span>
 
 
 
811
  <span>${(item.price * item.qty).toFixed(2)} บาท</span>
812
  </div>
813
  `).join('');
@@ -818,15 +973,15 @@
818
  }
819
 
820
  function closeModal() {
 
 
 
 
821
  checkoutModal.classList.remove('active');
822
  cart = [];
823
  updateCartUI();
824
  }
825
 
826
- function printReceipt() {
827
- window.print();
828
- }
829
-
830
  function logout() {
831
  if(confirm('คุณต้องการออกจากระบบใช่หรือไม่?')) {
832
  alert('กำลังออกจากระบบ...');
@@ -850,6 +1005,17 @@
850
  // Start the app
851
  init();
852
 
 
 
 
 
 
 
 
 
 
 
853
  </script>
854
  </body>
 
855
  </html>
 
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;
 
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
 
378
+ @keyframes slideIn {
379
+ from { opacity: 0; transform: translateX(20px); }
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 {
 
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) {
 
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 -->
 
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>
 
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>
 
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 = [];
 
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;
 
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
  }
 
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('');
 
918
 
919
  summaryQty.innerText = totalQty;
920
  summaryTotal.innerText = totalPrice.toFixed(2) + ' บาท';
 
 
 
 
 
 
 
921
  }
922
 
923
  function changeQty(id, change) {
 
932
  }
933
 
934
  function clearCart() {
935
+ if (cart.length === 0) return;
936
  if (confirm('ต้องการยกเลิกรายการทั้งหมดหรือไม่?')) {
937
  cart = [];
938
  updateCartUI();
 
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('');
 
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('กำลังออกจากระบบ...');
 
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>