Files
octopus/myproject/pos/static/pos/css/terminal.css
Andrey Smakotin c77fcaf669 feat: Добавить мобильную адаптацию для POS-терминала
- Добавить фиксированную панель корзины внизу экрана на мобильных
  - Отображение количества товаров и суммы
  - Кнопки "Продать" и "Очистить" всегда доступны
  - Тап на панель открывает корзину как overlay

- Фиксировать поиск и категории сверху на мобильных
  - Поиск всегда виден при скролле
  - Категории в collapsible-блоке (сворачиваются)
  - Категории в 3 колонки на мобильных

- Улучшить поиск по токенам (разбивает фразу на слова)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 23:03:40 +03:00

848 lines
18 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* POS Terminal Styles */
body {
background-color: #e9ecef;
}
/* Основной контейнер POS */
.pos-main-container {
position: fixed;
top: 56px; /* высота navbar */
left: 0;
right: 0;
bottom: 0;
background-color: white;
box-shadow: 0 0 20px rgba(0,0,0,0.1);
overflow: hidden;
}
.pos-container {
max-width: 100%;
padding: 1rem;
height: 100%;
overflow: hidden;
display: flex;
flex-direction: column;
}
/* Прокручиваемая область товаров */
.products-scrollable {
overflow-y: auto;
overflow-x: hidden;
flex-grow: 1;
}
/* 5 колонок для товаров и категорий на экранах от 1100px */
@media (min-width: 1100px) {
.col-lg-custom-5 {
flex: 0 0 20%;
max-width: 20%;
}
}
/* Стили для корзины */
.cart-item {
display: flex;
align-items: center;
gap: 0.25rem;
padding: 0.25rem 0;
border-bottom: 1px solid #e9ecef;
}
.item-name-price {
flex: 1;
min-width: 0;
}
.item-name-price .fw-semibold {
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
line-height: 1.3;
}
.item-name-price .text-muted {
margin-top: 0.15rem;
}
/* Цена и единица измерения на одной строке */
.price-unit-row {
display: flex;
align-items: center;
gap: 0.35rem;
}
.multiply-sign {
font-weight: bold;
color: #6c757d;
font-size: 0.9rem;
flex-shrink: 0;
}
.qty-input {
width: 45px;
padding: 0.15rem 0.35rem;
border: 1px solid #dee2e6;
border-radius: 4px;
text-align: center;
font-size: 0.85rem;
flex-shrink: 0;
}
.qty-input::-webkit-outer-spin-button,
.qty-input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
.qty-input[type=number] {
-moz-appearance: textfield;
}
.item-total {
font-weight: 600;
font-size: 0.85rem;
color: #212529;
min-width: 50px;
text-align: right;
flex-shrink: 0;
}
.cart-item .btn-link {
font-size: 1.2rem;
line-height: 1;
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
margin-left: 0.15rem;
}
.cart-item .btn-link:hover {
background-color: #f8d7da;
border-radius: 4px;
}
/* Кнопки +/- компактнее */
.cart-item .btn-sm {
padding: 0.15rem 0.35rem;
font-size: 0.875rem;
}
.cart-item .btn-sm i {
font-size: 1em;
}
.product-card {
cursor: pointer;
user-select: none;
transition: all 0.2s;
border-radius: 12px;
border: 1px solid #dee2e6;
background: white;
height: 100%;
min-height: 200px;
display: flex;
flex-direction: column;
}
.product-card:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}
.product-card.selected {
background: #e7f3ff;
border-color: #0d6efd;
}
.product-card .card-body {
padding: 0;
display: flex;
flex-direction: column;
height: 100%;
}
.product-image {
width: 100%;
aspect-ratio: 1 / 1;
object-fit: cover;
border-radius: 12px 12px 0 0;
background: #f8f9fa;
display: flex;
align-items: center;
justify-content: center;
color: #adb5bd;
font-size: 3rem;
flex-shrink: 0;
min-height: 150px;
}
.product-image img {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 12px 12px 0 0;
}
.product-info {
padding: 0.75rem;
display: flex;
flex-direction: column;
gap: 0.25rem;
flex-grow: 1;
}
.product-name {
font-weight: 600;
font-size: 0.9rem;
line-height: 1.2;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
color: #212529;
}
.product-stock {
font-size: 0.8rem;
color: #6c757d;
margin-top: auto;
margin-bottom: 0.15rem;
}
.product-sku {
font-size: 0.65rem;
color: #adb5bd;
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: nowrap;
gap: 0.5rem;
}
.product-price {
font-size: 0.85rem;
font-weight: 600;
color: #212529;
border: 1px solid #dee2e6;
border-radius: 6px;
padding: 2px 8px;
background: #f8f9fa;
}
/* Карточки категорий */
.category-card {
cursor: pointer;
user-select: none;
transition: all 0.2s;
border-radius: 12px;
border: 2px solid #dee2e6;
background: white;
height: 100%;
min-height: 40px;
}
.category-card:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
border-color: #0d6efd;
}
.category-card.active {
background: #0d6efd;
border-color: #0d6efd;
color: white;
}
/* Специальный стиль для активной кнопки витрины */
.showcase-card.active {
background: #ff6600;
border-color: #ff6600;
border-width: 3px;
color: #000000;
font-weight: bold;
box-shadow: 0 6px 16px rgba(255, 102, 0, 0.6);
transform: scale(1.05);
}
.category-card .card-body {
padding: 0.5rem;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
}
.category-name {
font-weight: 600;
font-size: 0.85rem;
}
/* Фиксация правой панели (корзина + кнопки) */
.right-panel-fixed {
position: absolute;
top: 0;
right: 0;
bottom: 0;
width: 41.667%; /* 5/12 колонок */
overflow-y: auto;
padding: 1rem;
padding-right: 1.5rem;
z-index: 10;
display: flex;
flex-direction: column;
}
@media (max-width: 767.98px) {
.right-panel-fixed {
position: relative;
width: 100%;
top: auto;
right: auto;
bottom: auto;
left: auto;
padding: 0.75rem;
padding-right: 0.75rem;
z-index: auto;
}
/* На мобильных меняем layout контейнера */
.pos-container {
overflow-y: auto;
height: auto;
padding: 0.75rem;
}
/* Убираем fixed высоту из основного контейнера на мобильных */
.pos-main-container {
position: relative;
top: auto;
bottom: auto;
overflow-y: auto;
}
/* Левая колонка (товары) не должна быть flex */
.col-12.col-md-8[style*="flex-direction: column"] {
display: block !important;
height: auto !important;
}
}
/* Панель кнопок внутри фиксированного блока */
.action-buttons-panel {
margin-top: auto;
}
/* Стили для кнопок в панели действий */
.action-buttons-panel .btn {
font-size: 0.85rem;
font-weight: 700;
line-height: 1.1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 0.5rem;
}
/* Исключение для кнопки "Отложенный заказ" - разрешаем перенос */
.action-buttons-panel #scheduleLater {
white-space: normal;
}
/* Адаптивность для элементов корзины на маленьких экранах */
@media (max-width: 991.98px) {
.cart-item {
align-items: flex-start;
}
.multiply-sign {
display: none;
}
.item-name-price .fw-semibold {
-webkit-line-clamp: 1;
}
}
/* Адаптивность для карточек товаров и витринных комплектов на маленьких экранах */
@media (max-width: 575.98px) {
/* Уменьшаем минимальную высоту карточки */
.product-card {
min-height: 160px;
}
/* Уменьшаем высоту изображения */
.product-image {
min-height: 100px;
font-size: 2rem;
}
/* Уменьшаем отступы в информационном блоке */
.product-info {
padding: 0.5rem;
gap: 0.2rem;
}
/* Уменьшаем размер названия товара */
.product-name {
font-size: 0.8rem;
-webkit-line-clamp: 2;
}
/* Уменьшаем размер информации об остатках */
.product-stock {
font-size: 0.7rem;
}
/* Уменьшаем размер артикула и цены */
.product-sku {
font-size: 0.7rem;
}
.product-price {
font-size: 0.8rem;
}
}
/* Стили для модального окна выбора единицы продажи */
.unit-selection-card {
border: 2px solid #dee2e6;
border-radius: 8px;
padding: 12px;
cursor: pointer;
transition: all 0.2s;
background: white;
}
.unit-selection-card:hover {
border-color: #0d6efd;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
transform: translateY(-1px);
}
.unit-selection-card.selected {
border-color: #0d6efd;
background: #e7f3ff;
box-shadow: 0 2px 12px rgba(13,110,253,0.3);
}
.unit-selection-card .unit-name {
font-weight: 600;
font-size: 1rem;
color: #212529;
margin-bottom: 4px;
}
.unit-selection-card .unit-price {
font-size: 1.1rem;
font-weight: 600;
color: #0d6efd;
margin-bottom: 4px;
}
.unit-selection-card .unit-availability {
font-size: 0.85rem;
color: #6c757d;
}
.unit-selection-card .unit-code {
font-size: 0.8rem;
color: #adb5bd;
}
.unit-selection-card .badge {
font-size: 0.75rem;
padding: 4px 8px;
}
/* Индикаторы наличия */
.stock-badge-good {
background-color: #d4edda;
color: #155724;
}
.stock-badge-low {
background-color: #fff3cd;
color: #856404;
}
.stock-badge-none {
background-color: #f8d7da;
color: #721c24;
}
/* ============================================================
АДАПТИВНОСТЬ ДЛЯ МОБИЛЬНЫХ УСТРОЙСТВ
============================================================ */
/* Увеличение размера элементов управления на мобильных */
@media (max-width: 767.98px) {
/* Поля ввода - минимальный размер для тапа */
.form-control,
.form-select {
min-height: 44px;
font-size: 16px; /* Предотвращает зум на iOS при фокусе */
}
/* Кнопки - минимальный размер для тапа */
.btn {
min-height: 44px;
}
}
/* На десктопе возвращаем фиксированную высоту для кнопок действий */
@media (min-width: 768px) {
.action-buttons-panel .btn {
height: 60px;
}
}
/* Оптимизация модалок на мобильных */
@media (max-width: 767.98px) {
/* Уменьшаем отступы в модалках */
.modal-body {
padding: 1rem 0.75rem;
}
.modal-footer {
padding: 0.75rem;
}
/* Прокручиваемые списки */
#tempKitItemsList,
#unitSelectionList {
max-height: 150px !important;
}
}
/* Улучшение UX для тач-устройств */
@media (hover: none) and (pointer: coarse) {
/* Убираем hover-эффекты */
.product-card:hover,
.category-card:hover,
.unit-selection-card:hover {
transform: none;
}
/* Добавляем эффект нажатия */
.product-card:active,
.category-card:active,
.unit-selection-card:active {
transform: scale(0.98);
transition: transform 0.1s;
}
/* Подсветка при тапе */
.btn,
.cart-item .btn-link {
-webkit-tap-highlight-color: rgba(13, 110, 253, 0.2);
}
}
/* Плавная прокрутка на iOS */
.products-scrollable {
-webkit-overflow-scrolling: touch;
}
/* ============================================================
КОМПАКТНАЯ КНОПКА ВЫБОРА КЛИЕНТА
============================================================ */
#customerSelectBtn {
min-width: 160px;
max-width: 200px;
height: 38px;
padding: 0.25rem 0.75rem;
gap: 0.5rem;
}
#customerSelectBtn i {
font-size: 1rem;
flex-shrink: 0;
}
#customerSelectBtnText {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/* На мобильных - такой же вид с текстом */
/* ============================================================
МОБИЛЬНАЯ ПЛАВАЮЩАЯ КОРЗИНА
============================================================ */
/* Фиксированный бар внизу экрана */
.mobile-cart-bar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
background: white;
border-top: 2px solid #dee2e6;
padding: 0.75rem;
display: none; /* скрываем на десктопе */
justify-content: space-between;
align-items: center;
gap: 0.75rem;
z-index: 1000;
box-shadow: 0 -2px 10px rgba(0,0,0,0.1);
}
/* Сводка по корзине (кликабельная) */
.mobile-cart-summary {
flex: 1;
display: flex;
flex-direction: column;
cursor: pointer;
padding: 0.25rem;
border-radius: 8px;
transition: background-color 0.2s;
}
.mobile-cart-summary:hover {
background-color: #f8f9fa;
}
.mobile-cart-summary:active {
background-color: #e9ecef;
}
/* Количество товаров */
.mobile-cart-count {
font-size: 0.8rem;
color: #6c757d;
font-weight: 500;
}
/* Итоговая сумма */
.mobile-cart-total {
font-size: 1.35rem;
font-weight: 700;
color: #198754;
line-height: 1.2;
}
/* Кнопки действий в мобильном баре */
.mobile-cart-actions {
display: flex;
gap: 0.5rem;
}
.mobile-cart-actions .btn {
min-height: 44px;
display: flex;
align-items: center;
justify-content: center;
gap: 0.35rem;
white-space: nowrap;
}
.mobile-cart-actions .btn span {
display: inline;
}
/* Overlay корзины (фон затемнения) */
.mobile-cart-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0,0,0,0.5);
z-index: 1100;
display: none;
}
.mobile-cart-overlay.active {
display: flex;
align-items: flex-end;
}
/* Контент корзины в overlay */
.mobile-cart-content {
background: white;
width: 100%;
max-height: 75vh;
display: flex;
flex-direction: column;
animation: slideUp 0.3s ease-out;
border-radius: 16px 16px 0 0;
}
@keyframes slideUp {
from { transform: translateY(100%); }
to { transform: translateY(0); }
}
/* Заголовок мобильной корзины */
.mobile-cart-header {
padding: 1rem;
border-bottom: 1px solid #dee2e6;
display: flex;
justify-content: space-between;
align-items: center;
background: #f8f9fa;
border-radius: 16px 16px 0 0;
}
.mobile-cart-header h6 {
font-weight: 600;
}
/* Тело корзины с прокруткой */
.mobile-cart-body {
padding: 1rem;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
}
/* Копия стилей корзины для мобильного view */
.mobile-cart-body .cart-item {
padding: 0.5rem 0;
}
.mobile-cart-body .item-name-price .fw-semibold {
font-size: 0.95rem;
}
/* Показываем мобильный бар только на маленьких экранах */
@media (max-width: 767.98px) {
.mobile-cart-bar {
display: flex;
}
/* Скрываем десктопную правую панель на мобильных */
.right-panel-fixed {
display: none !important;
}
/* Добавляем отступы чтобы контент не перекрывался барами */
.pos-container {
padding-bottom: 80px;
padding-top: 70px; /* место для фиксированного поиска */
}
/* Фиксируем основной контейнер для работы с позиционированием */
.pos-main-container {
overflow: visible; /* меняем для работы fixed внутри */
}
/* Создаём фиксированный бар поиска на мобильных */
.pos-container > .row {
position: relative;
}
/* Левая колонка с товарами */
.pos-container > .row > .col-12:first-child {
position: relative;
}
/* Блок поиска выносим в фиксированный бар */
.pos-container > .row > .col-12:first-child > div:first-child,
.pos-container > .row > .col-12:first-child > .mb-3:first-child {
position: fixed;
top: 56px; /* сразу под navbar */
left: 0;
right: 0;
z-index: 900;
background: white;
padding: 0.75rem;
margin: 0;
border-bottom: 1px solid #dee2e6;
box-shadow: 0 2px 4px rgba(0,0,0,0.08);
}
/* Категории тоже фиксируем под поиском */
.pos-container > .row > .col-12:first-child > div:nth-child(2) {
position: fixed;
top: 115px; /* поиск (56+~55) + категории */
left: 0;
right: 0;
z-index: 899;
background: white;
padding: 0.5rem 0.75rem;
margin: 0;
border-bottom: 1px solid #e9ecef;
}
/* Сворачивание категорий на мобильных */
.categories-wrapper {
margin-bottom: 0.5rem !important;
}
/* Кнопка переключения категорий */
.categories-toggle {
cursor: pointer;
color: #495057;
font-size: 0.9rem;
}
.categories-toggle:hover {
color: #212529;
}
/* Иконка chevron с поворотом */
.categories-toggle .bi-chevron-down {
transition: transform 0.2s ease;
}
.categories-toggle.collapsed .bi-chevron-down {
transform: rotate(-90deg);
}
/* Содержимое категорий */
.categories-content {
max-height: 200px;
overflow-y: auto;
overflow-x: hidden;
transition: max-height 0.3s ease, opacity 0.3s ease;
-webkit-overflow-scrolling: touch;
}
.categories-content.collapsed {
max-height: 0;
opacity: 0;
overflow: hidden;
}
/* Меньшие карточки категорий на мобильных */
.category-card {
min-height: 32px !important;
padding: 0.25rem 0.5rem !important;
}
.category-card .card-body {
padding: 0.25rem !important;
}
.category-name {
font-size: 0.75rem !important;
}
/* Уменьшаем gap между категориями */
#categoryGrid {
gap: 0.5rem !important;
}
/* Категории в 3 колонки на мобильных */
#categoryGrid > div {
flex: 0 0 calc(33.333% - 0.33rem);
max-width: calc(33.333% - 0.33rem);
}
/* Прокручиваемая область товаров смещаем вниз */
.products-scrollable {
margin-top: 90px; /* учитываем поиск и категории */
}
}