diff --git a/docs/site-screenshots/index.html b/docs/site-screenshots/index.html index e9768dd..b92a554 100644 --- a/docs/site-screenshots/index.html +++ b/docs/site-screenshots/index.html @@ -13,7 +13,7 @@ .thumb{max-height:620px;overflow:auto}

ALL MARKET — публичный сайт (https://test.food-market.kz)

-
Снято 2026-10-08 17:21 · проверка после выкладки свежих скриншотов
+
Снято 2026-10-08 18:04 · проверка после выкладки свежих скриншотов

Главная/ ↗

Главная

Касса для Windows/pos ↗

Касса для Windows
diff --git a/docs/site-screenshots/pages/index.png b/docs/site-screenshots/pages/index.png index c4fe7ff..ca615f0 100644 Binary files a/docs/site-screenshots/pages/index.png and b/docs/site-screenshots/pages/index.png differ diff --git a/docs/site-screenshots/pages/pos.png b/docs/site-screenshots/pages/pos.png index 36d9805..1db2d8a 100644 Binary files a/docs/site-screenshots/pages/pos.png and b/docs/site-screenshots/pages/pos.png differ diff --git a/docs/ui-review-fixes-progress.md b/docs/ui-review-fixes-progress.md index 1d34b38..b8fa40e 100644 --- a/docs/ui-review-fixes-progress.md +++ b/docs/ui-review-fixes-progress.md @@ -4,17 +4,34 @@ самой программы (не только скриншотов). ## План / статус -1. [ ] Английские строки в админке: «Dashboard», «Low-stock alerts», «live» и др. — - перевести; grep по web/src на видимые латинские строки; лингва-проверка в menu-walk. -2. [ ] Каталог: дубль «Все товары» (корень дерева + системная группа). Убрать дубль. -3. [ ] Валюта: везде «₸» и формат «1 300 ₸» (сейчас розничная — «510 KZT»). -4. [ ] Касса на сайте: заменить рендер HTML-макета на НАСТОЯЩИЙ экран Avalonia-кассы - (--screenshots, витринные данные «Магазин у дома», с логотипом). Макет не использовать. -5. [ ] Витрина: packaging по товарам (Авокадо 1шт — штучный, Бешбармак 1кг — весовой и т.п.). -6. [ ] Выложить сайт+стенд, переснять затронутые скриншоты, посмотреть каждый кадр. +1. [x] Английские строки в админке → русский. ru.json: `dashboard.title` «Dashboard»→ + «Сводка», `common.live/offline` «live/offline»→«онлайн/офлайн». Дашборд-виджеты: + defaultValue «Low-stock alerts»→«Низкий остаток», «Live-обновление»→«Обновляется в + реальном времени». Grep по web/src — других видимых латинских UI-строк нет (бренды/ + единицы — ок). Тест: лингва-проверка в `stage-ui-menu-walk.spec.ts` (denylist UI-English + на видимом тексте каждой страницы, бренды/единицы не ловятся). +2. [x] Каталог: системная группа «Все товары» больше не дублирует корень дерева. + `ProductGroupDto.IsSystem` + `ProductGroupTree` прячет системные группы (корень «Все + товары» = все товары, по модели МойСклада). Группа остаётся в справочнике (дефолт для + товаров без группы) — фильтры/импорт/карточка не ломаются. +3. [x] Валюта: розничная цена в каталоге теперь «₸» (символ), а не «KZT» (код). Формат + «1 300 ₸» как у себестоимости. +4. [x] Касса на сайте: HTML-макет заменён НАСТОЯЩИМ экраном Avalonia-кассы (--screenshots): + продажа (04-sale-items) и оплата (05-payment-cash) с логотипом, витринные данные + «Магазин у дома», кассир Виктория Ким. Убран префикс «Магазин » в шапке кассы (не было + «Магазин Магазин у дома»). HTML-макет удалён из публичного пайплайна. +5. [x] Витрина: фасовка/единица выводится из названия (кг→весовой/кг, иначе штучный/штука). + Проверено API: Авокадо 1шт→штучный, Бешбармак 1кг→весовой, Кола 0.5л→штучный. +6. [x] Выложено: стенд (api+web) + витрина пересеяна (RESET) + публичный сайт. Пересняты + затронутые экраны, пережаты в WebP (≤300 КБ). Просмотрено глазами: дашборд «Сводка»/ + «онлайн»/«Низкий остаток»; каталог ₸/один «Все товары»/корректная фасовка; /pos — + настоящая касса с логотипом. Галерея `docs/site-screenshots/index.html`. ## Что НЕ трогаем Прод, shared-postgres, global.json, gateway nginx, sklad. ## Журнал - 08.10 — старт: план, разбор замечаний. +- 08.10 — код: ru.json + виджеты (1), ProductGroupDto.IsSystem + tree (2), ₸ в каталоге (3), + ShowcaseSeeder packaging из названия (5), реальная Avalonia-касса + шапка (4), лингва-тест. +- 08.10 — деплой api+web, RESET-пересев витрины, пересъёмка экранов, деплой сайта, галерея. diff --git a/src/food-market.web/src/locales/ru.json b/src/food-market.web/src/locales/ru.json index d406104..e14a157 100644 --- a/src/food-market.web/src/locales/ru.json +++ b/src/food-market.web/src/locales/ru.json @@ -146,7 +146,7 @@ "orgTitle": "Настройки организации", "orgDescription": "Страна, валюта, ставка НДС по умолчанию.", "telegramTitle": "📨 Telegram владельца", - "telegramDescription": "Ежедневная сводка (выручка вчера, топ-3 товара, low-stock) в 09:00 МСК.", + "telegramDescription": "Ежедневная сводка (выручка вчера, топ-3 товара, низкий остаток) в 09:00 МСК.", "telegramBotDisabled": "Бот не настроен на сервере (нет токена в env). Привязка пока недоступна.", "telegramBound": "Привязан: chat_id={{id}}", "telegramUnbind": "Отвязать", diff --git a/src/food-market.web/src/pages/OrganizationSettingsPage.tsx b/src/food-market.web/src/pages/OrganizationSettingsPage.tsx index 22f6f0a..c866074 100644 --- a/src/food-market.web/src/pages/OrganizationSettingsPage.tsx +++ b/src/food-market.web/src/pages/OrganizationSettingsPage.tsx @@ -265,7 +265,7 @@ function TelegramSection() {

📨 Telegram владельца

- Ежедневная сводка (выручка вчера, топ-3 товара, low-stock) в 09:00 МСК. + Ежедневная сводка (выручка вчера, топ-3 товара, низкий остаток) в 09:00 МСК.

{!s?.botEnabled && ( diff --git a/tests/e2e/scenarios/stage-ui-menu-walk.spec.ts b/tests/e2e/scenarios/stage-ui-menu-walk.spec.ts index 82ba09c..5ba6915 100644 --- a/tests/e2e/scenarios/stage-ui-menu-walk.spec.ts +++ b/tests/e2e/scenarios/stage-ui-menu-walk.spec.ts @@ -94,6 +94,32 @@ async function assertNoErrorToasts(page: Page, where: string) { } } +// Лингва-проверка: в видимом тексте страницы не должно быть непереведённого +// UI-английского. Проверяем узкий denylist именно «хромовых» строк интерфейса +// (заголовок/виджет/статус), а НЕ «любое латинское слово» — иначе ловили бы +// легитимные бренды товаров (Lay's, Snickers, Kaspi), единицы, названия клавиш +// (Delete/Enter/Esc) и технические идентификаторы в доке. Denylist ловит класс +// регрессий «забыли перевести строку интерфейса». +const UI_ENGLISH_DENY: RegExp[] = [ + /\bDashboard\b/, // заголовок страницы (должно быть «Сводка») + /Low-stock alerts/i, // заголовок виджета (должно быть «Низкий остаток») + /Live-обновл/, // латинское «Live» в русской строке + /\blive\b/, /\boffline\b/, // статус-чип (должно быть «онлайн»/«офлайн») +] +// Документация/диагностика содержат названия клавиш, код-идентификаторы и +// технические термины — там латиница легитимна, лингва-проверку не применяем. +const LINGUA_SKIP = ['/help', '/whats-new', '/admin/diagnostic'] +async function assertNoUiEnglish(page: Page, where: string, href: string) { + if (LINGUA_SKIP.some((p) => href.startsWith(p))) return + const bodyText = await page.locator('body').innerText() + const hits = UI_ENGLISH_DENY + .map((re) => bodyText.match(re)?.[0]) + .filter((x): x is string => !!x) + if (hits.length > 0) { + throw new Error(`Непереведённый UI-английский на ${where}: ${[...new Set(hits)].join(', ')}`) + } +} + // -------------------------------------------------------------------------- test.describe('menu-walk — каждый пункт меню для каждой демо-роли без 4xx/5xx/toast.error/console.error', () => { @@ -131,6 +157,7 @@ test.describe('menu-walk — каждый пункт меню для каждо const bodyText = await page.locator('body').innerText() expect(bodyText.length, `body на ${where}`).toBeGreaterThan(MIN_BODY_LEN) await assertNoErrorToasts(page, where) + await assertNoUiEnglish(page, where, href) // Теперь — reload (F5): это тот сценарий, где владелец словил 403-тосты. await page.reload({ waitUntil: 'domcontentloaded' })