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
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:
parent
0ce0e0df77
commit
6510ccafb5
|
|
@ -72,7 +72,16 @@ export function PhoneInput({ value, onChange, className, disabled, ...rest }: Ph
|
||||||
|
|
||||||
const handleBeforeInput = (e: FormEvent<HTMLInputElement>) => {
|
const handleBeforeInput = (e: FormEvent<HTMLInputElement>) => {
|
||||||
const native = e.nativeEvent as InputEvent
|
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>) => {
|
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,14 @@ export function PhoneInput({ value, onChange, className, disabled, ...rest }: Ph
|
||||||
// deleteContentBackward и т.п. — там не вмешиваемся, пусть браузер удаляет.
|
// deleteContentBackward и т.п. — там не вмешиваемся, пусть браузер удаляет.
|
||||||
const handleBeforeInput = (e: FormEvent<HTMLInputElement>) => {
|
const handleBeforeInput = (e: FormEvent<HTMLInputElement>) => {
|
||||||
const native = e.nativeEvent as InputEvent
|
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()
|
e.preventDefault()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ export function ProfitHomeBlock() {
|
||||||
<Card label="Прибыль за месяц" q={month} />
|
<Card label="Прибыль за месяц" q={month} />
|
||||||
</div>
|
</div>
|
||||||
<p className="mt-1.5 text-[11px] text-slate-400">
|
<p className="mt-1.5 text-[11px] text-slate-400">
|
||||||
Прибыль приблизительная (по текущей себестоимости из карточек). Точной станет после перехода на FIFO.
|
Прибыль приблизительная — считается по текущей себестоимости из карточек товаров.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,16 @@ import { PageHeader } from '@/components/PageHeader'
|
||||||
import { useOnboardingProgress } from '@/lib/useOnboardingProgress'
|
import { useOnboardingProgress } from '@/lib/useOnboardingProgress'
|
||||||
import { isOnboardingHidden, setOnboardingHidden } from '@/lib/onboardingPrefs'
|
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 {
|
interface StepCard {
|
||||||
done: boolean
|
done: boolean
|
||||||
badge: string
|
badge: string
|
||||||
|
|
@ -44,8 +54,8 @@ export function OnboardingPage() {
|
||||||
? {
|
? {
|
||||||
done: true,
|
done: true,
|
||||||
badge: 'Каталог',
|
badge: 'Каталог',
|
||||||
title: `Каталог готов: ${p.productCount} товаров из реестра ALL MARKET`,
|
title: `Каталог готов: ${p.productCount.toLocaleString('ru-RU')} ${pluralProduct(p.productCount)} из реестра ALL MARKET`,
|
||||||
description: 'Товары скопированы из реестра ALL MARKET. Проверьте продажные цены — закупочные и себестоимость появятся после первой приёмки.',
|
description: 'Товары скопированы из реестра ALL MARKET вместе с закупочной ценой и себестоимостью. Проверьте продажные цены — они взяты из реестра.',
|
||||||
ctaLabel: 'Проверить продажные цены',
|
ctaLabel: 'Проверить продажные цены',
|
||||||
ctaTo: '/catalog/products',
|
ctaTo: '/catalog/products',
|
||||||
icon: Package,
|
icon: Package,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue