fix(регистрация): вставка телефона + 3 мелочи перепроверки (12.10)
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker Public / Build + push Public (test + latest) (push) Waiting to run
Docker Public / Deploy :test → test.food-market.kz (push) Blocked by required conditions
Docker Web / Build + push Web (push) Waiting to run
Docker Web / Deploy Web on stage (push) Blocked by required conditions

Маска телефона: onBeforeInput больше не блокирует ВСТАВКУ. Раньше он
отменял любой ввод с не-цифрами в data, из-за чего вставка «+7 701…» /
«8 (701) 000-00-00» через CDP insertText блокировалась целиком и номер
пропадал («+7 »). Теперь блокируется только одиночный набранный не-цифровой
символ; вставку нормализует handleChange. Обе копии (public + admin).
Проверено в реальном Chromium (Playwright): посимвольный ввод (delay 0 и 20),
все варианты вставки и Backspace посреди номера → «+7 701 000 00 00».

1. Мастер «Первые шаги», шаг каталога: число товаров с разделителем разрядов
   и склонением («30 951 товар»); текст исправлен — закупочная и себестоимость
   приходят из реестра вместе с товаром, оставлено «Проверьте продажные цены —
   они взяты из реестра».
2. Прибыль на главной: убрана фраза про «переход на FIFO» (внутренняя кухня);
   оставлено «Прибыль приблизительная — по текущей себестоимости из карточек».

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
nns 2026-10-12 22:10:20 +05:00
parent 0ce0e0df77
commit 6510ccafb5
4 changed files with 31 additions and 5 deletions

View file

@ -72,7 +72,16 @@ export function PhoneInput({ value, onChange, className, disabled, ...rest }: Ph
const handleBeforeInput = (e: FormEvent<HTMLInputElement>) => {
const native = e.nativeEvent as InputEvent
if (native.data && /\D/.test(native.data)) e.preventDefault()
// Блокируем ТОЛЬКО одиночный набранный не-цифровой символ (буква/знак при
// печати). Вставку (insertFromPaste, либо insertText с многосимвольной
// строкой) НЕ трогаем — её очистит и нормализует handleChange, иначе
// вставка «+7 701…» / «8 (701)…» блокировалась целиком и номер пропадал.
if (native.inputType === 'insertText'
&& typeof native.data === 'string'
&& native.data.length === 1
&& /\D/.test(native.data)) {
e.preventDefault()
}
}
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {

View file

@ -99,7 +99,14 @@ export function PhoneInput({ value, onChange, className, disabled, ...rest }: Ph
// deleteContentBackward и т.п. — там не вмешиваемся, пусть браузер удаляет.
const handleBeforeInput = (e: FormEvent<HTMLInputElement>) => {
const native = e.nativeEvent as InputEvent
if (native.data && /\D/.test(native.data)) {
// Блокируем ТОЛЬКО одиночный набранный не-цифровой символ. Вставку
// (insertFromPaste или insertText с многосимвольной строкой) пропускаем —
// её нормализует handleChange, иначе вставка «+7 701…» / «8 (701)…»
// блокировалась целиком и номер пропадал.
if (native.inputType === 'insertText'
&& typeof native.data === 'string'
&& native.data.length === 1
&& /\D/.test(native.data)) {
e.preventDefault()
}
}

View file

@ -46,7 +46,7 @@ export function ProfitHomeBlock() {
<Card label="Прибыль за месяц" q={month} />
</div>
<p className="mt-1.5 text-[11px] text-slate-400">
Прибыль приблизительная (по текущей себестоимости из карточек). Точной станет после перехода на FIFO.
Прибыль приблизительная — считается по текущей себестоимости из карточек товаров.
</p>
</div>
)

View file

@ -4,6 +4,16 @@ import { PageHeader } from '@/components/PageHeader'
import { useOnboardingProgress } from '@/lib/useOnboardingProgress'
import { isOnboardingHidden, setOnboardingHidden } from '@/lib/onboardingPrefs'
/** Русское склонение «товар»: 1 товар, 2–4 товара, 5+ товаров (с учётом 11–14). */
function pluralProduct(n: number): string {
const mod100 = n % 100
const mod10 = n % 10
if (mod100 >= 11 && mod100 <= 14) return 'товаров'
if (mod10 === 1) return 'товар'
if (mod10 >= 2 && mod10 <= 4) return 'товара'
return 'товаров'
}
interface StepCard {
done: boolean
badge: string
@ -44,8 +54,8 @@ export function OnboardingPage() {
? {
done: true,
badge: 'Каталог',
title: `Каталог готов: ${p.productCount} товаров из реестра ALL MARKET`,
description: 'Товары скопированы из реестра ALL MARKET. Проверьте продажные цены — закупочные и себестоимость появятся после первой приёмки.',
title: `Каталог готов: ${p.productCount.toLocaleString('ru-RU')} ${pluralProduct(p.productCount)} из реестра ALL MARKET`,
description: 'Товары скопированы из реестра ALL MARKET вместе с закупочной ценой и себестоимостью. Проверьте продажные цены — они взяты из реестра.',
ctaLabel: 'Проверить продажные цены',
ctaTo: '/catalog/products',
icon: Package,