diff --git a/src/food-market.public/src/components/PhoneInput.tsx b/src/food-market.public/src/components/PhoneInput.tsx index eedadc0..6031b3f 100644 --- a/src/food-market.public/src/components/PhoneInput.tsx +++ b/src/food-market.public/src/components/PhoneInput.tsx @@ -72,7 +72,16 @@ export function PhoneInput({ value, onChange, className, disabled, ...rest }: Ph const handleBeforeInput = (e: FormEvent) => { 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) => { diff --git a/src/food-market.web/src/components/PhoneInput.tsx b/src/food-market.web/src/components/PhoneInput.tsx index e2a2e59..9933041 100644 --- a/src/food-market.web/src/components/PhoneInput.tsx +++ b/src/food-market.web/src/components/PhoneInput.tsx @@ -99,7 +99,14 @@ export function PhoneInput({ value, onChange, className, disabled, ...rest }: Ph // deleteContentBackward и т.п. — там не вмешиваемся, пусть браузер удаляет. const handleBeforeInput = (e: FormEvent) => { 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() } } diff --git a/src/food-market.web/src/components/ProfitHomeBlock.tsx b/src/food-market.web/src/components/ProfitHomeBlock.tsx index 8bae62a..0ae7166 100644 --- a/src/food-market.web/src/components/ProfitHomeBlock.tsx +++ b/src/food-market.web/src/components/ProfitHomeBlock.tsx @@ -46,7 +46,7 @@ export function ProfitHomeBlock() {

- Прибыль приблизительная (по текущей себестоимости из карточек). Точной станет после перехода на FIFO. + Прибыль приблизительная — считается по текущей себестоимости из карточек товаров.

) diff --git a/src/food-market.web/src/pages/OnboardingPage.tsx b/src/food-market.web/src/pages/OnboardingPage.tsx index 24333a0..bbac961 100644 --- a/src/food-market.web/src/pages/OnboardingPage.tsx +++ b/src/food-market.web/src/pages/OnboardingPage.tsx @@ -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,