Spaces:
Running
Running
Update customer.html
Browse files- customer.html +408 -304
customer.html
CHANGED
|
@@ -2,7 +2,8 @@
|
|
| 2 |
<html lang="fa" dir="rtl">
|
| 3 |
<head>
|
| 4 |
<meta charset="UTF-8">
|
| 5 |
-
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
|
|
|
| 6 |
<title>Cafe AI — کافه هوشمند تبریز</title>
|
| 7 |
|
| 8 |
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
@@ -21,7 +22,6 @@
|
|
| 21 |
display: ['Lalezar', 'serif'],
|
| 22 |
},
|
| 23 |
colors: {
|
| 24 |
-
// پالت تبریز: الهام از مسجد کبود، فرش تبریز، بازار سرپوشیده
|
| 25 |
bazaar: {
|
| 26 |
950: '#1a0d07',
|
| 27 |
900: '#2d1810',
|
|
@@ -75,6 +75,7 @@
|
|
| 75 |
'float': 'float 6s ease-in-out infinite',
|
| 76 |
'shimmer': 'shimmer 3s ease-in-out infinite',
|
| 77 |
'pulse-glow': 'pulseGlow 2.5s ease-in-out infinite',
|
|
|
|
| 78 |
},
|
| 79 |
keyframes: {
|
| 80 |
float: {
|
|
@@ -89,6 +90,10 @@
|
|
| 89 |
'0%, 100%': { boxShadow: '0 0 20px rgba(201, 169, 97, 0.3)' },
|
| 90 |
'50%': { boxShadow: '0 0 40px rgba(201, 169, 97, 0.6)' },
|
| 91 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
| 92 |
},
|
| 93 |
}
|
| 94 |
}
|
|
@@ -98,15 +103,35 @@
|
|
| 98 |
<style>
|
| 99 |
:root {
|
| 100 |
--pattern-url: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='80' height='80' viewBox='0 0 80 80'%3E%3Cg fill='none' stroke='%23c9a961' stroke-width='0.6' opacity='0.08'%3E%3Cpath d='M40 10 L50 20 L60 10 L70 20 L60 30 L70 40 L60 50 L70 60 L60 70 L50 60 L40 70 L30 60 L20 70 L10 60 L20 50 L10 40 L20 30 L10 20 L20 10 L30 20 Z'/%3E%3Ccircle cx='40' cy='40' r='12'/%3E%3Ccircle cx='40' cy='40' r='6'/%3E%3Cpath d='M40 28 L40 52 M28 40 L52 40'/%3E%3C/g%3E%3C/svg%3E");
|
|
|
|
| 101 |
}
|
| 102 |
|
| 103 |
-
html {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 104 |
|
| 105 |
body {
|
| 106 |
background-color: #1a0d07;
|
| 107 |
color: #f5e6d3;
|
| 108 |
-webkit-tap-highlight-color: transparent;
|
| 109 |
font-feature-settings: "ss01", "cv01";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 110 |
}
|
| 111 |
|
| 112 |
.bg-pattern {
|
|
@@ -125,14 +150,13 @@
|
|
| 125 |
|
| 126 |
/* Scrollbar */
|
| 127 |
::-webkit-scrollbar { width: 6px; height: 6px; }
|
| 128 |
-
::-webkit-scrollbar-track { background:
|
| 129 |
::-webkit-scrollbar-thumb {
|
| 130 |
background: linear-gradient(180deg, #c9a961, #8b1e3f);
|
| 131 |
border-radius: 4px;
|
| 132 |
}
|
| 133 |
::-webkit-scrollbar-thumb:hover { background: linear-gradient(180deg, #e4c97a, #c23d5f); }
|
| 134 |
|
| 135 |
-
/* Glass card - باری با شیشه بازار تبریز */
|
| 136 |
.glass-card {
|
| 137 |
background: linear-gradient(135deg, rgba(45, 24, 16, 0.82) 0%, rgba(26, 13, 7, 0.78) 100%);
|
| 138 |
backdrop-filter: blur(20px);
|
|
@@ -158,8 +182,10 @@
|
|
| 158 |
position: relative;
|
| 159 |
background: linear-gradient(145deg, rgba(139, 30, 63, 0.15), rgba(90, 16, 40, 0.25));
|
| 160 |
border: 1px solid rgba(201, 169, 97, 0.25);
|
| 161 |
-
transition: all 0.
|
| 162 |
overflow: hidden;
|
|
|
|
|
|
|
| 163 |
}
|
| 164 |
.table-btn::before {
|
| 165 |
content: '';
|
|
@@ -168,22 +194,22 @@
|
|
| 168 |
border: 1px dashed rgba(201, 169, 97, 0.2);
|
| 169 |
border-radius: inherit;
|
| 170 |
pointer-events: none;
|
| 171 |
-
transition: all 0.
|
| 172 |
}
|
| 173 |
-
.table-btn:hover {
|
| 174 |
-
transform: translateY(-
|
| 175 |
background: linear-gradient(145deg, rgba(194, 61, 95, 0.35), rgba(139, 30, 63, 0.45));
|
| 176 |
border-color: rgba(201, 169, 97, 0.6);
|
| 177 |
box-shadow:
|
| 178 |
-
0
|
| 179 |
0 0 0 1px rgba(201, 169, 97, 0.4),
|
| 180 |
inset 0 1px 0 rgba(244, 228, 163, 0.2);
|
| 181 |
}
|
| 182 |
-
.table-btn:hover::before {
|
| 183 |
border-color: rgba(201, 169, 97, 0.5);
|
| 184 |
inset: 6px;
|
| 185 |
}
|
| 186 |
-
.table-btn:active { transform: translateY(-
|
| 187 |
|
| 188 |
/* Ornament divider */
|
| 189 |
.ornament-divider {
|
|
@@ -202,8 +228,8 @@
|
|
| 202 |
.ornament-divider::before { left: 0; }
|
| 203 |
.ornament-divider::after { right: 0; }
|
| 204 |
|
| 205 |
-
/* Chat Markdown Styles
|
| 206 |
-
.chat-markdown { line-height: 1.85; }
|
| 207 |
.chat-markdown > * + * { margin-top: 0.6em; }
|
| 208 |
|
| 209 |
.chat-markdown h1, .chat-markdown h2, .chat-markdown h3,
|
|
@@ -244,9 +270,7 @@
|
|
| 244 |
color: #2dd4bf;
|
| 245 |
text-decoration: underline;
|
| 246 |
text-underline-offset: 3px;
|
| 247 |
-
transition: color 0.2s;
|
| 248 |
}
|
| 249 |
-
.chat-markdown a:hover { color: #5eead4; }
|
| 250 |
|
| 251 |
.chat-markdown code {
|
| 252 |
background: rgba(13, 148, 136, 0.18);
|
|
@@ -306,6 +330,8 @@
|
|
| 306 |
border-radius: 8px;
|
| 307 |
overflow: hidden;
|
| 308 |
border: 1px solid rgba(201, 169, 97, 0.25);
|
|
|
|
|
|
|
| 309 |
}
|
| 310 |
.chat-markdown thead {
|
| 311 |
background: linear-gradient(90deg, rgba(139, 30, 63, 0.4), rgba(201, 169, 97, 0.2));
|
|
@@ -323,7 +349,6 @@
|
|
| 323 |
border-bottom: 1px solid rgba(201, 169, 97, 0.1);
|
| 324 |
}
|
| 325 |
.chat-markdown tr:last-child td { border-bottom: none; }
|
| 326 |
-
.chat-markdown tr:hover td { background: rgba(201, 169, 97, 0.05); }
|
| 327 |
|
| 328 |
.chat-markdown img {
|
| 329 |
max-width: 100%;
|
|
@@ -336,41 +361,9 @@
|
|
| 336 |
text-shadow: 0 0 10px rgba(201, 169, 97, 0.8), 0 0 20px rgba(201, 169, 97, 0.4);
|
| 337 |
}
|
| 338 |
|
| 339 |
-
/* View transitions */
|
| 340 |
-
.view {
|
| 341 |
-
transition: opacity 0.5s ease, transform 0.5s ease;
|
| 342 |
-
}
|
| 343 |
-
.view-hidden {
|
| 344 |
-
opacity: 0;
|
| 345 |
-
pointer-events: none;
|
| 346 |
-
transform: translateY(20px);
|
| 347 |
-
position: absolute;
|
| 348 |
-
inset: 0;
|
| 349 |
-
visibility: hidden;
|
| 350 |
-
}
|
| 351 |
-
.view-visible {
|
| 352 |
-
opacity: 1;
|
| 353 |
-
pointer-events: auto;
|
| 354 |
-
transform: translateY(0);
|
| 355 |
-
visibility: visible;
|
| 356 |
-
}
|
| 357 |
-
|
| 358 |
/* Decorative frame */
|
| 359 |
-
.
|
| 360 |
-
|
| 361 |
-
}
|
| 362 |
-
.ornate-frame::before {
|
| 363 |
-
content: '';
|
| 364 |
-
position: absolute;
|
| 365 |
-
inset: 0;
|
| 366 |
-
border: 1px solid rgba(201, 169, 97, 0.3);
|
| 367 |
-
pointer-events: none;
|
| 368 |
-
border-radius: inherit;
|
| 369 |
-
mask:
|
| 370 |
-
linear-gradient(#000 0 0) content-box,
|
| 371 |
-
linear-gradient(#000 0 0);
|
| 372 |
-
mask-composite: exclude;
|
| 373 |
-
padding: 8px;
|
| 374 |
}
|
| 375 |
|
| 376 |
/* Button primary */
|
|
@@ -418,313 +411,370 @@
|
|
| 418 |
30% { transform: translateY(-8px); opacity: 1; }
|
| 419 |
}
|
| 420 |
|
| 421 |
-
/* Arch decoration */
|
| 422 |
-
.arch-shape {
|
| 423 |
-
border-radius: 50% 50% 1rem 1rem / 35% 35% 1rem 1rem;
|
| 424 |
-
}
|
| 425 |
-
|
| 426 |
/* Input focus */
|
| 427 |
input:focus {
|
| 428 |
outline: none;
|
| 429 |
-
border-color: rgba(201, 169, 97, 0.6);
|
| 430 |
box-shadow: 0 0 0 3px rgba(201, 169, 97, 0.15);
|
| 431 |
}
|
| 432 |
|
| 433 |
-
/*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 434 |
@media (max-width: 640px) {
|
| 435 |
-
.chat-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 436 |
}
|
| 437 |
</style>
|
| 438 |
</head>
|
| 439 |
-
<body class="
|
| 440 |
-
|
| 441 |
-
<!-- Ambient Background -->
|
| 442 |
-
<div class="fixed inset-0 overflow-hidden pointer-events-none z-0">
|
| 443 |
-
<div class="absolute inset-0 bg-gradient-to-br from-bazaar-950 via-bazaar-900 to-azure-950"></div>
|
| 444 |
-
<div class="absolute inset-0 bg-pattern opacity-40"></div>
|
| 445 |
-
<div class="absolute -top-40 -right-40 w-[600px] h-[600px] rounded-full bg-rug/10 blur-[140px] animate-float"></div>
|
| 446 |
-
<div class="absolute -bottom-40 -left-40 w-[600px] h-[600px] rounded-full bg-turk/10 blur-[140px] animate-float" style="animation-delay: -3s;"></div>
|
| 447 |
-
<div class="absolute top-1/3 left-1/4 w-[400px] h-[400px] rounded-full bg-ochre/8 blur-[120px] animate-shimmer"></div>
|
| 448 |
-
</div>
|
| 449 |
|
| 450 |
<!-- ============ VIEW 1: TABLE SELECTION ============ -->
|
| 451 |
-
<section id="view-table-selection" class="view view-visible
|
| 452 |
|
| 453 |
-
<!--
|
| 454 |
-
<
|
| 455 |
-
<div class="
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 456 |
|
| 457 |
-
|
| 458 |
-
|
| 459 |
-
|
| 460 |
-
|
| 461 |
-
|
| 462 |
-
|
| 463 |
-
|
| 464 |
-
|
| 465 |
-
|
| 466 |
-
|
| 467 |
-
<
|
| 468 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 469 |
</div>
|
| 470 |
-
<div class="absolute -bottom-1 -right-1 w-6 h-6 rounded-full bg-turk border-2 border-ochre animate-pulse-glow"></div>
|
| 471 |
</div>
|
| 472 |
-
</div>
|
| 473 |
|
| 474 |
-
|
| 475 |
-
|
| 476 |
-
|
| 477 |
-
|
| 478 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 479 |
</div>
|
| 480 |
-
|
| 481 |
-
دستیار هوشمند سفارش، با الهام از <span class="text-turk-light font-semibold">کاشیکاریهای مسجد کبود</span>
|
| 482 |
-
و گرمای <span class="text-rug-light font-semibold">بازار سرپوشیده</span>
|
| 483 |
-
</p>
|
| 484 |
-
</div>
|
| 485 |
-
</header>
|
| 486 |
|
| 487 |
-
|
| 488 |
-
|
| 489 |
-
|
| 490 |
|
| 491 |
-
|
| 492 |
-
|
| 493 |
-
<div class="absolute inset-0 bg-arch opacity-30 pointer-events-none"></div>
|
| 494 |
|
| 495 |
-
|
| 496 |
-
|
| 497 |
-
|
| 498 |
-
|
| 499 |
-
|
| 500 |
-
|
| 501 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 502 |
</div>
|
| 503 |
-
<div>
|
| 504 |
-
<
|
| 505 |
-
<
|
| 506 |
</div>
|
| 507 |
</div>
|
| 508 |
-
<div class="flex items-center gap-2 px-3 py-1.5 rounded-full bg-turk/10 border border-turk/30">
|
| 509 |
-
<span class="w-2 h-2 rounded-full bg-turk-light animate-pulse"></span>
|
| 510 |
-
<span class="text-xs text-turk-light font-medium">۲۰ میز آماده پذیرایی</span>
|
| 511 |
-
</div>
|
| 512 |
-
</div>
|
| 513 |
|
| 514 |
-
|
| 515 |
-
|
| 516 |
-
<!-- Tables injected by JS -->
|
| 517 |
-
</div>
|
| 518 |
|
| 519 |
-
|
| 520 |
-
|
| 521 |
-
|
| 522 |
-
|
| 523 |
-
|
| 524 |
-
|
| 525 |
-
|
| 526 |
-
|
|
|
|
| 527 |
</div>
|
| 528 |
</div>
|
| 529 |
-
</div>
|
| 530 |
|
| 531 |
-
|
| 532 |
-
|
| 533 |
-
|
| 534 |
-
|
| 535 |
-
|
| 536 |
-
|
| 537 |
-
|
| 538 |
-
|
| 539 |
-
|
|
|
|
|
|
|
|
|
|
| 540 |
</div>
|
| 541 |
-
<h3 class="font-display text-lg text-ochre-light mb-1">گفتگوی هوشمند</h3>
|
| 542 |
-
<p class="text-xs text-cream/70 leading-relaxed">با نیلا، دستیار کافه، به زبان طبیعی سفارش دهید</p>
|
| 543 |
</div>
|
| 544 |
-
</div>
|
| 545 |
|
| 546 |
-
|
| 547 |
-
|
| 548 |
-
|
| 549 |
-
|
| 550 |
-
|
| 551 |
-
|
| 552 |
-
|
|
|
|
|
|
|
|
|
|
| 553 |
</div>
|
| 554 |
-
<h3 class="font-display text-lg text-ochre-light mb-1">پیشنویس زنده</h3>
|
| 555 |
-
<p class="text-xs text-cream/70 leading-relaxed">سفارش شما قبل از ثبت نهایی، قابل ویرایش است</p>
|
| 556 |
</div>
|
| 557 |
-
</div>
|
| 558 |
|
| 559 |
-
|
| 560 |
-
|
| 561 |
-
|
| 562 |
-
|
| 563 |
-
|
| 564 |
-
|
| 565 |
-
|
|
|
|
|
|
|
|
|
|
| 566 |
</div>
|
| 567 |
-
<h3 class="font-display text-lg text-ochre-light mb-1">ارسال آنی</h3>
|
| 568 |
-
<p class="text-xs text-cream/70 leading-relaxed">سفارش شما مستقیماً به آشپزخانه ارسال میشود</p>
|
| 569 |
</div>
|
| 570 |
</div>
|
| 571 |
</div>
|
| 572 |
-
</
|
| 573 |
-
</main>
|
| 574 |
|
| 575 |
-
|
| 576 |
-
|
| 577 |
-
|
|
|
|
| 578 |
</section>
|
| 579 |
|
| 580 |
|
| 581 |
<!-- ============ VIEW 2: CHAT ============ -->
|
| 582 |
-
<section id="view-chat" class="view view-hidden
|
| 583 |
-
|
| 584 |
-
<!--
|
| 585 |
-
<
|
| 586 |
-
<div class="
|
| 587 |
-
|
| 588 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 589 |
title="بازگشت به انتخاب میز">
|
| 590 |
<svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
| 591 |
-
<path stroke-linecap="round" stroke-linejoin="round" d="
|
| 592 |
</svg>
|
| 593 |
</button>
|
| 594 |
-
<div class="w-
|
| 595 |
-
<svg class="w-
|
| 596 |
<path d="M17 8h1a4 4 0 1 1 0 8h-1" stroke-linecap="round"/>
|
| 597 |
<path d="M3 8h14v9a4 4 0 0 1-4 4H7a4 4 0 0 1-4-4Z" stroke-linecap="round"/>
|
| 598 |
-
<line x1="6" y1="2" x2="6" y2="4" stroke-linecap="round"/>
|
| 599 |
-
<line x1="10" y1="2" x2="10" y2="4" stroke-linecap="round"/>
|
| 600 |
-
<line x1="14" y1="2" x2="14" y2="4" stroke-linecap="round"/>
|
| 601 |
</svg>
|
| 602 |
</div>
|
| 603 |
-
<div>
|
| 604 |
-
<h1 class="text-sm font-display text-ochre-light tracking-wide flex items-center gap-
|
| 605 |
-
<span class="text-rug-light">Cafe AI</span>
|
| 606 |
-
<span class="text-cream/
|
| 607 |
-
<span class="text-cream/80 text-xs font-sans font-normal">
|
| 608 |
</h1>
|
| 609 |
</div>
|
| 610 |
</div>
|
| 611 |
|
| 612 |
-
<!-- Table number
|
| 613 |
-
<div class="flex items-center gap-
|
| 614 |
-
<div class="flex items-center gap-
|
| 615 |
-
<svg class="w-
|
| 616 |
<path stroke-linecap="round" stroke-linejoin="round" d="M3 10h18M3 14h18m-9-4v8m-7 0h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z"/>
|
| 617 |
</svg>
|
| 618 |
-
<span class="text-
|
| 619 |
-
<span id="tableNumberDisplay" class="text-lg font-display text-ochre-light table-number-glow">---</span>
|
| 620 |
</div>
|
| 621 |
-
<button onclick="changeTableNumber()" class="p-2 text-turk/60 hover:text-ochre-light transition-colors rounded-lg hover:bg-bazaar-800/50"
|
| 622 |
-
title="تغییر شماره میز">
|
| 623 |
-
<svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
| 624 |
-
<path stroke-linecap="round" stroke-linejoin="round" d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z"/>
|
| 625 |
-
</svg>
|
| 626 |
-
</button>
|
| 627 |
</div>
|
| 628 |
</div>
|
| 629 |
</header>
|
| 630 |
|
| 631 |
<!-- Main content -->
|
| 632 |
-
<main class="flex-1
|
| 633 |
-
|
| 634 |
-
|
| 635 |
-
|
| 636 |
-
<div class="
|
| 637 |
-
|
| 638 |
-
<div class="
|
| 639 |
-
<
|
| 640 |
-
<
|
| 641 |
-
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 642 |
</svg>
|
| 643 |
-
|
| 644 |
-
</
|
| 645 |
-
<span class="text-[10px] text-turk/70 bg-turk/10 px-2 py-1 rounded-md border border-turk/20">
|
| 646 |
-
جهت تأیید نهایی
|
| 647 |
-
</span>
|
| 648 |
</div>
|
| 649 |
-
<div id="draftItems" class="space-y-2 mb-4"></div>
|
| 650 |
-
<button id="confirmOrderBtn" onclick="confirmOrder()"
|
| 651 |
-
class="btn-primary w-full py-3 rounded-xl text-sm transition-all flex items-center justify-center gap-2">
|
| 652 |
-
<svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2.5">
|
| 653 |
-
<path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/>
|
| 654 |
-
</svg>
|
| 655 |
-
تأیید نهایی و ارسال به آشپزخانه
|
| 656 |
-
</button>
|
| 657 |
</div>
|
| 658 |
-
</div>
|
| 659 |
|
| 660 |
-
|
| 661 |
-
|
| 662 |
-
|
| 663 |
-
|
| 664 |
-
|
| 665 |
-
|
| 666 |
-
|
| 667 |
-
|
| 668 |
-
|
| 669 |
-
|
| 670 |
-
|
| 671 |
-
|
| 672 |
-
|
| 673 |
-
|
| 674 |
-
|
| 675 |
-
|
| 676 |
-
|
| 677 |
-
|
| 678 |
-
|
| 679 |
-
|
|
|
|
| 680 |
</div>
|
| 681 |
-
</div>
|
| 682 |
|
| 683 |
-
|
| 684 |
-
|
| 685 |
-
|
| 686 |
-
|
| 687 |
-
|
| 688 |
-
|
| 689 |
-
|
| 690 |
-
|
| 691 |
-
|
|
|
|
| 692 |
</div>
|
| 693 |
</div>
|
| 694 |
-
</div>
|
| 695 |
|
| 696 |
-
|
| 697 |
-
|
| 698 |
-
|
| 699 |
-
|
| 700 |
-
|
|
|
|
|
|
|
| 701 |
</div>
|
| 702 |
-
<
|
|
|
|
|
|
|
| 703 |
</div>
|
| 704 |
-
<button onclick="stopGeneration()" class="px-3 py-1.5 bg-rug-dark/40 border border-rug/40 hover:bg-rug/40 rounded-lg text-[10px] text-rug-light font-bold transition-all">
|
| 705 |
-
توقف
|
| 706 |
-
</button>
|
| 707 |
-
</div>
|
| 708 |
|
| 709 |
-
|
| 710 |
-
|
| 711 |
-
|
| 712 |
-
|
| 713 |
-
|
| 714 |
-
|
| 715 |
-
|
| 716 |
-
|
| 717 |
-
|
| 718 |
-
|
|
|
|
| 719 |
</div>
|
| 720 |
</main>
|
| 721 |
-
|
| 722 |
-
<footer class="border-t border-ochre/15 py-4 text-center text-[10px] text-cream/40 bg-bazaar-950/60 backdrop-blur">
|
| 723 |
-
طراحی و توسعه توسط الگوریتم داده نسترن | با الهام از فرهنگ تبریز © ۲۰۲۶
|
| 724 |
-
</footer>
|
| 725 |
</section>
|
| 726 |
|
| 727 |
<script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 728 |
// ------------------- Configuration -------------------
|
| 729 |
let currentTable = "{{ table_number }}" !== "None" && "{{ table_number }}" !== "" ? "{{ table_number }}" : null;
|
| 730 |
let abortController = null;
|
|
@@ -737,14 +787,23 @@
|
|
| 737 |
window.addEventListener('DOMContentLoaded', () => {
|
| 738 |
renderTablesGrid();
|
| 739 |
if (currentTable && currentTable.trim() !== '') {
|
| 740 |
-
|
|
|
|
| 741 |
}
|
| 742 |
});
|
| 743 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 744 |
// ------------------- View Management -------------------
|
| 745 |
function switchView(targetView) {
|
| 746 |
const sel = document.getElementById('view-table-selection');
|
| 747 |
const chat = document.getElementById('view-chat');
|
|
|
|
| 748 |
if (targetView === 'chat') {
|
| 749 |
sel.classList.remove('view-visible');
|
| 750 |
sel.classList.add('view-hidden');
|
|
@@ -756,15 +815,32 @@
|
|
| 756 |
sel.classList.remove('view-hidden');
|
| 757 |
sel.classList.add('view-visible');
|
| 758 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 759 |
}
|
| 760 |
|
| 761 |
-
function enterChatView(tableNumber) {
|
| 762 |
currentTable = tableNumber;
|
| 763 |
updateTableNumberDisplay(tableNumber);
|
| 764 |
-
|
|
|
|
|
|
|
| 765 |
switchView('chat');
|
| 766 |
initializeChatSession(tableNumber);
|
| 767 |
-
|
|
|
|
|
|
|
|
|
|
| 768 |
}
|
| 769 |
|
| 770 |
function backToTables() {
|
|
@@ -782,13 +858,13 @@
|
|
| 782 |
grid.innerHTML = '';
|
| 783 |
for (let i = 1; i <= TOTAL_TABLES; i++) {
|
| 784 |
const btn = document.createElement('button');
|
| 785 |
-
btn.className = 'table-btn arch-shape aspect-[3/4] flex flex-col items-center justify-center gap-1 p-2 group';
|
| 786 |
btn.innerHTML = `
|
| 787 |
-
<svg class="w-
|
| 788 |
<path stroke-linecap="round" stroke-linejoin="round" d="M3 10h18M3 14h18m-9-4v8m-7 0h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z"/>
|
| 789 |
</svg>
|
| 790 |
-
<span class="font-display text-
|
| 791 |
-
<span class="text-[9px] text-cream/50 group-hover:text-cream/80 transition-colors tracking-wide">میز</span>
|
| 792 |
`;
|
| 793 |
btn.onclick = () => enterChatView(String(i));
|
| 794 |
grid.appendChild(btn);
|
|
@@ -823,11 +899,11 @@
|
|
| 823 |
function appendInitialGreeting() {
|
| 824 |
const container = document.getElementById('chatMessages');
|
| 825 |
container.innerHTML = `
|
| 826 |
-
<div class="flex gap-2.5 max-w-[
|
| 827 |
-
<div class="w-8 h-8 rounded-xl bg-gradient-to-br from-turk/20 to-azure-700/20 border border-turk/30 flex items-center justify-center flex-shrink-0">
|
| 828 |
-
<span class="text-ochre-light font-display text-[11px]">ن</span>
|
| 829 |
</div>
|
| 830 |
-
<div class="bg-bazaar-950/70 border border-ochre/20 text-cream text-xs rounded-2xl rounded-tr-none px-3.5 py-2.5 leading-relaxed shadow-inner-soft chat-markdown">
|
| 831 |
سلام! من <strong>نیلا</strong> هستم، دستیار هوشمند کافه آی. به میزتون خوش اومدید 🌸<br>
|
| 832 |
چه نوشیدنی، غذا یا شیرینیای میپسندید؟ <em>منوی امروز</em> رو میتونم براتون بگم. 😊
|
| 833 |
</div>
|
|
@@ -889,8 +965,8 @@
|
|
| 889 |
if (data.type === 'text') {
|
| 890 |
fullText += data.content;
|
| 891 |
botBubble.textContent = fullText;
|
| 892 |
-
document.getElementById('chatMessages')
|
| 893 |
-
|
| 894 |
} else if (data.type === 'draft') {
|
| 895 |
currentDraft = data.items;
|
| 896 |
showDraftPanel(currentDraft);
|
|
@@ -905,6 +981,8 @@
|
|
| 905 |
// After stream ends, convert to rendered Markdown
|
| 906 |
botBubble.textContent = '';
|
| 907 |
botBubble.innerHTML = marked.parse(fullText);
|
|
|
|
|
|
|
| 908 |
|
| 909 |
} catch (err) {
|
| 910 |
if (err.name !== 'AbortError') {
|
|
@@ -952,19 +1030,19 @@
|
|
| 952 |
draftItems.innerHTML = '';
|
| 953 |
items.forEach(item => {
|
| 954 |
draftItems.innerHTML += `
|
| 955 |
-
<div class="flex items-center justify-between text-xs bg-bazaar-900/70 px-
|
| 956 |
<span class="text-cream font-bold flex items-center gap-2">
|
| 957 |
-
<span class="w-1 h-
|
| 958 |
-
${escapeHtml(item.name)}
|
| 959 |
</span>
|
| 960 |
-
<span class="text-ochre-light bg-ochre/10 px-2
|
| 961 |
×${item.quantity}
|
| 962 |
</span>
|
| 963 |
</div>
|
| 964 |
`;
|
| 965 |
});
|
| 966 |
panel.classList.remove('hidden');
|
| 967 |
-
|
| 968 |
}
|
| 969 |
|
| 970 |
async function confirmOrder() {
|
|
@@ -1002,12 +1080,12 @@
|
|
| 1002 |
|
| 1003 |
if (role === 'user') {
|
| 1004 |
html = `
|
| 1005 |
-
<div class="flex justify-end gap-2
|
| 1006 |
-
<div class="bg-gradient-to-br from-rug/20 to-rug-dark/30 border border-rug/30 text-cream text-xs rounded-2xl rounded-tl-none px-3.5 py-2.5 leading-relaxed shadow-inner-soft">
|
| 1007 |
${escapeHtml(content)}
|
| 1008 |
</div>
|
| 1009 |
-
<div class="w-8 h-8 rounded-xl bg-gradient-to-br from-ochre/30 to-rug/20 border border-ochre/40 flex items-center justify-center flex-shrink-0">
|
| 1010 |
-
<svg class="w-4 h-4 text-ochre-light" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
| 1011 |
<path stroke-linecap="round" stroke-linejoin="round" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"/>
|
| 1012 |
</svg>
|
| 1013 |
</div>
|
|
@@ -1015,11 +1093,11 @@
|
|
| 1015 |
`;
|
| 1016 |
} else {
|
| 1017 |
html = `
|
| 1018 |
-
<div class="flex gap-2.5 max-w-[
|
| 1019 |
-
<div class="w-8 h-8 rounded-xl bg-gradient-to-br from-turk/20 to-azure-700/20 border border-turk/30 flex items-center justify-center flex-shrink-0">
|
| 1020 |
-
<span class="text-ochre-light font-display text-[11px]">ن</span>
|
| 1021 |
</div>
|
| 1022 |
-
<div id="${bubbleId}" class="bg-bazaar-950/70 border border-ochre/20 text-cream text-xs rounded-2xl rounded-tr-none px-3.5 py-2.5 leading-relaxed shadow-inner-soft chat-markdown">
|
| 1023 |
${content ? marked.parse(content) : ''}
|
| 1024 |
</div>
|
| 1025 |
</div>
|
|
@@ -1034,6 +1112,32 @@
|
|
| 1034 |
function escapeHtml(text) {
|
| 1035 |
return String(text).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''');
|
| 1036 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1037 |
</script>
|
| 1038 |
</body>
|
| 1039 |
</html>
|
|
|
|
| 2 |
<html lang="fa" dir="rtl">
|
| 3 |
<head>
|
| 4 |
<meta charset="UTF-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
|
| 6 |
+
<meta name="theme-color" content="#1a0d07">
|
| 7 |
<title>Cafe AI — کافه هوشمند تبریز</title>
|
| 8 |
|
| 9 |
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
|
|
| 22 |
display: ['Lalezar', 'serif'],
|
| 23 |
},
|
| 24 |
colors: {
|
|
|
|
| 25 |
bazaar: {
|
| 26 |
950: '#1a0d07',
|
| 27 |
900: '#2d1810',
|
|
|
|
| 75 |
'float': 'float 6s ease-in-out infinite',
|
| 76 |
'shimmer': 'shimmer 3s ease-in-out infinite',
|
| 77 |
'pulse-glow': 'pulseGlow 2.5s ease-in-out infinite',
|
| 78 |
+
'fade-in': 'fadeIn 0.35s ease-out',
|
| 79 |
},
|
| 80 |
keyframes: {
|
| 81 |
float: {
|
|
|
|
| 90 |
'0%, 100%': { boxShadow: '0 0 20px rgba(201, 169, 97, 0.3)' },
|
| 91 |
'50%': { boxShadow: '0 0 40px rgba(201, 169, 97, 0.6)' },
|
| 92 |
},
|
| 93 |
+
fadeIn: {
|
| 94 |
+
'0%': { opacity: '0', transform: 'translateY(8px)' },
|
| 95 |
+
'100%': { opacity: '1', transform: 'translateY(0)' },
|
| 96 |
+
},
|
| 97 |
},
|
| 98 |
}
|
| 99 |
}
|
|
|
|
| 103 |
<style>
|
| 104 |
:root {
|
| 105 |
--pattern-url: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='80' height='80' viewBox='0 0 80 80'%3E%3Cg fill='none' stroke='%23c9a961' stroke-width='0.6' opacity='0.08'%3E%3Cpath d='M40 10 L50 20 L60 10 L70 20 L60 30 L70 40 L60 50 L70 60 L60 70 L50 60 L40 70 L30 60 L20 70 L10 60 L20 50 L10 40 L20 30 L10 20 L20 10 L30 20 Z'/%3E%3Ccircle cx='40' cy='40' r='12'/%3E%3Ccircle cx='40' cy='40' r='6'/%3E%3Cpath d='M40 28 L40 52 M28 40 L52 40'/%3E%3C/g%3E%3C/svg%3E");
|
| 106 |
+
--vh: 1vh;
|
| 107 |
}
|
| 108 |
|
| 109 |
+
html {
|
| 110 |
+
scroll-behavior: smooth;
|
| 111 |
+
height: 100%;
|
| 112 |
+
overflow: hidden;
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
+
html, body {
|
| 116 |
+
overscroll-behavior: none;
|
| 117 |
+
-webkit-overflow-scrolling: touch;
|
| 118 |
+
}
|
| 119 |
|
| 120 |
body {
|
| 121 |
background-color: #1a0d07;
|
| 122 |
color: #f5e6d3;
|
| 123 |
-webkit-tap-highlight-color: transparent;
|
| 124 |
font-feature-settings: "ss01", "cv01";
|
| 125 |
+
height: 100%;
|
| 126 |
+
overflow: hidden;
|
| 127 |
+
position: fixed;
|
| 128 |
+
inset: 0;
|
| 129 |
+
width: 100%;
|
| 130 |
+
}
|
| 131 |
+
|
| 132 |
+
/* Fix for iOS 100dvh */
|
| 133 |
+
@supports (height: 100dvh) {
|
| 134 |
+
body { height: 100dvh; }
|
| 135 |
}
|
| 136 |
|
| 137 |
.bg-pattern {
|
|
|
|
| 150 |
|
| 151 |
/* Scrollbar */
|
| 152 |
::-webkit-scrollbar { width: 6px; height: 6px; }
|
| 153 |
+
::-webkit-scrollbar-track { background: transparent; }
|
| 154 |
::-webkit-scrollbar-thumb {
|
| 155 |
background: linear-gradient(180deg, #c9a961, #8b1e3f);
|
| 156 |
border-radius: 4px;
|
| 157 |
}
|
| 158 |
::-webkit-scrollbar-thumb:hover { background: linear-gradient(180deg, #e4c97a, #c23d5f); }
|
| 159 |
|
|
|
|
| 160 |
.glass-card {
|
| 161 |
background: linear-gradient(135deg, rgba(45, 24, 16, 0.82) 0%, rgba(26, 13, 7, 0.78) 100%);
|
| 162 |
backdrop-filter: blur(20px);
|
|
|
|
| 182 |
position: relative;
|
| 183 |
background: linear-gradient(145deg, rgba(139, 30, 63, 0.15), rgba(90, 16, 40, 0.25));
|
| 184 |
border: 1px solid rgba(201, 169, 97, 0.25);
|
| 185 |
+
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
| 186 |
overflow: hidden;
|
| 187 |
+
-webkit-user-select: none;
|
| 188 |
+
user-select: none;
|
| 189 |
}
|
| 190 |
.table-btn::before {
|
| 191 |
content: '';
|
|
|
|
| 194 |
border: 1px dashed rgba(201, 169, 97, 0.2);
|
| 195 |
border-radius: inherit;
|
| 196 |
pointer-events: none;
|
| 197 |
+
transition: all 0.3s ease;
|
| 198 |
}
|
| 199 |
+
.table-btn:hover, .table-btn:focus-visible {
|
| 200 |
+
transform: translateY(-3px) scale(1.02);
|
| 201 |
background: linear-gradient(145deg, rgba(194, 61, 95, 0.35), rgba(139, 30, 63, 0.45));
|
| 202 |
border-color: rgba(201, 169, 97, 0.6);
|
| 203 |
box-shadow:
|
| 204 |
+
0 15px 30px -8px rgba(139, 30, 63, 0.5),
|
| 205 |
0 0 0 1px rgba(201, 169, 97, 0.4),
|
| 206 |
inset 0 1px 0 rgba(244, 228, 163, 0.2);
|
| 207 |
}
|
| 208 |
+
.table-btn:hover::before, .table-btn:focus-visible::before {
|
| 209 |
border-color: rgba(201, 169, 97, 0.5);
|
| 210 |
inset: 6px;
|
| 211 |
}
|
| 212 |
+
.table-btn:active { transform: translateY(-1px) scale(1); }
|
| 213 |
|
| 214 |
/* Ornament divider */
|
| 215 |
.ornament-divider {
|
|
|
|
| 228 |
.ornament-divider::before { left: 0; }
|
| 229 |
.ornament-divider::after { right: 0; }
|
| 230 |
|
| 231 |
+
/* Chat Markdown Styles */
|
| 232 |
+
.chat-markdown { line-height: 1.85; word-wrap: break-word; overflow-wrap: break-word; }
|
| 233 |
.chat-markdown > * + * { margin-top: 0.6em; }
|
| 234 |
|
| 235 |
.chat-markdown h1, .chat-markdown h2, .chat-markdown h3,
|
|
|
|
| 270 |
color: #2dd4bf;
|
| 271 |
text-decoration: underline;
|
| 272 |
text-underline-offset: 3px;
|
|
|
|
| 273 |
}
|
|
|
|
| 274 |
|
| 275 |
.chat-markdown code {
|
| 276 |
background: rgba(13, 148, 136, 0.18);
|
|
|
|
| 330 |
border-radius: 8px;
|
| 331 |
overflow: hidden;
|
| 332 |
border: 1px solid rgba(201, 169, 97, 0.25);
|
| 333 |
+
display: block;
|
| 334 |
+
overflow-x: auto;
|
| 335 |
}
|
| 336 |
.chat-markdown thead {
|
| 337 |
background: linear-gradient(90deg, rgba(139, 30, 63, 0.4), rgba(201, 169, 97, 0.2));
|
|
|
|
| 349 |
border-bottom: 1px solid rgba(201, 169, 97, 0.1);
|
| 350 |
}
|
| 351 |
.chat-markdown tr:last-child td { border-bottom: none; }
|
|
|
|
| 352 |
|
| 353 |
.chat-markdown img {
|
| 354 |
max-width: 100%;
|
|
|
|
| 361 |
text-shadow: 0 0 10px rgba(201, 169, 97, 0.8), 0 0 20px rgba(201, 169, 97, 0.4);
|
| 362 |
}
|
| 363 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 364 |
/* Decorative frame */
|
| 365 |
+
.arch-shape {
|
| 366 |
+
border-radius: 50% 50% 1rem 1rem / 35% 35% 1rem 1rem;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 367 |
}
|
| 368 |
|
| 369 |
/* Button primary */
|
|
|
|
| 411 |
30% { transform: translateY(-8px); opacity: 1; }
|
| 412 |
}
|
| 413 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 414 |
/* Input focus */
|
| 415 |
input:focus {
|
| 416 |
outline: none;
|
| 417 |
+
border-color: rgba(201, 169, 97, 0.6) !important;
|
| 418 |
box-shadow: 0 0 0 3px rgba(201, 169, 97, 0.15);
|
| 419 |
}
|
| 420 |
|
| 421 |
+
/* Safe area padding for iOS */
|
| 422 |
+
.safe-bottom {
|
| 423 |
+
padding-bottom: env(safe-area-inset-bottom);
|
| 424 |
+
}
|
| 425 |
+
|
| 426 |
+
/* View container */
|
| 427 |
+
.view-container {
|
| 428 |
+
position: fixed;
|
| 429 |
+
inset: 0;
|
| 430 |
+
display: flex;
|
| 431 |
+
flex-direction: column;
|
| 432 |
+
overflow: hidden;
|
| 433 |
+
}
|
| 434 |
+
|
| 435 |
+
/* Scrollable areas */
|
| 436 |
+
.scroll-area {
|
| 437 |
+
overflow-y: auto;
|
| 438 |
+
overflow-x: hidden;
|
| 439 |
+
overscroll-behavior: contain;
|
| 440 |
+
-webkit-overflow-scrolling: touch;
|
| 441 |
+
}
|
| 442 |
+
|
| 443 |
+
/* Mobile chat input adjustments */
|
| 444 |
@media (max-width: 640px) {
|
| 445 |
+
.chat-input-area {
|
| 446 |
+
padding-bottom: calc(0.75rem + env(safe-area-inset-bottom));
|
| 447 |
+
}
|
| 448 |
+
.chat-markdown { font-size: 0.95rem; }
|
| 449 |
+
}
|
| 450 |
+
|
| 451 |
+
/* Landscape mobile */
|
| 452 |
+
@media (max-height: 500px) and (orientation: landscape) {
|
| 453 |
+
.hero-title { font-size: 2.5rem !important; }
|
| 454 |
+
.hero-logo { width: 60px !important; height: 60px !important; }
|
| 455 |
+
}
|
| 456 |
+
|
| 457 |
+
/* Prevent text selection on buttons */
|
| 458 |
+
button, .no-select {
|
| 459 |
+
-webkit-user-select: none;
|
| 460 |
+
user-select: none;
|
| 461 |
+
}
|
| 462 |
+
|
| 463 |
+
/* Hide view cleanly */
|
| 464 |
+
.view-hidden {
|
| 465 |
+
display: none !important;
|
| 466 |
+
}
|
| 467 |
+
|
| 468 |
+
/* Show view with animation */
|
| 469 |
+
.view-visible {
|
| 470 |
+
display: flex !important;
|
| 471 |
+
animation: fadeIn 0.35s ease-out;
|
| 472 |
+
}
|
| 473 |
+
|
| 474 |
+
/* Small mobile tables grid */
|
| 475 |
+
@media (max-width: 480px) {
|
| 476 |
+
.tables-grid-mobile {
|
| 477 |
+
grid-template-columns: repeat(4, 1fr);
|
| 478 |
+
gap: 0.5rem;
|
| 479 |
+
}
|
| 480 |
}
|
| 481 |
</style>
|
| 482 |
</head>
|
| 483 |
+
<body class="font-sans selection:bg-ochre selection:text-bazaar-950 antialiased">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 484 |
|
| 485 |
<!-- ============ VIEW 1: TABLE SELECTION ============ -->
|
| 486 |
+
<section id="view-table-selection" class="view-container view-visible">
|
| 487 |
|
| 488 |
+
<!-- Ambient Background -->
|
| 489 |
+
<div class="absolute inset-0 overflow-hidden pointer-events-none z-0">
|
| 490 |
+
<div class="absolute inset-0 bg-gradient-to-br from-bazaar-950 via-bazaar-900 to-azure-950"></div>
|
| 491 |
+
<div class="absolute inset-0 bg-pattern opacity-40"></div>
|
| 492 |
+
<div class="absolute -top-40 -right-40 w-[600px] h-[600px] rounded-full bg-rug/10 blur-[140px] animate-float"></div>
|
| 493 |
+
<div class="absolute -bottom-40 -left-40 w-[600px] h-[600px] rounded-full bg-turk/10 blur-[140px] animate-float" style="animation-delay: -3s;"></div>
|
| 494 |
+
<div class="absolute top-1/3 left-1/4 w-[400px] h-[400px] rounded-full bg-ochre/8 blur-[120px] animate-shimmer"></div>
|
| 495 |
+
</div>
|
| 496 |
|
| 497 |
+
<!-- Scrollable wrapper -->
|
| 498 |
+
<div class="scroll-area flex-1 relative z-10 flex flex-col min-h-0">
|
| 499 |
+
|
| 500 |
+
<!-- Hero Header -->
|
| 501 |
+
<header class="px-4 pt-6 pb-3 md:pt-10 md:pb-4 text-center relative flex-shrink-0">
|
| 502 |
+
<div class="max-w-4xl mx-auto">
|
| 503 |
+
|
| 504 |
+
<div class="inline-flex items-center gap-4 mb-4 animate-float">
|
| 505 |
+
<div class="relative">
|
| 506 |
+
<div class="hero-logo w-16 h-16 md:w-20 md:h-20 arch-shape bg-gradient-to-br from-rug via-rug-dark to-bazaar-900 border-2 border-ochre/60 flex items-center justify-center shadow-carpet">
|
| 507 |
+
<svg class="w-8 h-8 md:w-10 md:h-10 text-ochre-light" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8">
|
| 508 |
+
<path d="M17 8h1a4 4 0 1 1 0 8h-1" stroke-linecap="round"/>
|
| 509 |
+
<path d="M3 8h14v9a4 4 0 0 1-4 4H7a4 4 0 0 1-4-4Z" stroke-linecap="round"/>
|
| 510 |
+
<line x1="6" y1="2" x2="6" y2="4" stroke-linecap="round"/>
|
| 511 |
+
<line x1="10" y1="2" x2="10" y2="4" stroke-linecap="round"/>
|
| 512 |
+
<line x1="14" y1="2" x2="14" y2="4" stroke-linecap="round"/>
|
| 513 |
+
<path d="M7 13h6" stroke-linecap="round" opacity="0.6"/>
|
| 514 |
+
</svg>
|
| 515 |
+
</div>
|
| 516 |
+
<div class="absolute -bottom-1 -right-1 w-5 h-5 rounded-full bg-turk border-2 border-ochre animate-pulse-glow"></div>
|
| 517 |
</div>
|
|
|
|
| 518 |
</div>
|
|
|
|
| 519 |
|
| 520 |
+
<h1 class="hero-title font-display text-4xl md:text-6xl text-ochre-light mb-2 tracking-wide drop-shadow-lg">
|
| 521 |
+
کافه آی
|
| 522 |
+
</h1>
|
| 523 |
+
<div class="ornament-divider inline-block mb-3">
|
| 524 |
+
<span class="px-4 text-ochre/80 text-sm font-display tracking-widest">✦ تبریز ✦</span>
|
| 525 |
+
</div>
|
| 526 |
+
<p class="text-cream/90 text-sm md:text-base max-w-xl mx-auto leading-relaxed font-light px-2">
|
| 527 |
+
دستیار هوشمند سفارش، با الهام از <span class="text-turk-light font-semibold">کاشیکاریهای مسجد کبود</span>
|
| 528 |
+
و گرمای <span class="text-rug-light font-semibold">بازار سرپوشیده</span>
|
| 529 |
+
</p>
|
| 530 |
</div>
|
| 531 |
+
</header>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 532 |
|
| 533 |
+
<!-- Table Selection Grid -->
|
| 534 |
+
<main class="flex-1 px-4 md:px-8 pb-4 relative min-h-0">
|
| 535 |
+
<div class="max-w-5xl mx-auto">
|
| 536 |
|
| 537 |
+
<div class="glass-card rounded-3xl p-4 md:p-6 mb-4 relative overflow-hidden">
|
| 538 |
+
<div class="absolute inset-0 bg-arch opacity-30 pointer-events-none"></div>
|
|
|
|
| 539 |
|
| 540 |
+
<div class="relative">
|
| 541 |
+
<div class="flex items-center justify-between mb-4 flex-wrap gap-2">
|
| 542 |
+
<div class="flex items-center gap-2.5">
|
| 543 |
+
<div class="w-9 h-9 rounded-xl bg-ochre/15 border border-ochre/30 flex items-center justify-center flex-shrink-0">
|
| 544 |
+
<svg class="w-5 h-5 text-ochre-light" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
| 545 |
+
<path stroke-linecap="round" stroke-linejoin="round" d="M3 10h18M3 14h18m-9-4v8m-7 0h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z"/>
|
| 546 |
+
</svg>
|
| 547 |
+
</div>
|
| 548 |
+
<div>
|
| 549 |
+
<h2 class="font-display text-xl md:text-2xl text-ochre-light">شماره میز خود را برگزینید</h2>
|
| 550 |
+
<p class="text-[10px] text-cream/60 mt-0.5">با انتخاب میز، دستیار نیلا در خدمت شماست</p>
|
| 551 |
+
</div>
|
| 552 |
</div>
|
| 553 |
+
<div class="flex items-center gap-2 px-2.5 py-1 rounded-full bg-turk/10 border border-turk/30 text-[10px]">
|
| 554 |
+
<span class="w-1.5 h-1.5 rounded-full bg-turk-light animate-pulse"></span>
|
| 555 |
+
<span class="text-turk-light font-medium">۲۰ میز آماده</span>
|
| 556 |
</div>
|
| 557 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 558 |
|
| 559 |
+
<!-- 20 Tables Grid -->
|
| 560 |
+
<div id="tablesGrid" class="tables-grid-mobile grid grid-cols-4 sm:grid-cols-5 md:grid-cols-5 lg:grid-cols-10 gap-2 md:gap-3"></div>
|
|
|
|
|
|
|
| 561 |
|
| 562 |
+
<div class="mt-4 pt-3 border-t border-ochre/15 flex items-center justify-between text-[10px] text-cream/50 flex-wrap gap-1.5">
|
| 563 |
+
<span class="flex items-center gap-1.5">
|
| 564 |
+
<svg class="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
| 565 |
+
<path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
|
| 566 |
+
</svg>
|
| 567 |
+
با لمس هر میز، به گپ هوشمند منتقل میشوید
|
| 568 |
+
</span>
|
| 569 |
+
<span>طراحی با عشق از تبریز 🏛️</span>
|
| 570 |
+
</div>
|
| 571 |
</div>
|
| 572 |
</div>
|
|
|
|
| 573 |
|
| 574 |
+
<!-- Info Cards -->
|
| 575 |
+
<div class="grid grid-cols-1 md:grid-cols-3 gap-3">
|
| 576 |
+
<div class="glass-card rounded-2xl p-4 relative overflow-hidden group">
|
| 577 |
+
<div class="absolute top-0 right-0 w-20 h-20 bg-rug/15 rounded-full blur-2xl group-hover:bg-rug/25 transition-all"></div>
|
| 578 |
+
<div class="relative">
|
| 579 |
+
<div class="w-9 h-9 rounded-lg bg-rug/20 border border-rug/40 flex items-center justify-center mb-2">
|
| 580 |
+
<svg class="w-5 h-5 text-rug-light" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
| 581 |
+
<path stroke-linecap="round" stroke-linejoin="round" d="M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z"/>
|
| 582 |
+
</svg>
|
| 583 |
+
</div>
|
| 584 |
+
<h3 class="font-display text-base text-ochre-light mb-1">گفتگوی هوشمند</h3>
|
| 585 |
+
<p class="text-[11px] text-cream/70 leading-relaxed">با نیلا به زبان طبیعی سفارش دهید</p>
|
| 586 |
</div>
|
|
|
|
|
|
|
| 587 |
</div>
|
|
|
|
| 588 |
|
| 589 |
+
<div class="glass-card rounded-2xl p-4 relative overflow-hidden group">
|
| 590 |
+
<div class="absolute top-0 right-0 w-20 h-20 bg-turk/15 rounded-full blur-2xl group-hover:bg-turk/25 transition-all"></div>
|
| 591 |
+
<div class="relative">
|
| 592 |
+
<div class="w-9 h-9 rounded-lg bg-turk/20 border border-turk/40 flex items-center justify-center mb-2">
|
| 593 |
+
<svg class="w-5 h-5 text-turk-light" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
| 594 |
+
<path stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"/>
|
| 595 |
+
</svg>
|
| 596 |
+
</div>
|
| 597 |
+
<h3 class="font-display text-base text-ochre-light mb-1">پیشنویس زنده</h3>
|
| 598 |
+
<p class="text-[11px] text-cream/70 leading-relaxed">سفارش قبل از ثبت نهایی، قابل ویرایش</p>
|
| 599 |
</div>
|
|
|
|
|
|
|
| 600 |
</div>
|
|
|
|
| 601 |
|
| 602 |
+
<div class="glass-card rounded-2xl p-4 relative overflow-hidden group">
|
| 603 |
+
<div class="absolute top-0 right-0 w-20 h-20 bg-ochre/15 rounded-full blur-2xl group-hover:bg-ochre/25 transition-all"></div>
|
| 604 |
+
<div class="relative">
|
| 605 |
+
<div class="w-9 h-9 rounded-lg bg-ochre/20 border border-ochre/40 flex items-center justify-center mb-2">
|
| 606 |
+
<svg class="w-5 h-5 text-ochre-light" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
| 607 |
+
<path stroke-linecap="round" stroke-linejoin="round" d="M13 10V3L4 14h7v7l9-11h-7z"/>
|
| 608 |
+
</svg>
|
| 609 |
+
</div>
|
| 610 |
+
<h3 class="font-display text-base text-ochre-light mb-1">ارسال آنی</h3>
|
| 611 |
+
<p class="text-[11px] text-cream/70 leading-relaxed">ارسال مستقیم به آشپزخانه</p>
|
| 612 |
</div>
|
|
|
|
|
|
|
| 613 |
</div>
|
| 614 |
</div>
|
| 615 |
</div>
|
| 616 |
+
</main>
|
|
|
|
| 617 |
|
| 618 |
+
<footer class="flex-shrink-0 border-t border-ochre/15 py-3 text-center text-[10px] text-cream/40 bg-bazaar-950/60 backdrop-blur safe-bottom">
|
| 619 |
+
طراحی و توسعه توسط الگوریتم داده نسترن | با الهام از فرهنگ تبریز © ۲۰۲۶
|
| 620 |
+
</footer>
|
| 621 |
+
</div>
|
| 622 |
</section>
|
| 623 |
|
| 624 |
|
| 625 |
<!-- ============ VIEW 2: CHAT ============ -->
|
| 626 |
+
<section id="view-chat" class="view-container view-hidden">
|
| 627 |
+
|
| 628 |
+
<!-- Ambient Background -->
|
| 629 |
+
<div class="absolute inset-0 overflow-hidden pointer-events-none z-0">
|
| 630 |
+
<div class="absolute inset-0 bg-gradient-to-br from-bazaar-950 via-bazaar-900 to-azure-950"></div>
|
| 631 |
+
<div class="absolute inset-0 bg-pattern opacity-30"></div>
|
| 632 |
+
<div class="absolute -top-40 -right-40 w-[500px] h-[500px] rounded-full bg-rug/10 blur-[140px]"></div>
|
| 633 |
+
<div class="absolute -bottom-40 -left-40 w-[500px] h-[500px] rounded-full bg-turk/10 blur-[140px]"></div>
|
| 634 |
+
</div>
|
| 635 |
+
|
| 636 |
+
<!-- Header -->
|
| 637 |
+
<header class="flex-shrink-0 border-b border-ochre/20 bg-bazaar-900/70 backdrop-blur-2xl z-20 px-3 py-2.5 md:px-6 md:py-3 shadow-lg">
|
| 638 |
+
<div class="max-w-5xl mx-auto flex items-center justify-between gap-2">
|
| 639 |
+
<div class="flex items-center gap-2 min-w-0">
|
| 640 |
+
<button onclick="backToTables()" class="p-2 text-ochre/70 hover:text-ochre-light transition-colors rounded-lg hover:bg-bazaar-800/50 flex-shrink-0"
|
| 641 |
title="بازگشت به انتخاب میز">
|
| 642 |
<svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
| 643 |
+
<path stroke-linecap="round" stroke-linejoin="round" d="M9 5l7 7-7 7"/>
|
| 644 |
</svg>
|
| 645 |
</button>
|
| 646 |
+
<div class="w-9 h-9 rounded-xl bg-gradient-to-br from-rug/30 to-ochre/15 border border-ochre/30 flex items-center justify-center shadow-carpet flex-shrink-0">
|
| 647 |
+
<svg class="w-5 h-5 text-ochre-light" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8">
|
| 648 |
<path d="M17 8h1a4 4 0 1 1 0 8h-1" stroke-linecap="round"/>
|
| 649 |
<path d="M3 8h14v9a4 4 0 0 1-4 4H7a4 4 0 0 1-4-4Z" stroke-linecap="round"/>
|
|
|
|
|
|
|
|
|
|
| 650 |
</svg>
|
| 651 |
</div>
|
| 652 |
+
<div class="min-w-0">
|
| 653 |
+
<h1 class="text-xs md:text-sm font-display text-ochre-light tracking-wide flex items-center gap-1.5 truncate">
|
| 654 |
+
<span class="text-rug-light flex-shrink-0">Cafe AI</span>
|
| 655 |
+
<span class="text-cream/40 flex-shrink-0">|</span>
|
| 656 |
+
<span class="text-cream/80 text-[10px] md:text-xs font-sans font-normal truncate">کافه هوشمند تبریز</span>
|
| 657 |
</h1>
|
| 658 |
</div>
|
| 659 |
</div>
|
| 660 |
|
| 661 |
+
<!-- Table number -->
|
| 662 |
+
<div class="flex items-center gap-1.5 flex-shrink-0">
|
| 663 |
+
<div class="flex items-center gap-1.5 px-3 py-1.5 rounded-full bg-bazaar-950/70 border border-ochre/30 shadow-inner-gold">
|
| 664 |
+
<svg class="w-3.5 h-3.5 text-ochre flex-shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
| 665 |
<path stroke-linecap="round" stroke-linejoin="round" d="M3 10h18M3 14h18m-9-4v8m-7 0h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z"/>
|
| 666 |
</svg>
|
| 667 |
+
<span class="text-[10px] text-cream/60">میز</span>
|
| 668 |
+
<span id="tableNumberDisplay" class="text-base md:text-lg font-display text-ochre-light table-number-glow">---</span>
|
| 669 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 670 |
</div>
|
| 671 |
</div>
|
| 672 |
</header>
|
| 673 |
|
| 674 |
<!-- Main content -->
|
| 675 |
+
<main class="flex-1 flex flex-col min-h-0 p-2.5 md:p-4 lg:p-6 z-10 relative gap-3 overflow-hidden">
|
| 676 |
+
<div class="max-w-5xl w-full mx-auto flex-1 flex flex-col min-h-0 gap-3">
|
| 677 |
+
|
| 678 |
+
<!-- Draft order panel -->
|
| 679 |
+
<div id="draftOrderPanel" class="glass-card rounded-2xl p-3 md:p-4 hidden transition-all duration-300 relative overflow-hidden flex-shrink-0">
|
| 680 |
+
<div class="absolute inset-0 bg-pattern-fine opacity-30 pointer-events-none"></div>
|
| 681 |
+
<div class="relative">
|
| 682 |
+
<div class="flex items-center justify-between border-b border-ochre/25 pb-2 mb-2">
|
| 683 |
+
<h3 class="text-sm md:text-base font-display text-ochre-light flex items-center gap-2 tracking-wide">
|
| 684 |
+
<svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
| 685 |
+
<path stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"/>
|
| 686 |
+
</svg>
|
| 687 |
+
پیشنویس سفارش · میز <span id="draftTableNumber" class="text-rug-light">---</span>
|
| 688 |
+
</h3>
|
| 689 |
+
<span class="text-[9px] md:text-[10px] text-turk/70 bg-turk/10 px-2 py-1 rounded-md border border-turk/20">
|
| 690 |
+
جهت تأیید نهایی
|
| 691 |
+
</span>
|
| 692 |
+
</div>
|
| 693 |
+
<div id="draftItems" class="space-y-1.5 mb-3 max-h-40 overflow-y-auto scroll-area"></div>
|
| 694 |
+
<button id="confirmOrderBtn" onclick="confirmOrder()"
|
| 695 |
+
class="btn-primary w-full py-2.5 md:py-3 rounded-xl text-xs md:text-sm transition-all flex items-center justify-center gap-2">
|
| 696 |
+
<svg class="w-4 h-4 md:w-5 md:h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2.5">
|
| 697 |
+
<path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/>
|
| 698 |
</svg>
|
| 699 |
+
تأیید نهایی و ارسال به آشپزخانه
|
| 700 |
+
</button>
|
|
|
|
|
|
|
|
|
|
| 701 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 702 |
</div>
|
|
|
|
| 703 |
|
| 704 |
+
<!-- Chat card -->
|
| 705 |
+
<div class="flex-1 flex flex-col glass-card-azure rounded-2xl md:rounded-3xl overflow-hidden shadow-xl min-h-0 relative">
|
| 706 |
+
<!-- Decorative pattern -->
|
| 707 |
+
<div class="absolute inset-0 bg-arch opacity-20 pointer-events-none"></div>
|
| 708 |
+
|
| 709 |
+
<!-- Chat header -->
|
| 710 |
+
<div class="relative flex-shrink-0 px-3.5 py-2.5 md:px-5 md:py-3 border-b border-turk/25 flex items-center gap-2.5 bg-gradient-to-l from-azure-950/60 to-azure-900/40">
|
| 711 |
+
<div class="w-9 h-9 md:w-10 md:h-10 rounded-xl bg-gradient-to-br from-turk/30 to-azure-700/30 border border-turk/40 flex items-center justify-center shadow-mosque flex-shrink-0">
|
| 712 |
+
<svg class="w-5 h-5 md:w-6 md:h-6 text-turk-glow" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8">
|
| 713 |
+
<circle cx="12" cy="8" r="4"/>
|
| 714 |
+
<path d="M5 20v-1a7 7 0 0114 0v1" stroke-linecap="round"/>
|
| 715 |
+
<path d="M9 10l2 2 4-4" stroke-linecap="round" stroke-linejoin="round" opacity="0.7"/>
|
| 716 |
+
</svg>
|
| 717 |
+
</div>
|
| 718 |
+
<div class="min-w-0">
|
| 719 |
+
<h3 class="text-xs md:text-sm font-display text-ochre-light tracking-wide">نیلا، دستیار کافه</h3>
|
| 720 |
+
<p class="text-[9px] md:text-[10px] text-turk-light/80 font-medium flex items-center gap-1.5">
|
| 721 |
+
<span class="w-1.5 h-1.5 rounded-full bg-turk-light animate-pulse"></span>
|
| 722 |
+
<span class="truncate">برای سفارش از منو، با من گفتگو کنید ☕️</span>
|
| 723 |
+
</p>
|
| 724 |
+
</div>
|
| 725 |
</div>
|
|
|
|
| 726 |
|
| 727 |
+
<!-- Chat messages area -->
|
| 728 |
+
<div id="chatMessages" class="relative flex-1 overflow-y-auto scroll-area p-3 md:p-4 space-y-3 min-h-0">
|
| 729 |
+
<div class="flex gap-2.5 max-w-[88%]">
|
| 730 |
+
<div class="w-7 h-7 md:w-8 md:h-8 rounded-xl bg-gradient-to-br from-turk/20 to-azure-700/20 border border-turk/30 flex items-center justify-center flex-shrink-0">
|
| 731 |
+
<span class="text-ochre-light font-display text-[10px] md:text-[11px]">ن</span>
|
| 732 |
+
</div>
|
| 733 |
+
<div class="bg-bazaar-950/70 border border-ochre/20 text-cream text-xs md:text-sm rounded-2xl rounded-tr-none px-3 py-2 md:px-3.5 md:py-2.5 leading-relaxed shadow-inner-soft chat-markdown">
|
| 734 |
+
سلام! من <strong>نیلا</strong> هستم، دستیار هوشمند کافه آی. به میزتون خوش اومدید 🌸<br>
|
| 735 |
+
چه نوشیدنی، غذا یا شیرینیای میپسندید؟ <em>منوی امروز</em> رو میتونم براتون بگم. 😊
|
| 736 |
+
</div>
|
| 737 |
</div>
|
| 738 |
</div>
|
|
|
|
| 739 |
|
| 740 |
+
<!-- Chat loader -->
|
| 741 |
+
<div id="chatLoader" class="hidden relative flex-shrink-0 px-3 py-2 md:px-4 md:py-2.5 flex items-center justify-between bg-azure-950/70 text-[9px] md:text-[10px] text-turk-light font-semibold border-t border-turk/20">
|
| 742 |
+
<div class="flex items-center gap-2">
|
| 743 |
+
<div class="typing-dots flex gap-1">
|
| 744 |
+
<span></span><span></span><span></span>
|
| 745 |
+
</div>
|
| 746 |
+
<span>نیلا در حال فکر کردن...</span>
|
| 747 |
</div>
|
| 748 |
+
<button onclick="stopGeneration()" class="px-2.5 py-1 md:px-3 md:py-1.5 bg-rug-dark/40 border border-rug/40 hover:bg-rug/40 rounded-lg text-[9px] md:text-[10px] text-rug-light font-bold transition-all">
|
| 749 |
+
توقف
|
| 750 |
+
</button>
|
| 751 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
| 752 |
|
| 753 |
+
<!-- Chat input -->
|
| 754 |
+
<form id="chatForm" onsubmit="sendCustomerMessage(event)" class="relative flex-shrink-0 p-2 md:p-3 border-t border-turk/20 bg-bazaar-950/60 flex gap-2 chat-input-area safe-bottom">
|
| 755 |
+
<input type="text" id="chatInput" placeholder="پیام خود را بنویسید..." autocomplete="off"
|
| 756 |
+
class="flex-1 min-w-0 bg-azure-950/60 border border-azure-700/40 text-xs md:text-sm text-cream placeholder-ochre/40 rounded-xl px-3.5 py-2.5 md:py-3 focus:outline-none focus:border-ochre/60 transition-all duration-300">
|
| 757 |
+
<button type="submit" id="sendBtn" class="btn-primary px-3.5 md:px-4 py-2.5 md:py-3 rounded-xl text-xs flex items-center justify-center flex-shrink-0">
|
| 758 |
+
<svg class="w-4 h-4 md:w-5 md:h-5 rotate-180" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2.5">
|
| 759 |
+
<path stroke-linecap="round" stroke-linejoin="round" d="M14 5l7 7m0 0l-7 7m7-7H3"/>
|
| 760 |
+
</svg>
|
| 761 |
+
</button>
|
| 762 |
+
</form>
|
| 763 |
+
</div>
|
| 764 |
</div>
|
| 765 |
</main>
|
|
|
|
|
|
|
|
|
|
|
|
|
| 766 |
</section>
|
| 767 |
|
| 768 |
<script>
|
| 769 |
+
// ------------------- Viewport Height Fix (iOS) -------------------
|
| 770 |
+
function setVh() {
|
| 771 |
+
const vh = window.innerHeight * 0.01;
|
| 772 |
+
document.documentElement.style.setProperty('--vh', `${vh}px`);
|
| 773 |
+
}
|
| 774 |
+
setVh();
|
| 775 |
+
window.addEventListener('resize', setVh);
|
| 776 |
+
window.addEventListener('orientationchange', () => setTimeout(setVh, 100));
|
| 777 |
+
|
| 778 |
// ------------------- Configuration -------------------
|
| 779 |
let currentTable = "{{ table_number }}" !== "None" && "{{ table_number }}" !== "" ? "{{ table_number }}" : null;
|
| 780 |
let abortController = null;
|
|
|
|
| 787 |
window.addEventListener('DOMContentLoaded', () => {
|
| 788 |
renderTablesGrid();
|
| 789 |
if (currentTable && currentTable.trim() !== '') {
|
| 790 |
+
// Direct URL access with table number
|
| 791 |
+
enterChatView(currentTable, false);
|
| 792 |
}
|
| 793 |
});
|
| 794 |
|
| 795 |
+
// Prevent body scroll bounce on iOS
|
| 796 |
+
document.addEventListener('touchmove', function(e) {
|
| 797 |
+
if (!e.target.closest('.scroll-area')) {
|
| 798 |
+
e.preventDefault();
|
| 799 |
+
}
|
| 800 |
+
}, { passive: false });
|
| 801 |
+
|
| 802 |
// ------------------- View Management -------------------
|
| 803 |
function switchView(targetView) {
|
| 804 |
const sel = document.getElementById('view-table-selection');
|
| 805 |
const chat = document.getElementById('view-chat');
|
| 806 |
+
|
| 807 |
if (targetView === 'chat') {
|
| 808 |
sel.classList.remove('view-visible');
|
| 809 |
sel.classList.add('view-hidden');
|
|
|
|
| 815 |
sel.classList.remove('view-hidden');
|
| 816 |
sel.classList.add('view-visible');
|
| 817 |
}
|
| 818 |
+
|
| 819 |
+
// Reset scroll positions
|
| 820 |
+
window.scrollTo(0, 0);
|
| 821 |
+
const tablesScroll = sel.querySelector('.scroll-area');
|
| 822 |
+
if (tablesScroll) tablesScroll.scrollTop = 0;
|
| 823 |
+
const chatScroll = document.getElementById('chatMessages');
|
| 824 |
+
if (chatScroll && targetView === 'chat') {
|
| 825 |
+
// Scroll chat to bottom when entering
|
| 826 |
+
setTimeout(() => {
|
| 827 |
+
chatScroll.scrollTop = chatScroll.scrollHeight;
|
| 828 |
+
}, 100);
|
| 829 |
+
}
|
| 830 |
}
|
| 831 |
|
| 832 |
+
function enterChatView(tableNumber, updateUrl = true) {
|
| 833 |
currentTable = tableNumber;
|
| 834 |
updateTableNumberDisplay(tableNumber);
|
| 835 |
+
if (updateUrl) {
|
| 836 |
+
window.history.replaceState(null, '', `/customer/${tableNumber}`);
|
| 837 |
+
}
|
| 838 |
switchView('chat');
|
| 839 |
initializeChatSession(tableNumber);
|
| 840 |
+
setTimeout(() => {
|
| 841 |
+
const input = document.getElementById('chatInput');
|
| 842 |
+
if (input && window.innerWidth > 768) input.focus();
|
| 843 |
+
}, 400);
|
| 844 |
}
|
| 845 |
|
| 846 |
function backToTables() {
|
|
|
|
| 858 |
grid.innerHTML = '';
|
| 859 |
for (let i = 1; i <= TOTAL_TABLES; i++) {
|
| 860 |
const btn = document.createElement('button');
|
| 861 |
+
btn.className = 'table-btn arch-shape aspect-[3/4] flex flex-col items-center justify-center gap-0.5 p-1.5 md:p-2 group focus:outline-none';
|
| 862 |
btn.innerHTML = `
|
| 863 |
+
<svg class="w-3.5 h-3.5 md:w-4 md:h-4 text-ochre/60 group-hover:text-ochre-light transition-colors" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.8">
|
| 864 |
<path stroke-linecap="round" stroke-linejoin="round" d="M3 10h18M3 14h18m-9-4v8m-7 0h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z"/>
|
| 865 |
</svg>
|
| 866 |
+
<span class="font-display text-xl md:text-2xl lg:text-3xl text-ochre-light group-hover:text-ochre-pale transition-colors leading-none">${i}</span>
|
| 867 |
+
<span class="text-[8px] md:text-[9px] text-cream/50 group-hover:text-cream/80 transition-colors tracking-wide">میز</span>
|
| 868 |
`;
|
| 869 |
btn.onclick = () => enterChatView(String(i));
|
| 870 |
grid.appendChild(btn);
|
|
|
|
| 899 |
function appendInitialGreeting() {
|
| 900 |
const container = document.getElementById('chatMessages');
|
| 901 |
container.innerHTML = `
|
| 902 |
+
<div class="flex gap-2.5 max-w-[88%]">
|
| 903 |
+
<div class="w-7 h-7 md:w-8 md:h-8 rounded-xl bg-gradient-to-br from-turk/20 to-azure-700/20 border border-turk/30 flex items-center justify-center flex-shrink-0">
|
| 904 |
+
<span class="text-ochre-light font-display text-[10px] md:text-[11px]">ن</span>
|
| 905 |
</div>
|
| 906 |
+
<div class="bg-bazaar-950/70 border border-ochre/20 text-cream text-xs md:text-sm rounded-2xl rounded-tr-none px-3 py-2 md:px-3.5 md:py-2.5 leading-relaxed shadow-inner-soft chat-markdown">
|
| 907 |
سلام! من <strong>نیلا</strong> هستم، دستیار هوشمند کافه آی. به میزتون خوش اومدید 🌸<br>
|
| 908 |
چه نوشیدنی، غذا یا شیرینیای میپسندید؟ <em>منوی امروز</em> رو میتونم براتون بگم. 😊
|
| 909 |
</div>
|
|
|
|
| 965 |
if (data.type === 'text') {
|
| 966 |
fullText += data.content;
|
| 967 |
botBubble.textContent = fullText;
|
| 968 |
+
const chatScroll = document.getElementById('chatMessages');
|
| 969 |
+
chatScroll.scrollTop = chatScroll.scrollHeight;
|
| 970 |
} else if (data.type === 'draft') {
|
| 971 |
currentDraft = data.items;
|
| 972 |
showDraftPanel(currentDraft);
|
|
|
|
| 981 |
// After stream ends, convert to rendered Markdown
|
| 982 |
botBubble.textContent = '';
|
| 983 |
botBubble.innerHTML = marked.parse(fullText);
|
| 984 |
+
const chatScroll = document.getElementById('chatMessages');
|
| 985 |
+
chatScroll.scrollTop = chatScroll.scrollHeight;
|
| 986 |
|
| 987 |
} catch (err) {
|
| 988 |
if (err.name !== 'AbortError') {
|
|
|
|
| 1030 |
draftItems.innerHTML = '';
|
| 1031 |
items.forEach(item => {
|
| 1032 |
draftItems.innerHTML += `
|
| 1033 |
+
<div class="flex items-center justify-between text-[11px] md:text-xs bg-bazaar-900/70 px-2.5 py-2 rounded-lg border border-ochre/20 group">
|
| 1034 |
<span class="text-cream font-bold flex items-center gap-2">
|
| 1035 |
+
<span class="w-1 h-5 bg-gradient-to-b from-rug to-ochre rounded-full flex-shrink-0"></span>
|
| 1036 |
+
<span class="truncate">${escapeHtml(item.name)}</span>
|
| 1037 |
</span>
|
| 1038 |
+
<span class="text-ochre-light bg-ochre/10 px-2 py-0.5 rounded-md font-display text-[10px] border border-ochre/25 flex-shrink-0 mr-2">
|
| 1039 |
×${item.quantity}
|
| 1040 |
</span>
|
| 1041 |
</div>
|
| 1042 |
`;
|
| 1043 |
});
|
| 1044 |
panel.classList.remove('hidden');
|
| 1045 |
+
// Don't scroll body - we're in flex layout
|
| 1046 |
}
|
| 1047 |
|
| 1048 |
async function confirmOrder() {
|
|
|
|
| 1080 |
|
| 1081 |
if (role === 'user') {
|
| 1082 |
html = `
|
| 1083 |
+
<div class="flex justify-end gap-2 max-w-[88%] mr-auto">
|
| 1084 |
+
<div class="bg-gradient-to-br from-rug/20 to-rug-dark/30 border border-rug/30 text-cream text-xs md:text-sm rounded-2xl rounded-tl-none px-3 py-2 md:px-3.5 md:py-2.5 leading-relaxed shadow-inner-soft break-words">
|
| 1085 |
${escapeHtml(content)}
|
| 1086 |
</div>
|
| 1087 |
+
<div class="w-7 h-7 md:w-8 md:h-8 rounded-xl bg-gradient-to-br from-ochre/30 to-rug/20 border border-ochre/40 flex items-center justify-center flex-shrink-0">
|
| 1088 |
+
<svg class="w-3.5 h-3.5 md:w-4 md:h-4 text-ochre-light" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
| 1089 |
<path stroke-linecap="round" stroke-linejoin="round" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"/>
|
| 1090 |
</svg>
|
| 1091 |
</div>
|
|
|
|
| 1093 |
`;
|
| 1094 |
} else {
|
| 1095 |
html = `
|
| 1096 |
+
<div class="flex gap-2.5 max-w-[88%]">
|
| 1097 |
+
<div class="w-7 h-7 md:w-8 md:h-8 rounded-xl bg-gradient-to-br from-turk/20 to-azure-700/20 border border-turk/30 flex items-center justify-center flex-shrink-0">
|
| 1098 |
+
<span class="text-ochre-light font-display text-[10px] md:text-[11px]">ن</span>
|
| 1099 |
</div>
|
| 1100 |
+
<div id="${bubbleId}" class="bg-bazaar-950/70 border border-ochre/20 text-cream text-xs md:text-sm rounded-2xl rounded-tr-none px-3 py-2 md:px-3.5 md:py-2.5 leading-relaxed shadow-inner-soft chat-markdown min-w-0 break-words" style="flex: 1; max-width: calc(100% - 2.5rem);">
|
| 1101 |
${content ? marked.parse(content) : ''}
|
| 1102 |
</div>
|
| 1103 |
</div>
|
|
|
|
| 1112 |
function escapeHtml(text) {
|
| 1113 |
return String(text).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''');
|
| 1114 |
}
|
| 1115 |
+
|
| 1116 |
+
// Handle mobile keyboard - scroll input into view
|
| 1117 |
+
const chatInput = document.getElementById('chatInput');
|
| 1118 |
+
if (chatInput) {
|
| 1119 |
+
chatInput.addEventListener('focus', () => {
|
| 1120 |
+
setTimeout(() => {
|
| 1121 |
+
const chatScroll = document.getElementById('chatMessages');
|
| 1122 |
+
if (chatScroll) {
|
| 1123 |
+
chatScroll.scrollTop = chatScroll.scrollHeight;
|
| 1124 |
+
}
|
| 1125 |
+
window.scrollTo(0, document.body.scrollHeight);
|
| 1126 |
+
}, 300);
|
| 1127 |
+
});
|
| 1128 |
+
}
|
| 1129 |
+
|
| 1130 |
+
// Handle viewport resize (e.g., keyboard show/hide on mobile)
|
| 1131 |
+
let initialHeight = window.innerHeight;
|
| 1132 |
+
window.addEventListener('resize', () => {
|
| 1133 |
+
setVh();
|
| 1134 |
+
const chatScroll = document.getElementById('chatMessages');
|
| 1135 |
+
if (chatScroll && document.getElementById('view-chat').classList.contains('view-visible')) {
|
| 1136 |
+
setTimeout(() => {
|
| 1137 |
+
chatScroll.scrollTop = chatScroll.scrollHeight;
|
| 1138 |
+
}, 100);
|
| 1139 |
+
}
|
| 1140 |
+
});
|
| 1141 |
</script>
|
| 1142 |
</body>
|
| 1143 |
</html>
|