feat(web-client-tpos): unify POS page with tabs and inline payment

This commit is contained in:
Ho Ngoc Hai
2026-03-03 11:12:48 +07:00
parent 617a7caf81
commit 15404a859f

View File

@@ -345,4 +345,551 @@
max-height: 90vh;
overflow-y: auto;
box-shadow: 0 24px 48px rgba(0, 0, 0, 0.4);
}
/* ═════════════════════════════════════════════════════════════════════════
7. POS BOTTOM NAVIGATION — Tab bar for Sale / History / Dashboard
═════════════════════════════════════════════════════════════════════════ */
.pos-bottom-nav {
display: flex;
height: 52px;
background-color: var(--pos-bg-elevated);
border-top: 1px solid var(--pos-border-subtle);
flex-shrink: 0;
}
.pos-bottom-nav__tab {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 3px;
border: none;
background: transparent;
color: var(--pos-text-tertiary);
cursor: pointer;
font-family: var(--pos-font);
font-size: 11px;
font-weight: 500;
transition: color 0.2s ease;
position: relative;
}
.pos-bottom-nav__tab:hover {
color: var(--pos-text-secondary);
}
.pos-bottom-nav__tab--active {
color: var(--pos-orange-primary);
}
.pos-bottom-nav__tab--active::before {
content: '';
position: absolute;
top: 0;
left: 25%;
right: 25%;
height: 2px;
background: var(--pos-orange-primary);
border-radius: 0 0 2px 2px;
}
.pos-bottom-nav__icon {
width: 20px;
height: 20px;
}
/* ═════════════════════════════════════════════════════════════════════════
8. POS PAYMENT INLINE — Cart panel transforms to payment mode
═════════════════════════════════════════════════════════════════════════ */
.pos-payment-panel {
display: flex;
flex-direction: column;
height: 100%;
animation: posFadeIn 0.25s ease-out;
}
.pos-payment-header {
display: flex;
align-items: center;
gap: 10px;
padding: 14px 16px;
border-bottom: 1px solid var(--pos-border-subtle);
}
.pos-payment-header__back {
width: 32px;
height: 32px;
border-radius: 8px;
border: 1px solid var(--pos-border-default);
background: transparent;
color: var(--pos-text-secondary);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
}
.pos-payment-methods {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 10px;
padding: 16px;
}
.pos-payment-method-btn {
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
padding: 20px 12px;
border-radius: var(--pos-radius);
border: 2px solid var(--pos-border-default);
background: var(--pos-bg-page);
color: var(--pos-text-primary);
cursor: pointer;
transition: border-color 0.2s, background-color 0.2s;
font-family: var(--pos-font);
}
.pos-payment-method-btn:hover {
border-color: var(--pos-orange-primary);
background: rgba(255, 92, 0, 0.05);
}
.pos-payment-method-btn--selected {
border-color: var(--pos-orange-primary);
background: rgba(255, 92, 0, 0.1);
}
.pos-payment-method-btn__icon {
font-size: 28px;
}
.pos-payment-method-btn__label {
font-size: 13px;
font-weight: 600;
}
.pos-payment-amount-section {
padding: 16px;
flex: 1;
overflow-y: auto;
}
.pos-payment-quick-amounts {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 8px;
margin-bottom: 16px;
}
.pos-payment-quick-btn {
padding: 12px 8px;
border-radius: var(--pos-radius);
border: 2px solid var(--pos-border-default);
background: var(--pos-bg-page);
color: var(--pos-text-primary);
cursor: pointer;
font-size: 13px;
font-weight: 600;
font-family: var(--pos-font);
text-align: center;
transition: border-color 0.2s;
}
.pos-payment-quick-btn:hover,
.pos-payment-quick-btn--selected {
border-color: var(--pos-orange-primary);
background: rgba(255, 92, 0, 0.1);
}
.pos-payment-input {
width: 100%;
padding: 12px 14px;
border-radius: var(--pos-radius);
border: 1px solid var(--pos-border-default);
background: var(--pos-bg-page);
color: var(--pos-text-primary);
font-size: 15px;
font-family: var(--pos-font);
outline: none;
margin-bottom: 16px;
}
.pos-payment-input:focus {
border-color: var(--pos-orange-primary);
}
.pos-payment-change {
background: var(--pos-bg-page);
border-radius: var(--pos-radius);
padding: 14px;
display: flex;
flex-direction: column;
gap: 8px;
}
.pos-payment-change__row {
display: flex;
justify-content: space-between;
font-size: 13px;
}
/* Payment success animation */
.pos-payment-success {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
gap: 16px;
animation: posFadeIn 0.3s ease-out;
}
.pos-payment-success__circle {
width: 80px;
height: 80px;
border-radius: 50%;
background: rgba(34, 197, 94, 0.15);
display: flex;
align-items: center;
justify-content: center;
animation: posScaleIn 0.4s ease-out;
}
.pos-payment-success__inner {
width: 56px;
height: 56px;
border-radius: 50%;
background: var(--pos-success);
display: flex;
align-items: center;
justify-content: center;
}
@keyframes posFadeIn {
from {
opacity: 0;
transform: translateY(8px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes posScaleIn {
from {
transform: scale(0);
}
to {
transform: scale(1);
}
}
/* ═════════════════════════════════════════════════════════════════════════
9. POS ORDER HISTORY
═════════════════════════════════════════════════════════════════════════ */
.pos-history {
display: flex;
flex-direction: column;
height: 100%;
overflow: hidden;
}
.pos-history__toolbar {
display: flex;
gap: 10px;
padding: 14px 16px;
border-bottom: 1px solid var(--pos-border-subtle);
flex-shrink: 0;
align-items: center;
}
.pos-history__search {
flex: 1;
padding: 10px 14px;
border-radius: var(--pos-radius);
border: 1px solid var(--pos-border-default);
background: var(--pos-bg-elevated);
color: var(--pos-text-primary);
font-size: 13px;
font-family: var(--pos-font);
outline: none;
}
.pos-history__search:focus {
border-color: var(--pos-orange-primary);
}
.pos-history__filter-btn {
padding: 10px 14px;
border-radius: var(--pos-radius);
border: 1px solid var(--pos-border-default);
background: transparent;
color: var(--pos-text-secondary);
cursor: pointer;
font-size: 12px;
font-weight: 600;
font-family: var(--pos-font);
white-space: nowrap;
}
.pos-history__filter-btn--active {
border-color: var(--pos-orange-primary);
background: rgba(255, 92, 0, 0.1);
color: var(--pos-orange-primary);
}
.pos-history__list {
flex: 1;
overflow-y: auto;
padding: 8px 16px;
display: flex;
flex-direction: column;
gap: 8px;
}
.pos-history__card {
background: var(--pos-bg-elevated);
border-radius: var(--pos-radius);
padding: 14px 16px;
cursor: pointer;
border: 1px solid transparent;
transition: border-color 0.2s;
}
.pos-history__card:hover {
border-color: var(--pos-border-default);
}
.pos-history__card-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 8px;
}
.pos-history__order-id {
font-size: 13px;
font-weight: 700;
color: var(--pos-text-primary);
}
.pos-history__status {
padding: 3px 10px;
border-radius: 6px;
font-size: 11px;
font-weight: 600;
}
.pos-history__status--completed {
background: rgba(34, 197, 94, 0.15);
color: var(--pos-success);
}
.pos-history__status--refunded {
background: rgba(239, 68, 68, 0.15);
color: var(--pos-danger);
}
.pos-history__card-body {
display: flex;
justify-content: space-between;
align-items: flex-end;
}
.pos-history__items-preview {
font-size: 12px;
color: var(--pos-text-tertiary);
max-width: 60%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.pos-history__card-meta {
text-align: right;
}
.pos-history__total {
font-size: 15px;
font-weight: 700;
color: var(--pos-orange-primary);
}
.pos-history__time {
font-size: 11px;
color: var(--pos-text-tertiary);
margin-top: 2px;
}
.pos-history__method {
font-size: 11px;
color: var(--pos-text-tertiary);
}
/* ═════════════════════════════════════════════════════════════════════════
10. POS DASHBOARD
═════════════════════════════════════════════════════════════════════════ */
.pos-dashboard {
padding: 20px;
overflow-y: auto;
height: 100%;
}
.pos-dashboard__header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}
.pos-dashboard__title {
font-size: 20px;
font-weight: 700;
}
.pos-dashboard__subtitle {
font-size: 12px;
color: var(--pos-text-tertiary);
margin-top: 2px;
}
.pos-dashboard__stats {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 12px;
margin-bottom: 20px;
}
.pos-dashboard__stat-card {
background: var(--pos-bg-elevated);
border-radius: var(--pos-radius);
padding: 16px;
}
.pos-dashboard__stat-label {
font-size: 11px;
color: var(--pos-text-tertiary);
margin-bottom: 6px;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.pos-dashboard__stat-value {
font-size: 22px;
font-weight: 700;
}
.pos-dashboard__stat-sub {
font-size: 11px;
color: var(--pos-text-tertiary);
margin-top: 4px;
}
.pos-dashboard__grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
}
.pos-dashboard__section {
background: var(--pos-bg-elevated);
border-radius: var(--pos-radius);
padding: 16px;
}
.pos-dashboard__section-title {
font-size: 14px;
font-weight: 600;
margin-bottom: 14px;
}
.pos-dashboard__popular-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 0;
border-bottom: 1px solid var(--pos-border-subtle);
}
.pos-dashboard__popular-item:last-child {
border-bottom: none;
}
.pos-dashboard__hourly-chart {
display: flex;
align-items: flex-end;
gap: 4px;
height: 100px;
margin-top: 8px;
}
.pos-dashboard__hourly-bar {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
gap: 4px;
}
.pos-dashboard__hourly-fill {
width: 100%;
background: var(--pos-orange-primary);
border-radius: 3px 3px 0 0;
min-height: 2px;
transition: height 0.3s ease;
}
.pos-dashboard__hourly-label {
font-size: 9px;
color: var(--pos-text-tertiary);
}
/* Payment method progress bar */
.pos-dashboard__payment-row {
margin-bottom: 12px;
}
.pos-dashboard__payment-header {
display: flex;
justify-content: space-between;
margin-bottom: 4px;
font-size: 12px;
}
.pos-dashboard__payment-bar {
height: 5px;
border-radius: 3px;
background: var(--pos-bg-interactive);
}
.pos-dashboard__payment-fill {
height: 100%;
border-radius: 3px;
}
/* ═════════════════════════════════════════════════════════════════════════
11. POS MAIN LAYOUT — adjusted for bottom nav
═════════════════════════════════════════════════════════════════════════ */
.pos-content-area {
flex: 1;
display: flex;
overflow: hidden;
}
/* Dimmed product panel during payment */
.pos-product-panel--dimmed {
opacity: 0.4;
pointer-events: none;
}