This commit is contained in:
54CHA
2025-07-29 18:55:22 +03:00
parent 1da9c6ac09
commit 72a9772934
19 changed files with 923 additions and 520 deletions

View File

@ -72,6 +72,10 @@ const BestPriceCard: React.FC<BestPriceCardProps> = ({
return parseFloat(cleanPrice) || 0;
};
// Note: BestPriceCard doesn't receive isInCart flags from backend
// Since it's a summary component, we'll remove cart state checking for now
const inCart = false; // Disabled for BestPriceCard
// Обработчик добавления в корзину
const handleAddToCart = async (e: React.MouseEvent) => {
e.preventDefault();
@ -108,10 +112,14 @@ const BestPriceCard: React.FC<BestPriceCardProps> = ({
});
if (result.success) {
// Показываем тоастер об успешном добавлении
// Показываем тоастер с разным текстом в зависимости от того, был ли товар уже в корзине
const toastMessage = inCart
? `Количество увеличено (+${count} шт.)`
: 'Товар добавлен в корзину!';
toast.success(
<div>
<div className="font-semibold" style={{ color: '#fff' }}>Товар добавлен в корзину!</div>
<div className="font-semibold" style={{ color: '#fff' }}>{toastMessage}</div>
<div className="text-sm" style={{ color: '#fff', opacity: 0.9 }}>{`${offer.brand} ${offer.articleNumber} (${count} шт.)`}</div>
</div>,
{
@ -176,17 +184,55 @@ const BestPriceCard: React.FC<BestPriceCardProps> = ({
</div>
</div>
<div className="w-layout-hflex flex-block-42">
<button
type="button"
onClick={handleAddToCart}
className="button-icon w-inline-block"
style={{ cursor: 'pointer', textDecoration: 'none' }}
aria-label="Добавить в корзину"
>
<div className="div-block-26">
<div className="icon-setting w-embed"><svg width="currentWidht" height="currentHeight" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M10.1998 22.2C8.8798 22.2 7.81184 23.28 7.81184 24.6C7.81184 25.92 8.8798 27 10.1998 27C11.5197 27 12.5997 25.92 12.5997 24.6C12.5997 23.28 11.5197 22.2 10.1998 22.2ZM3 3V5.4H5.39992L9.71977 14.508L8.09982 17.448C7.90783 17.784 7.79984 18.18 7.79984 18.6C7.79984 19.92 8.8798 21 10.1998 21H24.5993V18.6H10.7037C10.5357 18.6 10.4037 18.468 10.4037 18.3L10.4397 18.156L11.5197 16.2H20.4594C21.3594 16.2 22.1513 15.708 22.5593 14.964L26.8552 7.176C26.9542 6.99286 27.004 6.78718 26.9997 6.57904C26.9955 6.37089 26.9373 6.16741 26.8309 5.98847C26.7245 5.80952 26.5736 5.66124 26.3927 5.55809C26.2119 5.45495 26.0074 5.40048 25.7992 5.4H8.05183L6.92387 3H3ZM22.1993 22.2C20.8794 22.2 19.8114 23.28 19.8114 24.6C19.8114 25.92 20.8794 27 22.1993 27C23.5193 27 24.5993 25.92 24.5993 24.6C24.5993 23.28 23.5193 22.2 22.1993 22.2Z" fill="currentColor"/></svg></div>
</div>
</button>
<div style={{ position: 'relative', display: 'inline-block' }}>
<button
type="button"
onClick={handleAddToCart}
className={`button-icon w-inline-block ${inCart ? 'in-cart' : ''}`}
style={{
cursor: 'pointer',
textDecoration: 'none',
opacity: inCart ? 0.5 : 1,
backgroundColor: inCart ? '#9ca3af' : undefined
}}
aria-label={inCart ? "Товар уже в корзине" : "Добавить в корзину"}
title={inCart ? "Товар уже в корзине - нажмите для добавления еще" : "Добавить в корзину"}
>
<div className="div-block-26">
<div
className="icon-setting w-embed"
style={{
filter: inCart ? 'brightness(0.7)' : undefined
}}
>
<svg width="currentWidht" height="currentHeight" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M10.1998 22.2C8.8798 22.2 7.81184 23.28 7.81184 24.6C7.81184 25.92 8.8798 27 10.1998 27C11.5197 27 12.5997 25.92 12.5997 24.6C12.5997 23.28 11.5197 22.2 10.1998 22.2ZM3 3V5.4H5.39992L9.71977 14.508L8.09982 17.448C7.90783 17.784 7.79984 18.18 7.79984 18.6C7.79984 19.92 8.8798 21 10.1998 21H24.5993V18.6H10.7037C10.5357 18.6 10.4037 18.468 10.4037 18.3L10.4397 18.156L11.5197 16.2H20.4594C21.3594 16.2 22.1513 15.708 22.5593 14.964L26.8552 7.176C26.9542 6.99286 27.004 6.78718 26.9997 6.57904C26.9955 6.37089 26.9373 6.16741 26.8309 5.98847C26.7245 5.80952 26.5736 5.66124 26.3927 5.55809C26.2119 5.45495 26.0074 5.40048 25.7992 5.4H8.05183L6.92387 3H3ZM22.1993 22.2C20.8794 22.2 19.8114 23.28 19.8114 24.6C19.8114 25.92 20.8794 27 22.1993 27C23.5193 27 24.5993 25.92 24.5993 24.6C24.5993 23.28 23.5193 22.2 22.1993 22.2Z" fill="currentColor"/></svg>
</div>
</div>
</button>
{inCart && (
<div
style={{
position: 'absolute',
top: '-8px',
right: '-8px',
backgroundColor: '#22c55e',
color: 'white',
borderRadius: '50%',
width: '16px',
height: '16px',
fontSize: '10px',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
fontWeight: 'bold',
zIndex: 1
}}
title="В корзине"
>
</div>
)}
</div>
</div>
</div>
</div>

View File

@ -122,7 +122,6 @@ const BestPriceItem: React.FC<BestPriceItemProps> = ({
currency: 'RUB',
image: image
});
toast.success('Товар добавлен в избранное');
}
};

View File

@ -1,79 +1,54 @@
import React, { useState, useEffect } from 'react';
import React from 'react';
import { useCart } from '@/contexts/CartContext';
const CartDebug: React.FC = () => {
const { state, addItem, clearCart } = useCart();
const [debugInfo, setDebugInfo] = useState<any>({});
const { state, isInCart } = useCart();
useEffect(() => {
if (typeof window !== 'undefined') {
const cartState = localStorage.getItem('cartState');
const cartSummaryState = localStorage.getItem('cartSummaryState');
const oldCart = localStorage.getItem('cart');
setDebugInfo({
cartState: cartState ? JSON.parse(cartState) : null,
cartSummaryState: cartSummaryState ? JSON.parse(cartSummaryState) : null,
oldCart: oldCart ? JSON.parse(oldCart) : null,
currentItems: state.items.length
});
}
}, [state.items]);
if (process.env.NODE_ENV !== 'development') {
return null;
}
const addTestItem = () => {
addItem({
name: 'Тестовый товар',
description: 'Описание тестового товара',
article: 'TEST123',
brand: 'TestBrand',
price: 1000,
currency: 'RUB',
quantity: 1,
image: '',
productId: 'test-product',
offerKey: 'test-offer',
isExternal: false
});
};
const clearStorage = () => {
if (typeof window !== 'undefined') {
localStorage.removeItem('cartState');
localStorage.removeItem('cartSummaryState');
localStorage.removeItem('cart');
window.location.reload();
}
};
// Test the isInCart function with some example values from the cart
const testItem = state.items[0];
const testResult = testItem ? isInCart(testItem.productId, testItem.offerKey, testItem.article, testItem.brand) : false;
return (
<div style={{
position: 'fixed',
top: '10px',
right: '10px',
background: 'white',
border: '1px solid #ccc',
padding: '10px',
borderRadius: '5px',
maxWidth: '300px',
fontSize: '12px',
zIndex: 9999
}}>
<h4>Cart Debug</h4>
<button onClick={addTestItem} style={{ marginBottom: '5px', marginRight: '5px' }}>
Добавить товар
</button>
<button onClick={clearCart} style={{ marginBottom: '5px', marginRight: '5px' }}>
Очистить корзину
</button>
<button onClick={clearStorage} style={{ marginBottom: '10px' }}>
Очистить localStorage
</button>
<div>
<strong>Товаров в корзине:</strong> {state.items.length}
</div>
<pre style={{ fontSize: '10px', maxHeight: '200px', overflow: 'auto' }}>
{JSON.stringify(debugInfo, null, 2)}
</pre>
<div
style={{
position: 'fixed',
top: '10px',
right: '10px',
background: 'rgba(0,0,0,0.9)',
color: 'white',
padding: '10px',
borderRadius: '5px',
fontSize: '11px',
maxWidth: '350px',
zIndex: 9999,
maxHeight: '400px',
overflow: 'auto'
}}
>
<div style={{ fontWeight: 'bold', marginBottom: '5px' }}>🛒 Cart Debug: {state.items.length} items</div>
{testItem && (
<div style={{ background: 'rgba(255,255,255,0.1)', padding: '5px', marginBottom: '5px', fontSize: '10px' }}>
<div>Testing isInCart for first item:</div>
<div>Brand: {testItem.brand}, Article: {testItem.article}</div>
<div>Result: {testResult ? '✅ Found' : '❌ Not found'}</div>
</div>
)}
{state.items.slice(0, 6).map((item, idx) => (
<div key={idx} style={{ fontSize: '9px', marginTop: '3px', borderBottom: '1px solid rgba(255,255,255,0.2)', paddingBottom: '2px' }}>
{item.brand} {item.article}
{item.productId && <div style={{ color: '#90EE90' }}>PID: {item.productId.substring(0, 8)}...</div>}
{item.offerKey && <div style={{ color: '#87CEEB' }}>OK: {item.offerKey.substring(0, 15)}...</div>}
</div>
))}
{state.items.length > 6 && (
<div style={{ fontSize: '9px', marginTop: '3px', opacity: 0.7 }}>
...и еще {state.items.length - 6} товаров
</div>
)}
</div>
);
};

View File

@ -17,6 +17,7 @@ interface CatalogProductCardProps {
currency?: string;
priceElement?: React.ReactNode; // Элемент для отображения цены (например, скелетон)
onAddToCart?: (e: React.MouseEvent) => void | Promise<void>;
isInCart?: boolean;
}
const CatalogProductCard: React.FC<CatalogProductCardProps> = ({
@ -34,6 +35,7 @@ const CatalogProductCard: React.FC<CatalogProductCardProps> = ({
currency = 'RUB',
priceElement,
onAddToCart,
isInCart = false,
}) => {
const { addToFavorites, removeFromFavorites, isFavorite, favorites } = useFavorites();
@ -150,7 +152,15 @@ const CatalogProductCard: React.FC<CatalogProductCardProps> = ({
</Link>
{/* Обновляем кнопку купить */}
<div className="catc w-inline-block" onClick={handleBuyClick} style={{ cursor: 'pointer' }}>
<div
className="catc w-inline-block"
onClick={handleBuyClick}
style={{
cursor: isInCart ? 'default' : 'pointer',
opacity: isInCart ? 0.5 : 1,
filter: isInCart ? 'grayscale(1)' : 'none'
}}
>
<div className="div-block-25">
<div className="icon-setting w-embed">
<svg width="currentWidht" height="currentHeight" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
@ -158,7 +168,7 @@ const CatalogProductCard: React.FC<CatalogProductCardProps> = ({
</svg>
</div>
</div>
<div className="text-block-6">Купить</div>
<div className="text-block-6">{isInCart ? 'В корзине' : 'Купить'}</div>
</div>
</div>
);

View File

@ -21,6 +21,8 @@ interface CoreProductCardOffer {
warehouse?: string;
supplier?: string;
deliveryTime?: number;
hasStock?: boolean;
isInCart?: boolean;
}
interface CoreProductCardProps {
@ -34,6 +36,7 @@ interface CoreProductCardProps {
isLoadingOffers?: boolean;
onLoadOffers?: () => void;
partsIndexPowered?: boolean;
hasStock?: boolean;
}
const CoreProductCard: React.FC<CoreProductCardProps> = ({
@ -46,7 +49,8 @@ const CoreProductCard: React.FC<CoreProductCardProps> = ({
isAnalog = false,
isLoadingOffers = false,
onLoadOffers,
partsIndexPowered = false
partsIndexPowered = false,
hasStock = true
}) => {
const { addItem } = useCart();
const { addToFavorites, removeFromFavorites, isFavorite, favorites } = useFavorites();
@ -120,6 +124,8 @@ const CoreProductCard: React.FC<CoreProductCardProps> = ({
brand
);
// Теперь используем isInCart флаг из backend вместо frontend проверки
const handleInputChange = (idx: number, val: string) => {
setInputValues(prev => ({ ...prev, [idx]: val }));
if (val === "") return;
@ -154,6 +160,7 @@ const CoreProductCard: React.FC<CoreProductCardProps> = ({
const handleAddToCart = async (offer: CoreProductCardOffer, index: number) => {
const quantity = quantities[index] || 1;
const availableStock = parseStock(offer.pcs);
const inCart = offer.isInCart || false; // Use backend flag
const numericPrice = parsePrice(offer.price);
@ -176,10 +183,14 @@ const CoreProductCard: React.FC<CoreProductCardProps> = ({
});
if (result.success) {
// Показываем тоастер вместо alert
// Показываем тоастер с разным текстом в зависимости от того, был ли товар уже в корзине
const toastMessage = inCart
? `Количество увеличено (+${quantity} шт.)`
: 'Товар добавлен в корзину!';
toast.success(
<div>
<div className="font-semibold" style={{ color: '#fff' }}>Товар добавлен в корзину!</div>
<div className="font-semibold" style={{ color: '#fff' }}>{toastMessage}</div>
<div className="text-sm" style={{ color: '#fff', opacity: 0.9 }}>{`${brand} ${article} (${quantity} шт.)`}</div>
</div>,
{
@ -256,7 +267,7 @@ const CoreProductCard: React.FC<CoreProductCardProps> = ({
if (!offers || offers.length === 0) {
return (
<div className="w-layout-hflex core-product-search-s1">
<div className={`w-layout-hflex core-product-search-s1 ${!hasStock ? 'out-of-stock-highlight' : ''}`} style={!hasStock ? { backgroundColor: '#fee', borderColor: '#f87171' } : {}}>
<div className="w-layout-vflex core-product-s1">
<div className="w-layout-vflex flex-block-47">
<div className="div-block-19">
@ -266,6 +277,19 @@ const CoreProductCard: React.FC<CoreProductCardProps> = ({
<div className="w-layout-hflex flex-block-79">
<h3 className="heading-10 name">{brand}</h3>
<h3 className="heading-10">{article}</h3>
{!hasStock && (
<span className="out-of-stock-badge" style={{
backgroundColor: '#dc2626',
color: 'white',
padding: '2px 8px',
borderRadius: '4px',
fontSize: '12px',
fontWeight: '500',
marginLeft: '8px'
}}>
Нет в наличии
</span>
)}
</div>
<div className="text-block-21">{name}</div>
</div>
@ -299,7 +323,7 @@ const CoreProductCard: React.FC<CoreProductCardProps> = ({
return (
<>
<div className="w-layout-hflex core-product-search-s1">
<div className={`w-layout-hflex core-product-search-s1 ${!hasStock ? 'out-of-stock-highlight' : ''}`} style={!hasStock ? { backgroundColor: '#fee', borderColor: '#f87171' } : {}}>
<div className="w-layout-vflex flex-block-48-copy">
<div className="w-layout-vflex product-list-search-s1">
@ -315,6 +339,19 @@ const CoreProductCard: React.FC<CoreProductCardProps> = ({
<div className="flex flex-row flex-nowrap items-center gap-2">
<h3 className="heading-10 name" style={{marginRight: 8}}>{brand}</h3>
<h3 className="heading-10" style={{marginRight: 8}}>{article}</h3>
{!hasStock && (
<span className="out-of-stock-badge" style={{
backgroundColor: '#dc2626',
color: 'white',
padding: '2px 8px',
borderRadius: '4px',
fontSize: '12px',
fontWeight: '500',
marginLeft: '8px'
}}>
Нет в наличии
</span>
)}
<div
className="favorite-icon w-embed"
onClick={handleFavoriteClick}
@ -370,6 +407,10 @@ const CoreProductCard: React.FC<CoreProductCardProps> = ({
{displayedOffers.map((offer, idx) => {
const isLast = idx === displayedOffers.length - 1;
const maxCount = parseStock(offer.pcs);
const inCart = offer.isInCart || false; // Use backend flag
// Backend now provides isInCart flag directly
return (
<div
className="w-layout-hflex product-item-search-s1"
@ -439,17 +480,56 @@ const CoreProductCard: React.FC<CoreProductCardProps> = ({
</div>
</div>
</div>
<button
type="button"
onClick={() => handleAddToCart(offer, idx)}
className="button-icon w-inline-block"
style={{ cursor: 'pointer' }}
aria-label="Добавить в корзину"
>
<div className="div-block-26">
<img loading="lazy" src="/images/cart_icon.svg" alt="В корзину" className="image-11" />
</div>
</button>
<div style={{ position: 'relative', display: 'inline-block' }}>
<button
type="button"
onClick={() => handleAddToCart(offer, idx)}
className={`button-icon w-inline-block ${inCart ? 'in-cart' : ''}`}
style={{
cursor: 'pointer',
opacity: inCart ? 0.5 : 1,
backgroundColor: inCart ? '#9ca3af' : undefined
}}
aria-label={inCart ? "Товар уже в корзине" : "Добавить в корзину"}
title={inCart ? "Товар уже в корзине - нажмите для добавления еще" : "Добавить в корзину"}
>
<div className="div-block-26">
<img
loading="lazy"
src="/images/cart_icon.svg"
alt={inCart ? "В корзине" : "В корзину"}
className="image-11"
style={{
filter: inCart ? 'brightness(0.7)' : undefined
}}
/>
</div>
</button>
{inCart && (
<div
style={{
position: 'absolute',
top: '-8px',
right: '-8px',
backgroundColor: '#22c55e',
color: 'white',
borderRadius: '50%',
width: '16px',
height: '16px',
fontSize: '10px',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
fontWeight: 'bold',
zIndex: 1
}}
title="В корзине"
>
</div>
)}
</div>
</div>
</div>
</div>

View File

@ -89,7 +89,6 @@ const TopSalesItem: React.FC<TopSalesItemProps> = ({
currency: 'RUB',
image: image
});
toast.success('Товар добавлен в избранное');
}
};

View File

@ -112,6 +112,19 @@ const LegalEntityFormBlock: React.FC<LegalEntityFormBlockProps> = ({
onAdd,
onCancel,
}) => {
// Состояния для отображения ошибок валидации
const [validationErrors, setValidationErrors] = React.useState({
inn: false,
shortName: false,
jurAddress: false,
form: false,
taxSystem: false,
});
// Функция для очистки ошибки при изменении поля
const clearError = (field: keyof typeof validationErrors) => {
setValidationErrors(prev => ({ ...prev, [field]: false }));
};
const [createLegalEntity, { loading: createLoading }] = useMutation(CREATE_CLIENT_LEGAL_ENTITY, {
onCompleted: () => {
console.log('Юридическое лицо создано');
@ -137,29 +150,27 @@ const LegalEntityFormBlock: React.FC<LegalEntityFormBlockProps> = ({
const loading = createLoading || updateLoading;
const handleSave = async () => {
// Валидация
if (!inn || inn.length < 10) {
alert('Введите корректный ИНН');
return;
}
// Сброс предыдущих ошибок
setValidationErrors({
inn: false,
shortName: false,
jurAddress: false,
form: false,
taxSystem: false,
});
if (!shortName.trim()) {
alert('Введите краткое наименование');
return;
}
// Валидация с установкой ошибок
const errors = {
inn: !inn || inn.length < 10,
shortName: !shortName.trim(),
jurAddress: !jurAddress.trim(),
form: form === 'Выбрать',
taxSystem: taxSystem === 'Выбрать',
};
if (!jurAddress.trim()) {
alert('Введите юридический адрес');
return;
}
if (form === 'Выбрать') {
alert('Выберите форму организации');
return;
}
if (taxSystem === 'Выбрать') {
alert('Выберите систему налогообложения');
// Если есть ошибки, устанавливаем их и прерываем выполнение
if (Object.values(errors).some(error => error)) {
setValidationErrors(errors);
return;
}
@ -238,13 +249,18 @@ const LegalEntityFormBlock: React.FC<LegalEntityFormBlockProps> = ({
<div className="flex flex-wrap gap-5 items-start w-full whitespace-nowrap max-md:max-w-full">
<div className="flex flex-col flex-1 shrink basis-0 min-w-[240px]">
<div className="text-gray-950">ИНН</div>
<div className="gap-2.5 self-stretch px-6 py-3.5 mt-1.5 w-full bg-white rounded border border-solid border-stone-300 min-h-[46px] max-md:px-5">
<div className={`gap-2.5 self-stretch px-6 py-3.5 mt-1.5 w-full bg-white rounded border border-solid min-h-[46px] max-md:px-5 ${
validationErrors.inn ? 'border-red-500' : 'border-stone-300'
}`}>
<input
type="text"
placeholder="ИНН"
className="w-full bg-transparent outline-none text-gray-600"
value={inn}
onChange={e => setInn(e.target.value)}
onChange={e => {
setInn(e.target.value);
clearError('inn');
}}
/>
</div>
</div>
@ -252,7 +268,9 @@ const LegalEntityFormBlock: React.FC<LegalEntityFormBlockProps> = ({
<div className="text-gray-950">Форма</div>
<div className="relative mt-1.5">
<div
className="flex gap-10 justify-between items-center px-6 py-3.5 w-full bg-white rounded border border-solid border-stone-300 min-h-[46px] text-neutral-500 max-md:px-5 cursor-pointer select-none"
className={`flex gap-10 justify-between items-center px-6 py-3.5 w-full bg-white rounded border border-solid min-h-[46px] text-neutral-500 max-md:px-5 cursor-pointer select-none ${
validationErrors.form ? 'border-red-500' : 'border-stone-300'
}`}
onClick={() => setIsFormOpen((prev: boolean) => !prev)}
tabIndex={0}
onBlur={() => setIsFormOpen(false)}
@ -266,7 +284,11 @@ const LegalEntityFormBlock: React.FC<LegalEntityFormBlockProps> = ({
<li
key={option}
className={`px-6 py-3.5 cursor-pointer hover:bg-blue-100 ${option === form ? 'bg-blue-50 font-semibold' : ''}`}
onMouseDown={() => { setForm(option); setIsFormOpen(false); }}
onMouseDown={() => {
setForm(option);
setIsFormOpen(false);
clearError('form');
}}
>
{option}
</li>
@ -303,25 +325,35 @@ const LegalEntityFormBlock: React.FC<LegalEntityFormBlockProps> = ({
<div className="flex flex-wrap gap-5 items-start mt-5 w-full max-md:max-w-full">
<div className="flex flex-col flex-1 shrink basis-0 min-w-[240px]">
<div className="text-gray-950">Юридический адрес</div>
<div className="gap-2.5 self-stretch px-6 py-3.5 mt-1.5 w-full bg-white rounded border border-solid border-stone-300 min-h-[46px] text-neutral-500 max-md:px-5">
<div className={`gap-2.5 self-stretch px-6 py-3.5 mt-1.5 w-full bg-white rounded border border-solid min-h-[46px] text-neutral-500 max-md:px-5 ${
validationErrors.jurAddress ? 'border-red-500' : 'border-stone-300'
}`}>
<input
type="text"
placeholder="Юридический адрес"
className="w-full bg-transparent outline-none text-neutral-500"
value={jurAddress}
onChange={e => setJurAddress(e.target.value)}
onChange={e => {
setJurAddress(e.target.value);
clearError('jurAddress');
}}
/>
</div>
</div>
<div className="flex flex-col flex-1 shrink basis-0 min-w-[240px]">
<div className="text-gray-950">Краткое наименование</div>
<div className="gap-2.5 self-stretch px-6 py-3.5 mt-1.5 w-full bg-white rounded border border-solid border-stone-300 min-h-[46px] text-neutral-500 max-md:px-5">
<div className={`gap-2.5 self-stretch px-6 py-3.5 mt-1.5 w-full bg-white rounded border border-solid min-h-[46px] text-neutral-500 max-md:px-5 ${
validationErrors.shortName ? 'border-red-500' : 'border-stone-300'
}`}>
<input
type="text"
placeholder="Краткое наименование"
className="w-full bg-transparent outline-none text-neutral-500"
value={shortName}
onChange={e => setShortName(e.target.value)}
onChange={e => {
setShortName(e.target.value);
clearError('shortName');
}}
/>
</div>
</div>
@ -355,7 +387,9 @@ const LegalEntityFormBlock: React.FC<LegalEntityFormBlockProps> = ({
<div className="text-gray-950">Система налогоблажения</div>
<div className="relative mt-1.5">
<div
className="flex gap-10 justify-between items-center px-6 py-3.5 w-full whitespace-nowrap bg-white rounded border border-solid border-stone-300 min-h-[46px] text-neutral-500 max-md:px-5 cursor-pointer select-none"
className={`flex gap-10 justify-between items-center px-6 py-3.5 w-full whitespace-nowrap bg-white rounded border border-solid min-h-[46px] text-neutral-500 max-md:px-5 cursor-pointer select-none ${
validationErrors.taxSystem ? 'border-red-500' : 'border-stone-300'
}`}
onClick={() => setIsTaxSystemOpen((prev: boolean) => !prev)}
tabIndex={0}
onBlur={() => setIsTaxSystemOpen(false)}
@ -369,7 +403,11 @@ const LegalEntityFormBlock: React.FC<LegalEntityFormBlockProps> = ({
<li
key={option}
className={`px-6 py-3.5 cursor-pointer hover:bg-blue-100 ${option === taxSystem ? 'bg-blue-50 font-semibold' : ''}`}
onMouseDown={() => { setTaxSystem(option); setIsTaxSystemOpen(false); }}
onMouseDown={() => {
setTaxSystem(option);
setIsTaxSystemOpen(false);
clearError('taxSystem');
}}
>
{option}
</li>