Spaces:
Running
Running
Update customer.html
Browse files- customer.html +163 -172
customer.html
CHANGED
|
@@ -22,47 +22,12 @@
|
|
| 22 |
display: ['Lalezar', 'serif'],
|
| 23 |
},
|
| 24 |
colors: {
|
| 25 |
-
bazaar: {
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
500: '#9c6b4f',
|
| 32 |
-
400: '#b8856a',
|
| 33 |
-
300: '#d4a88c',
|
| 34 |
-
},
|
| 35 |
-
azure: {
|
| 36 |
-
950: '#051a2e',
|
| 37 |
-
900: '#0a2540',
|
| 38 |
-
800: '#123a5e',
|
| 39 |
-
700: '#1e4976',
|
| 40 |
-
600: '#2d6ca8',
|
| 41 |
-
500: '#3d8bc4',
|
| 42 |
-
400: '#6ba7d4',
|
| 43 |
-
300: '#a3c8e4',
|
| 44 |
-
},
|
| 45 |
-
turk: {
|
| 46 |
-
DEFAULT: '#0d9488',
|
| 47 |
-
light: '#2dd4bf',
|
| 48 |
-
glow: '#5eead4',
|
| 49 |
-
deep: '#134e4a',
|
| 50 |
-
},
|
| 51 |
-
rug: {
|
| 52 |
-
DEFAULT: '#8b1e3f',
|
| 53 |
-
light: '#c23d5f',
|
| 54 |
-
dark: '#5a1028',
|
| 55 |
-
glow: '#e85d7e',
|
| 56 |
-
},
|
| 57 |
-
ochre: {
|
| 58 |
-
DEFAULT: '#c9a961',
|
| 59 |
-
light: '#e4c97a',
|
| 60 |
-
dark: '#9c7d3a',
|
| 61 |
-
pale: '#f0dca3',
|
| 62 |
-
},
|
| 63 |
-
ivory: '#faf3e7',
|
| 64 |
-
cream: '#f5e6d3',
|
| 65 |
-
saffron: '#d97706',
|
| 66 |
},
|
| 67 |
boxShadow: {
|
| 68 |
'carpet': '0 10px 40px -10px rgba(139, 30, 63, 0.35), 0 0 0 1px rgba(201, 169, 97, 0.15)',
|
|
@@ -78,22 +43,10 @@
|
|
| 78 |
'fade-in': 'fadeIn 0.35s ease-out',
|
| 79 |
},
|
| 80 |
keyframes: {
|
| 81 |
-
float: {
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
},
|
| 85 |
-
shimmer: {
|
| 86 |
-
'0%, 100%': { opacity: '0.7' },
|
| 87 |
-
'50%': { opacity: '1' },
|
| 88 |
-
},
|
| 89 |
-
pulseGlow: {
|
| 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,21 +56,22 @@
|
|
| 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 |
}
|
| 107 |
|
| 108 |
* { box-sizing: border-box; }
|
| 109 |
|
| 110 |
-
html {
|
| 111 |
-
scroll-behavior: smooth;
|
| 112 |
height: 100%;
|
| 113 |
overflow: hidden;
|
| 114 |
-
}
|
| 115 |
-
|
| 116 |
-
html, body {
|
| 117 |
overscroll-behavior: none;
|
| 118 |
-webkit-overflow-scrolling: touch;
|
| 119 |
}
|
| 120 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 121 |
body {
|
| 122 |
background-color: #1a0d07;
|
| 123 |
color: #f5e6d3;
|
|
@@ -125,17 +79,10 @@
|
|
| 125 |
font-feature-settings: "ss01", "cv01";
|
| 126 |
margin: 0;
|
| 127 |
padding: 0;
|
| 128 |
-
height: 100vh;
|
| 129 |
-
height: 100dvh;
|
| 130 |
overflow: hidden;
|
| 131 |
-
position: fixed;
|
| 132 |
-
width: 100%;
|
| 133 |
}
|
| 134 |
|
| 135 |
-
.bg-pattern {
|
| 136 |
-
background-image: var(--pattern-url);
|
| 137 |
-
background-size: 80px 80px;
|
| 138 |
-
}
|
| 139 |
|
| 140 |
.bg-pattern-fine {
|
| 141 |
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40' viewBox='0 0 40 40'%3E%3Cg fill='none' stroke='%23c9a961' stroke-width='0.4' opacity='0.1'%3E%3Cpath d='M20 0 L20 40 M0 20 L40 20'/%3E%3Ccircle cx='20' cy='20' r='3'/%3E%3Ccircle cx='0' cy='0' r='2'/%3E%3Ccircle cx='40' cy='0' r='2'/%3E%3Ccircle cx='0' cy='40' r='2'/%3E%3Ccircle cx='40' cy='40' r='2'/%3E%3C/g%3E%3C/svg%3E");
|
|
@@ -152,6 +99,7 @@
|
|
| 152 |
background: linear-gradient(180deg, #c9a961, #8b1e3f);
|
| 153 |
border-radius: 4px;
|
| 154 |
}
|
|
|
|
| 155 |
|
| 156 |
.glass-card {
|
| 157 |
background: linear-gradient(135deg, rgba(45, 24, 16, 0.82) 0%, rgba(26, 13, 7, 0.78) 100%);
|
|
@@ -215,11 +163,8 @@
|
|
| 215 |
.chat-markdown > * + * { margin-top: 0.6em; }
|
| 216 |
.chat-markdown h1, .chat-markdown h2, .chat-markdown h3,
|
| 217 |
.chat-markdown h4, .chat-markdown h5, .chat-markdown h6 {
|
| 218 |
-
font-family: 'Lalezar', serif;
|
| 219 |
-
|
| 220 |
-
margin-top: 1em;
|
| 221 |
-
margin-bottom: 0.4em;
|
| 222 |
-
line-height: 1.3;
|
| 223 |
}
|
| 224 |
.chat-markdown h1 { font-size: 1.4em; }
|
| 225 |
.chat-markdown h2 { font-size: 1.25em; }
|
|
@@ -235,62 +180,45 @@
|
|
| 235 |
.chat-markdown em { color: #5eead4; font-style: italic; }
|
| 236 |
.chat-markdown a { color: #2dd4bf; text-decoration: underline; text-underline-offset: 3px; }
|
| 237 |
.chat-markdown code {
|
| 238 |
-
background: rgba(13, 148, 136, 0.18);
|
| 239 |
-
|
| 240 |
-
padding: 0.15em 0.4em;
|
| 241 |
-
border-radius: 5px;
|
| 242 |
-
font-size: 0.88em;
|
| 243 |
border: 1px solid rgba(45, 212, 191, 0.2);
|
| 244 |
font-family: 'Courier New', monospace;
|
| 245 |
-
direction: ltr;
|
| 246 |
-
display: inline-block;
|
| 247 |
}
|
| 248 |
.chat-markdown pre {
|
| 249 |
background: rgba(5, 26, 46, 0.7);
|
| 250 |
border: 1px solid rgba(45, 212, 191, 0.25);
|
| 251 |
border-right: 3px solid #0d9488;
|
| 252 |
-
padding: 0.9em 1em;
|
| 253 |
-
|
| 254 |
-
|
| 255 |
-
margin: 0.6em 0;
|
| 256 |
-
direction: ltr;
|
| 257 |
-
text-align: left;
|
| 258 |
}
|
| 259 |
.chat-markdown pre code { background: transparent; border: none; padding: 0; color: #a3c8e4; font-size: 0.85em; }
|
| 260 |
.chat-markdown blockquote {
|
| 261 |
border-right: 3px solid #c9a961;
|
| 262 |
background: linear-gradient(90deg, rgba(201, 169, 97, 0.08), transparent);
|
| 263 |
-
padding: 0.5em 1em;
|
| 264 |
-
|
| 265 |
-
color: #f0dca3;
|
| 266 |
-
font-style: italic;
|
| 267 |
border-radius: 0 8px 8px 0;
|
| 268 |
}
|
| 269 |
.chat-markdown blockquote p { margin: 0; }
|
| 270 |
.chat-markdown hr {
|
| 271 |
-
border: none;
|
| 272 |
-
height: 1px;
|
| 273 |
background: linear-gradient(90deg, transparent, rgba(201, 169, 97, 0.5), transparent);
|
| 274 |
margin: 1em 0;
|
| 275 |
}
|
| 276 |
.chat-markdown table {
|
| 277 |
-
width: 100%;
|
| 278 |
-
|
| 279 |
-
|
| 280 |
-
font-size: 0.92em;
|
| 281 |
-
background: rgba(45, 24, 16, 0.5);
|
| 282 |
-
border-radius: 8px;
|
| 283 |
-
overflow: hidden;
|
| 284 |
border: 1px solid rgba(201, 169, 97, 0.25);
|
| 285 |
-
display: block;
|
| 286 |
-
overflow-x: auto;
|
| 287 |
}
|
| 288 |
.chat-markdown thead { background: linear-gradient(90deg, rgba(139, 30, 63, 0.4), rgba(201, 169, 97, 0.2)); }
|
| 289 |
.chat-markdown th {
|
| 290 |
-
padding: 0.55em 0.8em;
|
| 291 |
-
|
| 292 |
-
color: #e4c97a;
|
| 293 |
-
font-weight: 700;
|
| 294 |
border-bottom: 1px solid rgba(201, 169, 97, 0.3);
|
| 295 |
font-family: 'Lalezar', serif;
|
| 296 |
}
|
|
@@ -303,8 +231,7 @@
|
|
| 303 |
|
| 304 |
.btn-primary {
|
| 305 |
background: linear-gradient(135deg, #c9a961 0%, #9c7d3a 100%);
|
| 306 |
-
color: #1a0d07;
|
| 307 |
-
font-weight: 800;
|
| 308 |
transition: all 0.3s ease;
|
| 309 |
box-shadow: 0 8px 20px -5px rgba(201, 169, 97, 0.4);
|
| 310 |
}
|
|
@@ -315,19 +242,9 @@
|
|
| 315 |
}
|
| 316 |
.btn-primary:disabled { opacity: 0.5; cursor: not-allowed; transform: none; }
|
| 317 |
|
| 318 |
-
.btn-rug {
|
| 319 |
-
background: linear-gradient(135deg, #8b1e3f 0%, #5a1028 100%);
|
| 320 |
-
color: #f5e6d3;
|
| 321 |
-
border: 1px solid rgba(201, 169, 97, 0.3);
|
| 322 |
-
}
|
| 323 |
-
.btn-rug:hover { background: linear-gradient(135deg, #c23d5f 0%, #8b1e3f 100%); border-color: rgba(201, 169, 97, 0.6); }
|
| 324 |
-
|
| 325 |
.typing-dots span {
|
| 326 |
-
display: inline-block;
|
| 327 |
-
|
| 328 |
-
height: 6px;
|
| 329 |
-
border-radius: 50%;
|
| 330 |
-
background: #c9a961;
|
| 331 |
animation: typing 1.4s infinite;
|
| 332 |
}
|
| 333 |
.typing-dots span:nth-child(2) { animation-delay: 0.2s; }
|
|
@@ -366,8 +283,7 @@
|
|
| 366 |
|
| 367 |
button, .no-select { -webkit-user-select: none; user-select: none; }
|
| 368 |
|
| 369 |
-
/* ============ FOOTER
|
| 370 |
-
/* فوتر به صورت ثابت در پایین view قرار میگیرد و هرگز روی محتوا نمیافتد */
|
| 371 |
.app-footer {
|
| 372 |
flex-shrink: 0;
|
| 373 |
position: relative;
|
|
@@ -378,42 +294,100 @@
|
|
| 378 |
border-top: 1px solid rgba(201, 169, 97, 0.15);
|
| 379 |
}
|
| 380 |
|
| 381 |
-
/*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 382 |
@media (max-width: 639px) {
|
| 383 |
.hero-title { font-size: 2.5rem !important; }
|
| 384 |
.hero-logo { width: 70px !important; height: 70px !important; }
|
| 385 |
.tables-grid { grid-template-columns: repeat(4, 1fr) !important; gap: 0.5rem !important; }
|
| 386 |
.table-btn span { font-size: 1.5rem !important; }
|
| 387 |
.info-cards { grid-template-columns: 1fr !important; }
|
| 388 |
-
.chat-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 389 |
}
|
| 390 |
|
|
|
|
| 391 |
@media (min-width: 640px) and (max-width: 1023px) {
|
| 392 |
.hero-title { font-size: 3.5rem !important; }
|
| 393 |
.hero-logo { width: 90px !important; height: 90px !important; }
|
| 394 |
.tables-grid { grid-template-columns: repeat(5, 1fr) !important; }
|
| 395 |
.info-cards { grid-template-columns: repeat(2, 1fr) !important; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 396 |
}
|
| 397 |
|
|
|
|
| 398 |
@media (min-width: 1024px) {
|
| 399 |
.hero-title { font-size: 4.5rem !important; }
|
| 400 |
.hero-logo { width: 100px !important; height: 100px !important; }
|
| 401 |
.tables-grid { grid-template-columns: repeat(10, 1fr) !important; }
|
| 402 |
.info-cards { grid-template-columns: repeat(3, 1fr) !important; }
|
|
|
|
|
|
|
|
|
|
|
|
|
| 403 |
}
|
| 404 |
|
|
|
|
| 405 |
@media (max-height: 500px) and (orientation: landscape) {
|
| 406 |
.hero-title { font-size: 2rem !important; }
|
| 407 |
.hero-logo { width: 50px !important; height: 50px !important; }
|
| 408 |
.hero-header { padding-top: 0.5rem !important; padding-bottom: 0.25rem !important; }
|
| 409 |
-
.chat-column {
|
|
|
|
|
|
|
|
|
|
| 410 |
}
|
| 411 |
|
|
|
|
| 412 |
@media (max-width: 380px) {
|
| 413 |
.tables-grid { grid-template-columns: repeat(4, 1fr) !important; }
|
| 414 |
.table-btn { padding: 0.375rem !important; }
|
| 415 |
.table-btn span { font-size: 1.25rem !important; }
|
| 416 |
.hero-title { font-size: 2rem !important; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 417 |
}
|
| 418 |
|
| 419 |
@supports (padding-bottom: env(safe-area-inset-bottom)) {
|
|
@@ -427,7 +401,6 @@
|
|
| 427 |
<!-- ============ VIEW 1: TABLE SELECTION ============ -->
|
| 428 |
<section id="view-table-selection" class="view-container view-visible">
|
| 429 |
|
| 430 |
-
<!-- Ambient Background (fixed) -->
|
| 431 |
<div class="absolute inset-0 overflow-hidden pointer-events-none z-0">
|
| 432 |
<div class="absolute inset-0 bg-gradient-to-br from-bazaar-950 via-bazaar-900 to-azure-950"></div>
|
| 433 |
<div class="absolute inset-0 bg-pattern opacity-40"></div>
|
|
@@ -436,10 +409,8 @@
|
|
| 436 |
<div class="absolute top-1/3 left-1/4 w-[400px] h-[400px] rounded-full bg-ochre/8 blur-[120px] animate-shimmer"></div>
|
| 437 |
</div>
|
| 438 |
|
| 439 |
-
<!-- Scrollable wrapper (فقط header و main، بدون footer) -->
|
| 440 |
<div class="scroll-area flex-1 min-h-0 relative z-10">
|
| 441 |
|
| 442 |
-
<!-- Hero Header -->
|
| 443 |
<header class="hero-header px-4 pt-6 pb-3 md:pt-10 md:pb-4 text-center relative flex-shrink-0">
|
| 444 |
<div class="max-w-4xl mx-auto">
|
| 445 |
<div class="inline-flex items-center gap-4 mb-4 animate-float">
|
|
@@ -469,7 +440,6 @@
|
|
| 469 |
</div>
|
| 470 |
</header>
|
| 471 |
|
| 472 |
-
<!-- Main content -->
|
| 473 |
<main class="px-4 md:px-8 pb-8 relative">
|
| 474 |
<div class="max-w-5xl mx-auto">
|
| 475 |
|
|
@@ -509,7 +479,6 @@
|
|
| 509 |
</div>
|
| 510 |
</div>
|
| 511 |
|
| 512 |
-
<!-- Info Cards -->
|
| 513 |
<div class="info-cards grid grid-cols-1 md:grid-cols-3 gap-3 mb-6">
|
| 514 |
<div class="glass-card rounded-2xl p-4 relative overflow-hidden group">
|
| 515 |
<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>
|
|
@@ -554,17 +523,15 @@
|
|
| 554 |
</main>
|
| 555 |
</div>
|
| 556 |
|
| 557 |
-
<!-- Footer (خارج از scroll-area، در پایین view-container) -->
|
| 558 |
<footer class="app-footer py-3 text-center text-[10px] text-cream/40 safe-top safe-bottom">
|
| 559 |
طراحی و توسعه توسط الگوریتم داده نسترن | با الهام از فرهنگ تبریز © ۲۰۲۶
|
| 560 |
</footer>
|
| 561 |
</section>
|
| 562 |
|
| 563 |
|
| 564 |
-
<!-- ============ VIEW 2: CHAT
|
| 565 |
<section id="view-chat" class="view-container view-hidden">
|
| 566 |
|
| 567 |
-
<!-- Ambient Background -->
|
| 568 |
<div class="absolute inset-0 overflow-hidden pointer-events-none z-0">
|
| 569 |
<div class="absolute inset-0 bg-gradient-to-br from-bazaar-950 via-bazaar-900 to-azure-950"></div>
|
| 570 |
<div class="absolute inset-0 bg-pattern opacity-30"></div>
|
|
@@ -604,11 +571,16 @@
|
|
| 604 |
<span class="text-[10px] text-cream/60">میز</span>
|
| 605 |
<span id="tableNumberDisplay" class="text-base md:text-lg font-display text-ochre-light table-number-glow">---</span>
|
| 606 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 607 |
</div>
|
| 608 |
</div>
|
| 609 |
</header>
|
| 610 |
|
| 611 |
-
<!-- Main content -->
|
| 612 |
<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">
|
| 613 |
<div class="max-w-5xl w-full mx-auto flex-1 flex flex-col min-h-0 gap-3">
|
| 614 |
|
|
@@ -635,11 +607,12 @@
|
|
| 635 |
</div>
|
| 636 |
</div>
|
| 637 |
|
| 638 |
-
<!-- Chat
|
| 639 |
-
<div class="chat-column
|
| 640 |
<div class="absolute inset-0 bg-arch opacity-20 pointer-events-none"></div>
|
| 641 |
|
| 642 |
-
<
|
|
|
|
| 643 |
<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">
|
| 644 |
<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">
|
| 645 |
<circle cx="12" cy="8" r="4"/>
|
|
@@ -647,7 +620,7 @@
|
|
| 647 |
<path d="M9 10l2 2 4-4" stroke-linecap="round" stroke-linejoin="round" opacity="0.7"/>
|
| 648 |
</svg>
|
| 649 |
</div>
|
| 650 |
-
<div class="min-w-0">
|
| 651 |
<h3 class="text-xs md:text-sm font-display text-ochre-light tracking-wide">نیلا، دستیار کافه</h3>
|
| 652 |
<p class="text-[9px] md:text-[10px] text-turk-light/80 font-medium flex items-center gap-1.5">
|
| 653 |
<span class="w-1.5 h-1.5 rounded-full bg-turk-light animate-pulse"></span>
|
|
@@ -656,19 +629,21 @@
|
|
| 656 |
</div>
|
| 657 |
</div>
|
| 658 |
|
| 659 |
-
<
|
| 660 |
-
|
|
|
|
| 661 |
<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">
|
| 662 |
<span class="text-ochre-light font-display text-[10px] md:text-[11px]">ن</span>
|
| 663 |
</div>
|
| 664 |
-
<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">
|
| 665 |
سلام! من <strong>نیلا</strong> هستم، دستیار هوشمند کافه آی. به میزتون خوش اومدید 🌸<br>
|
| 666 |
چه نوشیدنی، غذا یا شیرینیای میپسندید؟ <em>منوی امروز</em> رو میتونم براتون بگم. 😊
|
| 667 |
</div>
|
| 668 |
</div>
|
| 669 |
</div>
|
| 670 |
|
| 671 |
-
<
|
|
|
|
| 672 |
<div class="flex items-center gap-2">
|
| 673 |
<div class="typing-dots flex gap-1">
|
| 674 |
<span></span><span></span><span></span>
|
|
@@ -678,7 +653,8 @@
|
|
| 678 |
<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">توقف</button>
|
| 679 |
</div>
|
| 680 |
|
| 681 |
-
<
|
|
|
|
| 682 |
<input type="text" id="chatInput" placeholder="پیام خود را بنویسید..." autocomplete="off"
|
| 683 |
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">
|
| 684 |
<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">
|
|
@@ -693,6 +669,7 @@
|
|
| 693 |
</section>
|
| 694 |
|
| 695 |
<script>
|
|
|
|
| 696 |
function setVh() {
|
| 697 |
const vh = window.innerHeight * 0.01;
|
| 698 |
document.documentElement.style.setProperty('--vh', `${vh}px`);
|
|
@@ -701,6 +678,24 @@
|
|
| 701 |
window.addEventListener('resize', setVh);
|
| 702 |
window.addEventListener('orientationchange', () => setTimeout(setVh, 100));
|
| 703 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 704 |
let currentTable = "{{ table_number }}" !== "None" && "{{ table_number }}" !== "" ? "{{ table_number }}" : null;
|
| 705 |
let abortController = null;
|
| 706 |
let isGenerating = false;
|
|
@@ -714,14 +709,16 @@
|
|
| 714 |
if (currentTable && currentTable.trim() !== '') {
|
| 715 |
enterChatView(currentTable, false);
|
| 716 |
}
|
|
|
|
| 717 |
});
|
| 718 |
|
| 719 |
document.addEventListener('touchmove', function(e) {
|
| 720 |
-
if (!e.target.closest('.scroll-area')) {
|
| 721 |
e.preventDefault();
|
| 722 |
}
|
| 723 |
}, { passive: false });
|
| 724 |
|
|
|
|
| 725 |
function switchView(targetView) {
|
| 726 |
const sel = document.getElementById('view-table-selection');
|
| 727 |
const chat = document.getElementById('view-chat');
|
|
@@ -741,9 +738,8 @@
|
|
| 741 |
window.scrollTo(0, 0);
|
| 742 |
const tablesScroll = sel.querySelector('.scroll-area');
|
| 743 |
if (tablesScroll) tablesScroll.scrollTop = 0;
|
| 744 |
-
|
| 745 |
-
|
| 746 |
-
setTimeout(() => { chatScroll.scrollTop = chatScroll.scrollHeight; }, 100);
|
| 747 |
}
|
| 748 |
}
|
| 749 |
|
|
@@ -768,6 +764,7 @@
|
|
| 768 |
document.getElementById('draftOrderPanel').classList.add('hidden');
|
| 769 |
}
|
| 770 |
|
|
|
|
| 771 |
function renderTablesGrid() {
|
| 772 |
const grid = document.getElementById('tablesGrid');
|
| 773 |
grid.innerHTML = '';
|
|
@@ -800,23 +797,26 @@
|
|
| 800 |
currentDraft = null;
|
| 801 |
stopGeneration();
|
| 802 |
if (currentTable) fetch(`/api/customer/stop/${currentTable}`, { method: 'POST' }).catch(() => {});
|
|
|
|
| 803 |
}
|
| 804 |
|
| 805 |
function appendInitialGreeting() {
|
| 806 |
const container = document.getElementById('chatMessages');
|
| 807 |
container.innerHTML = `
|
| 808 |
-
<div class="flex gap-2.5 max-w-[88%]">
|
| 809 |
<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">
|
| 810 |
<span class="text-ochre-light font-display text-[10px] md:text-[11px]">ن</span>
|
| 811 |
</div>
|
| 812 |
-
<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">
|
| 813 |
سلام! من <strong>نیلا</strong> هستم، دستیار هوشمند کافه آی. به میزتون خوش اومدید 🌸<br>
|
| 814 |
چه نوشیدنی، غذا یا شیرینیای میپسندید؟ <em>منوی امروز</em> رو میتونم براتون بگم. 😊
|
| 815 |
</div>
|
| 816 |
</div>
|
| 817 |
`;
|
|
|
|
| 818 |
}
|
| 819 |
|
|
|
|
| 820 |
async function sendCustomerMessage(e) {
|
| 821 |
e.preventDefault();
|
| 822 |
if (isGenerating) return;
|
|
@@ -867,13 +867,13 @@
|
|
| 867 |
if (data.type === 'text') {
|
| 868 |
fullText += data.content;
|
| 869 |
botBubble.textContent = fullText;
|
| 870 |
-
|
| 871 |
-
chatScroll.scrollTop = chatScroll.scrollHeight;
|
| 872 |
} else if (data.type === 'draft') {
|
| 873 |
currentDraft = data.items;
|
| 874 |
showDraftPanel(currentDraft);
|
| 875 |
} else if (data.type === 'error') {
|
| 876 |
botBubble.textContent = '⚠️ ' + data.content;
|
|
|
|
| 877 |
}
|
| 878 |
} catch (parseErr) {}
|
| 879 |
}
|
|
@@ -882,8 +882,7 @@
|
|
| 882 |
|
| 883 |
botBubble.textContent = '';
|
| 884 |
botBubble.innerHTML = marked.parse(fullText);
|
| 885 |
-
|
| 886 |
-
chatScroll.scrollTop = chatScroll.scrollHeight;
|
| 887 |
|
| 888 |
} catch (err) {
|
| 889 |
if (err.name !== 'AbortError') {
|
|
@@ -928,8 +927,8 @@
|
|
| 928 |
draftItems.innerHTML = '';
|
| 929 |
items.forEach(item => {
|
| 930 |
draftItems.innerHTML += `
|
| 931 |
-
<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
|
| 932 |
-
<span class="text-cream font-bold flex items-center gap-2">
|
| 933 |
<span class="w-1 h-5 bg-gradient-to-b from-rug to-ochre rounded-full flex-shrink-0"></span>
|
| 934 |
<span class="truncate">${escapeHtml(item.name)}</span>
|
| 935 |
</span>
|
|
@@ -974,8 +973,8 @@
|
|
| 974 |
|
| 975 |
if (role === 'user') {
|
| 976 |
html = `
|
| 977 |
-
<div class="flex justify-end gap-2 max-w-[88%] mr-auto">
|
| 978 |
-
<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">
|
| 979 |
${escapeHtml(content)}
|
| 980 |
</div>
|
| 981 |
<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">
|
|
@@ -987,7 +986,7 @@
|
|
| 987 |
`;
|
| 988 |
} else {
|
| 989 |
html = `
|
| 990 |
-
<div class="flex gap-2.5 max-w-[88%]">
|
| 991 |
<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">
|
| 992 |
<span class="text-ochre-light font-display text-[10px] md:text-[11px]">ن</span>
|
| 993 |
</div>
|
|
@@ -999,7 +998,8 @@
|
|
| 999 |
}
|
| 1000 |
|
| 1001 |
container.insertAdjacentHTML('beforeend', html);
|
| 1002 |
-
|
|
|
|
| 1003 |
return bubbleId;
|
| 1004 |
}
|
| 1005 |
|
|
@@ -1007,23 +1007,14 @@
|
|
| 1007 |
return String(text).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''');
|
| 1008 |
}
|
| 1009 |
|
|
|
|
| 1010 |
const chatInput = document.getElementById('chatInput');
|
| 1011 |
if (chatInput) {
|
| 1012 |
chatInput.addEventListener('focus', () => {
|
| 1013 |
-
setTimeout(
|
| 1014 |
-
|
| 1015 |
-
if (chatScroll) chatScroll.scrollTop = chatScroll.scrollHeight;
|
| 1016 |
-
}, 300);
|
| 1017 |
});
|
| 1018 |
}
|
| 1019 |
-
|
| 1020 |
-
window.addEventListener('resize', () => {
|
| 1021 |
-
setVh();
|
| 1022 |
-
const chatScroll = document.getElementById('chatMessages');
|
| 1023 |
-
if (chatScroll && document.getElementById('view-chat').classList.contains('view-visible')) {
|
| 1024 |
-
setTimeout(() => { chatScroll.scrollTop = chatScroll.scrollHeight; }, 100);
|
| 1025 |
-
}
|
| 1026 |
-
});
|
| 1027 |
</script>
|
| 1028 |
</body>
|
| 1029 |
</html>
|
|
|
|
| 22 |
display: ['Lalezar', 'serif'],
|
| 23 |
},
|
| 24 |
colors: {
|
| 25 |
+
bazaar: { 950: '#1a0d07', 900: '#2d1810', 800: '#3d2418', 700: '#5c3a2a', 600: '#7a4e3a', 500: '#9c6b4f', 400: '#b8856a', 300: '#d4a88c' },
|
| 26 |
+
azure: { 950: '#051a2e', 900: '#0a2540', 800: '#123a5e', 700: '#1e4976', 600: '#2d6ca8', 500: '#3d8bc4', 400: '#6ba7d4', 300: '#a3c8e4' },
|
| 27 |
+
turk: { DEFAULT: '#0d9488', light: '#2dd4bf', glow: '#5eead4', deep: '#134e4a' },
|
| 28 |
+
rug: { DEFAULT: '#8b1e3f', light: '#c23d5f', dark: '#5a1028', glow: '#e85d7e' },
|
| 29 |
+
ochre: { DEFAULT: '#c9a961', light: '#e4c97a', dark: '#9c7d3a', pale: '#f0dca3' },
|
| 30 |
+
ivory: '#faf3e7', cream: '#f5e6d3', saffron: '#d97706',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 31 |
},
|
| 32 |
boxShadow: {
|
| 33 |
'carpet': '0 10px 40px -10px rgba(139, 30, 63, 0.35), 0 0 0 1px rgba(201, 169, 97, 0.15)',
|
|
|
|
| 43 |
'fade-in': 'fadeIn 0.35s ease-out',
|
| 44 |
},
|
| 45 |
keyframes: {
|
| 46 |
+
float: { '0%, 100%': { transform: 'translateY(0px)' }, '50%': { transform: 'translateY(-12px)' } },
|
| 47 |
+
shimmer: { '0%, 100%': { opacity: '0.7' }, '50%': { opacity: '1' } },
|
| 48 |
+
pulseGlow: { '0%, 100%': { boxShadow: '0 0 20px rgba(201, 169, 97, 0.3)' }, '50%': { boxShadow: '0 0 40px rgba(201, 169, 97, 0.6)' } },
|
| 49 |
+
fadeIn: { '0%': { opacity: '0', transform: 'translateY(8px)' }, '100%': { opacity: '1', transform: 'translateY(0)' } },
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
},
|
| 51 |
}
|
| 52 |
}
|
|
|
|
| 56 |
<style>
|
| 57 |
:root {
|
| 58 |
--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");
|
| 59 |
+
--vh: 1vh;
|
| 60 |
}
|
| 61 |
|
| 62 |
* { box-sizing: border-box; }
|
| 63 |
|
| 64 |
+
html, body {
|
|
|
|
| 65 |
height: 100%;
|
| 66 |
overflow: hidden;
|
|
|
|
|
|
|
|
|
|
| 67 |
overscroll-behavior: none;
|
| 68 |
-webkit-overflow-scrolling: touch;
|
| 69 |
}
|
| 70 |
|
| 71 |
+
@supports (height: 100dvh) {
|
| 72 |
+
html, body { height: 100dvh; }
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
body {
|
| 76 |
background-color: #1a0d07;
|
| 77 |
color: #f5e6d3;
|
|
|
|
| 79 |
font-feature-settings: "ss01", "cv01";
|
| 80 |
margin: 0;
|
| 81 |
padding: 0;
|
|
|
|
|
|
|
| 82 |
overflow: hidden;
|
|
|
|
|
|
|
| 83 |
}
|
| 84 |
|
| 85 |
+
.bg-pattern { background-image: var(--pattern-url); background-size: 80px 80px; }
|
|
|
|
|
|
|
|
|
|
| 86 |
|
| 87 |
.bg-pattern-fine {
|
| 88 |
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40' viewBox='0 0 40 40'%3E%3Cg fill='none' stroke='%23c9a961' stroke-width='0.4' opacity='0.1'%3E%3Cpath d='M20 0 L20 40 M0 20 L40 20'/%3E%3Ccircle cx='20' cy='20' r='3'/%3E%3Ccircle cx='0' cy='0' r='2'/%3E%3Ccircle cx='40' cy='0' r='2'/%3E%3Ccircle cx='0' cy='40' r='2'/%3E%3Ccircle cx='40' cy='40' r='2'/%3E%3C/g%3E%3C/svg%3E");
|
|
|
|
| 99 |
background: linear-gradient(180deg, #c9a961, #8b1e3f);
|
| 100 |
border-radius: 4px;
|
| 101 |
}
|
| 102 |
+
::-webkit-scrollbar-thumb:hover { background: linear-gradient(180deg, #e4c97a, #c23d5f); }
|
| 103 |
|
| 104 |
.glass-card {
|
| 105 |
background: linear-gradient(135deg, rgba(45, 24, 16, 0.82) 0%, rgba(26, 13, 7, 0.78) 100%);
|
|
|
|
| 163 |
.chat-markdown > * + * { margin-top: 0.6em; }
|
| 164 |
.chat-markdown h1, .chat-markdown h2, .chat-markdown h3,
|
| 165 |
.chat-markdown h4, .chat-markdown h5, .chat-markdown h6 {
|
| 166 |
+
font-family: 'Lalezar', serif; color: #e4c97a;
|
| 167 |
+
margin-top: 1em; margin-bottom: 0.4em; line-height: 1.3;
|
|
|
|
|
|
|
|
|
|
| 168 |
}
|
| 169 |
.chat-markdown h1 { font-size: 1.4em; }
|
| 170 |
.chat-markdown h2 { font-size: 1.25em; }
|
|
|
|
| 180 |
.chat-markdown em { color: #5eead4; font-style: italic; }
|
| 181 |
.chat-markdown a { color: #2dd4bf; text-decoration: underline; text-underline-offset: 3px; }
|
| 182 |
.chat-markdown code {
|
| 183 |
+
background: rgba(13, 148, 136, 0.18); color: #5eead4;
|
| 184 |
+
padding: 0.15em 0.4em; border-radius: 5px; font-size: 0.88em;
|
|
|
|
|
|
|
|
|
|
| 185 |
border: 1px solid rgba(45, 212, 191, 0.2);
|
| 186 |
font-family: 'Courier New', monospace;
|
| 187 |
+
direction: ltr; display: inline-block;
|
|
|
|
| 188 |
}
|
| 189 |
.chat-markdown pre {
|
| 190 |
background: rgba(5, 26, 46, 0.7);
|
| 191 |
border: 1px solid rgba(45, 212, 191, 0.25);
|
| 192 |
border-right: 3px solid #0d9488;
|
| 193 |
+
padding: 0.9em 1em; border-radius: 8px;
|
| 194 |
+
overflow-x: auto; margin: 0.6em 0;
|
| 195 |
+
direction: ltr; text-align: left;
|
|
|
|
|
|
|
|
|
|
| 196 |
}
|
| 197 |
.chat-markdown pre code { background: transparent; border: none; padding: 0; color: #a3c8e4; font-size: 0.85em; }
|
| 198 |
.chat-markdown blockquote {
|
| 199 |
border-right: 3px solid #c9a961;
|
| 200 |
background: linear-gradient(90deg, rgba(201, 169, 97, 0.08), transparent);
|
| 201 |
+
padding: 0.5em 1em; margin: 0.6em 0;
|
| 202 |
+
color: #f0dca3; font-style: italic;
|
|
|
|
|
|
|
| 203 |
border-radius: 0 8px 8px 0;
|
| 204 |
}
|
| 205 |
.chat-markdown blockquote p { margin: 0; }
|
| 206 |
.chat-markdown hr {
|
| 207 |
+
border: none; height: 1px;
|
|
|
|
| 208 |
background: linear-gradient(90deg, transparent, rgba(201, 169, 97, 0.5), transparent);
|
| 209 |
margin: 1em 0;
|
| 210 |
}
|
| 211 |
.chat-markdown table {
|
| 212 |
+
width: 100%; border-collapse: collapse; margin: 0.6em 0;
|
| 213 |
+
font-size: 0.92em; background: rgba(45, 24, 16, 0.5);
|
| 214 |
+
border-radius: 8px; overflow: hidden;
|
|
|
|
|
|
|
|
|
|
|
|
|
| 215 |
border: 1px solid rgba(201, 169, 97, 0.25);
|
| 216 |
+
display: block; overflow-x: auto;
|
|
|
|
| 217 |
}
|
| 218 |
.chat-markdown thead { background: linear-gradient(90deg, rgba(139, 30, 63, 0.4), rgba(201, 169, 97, 0.2)); }
|
| 219 |
.chat-markdown th {
|
| 220 |
+
padding: 0.55em 0.8em; text-align: right;
|
| 221 |
+
color: #e4c97a; font-weight: 700;
|
|
|
|
|
|
|
| 222 |
border-bottom: 1px solid rgba(201, 169, 97, 0.3);
|
| 223 |
font-family: 'Lalezar', serif;
|
| 224 |
}
|
|
|
|
| 231 |
|
| 232 |
.btn-primary {
|
| 233 |
background: linear-gradient(135deg, #c9a961 0%, #9c7d3a 100%);
|
| 234 |
+
color: #1a0d07; font-weight: 800;
|
|
|
|
| 235 |
transition: all 0.3s ease;
|
| 236 |
box-shadow: 0 8px 20px -5px rgba(201, 169, 97, 0.4);
|
| 237 |
}
|
|
|
|
| 242 |
}
|
| 243 |
.btn-primary:disabled { opacity: 0.5; cursor: not-allowed; transform: none; }
|
| 244 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 245 |
.typing-dots span {
|
| 246 |
+
display: inline-block; width: 6px; height: 6px;
|
| 247 |
+
border-radius: 50%; background: #c9a961;
|
|
|
|
|
|
|
|
|
|
| 248 |
animation: typing 1.4s infinite;
|
| 249 |
}
|
| 250 |
.typing-dots span:nth-child(2) { animation-delay: 0.2s; }
|
|
|
|
| 283 |
|
| 284 |
button, .no-select { -webkit-user-select: none; user-select: none; }
|
| 285 |
|
| 286 |
+
/* ============ FOOTER ============ */
|
|
|
|
| 287 |
.app-footer {
|
| 288 |
flex-shrink: 0;
|
| 289 |
position: relative;
|
|
|
|
| 294 |
border-top: 1px solid rgba(201, 169, 97, 0.15);
|
| 295 |
}
|
| 296 |
|
| 297 |
+
/* ============ CHAT COLUMN - KEY FIX ============ */
|
| 298 |
+
.chat-column {
|
| 299 |
+
display: flex;
|
| 300 |
+
flex-direction: column;
|
| 301 |
+
min-height: 0;
|
| 302 |
+
overflow: hidden;
|
| 303 |
+
}
|
| 304 |
+
|
| 305 |
+
.chat-messages-container {
|
| 306 |
+
flex: 1;
|
| 307 |
+
min-height: 0;
|
| 308 |
+
overflow-y: auto;
|
| 309 |
+
overflow-x: hidden;
|
| 310 |
+
overscroll-behavior: contain;
|
| 311 |
+
-webkit-overflow-scrolling: touch;
|
| 312 |
+
}
|
| 313 |
+
|
| 314 |
+
.chat-header-box,
|
| 315 |
+
.chat-loader-box,
|
| 316 |
+
.chat-input-box {
|
| 317 |
+
flex-shrink: 0;
|
| 318 |
+
}
|
| 319 |
+
|
| 320 |
+
/* ============ RESPONSIVE HEIGHTS ============ */
|
| 321 |
+
|
| 322 |
+
/* Mobile (< 640px) */
|
| 323 |
@media (max-width: 639px) {
|
| 324 |
.hero-title { font-size: 2.5rem !important; }
|
| 325 |
.hero-logo { width: 70px !important; height: 70px !important; }
|
| 326 |
.tables-grid { grid-template-columns: repeat(4, 1fr) !important; gap: 0.5rem !important; }
|
| 327 |
.table-btn span { font-size: 1.5rem !important; }
|
| 328 |
.info-cards { grid-template-columns: 1fr !important; }
|
| 329 |
+
.chat-column {
|
| 330 |
+
height: 65vh;
|
| 331 |
+
height: calc(var(--vh, 1vh) * 65);
|
| 332 |
+
min-height: 380px;
|
| 333 |
+
max-height: 550px;
|
| 334 |
+
flex-shrink: 0;
|
| 335 |
+
}
|
| 336 |
+
.chat-input-area {
|
| 337 |
+
padding-bottom: calc(0.75rem + env(safe-area-inset-bottom)) !important;
|
| 338 |
+
}
|
| 339 |
}
|
| 340 |
|
| 341 |
+
/* Tablet (640px - 1023px) */
|
| 342 |
@media (min-width: 640px) and (max-width: 1023px) {
|
| 343 |
.hero-title { font-size: 3.5rem !important; }
|
| 344 |
.hero-logo { width: 90px !important; height: 90px !important; }
|
| 345 |
.tables-grid { grid-template-columns: repeat(5, 1fr) !important; }
|
| 346 |
.info-cards { grid-template-columns: repeat(2, 1fr) !important; }
|
| 347 |
+
.chat-column {
|
| 348 |
+
height: 70vh;
|
| 349 |
+
height: calc(var(--vh, 1vh) * 70);
|
| 350 |
+
min-height: 420px;
|
| 351 |
+
max-height: 620px;
|
| 352 |
+
flex-shrink: 0;
|
| 353 |
+
}
|
| 354 |
}
|
| 355 |
|
| 356 |
+
/* Desktop (>= 1024px) - چت کل ارتفاع را میگیرد */
|
| 357 |
@media (min-width: 1024px) {
|
| 358 |
.hero-title { font-size: 4.5rem !important; }
|
| 359 |
.hero-logo { width: 100px !important; height: 100px !important; }
|
| 360 |
.tables-grid { grid-template-columns: repeat(10, 1fr) !important; }
|
| 361 |
.info-cards { grid-template-columns: repeat(3, 1fr) !important; }
|
| 362 |
+
.chat-column {
|
| 363 |
+
height: 100%;
|
| 364 |
+
max-height: 100%;
|
| 365 |
+
}
|
| 366 |
}
|
| 367 |
|
| 368 |
+
/* Landscape mobile */
|
| 369 |
@media (max-height: 500px) and (orientation: landscape) {
|
| 370 |
.hero-title { font-size: 2rem !important; }
|
| 371 |
.hero-logo { width: 50px !important; height: 50px !important; }
|
| 372 |
.hero-header { padding-top: 0.5rem !important; padding-bottom: 0.25rem !important; }
|
| 373 |
+
.chat-column {
|
| 374 |
+
height: 75vh !important;
|
| 375 |
+
min-height: 280px !important;
|
| 376 |
+
}
|
| 377 |
}
|
| 378 |
|
| 379 |
+
/* Small mobile */
|
| 380 |
@media (max-width: 380px) {
|
| 381 |
.tables-grid { grid-template-columns: repeat(4, 1fr) !important; }
|
| 382 |
.table-btn { padding: 0.375rem !important; }
|
| 383 |
.table-btn span { font-size: 1.25rem !important; }
|
| 384 |
.hero-title { font-size: 2rem !important; }
|
| 385 |
+
.chat-column {
|
| 386 |
+
height: 60vh;
|
| 387 |
+
height: calc(var(--vh, 1vh) * 60);
|
| 388 |
+
min-height: 340px;
|
| 389 |
+
max-height: 500px;
|
| 390 |
+
}
|
| 391 |
}
|
| 392 |
|
| 393 |
@supports (padding-bottom: env(safe-area-inset-bottom)) {
|
|
|
|
| 401 |
<!-- ============ VIEW 1: TABLE SELECTION ============ -->
|
| 402 |
<section id="view-table-selection" class="view-container view-visible">
|
| 403 |
|
|
|
|
| 404 |
<div class="absolute inset-0 overflow-hidden pointer-events-none z-0">
|
| 405 |
<div class="absolute inset-0 bg-gradient-to-br from-bazaar-950 via-bazaar-900 to-azure-950"></div>
|
| 406 |
<div class="absolute inset-0 bg-pattern opacity-40"></div>
|
|
|
|
| 409 |
<div class="absolute top-1/3 left-1/4 w-[400px] h-[400px] rounded-full bg-ochre/8 blur-[120px] animate-shimmer"></div>
|
| 410 |
</div>
|
| 411 |
|
|
|
|
| 412 |
<div class="scroll-area flex-1 min-h-0 relative z-10">
|
| 413 |
|
|
|
|
| 414 |
<header class="hero-header px-4 pt-6 pb-3 md:pt-10 md:pb-4 text-center relative flex-shrink-0">
|
| 415 |
<div class="max-w-4xl mx-auto">
|
| 416 |
<div class="inline-flex items-center gap-4 mb-4 animate-float">
|
|
|
|
| 440 |
</div>
|
| 441 |
</header>
|
| 442 |
|
|
|
|
| 443 |
<main class="px-4 md:px-8 pb-8 relative">
|
| 444 |
<div class="max-w-5xl mx-auto">
|
| 445 |
|
|
|
|
| 479 |
</div>
|
| 480 |
</div>
|
| 481 |
|
|
|
|
| 482 |
<div class="info-cards grid grid-cols-1 md:grid-cols-3 gap-3 mb-6">
|
| 483 |
<div class="glass-card rounded-2xl p-4 relative overflow-hidden group">
|
| 484 |
<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>
|
|
|
|
| 523 |
</main>
|
| 524 |
</div>
|
| 525 |
|
|
|
|
| 526 |
<footer class="app-footer py-3 text-center text-[10px] text-cream/40 safe-top safe-bottom">
|
| 527 |
طراحی و توسعه توسط الگوریتم داده نسترن | با الهام از فرهنگ تبریز © ۲۰۲۶
|
| 528 |
</footer>
|
| 529 |
</section>
|
| 530 |
|
| 531 |
|
| 532 |
+
<!-- ============ VIEW 2: CHAT ============ -->
|
| 533 |
<section id="view-chat" class="view-container view-hidden">
|
| 534 |
|
|
|
|
| 535 |
<div class="absolute inset-0 overflow-hidden pointer-events-none z-0">
|
| 536 |
<div class="absolute inset-0 bg-gradient-to-br from-bazaar-950 via-bazaar-900 to-azure-950"></div>
|
| 537 |
<div class="absolute inset-0 bg-pattern opacity-30"></div>
|
|
|
|
| 571 |
<span class="text-[10px] text-cream/60">میز</span>
|
| 572 |
<span id="tableNumberDisplay" class="text-base md:text-lg font-display text-ochre-light table-number-glow">---</span>
|
| 573 |
</div>
|
| 574 |
+
<button onclick="backToTables()" class="p-1.5 text-turk/60 hover:text-ochre-light transition-colors rounded-lg hover:bg-bazaar-800/50" title="تغییر میز">
|
| 575 |
+
<svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
| 576 |
+
<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"/>
|
| 577 |
+
</svg>
|
| 578 |
+
</button>
|
| 579 |
</div>
|
| 580 |
</div>
|
| 581 |
</header>
|
| 582 |
|
| 583 |
+
<!-- Main content with controlled height -->
|
| 584 |
<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">
|
| 585 |
<div class="max-w-5xl w-full mx-auto flex-1 flex flex-col min-h-0 gap-3">
|
| 586 |
|
|
|
|
| 607 |
</div>
|
| 608 |
</div>
|
| 609 |
|
| 610 |
+
<!-- Chat column (fixed height controlled by CSS) -->
|
| 611 |
+
<div class="chat-column glass-card-azure rounded-2xl md:rounded-3xl shadow-xl relative">
|
| 612 |
<div class="absolute inset-0 bg-arch opacity-20 pointer-events-none"></div>
|
| 613 |
|
| 614 |
+
<!-- Chat header (flex-shrink-0) -->
|
| 615 |
+
<div class="chat-header-box relative px-3.5 md:px-5 py-2.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">
|
| 616 |
<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">
|
| 617 |
<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">
|
| 618 |
<circle cx="12" cy="8" r="4"/>
|
|
|
|
| 620 |
<path d="M9 10l2 2 4-4" stroke-linecap="round" stroke-linejoin="round" opacity="0.7"/>
|
| 621 |
</svg>
|
| 622 |
</div>
|
| 623 |
+
<div class="min-w-0 flex-1">
|
| 624 |
<h3 class="text-xs md:text-sm font-display text-ochre-light tracking-wide">نیلا، دستیار کافه</h3>
|
| 625 |
<p class="text-[9px] md:text-[10px] text-turk-light/80 font-medium flex items-center gap-1.5">
|
| 626 |
<span class="w-1.5 h-1.5 rounded-full bg-turk-light animate-pulse"></span>
|
|
|
|
| 629 |
</div>
|
| 630 |
</div>
|
| 631 |
|
| 632 |
+
<!-- Chat messages (SCROLLABLE - key fix) -->
|
| 633 |
+
<div id="chatMessages" class="chat-messages-container p-3 md:p-4 space-y-3 relative">
|
| 634 |
+
<div class="flex gap-2 md:gap-2.5 max-w-[88%]">
|
| 635 |
<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">
|
| 636 |
<span class="text-ochre-light font-display text-[10px] md:text-[11px]">ن</span>
|
| 637 |
</div>
|
| 638 |
+
<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 break-words" style="flex: 1; max-width: calc(100% - 2.5rem);">
|
| 639 |
سلام! من <strong>نیلا</strong> هستم، دستیار هوشمند کافه آی. به میزتون خوش اومدید 🌸<br>
|
| 640 |
چه نوشیدنی، غذا یا شیرینیای میپسندید؟ <em>منوی امروز</em> رو میتونم براتون بگم. 😊
|
| 641 |
</div>
|
| 642 |
</div>
|
| 643 |
</div>
|
| 644 |
|
| 645 |
+
<!-- Chat loader (flex-shrink-0) -->
|
| 646 |
+
<div id="chatLoader" class="chat-loader-box hidden relative 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">
|
| 647 |
<div class="flex items-center gap-2">
|
| 648 |
<div class="typing-dots flex gap-1">
|
| 649 |
<span></span><span></span><span></span>
|
|
|
|
| 653 |
<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">توقف</button>
|
| 654 |
</div>
|
| 655 |
|
| 656 |
+
<!-- Chat input (flex-shrink-0) -->
|
| 657 |
+
<form id="chatForm" onsubmit="sendCustomerMessage(event)" class="chat-input-box relative p-2 md:p-3 border-t border-turk/20 bg-bazaar-950/60 flex gap-2 chat-input-area safe-bottom">
|
| 658 |
<input type="text" id="chatInput" placeholder="پیام خود را بنویسید..." autocomplete="off"
|
| 659 |
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">
|
| 660 |
<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">
|
|
|
|
| 669 |
</section>
|
| 670 |
|
| 671 |
<script>
|
| 672 |
+
// ============ VIEWPORT HEIGHT FIX ============
|
| 673 |
function setVh() {
|
| 674 |
const vh = window.innerHeight * 0.01;
|
| 675 |
document.documentElement.style.setProperty('--vh', `${vh}px`);
|
|
|
|
| 678 |
window.addEventListener('resize', setVh);
|
| 679 |
window.addEventListener('orientationchange', () => setTimeout(setVh, 100));
|
| 680 |
|
| 681 |
+
// ============ AUTO SCROLL HELPER ============
|
| 682 |
+
function scrollChatToBottom(smooth = true) {
|
| 683 |
+
const chatScroll = document.getElementById('chatMessages');
|
| 684 |
+
if (chatScroll) {
|
| 685 |
+
if (smooth) {
|
| 686 |
+
chatScroll.scrollTo({ top: chatScroll.scrollHeight, behavior: 'smooth' });
|
| 687 |
+
} else {
|
| 688 |
+
chatScroll.scrollTop = chatScroll.scrollHeight;
|
| 689 |
+
}
|
| 690 |
+
}
|
| 691 |
+
}
|
| 692 |
+
|
| 693 |
+
window.addEventListener('resize', () => {
|
| 694 |
+
setVh();
|
| 695 |
+
setTimeout(scrollChatToBottom, 150);
|
| 696 |
+
});
|
| 697 |
+
|
| 698 |
+
// ============ CONFIG ============
|
| 699 |
let currentTable = "{{ table_number }}" !== "None" && "{{ table_number }}" !== "" ? "{{ table_number }}" : null;
|
| 700 |
let abortController = null;
|
| 701 |
let isGenerating = false;
|
|
|
|
| 709 |
if (currentTable && currentTable.trim() !== '') {
|
| 710 |
enterChatView(currentTable, false);
|
| 711 |
}
|
| 712 |
+
setTimeout(scrollChatToBottom, 100);
|
| 713 |
});
|
| 714 |
|
| 715 |
document.addEventListener('touchmove', function(e) {
|
| 716 |
+
if (!e.target.closest('.scroll-area') && !e.target.closest('.chat-messages-container')) {
|
| 717 |
e.preventDefault();
|
| 718 |
}
|
| 719 |
}, { passive: false });
|
| 720 |
|
| 721 |
+
// ============ VIEW MANAGEMENT ============
|
| 722 |
function switchView(targetView) {
|
| 723 |
const sel = document.getElementById('view-table-selection');
|
| 724 |
const chat = document.getElementById('view-chat');
|
|
|
|
| 738 |
window.scrollTo(0, 0);
|
| 739 |
const tablesScroll = sel.querySelector('.scroll-area');
|
| 740 |
if (tablesScroll) tablesScroll.scrollTop = 0;
|
| 741 |
+
if (targetView === 'chat') {
|
| 742 |
+
setTimeout(scrollChatToBottom, 100);
|
|
|
|
| 743 |
}
|
| 744 |
}
|
| 745 |
|
|
|
|
| 764 |
document.getElementById('draftOrderPanel').classList.add('hidden');
|
| 765 |
}
|
| 766 |
|
| 767 |
+
// ============ TABLES GRID ============
|
| 768 |
function renderTablesGrid() {
|
| 769 |
const grid = document.getElementById('tablesGrid');
|
| 770 |
grid.innerHTML = '';
|
|
|
|
| 797 |
currentDraft = null;
|
| 798 |
stopGeneration();
|
| 799 |
if (currentTable) fetch(`/api/customer/stop/${currentTable}`, { method: 'POST' }).catch(() => {});
|
| 800 |
+
setTimeout(scrollChatToBottom, 100);
|
| 801 |
}
|
| 802 |
|
| 803 |
function appendInitialGreeting() {
|
| 804 |
const container = document.getElementById('chatMessages');
|
| 805 |
container.innerHTML = `
|
| 806 |
+
<div class="flex gap-2 md:gap-2.5 max-w-[88%]">
|
| 807 |
<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">
|
| 808 |
<span class="text-ochre-light font-display text-[10px] md:text-[11px]">ن</span>
|
| 809 |
</div>
|
| 810 |
+
<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 break-words" style="flex: 1; max-width: calc(100% - 2.5rem);">
|
| 811 |
سلام! من <strong>نیلا</strong> هستم، دستیار هوشمند کافه آی. به میزتون خوش اومدید 🌸<br>
|
| 812 |
چه نوشیدنی، غذا یا شیرینیای میپسندید؟ <em>منوی امروز</em> رو میتونم براتون بگم. 😊
|
| 813 |
</div>
|
| 814 |
</div>
|
| 815 |
`;
|
| 816 |
+
setTimeout(scrollChatToBottom, 50);
|
| 817 |
}
|
| 818 |
|
| 819 |
+
// ============ CHAT FUNCTIONS ============
|
| 820 |
async function sendCustomerMessage(e) {
|
| 821 |
e.preventDefault();
|
| 822 |
if (isGenerating) return;
|
|
|
|
| 867 |
if (data.type === 'text') {
|
| 868 |
fullText += data.content;
|
| 869 |
botBubble.textContent = fullText;
|
| 870 |
+
scrollChatToBottom(false);
|
|
|
|
| 871 |
} else if (data.type === 'draft') {
|
| 872 |
currentDraft = data.items;
|
| 873 |
showDraftPanel(currentDraft);
|
| 874 |
} else if (data.type === 'error') {
|
| 875 |
botBubble.textContent = '⚠️ ' + data.content;
|
| 876 |
+
scrollChatToBottom(false);
|
| 877 |
}
|
| 878 |
} catch (parseErr) {}
|
| 879 |
}
|
|
|
|
| 882 |
|
| 883 |
botBubble.textContent = '';
|
| 884 |
botBubble.innerHTML = marked.parse(fullText);
|
| 885 |
+
scrollChatToBottom(true);
|
|
|
|
| 886 |
|
| 887 |
} catch (err) {
|
| 888 |
if (err.name !== 'AbortError') {
|
|
|
|
| 927 |
draftItems.innerHTML = '';
|
| 928 |
items.forEach(item => {
|
| 929 |
draftItems.innerHTML += `
|
| 930 |
+
<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">
|
| 931 |
+
<span class="text-cream font-bold flex items-center gap-2 min-w-0">
|
| 932 |
<span class="w-1 h-5 bg-gradient-to-b from-rug to-ochre rounded-full flex-shrink-0"></span>
|
| 933 |
<span class="truncate">${escapeHtml(item.name)}</span>
|
| 934 |
</span>
|
|
|
|
| 973 |
|
| 974 |
if (role === 'user') {
|
| 975 |
html = `
|
| 976 |
+
<div class="flex justify-end gap-2 md:gap-2.5 max-w-[88%] mr-auto">
|
| 977 |
+
<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" style="flex: 1; max-width: calc(100% - 2.5rem);">
|
| 978 |
${escapeHtml(content)}
|
| 979 |
</div>
|
| 980 |
<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">
|
|
|
|
| 986 |
`;
|
| 987 |
} else {
|
| 988 |
html = `
|
| 989 |
+
<div class="flex gap-2 md:gap-2.5 max-w-[88%]">
|
| 990 |
<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">
|
| 991 |
<span class="text-ochre-light font-display text-[10px] md:text-[11px]">ن</span>
|
| 992 |
</div>
|
|
|
|
| 998 |
}
|
| 999 |
|
| 1000 |
container.insertAdjacentHTML('beforeend', html);
|
| 1001 |
+
// Always scroll to bottom after adding message
|
| 1002 |
+
scrollChatToBottom(true);
|
| 1003 |
return bubbleId;
|
| 1004 |
}
|
| 1005 |
|
|
|
|
| 1007 |
return String(text).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''');
|
| 1008 |
}
|
| 1009 |
|
| 1010 |
+
// Mobile keyboard handling
|
| 1011 |
const chatInput = document.getElementById('chatInput');
|
| 1012 |
if (chatInput) {
|
| 1013 |
chatInput.addEventListener('focus', () => {
|
| 1014 |
+
setTimeout(scrollChatToBottom, 300);
|
| 1015 |
+
setTimeout(scrollChatToBottom, 600);
|
|
|
|
|
|
|
| 1016 |
});
|
| 1017 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1018 |
</script>
|
| 1019 |
</body>
|
| 1020 |
</html>
|