Compare commits
5 Commits
numbers
...
4a3da4d5c5
Author | SHA1 | Date | |
---|---|---|---|
4a3da4d5c5 | |||
f894b7e023 | |||
a879e5e5e7 | |||
85f7634158 | |||
5e454a7367 |
@ -208,7 +208,7 @@ const CatalogGroupsSection: React.FC<CatalogGroupsSectionProps> = ({
|
||||
vehicleId,
|
||||
...(ssd && ssd.trim() !== '' && { ssd })
|
||||
},
|
||||
skip: !catalogCode || !vehicleId || catalogType !== 'quickGroups',
|
||||
skip: !catalogCode || vehicleId === undefined || vehicleId === null || catalogType !== 'quickGroups',
|
||||
errorPolicy: 'all'
|
||||
}
|
||||
);
|
||||
|
@ -33,7 +33,7 @@ const CategoriesSection: React.FC<CategoriesSectionProps> = ({
|
||||
vehicleId,
|
||||
...(ssd && ssd.trim() !== '' && { ssd })
|
||||
},
|
||||
skip: !catalogCode || !vehicleId,
|
||||
skip: !catalogCode || vehicleId === undefined || vehicleId === null,
|
||||
errorPolicy: 'all'
|
||||
}
|
||||
);
|
||||
|
@ -187,13 +187,13 @@ const GroupDetailsSection: React.FC<GroupDetailsSectionProps> = ({
|
||||
const { data, loading, error } = useQuery<{ laximoQuickDetail: LaximoQuickDetail }>(
|
||||
GET_LAXIMO_QUICK_DETAIL,
|
||||
{
|
||||
variables: {
|
||||
variables: quickGroupId ? {
|
||||
catalogCode,
|
||||
vehicleId,
|
||||
quickGroupId,
|
||||
ssd
|
||||
},
|
||||
skip: !catalogCode || !vehicleId || !quickGroupId || !ssd,
|
||||
} : undefined,
|
||||
skip: !catalogCode || vehicleId === undefined || vehicleId === null || !quickGroupId || !ssd || ssd.trim() === '',
|
||||
errorPolicy: 'all'
|
||||
}
|
||||
);
|
||||
|
@ -30,7 +30,7 @@ const Layout = ({ children }: { children: React.ReactNode }) => {
|
||||
onSuccess={handleAuthSuccess}
|
||||
/>
|
||||
</header>
|
||||
<main className="pt-[132px]">{children}</main>
|
||||
<main className="pt-[108px] md:pt-[131px]">{children}</main>
|
||||
<MobileMenuBottomSection onOpenAuthModal={() => setAuthModalOpen(true)} />
|
||||
</>
|
||||
);
|
||||
|
@ -154,13 +154,13 @@ const QuickDetailSection: React.FC<QuickDetailSectionProps> = ({
|
||||
const { data: quickDetailData, loading: quickDetailLoading, error: quickDetailError } = useQuery<{ laximoQuickDetail: LaximoQuickDetail }>(
|
||||
GET_LAXIMO_QUICK_DETAIL,
|
||||
{
|
||||
variables: {
|
||||
variables: selectedGroup?.quickgroupid ? {
|
||||
catalogCode,
|
||||
vehicleId,
|
||||
quickGroupId: selectedGroup.quickgroupid,
|
||||
ssd
|
||||
},
|
||||
skip: !catalogCode || !vehicleId || !selectedGroup.quickgroupid || !ssd,
|
||||
} : undefined,
|
||||
skip: !catalogCode || vehicleId === undefined || vehicleId === null || !selectedGroup?.quickgroupid || !ssd || ssd.trim() === '',
|
||||
errorPolicy: 'all',
|
||||
fetchPolicy: 'cache-and-network' // Принудительно запрашиваем данные
|
||||
}
|
||||
@ -169,11 +169,28 @@ const QuickDetailSection: React.FC<QuickDetailSectionProps> = ({
|
||||
const quickDetail = quickDetailData?.laximoQuickDetail;
|
||||
|
||||
// Добавляем отладочную информацию
|
||||
console.log('🔍 QuickDetailSection Debug:');
|
||||
console.log('📊 quickDetailData:', quickDetailData);
|
||||
console.log('📋 quickDetail:', quickDetail);
|
||||
console.log('🏗️ quickDetail.units:', quickDetail?.units);
|
||||
console.log('⚙️ Variables:', { catalogCode, vehicleId, quickGroupId: selectedGroup.quickgroupid, ssd });
|
||||
console.log('🔍 QuickDetailSection Debug:', {
|
||||
catalogCode,
|
||||
vehicleId,
|
||||
vehicleIdType: typeof vehicleId,
|
||||
quickGroupId: selectedGroup?.quickgroupid,
|
||||
quickGroupIdType: typeof selectedGroup?.quickgroupid,
|
||||
ssd: ssd ? `${ssd.substring(0, 30)}...` : 'отсутствует',
|
||||
ssdType: typeof ssd,
|
||||
ssdLength: ssd?.length,
|
||||
hasData: !!quickDetailData,
|
||||
hasQuickDetail: !!quickDetail,
|
||||
unitsCount: quickDetail?.units?.length || 0,
|
||||
loading: quickDetailLoading,
|
||||
error: quickDetailError?.message,
|
||||
skipCondition: !catalogCode || vehicleId === undefined || vehicleId === null || !selectedGroup?.quickgroupid || !ssd,
|
||||
skipDetails: {
|
||||
noCatalogCode: !catalogCode,
|
||||
noVehicleId: vehicleId === undefined || vehicleId === null,
|
||||
noQuickGroupId: !selectedGroup?.quickgroupid,
|
||||
noSsd: !ssd
|
||||
}
|
||||
});
|
||||
|
||||
// Если выбран узел для детального просмотра, показываем UnitDetailsSection
|
||||
if (selectedUnit) {
|
||||
@ -213,6 +230,20 @@ const QuickDetailSection: React.FC<QuickDetailSectionProps> = ({
|
||||
}
|
||||
|
||||
if (quickDetailError) {
|
||||
console.error('🚨 QuickDetailSection Error Details:', {
|
||||
message: quickDetailError.message,
|
||||
graphQLErrors: quickDetailError.graphQLErrors,
|
||||
networkError: quickDetailError.networkError,
|
||||
extraInfo: quickDetailError.extraInfo,
|
||||
selectedGroup: selectedGroup,
|
||||
variables: selectedGroup?.quickgroupid ? {
|
||||
catalogCode,
|
||||
vehicleId,
|
||||
quickGroupId: selectedGroup.quickgroupid,
|
||||
ssd
|
||||
} : 'undefined (no variables sent)'
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center justify-between">
|
||||
@ -231,6 +262,33 @@ const QuickDetailSection: React.FC<QuickDetailSectionProps> = ({
|
||||
<h3 className="text-lg font-medium text-red-600 mb-2">Ошибка загрузки деталей</h3>
|
||||
<p className="text-red-700">Не удалось загрузить детали для группы "{selectedGroup.name}"</p>
|
||||
<p className="text-sm text-red-600 mt-2">Ошибка: {quickDetailError.message}</p>
|
||||
|
||||
{/* Отладочная информация */}
|
||||
<details className="mt-4">
|
||||
<summary className="text-sm text-red-700 cursor-pointer hover:text-red-800">
|
||||
🔧 Показать отладочную информацию
|
||||
</summary>
|
||||
<div className="mt-2 p-3 bg-red-100 rounded text-xs">
|
||||
<div><strong>Catalog Code:</strong> {catalogCode}</div>
|
||||
<div><strong>Vehicle ID:</strong> {vehicleId} (type: {typeof vehicleId})</div>
|
||||
<div><strong>Quick Group ID:</strong> {selectedGroup?.quickgroupid} (type: {typeof selectedGroup?.quickgroupid})</div>
|
||||
<div><strong>SSD:</strong> {ssd ? `${ssd.substring(0, 100)}...` : 'отсутствует'} (length: {ssd?.length})</div>
|
||||
<div className="mt-2">
|
||||
<strong>GraphQL Errors:</strong>
|
||||
<pre className="mt-1 text-xs overflow-auto">
|
||||
{JSON.stringify(quickDetailError.graphQLErrors, null, 2)}
|
||||
</pre>
|
||||
</div>
|
||||
{quickDetailError.networkError && (
|
||||
<div className="mt-2">
|
||||
<strong>Network Error:</strong>
|
||||
<pre className="mt-1 text-xs overflow-auto">
|
||||
{JSON.stringify(quickDetailError.networkError, null, 2)}
|
||||
</pre>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@ -464,7 +522,7 @@ const QuickGroupsSection: React.FC<QuickGroupsSectionProps> = ({
|
||||
vehicleId,
|
||||
...(ssd && ssd.trim() !== '' && { ssd })
|
||||
},
|
||||
skip: !catalogCode || !vehicleId,
|
||||
skip: !catalogCode || vehicleId === undefined || vehicleId === null,
|
||||
errorPolicy: 'all'
|
||||
}
|
||||
);
|
||||
|
@ -39,7 +39,7 @@ const UnitDetailsSection: React.FC<UnitDetailsSectionProps> = ({
|
||||
unitId,
|
||||
ssd: ssd || ''
|
||||
},
|
||||
skip: !catalogCode || !vehicleId || !unitId,
|
||||
skip: !catalogCode || vehicleId === undefined || vehicleId === null || !unitId,
|
||||
errorPolicy: 'all'
|
||||
}
|
||||
);
|
||||
@ -54,7 +54,7 @@ const UnitDetailsSection: React.FC<UnitDetailsSectionProps> = ({
|
||||
unitId,
|
||||
ssd: ssd || ''
|
||||
},
|
||||
skip: !catalogCode || !vehicleId || !unitId,
|
||||
skip: !catalogCode || vehicleId === undefined || vehicleId === null || !unitId,
|
||||
errorPolicy: 'all'
|
||||
}
|
||||
);
|
||||
@ -69,7 +69,7 @@ const UnitDetailsSection: React.FC<UnitDetailsSectionProps> = ({
|
||||
unitId,
|
||||
ssd: ssd || ''
|
||||
},
|
||||
skip: !catalogCode || !vehicleId || !unitId,
|
||||
skip: !catalogCode || vehicleId === undefined || vehicleId === null || !unitId,
|
||||
errorPolicy: 'all'
|
||||
}
|
||||
);
|
||||
|
@ -59,7 +59,7 @@ const UnitsSection: React.FC<UnitsSectionProps> = ({
|
||||
categoryId,
|
||||
...(ssd && ssd.trim() !== '' && { ssd })
|
||||
},
|
||||
skip: !catalogCode || !vehicleId || !categoryId,
|
||||
skip: !catalogCode || vehicleId === undefined || vehicleId === null || !categoryId,
|
||||
errorPolicy: 'all',
|
||||
fetchPolicy: 'no-cache', // Полностью отключаем кэширование для гарантии свежих данных
|
||||
notifyOnNetworkStatusChange: true
|
||||
|
@ -110,7 +110,7 @@ const LegalEntityListBlock: React.FC<LegalEntityListBlockProps> = ({ legalEntiti
|
||||
</div>
|
||||
<div
|
||||
layer-name="link_control_element"
|
||||
className="flex relative gap-1.5 items-center cursor-pointer hover:text-red-600"
|
||||
className="flex relative gap-1.5 items-center cursor-pointer group"
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
onClick={() => router.push('/profile-requisites')}
|
||||
@ -130,7 +130,7 @@ const LegalEntityListBlock: React.FC<LegalEntityListBlockProps> = ({ legalEntiti
|
||||
</div>
|
||||
<div
|
||||
layer-name="Редактировать"
|
||||
className="text-sm leading-5 text-gray-600"
|
||||
className="text-sm leading-5 text-gray-600 group-hover:text-red-600"
|
||||
>
|
||||
Реквизиты компании
|
||||
</div>
|
||||
@ -141,8 +141,9 @@ const LegalEntityListBlock: React.FC<LegalEntityListBlockProps> = ({ legalEntiti
|
||||
<div
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
className="flex relative gap-1.5 items-center cursor-pointer hover:text-red-600"
|
||||
className="flex relative gap-1.5 items-center cursor-pointer group"
|
||||
onClick={() => onEdit && onEdit(entity)}
|
||||
aria-label="Редактировать юридическое лицо"
|
||||
>
|
||||
<div className="relative h-4 w-[18px]">
|
||||
<Image
|
||||
@ -153,26 +154,37 @@ const LegalEntityListBlock: React.FC<LegalEntityListBlockProps> = ({ legalEntiti
|
||||
className="absolute left-0.5 top-0"
|
||||
/>
|
||||
</div>
|
||||
<div className="text-sm leading-5 text-gray-600">
|
||||
<div className="text-sm leading-5 text-gray-600 group-hover:text-red-600">
|
||||
Редактировать
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
className="flex relative gap-1.5 items-center cursor-pointer hover:text-red-600"
|
||||
className="flex relative gap-1.5 items-center cursor-pointer group"
|
||||
aria-label="Удалить юридическое лицо"
|
||||
onClick={() => handleDelete(entity.id, entity.shortName)}
|
||||
onKeyDown={e => (e.key === 'Enter' || e.key === ' ') && handleDelete(entity.id, entity.shortName)}
|
||||
style={{ display: 'inline-flex', cursor: 'pointer', transition: 'color 0.2s' }}
|
||||
onMouseEnter={e => {
|
||||
const path = e.currentTarget.querySelector('path');
|
||||
if (path) path.setAttribute('fill', '#ec1c24');
|
||||
}}
|
||||
onMouseLeave={e => {
|
||||
const path = e.currentTarget.querySelector('path');
|
||||
if (path) path.setAttribute('fill', '#D0D0D0');
|
||||
}}
|
||||
>
|
||||
<div className="relative h-4 w-[18px]">
|
||||
<Image
|
||||
src="/images/delete.svg"
|
||||
alt="Удалить"
|
||||
width={16}
|
||||
height={16}
|
||||
className="absolute left-0.5 top-0"
|
||||
/>
|
||||
<div className="relative h-4 w-4">
|
||||
<svg width="16" height="16" viewBox="0 0 18 19" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M4.625 17.5C4.14375 17.5 3.73192 17.3261 3.3895 16.9782C3.04708 16.6304 2.87558 16.2117 2.875 15.7222V4.16667H2V2.38889H6.375V1.5H11.625V2.38889H16V4.16667H15.125V15.7222C15.125 16.2111 14.9538 16.6298 14.6114 16.9782C14.269 17.3267 13.8568 17.5006 13.375 17.5H4.625ZM6.375 13.9444H8.125V5.94444H6.375V13.9444ZM9.875 13.9444H11.625V5.94444H9.875V13.9444Z"
|
||||
fill="#D0D0D0"
|
||||
style={{ transition: 'fill 0.2s' }}
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div className="text-sm leading-5 text-gray-600">
|
||||
<div className="text-sm leading-5 text-gray-600 group-hover:text-red-600">
|
||||
Удалить
|
||||
</div>
|
||||
</div>
|
||||
|
@ -52,14 +52,50 @@ const ProfileAddressCard: React.FC<ProfileAddressCardProps> = ({
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="flex justify-between items-start self-stretch">
|
||||
<div className="flex gap-1.5 items-center cursor-pointer group" onClick={onEdit}>
|
||||
<img src="/images/edit.svg" alt="edit" width={18} height={18} className="mr-1.5 group-hover:filter-red" />
|
||||
<div className="relative text-sm leading-5 text-gray-600">Редактировать</div>
|
||||
<div className="flex justify-between items-start self-stretch max-sm:flex-row max-sm:gap-4 max-sm:justify-start max-sm:items-center">
|
||||
<div
|
||||
className="flex gap-1.5 items-center cursor-pointer group"
|
||||
onClick={onEdit}
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
aria-label="Редактировать адрес"
|
||||
onKeyDown={e => (e.key === 'Enter' || e.key === ' ') && onEdit && onEdit()}
|
||||
onMouseEnter={e => {
|
||||
const svg = (e.currentTarget as HTMLElement).querySelector('img');
|
||||
if (svg) (svg as HTMLImageElement).style.filter = 'invert(32%) sepia(97%) saturate(7490%) hue-rotate(355deg) brightness(97%) contrast(108%)';
|
||||
}}
|
||||
onMouseLeave={e => {
|
||||
const svg = (e.currentTarget as HTMLElement).querySelector('img');
|
||||
if (svg) (svg as HTMLImageElement).style.filter = '';
|
||||
}}
|
||||
>
|
||||
<img src="/images/edit.svg" alt="edit" width={18} height={18} className="mr-1.5" />
|
||||
<div className="relative text-sm leading-5 text-gray-600 group-hover:text-red-600 max-sm:hidden">Редактировать</div>
|
||||
</div>
|
||||
<div className="flex gap-1.5 items-center cursor-pointer group" onClick={onDelete}>
|
||||
<img src="/images/delete.svg" alt="delete" width={18} height={18} className="mr-1.5 group-hover:filter-red" />
|
||||
<div className="relative text-sm leading-5 text-gray-600">Удалить</div>
|
||||
<div
|
||||
className="flex gap-1.5 items-center cursor-pointer group"
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
aria-label="Удалить адрес"
|
||||
onClick={onDelete}
|
||||
onKeyDown={e => (e.key === 'Enter' || e.key === ' ') && onDelete && onDelete()}
|
||||
onMouseEnter={e => {
|
||||
const path = e.currentTarget.querySelector('path');
|
||||
if (path) path.setAttribute('fill', '#ec1c24');
|
||||
}}
|
||||
onMouseLeave={e => {
|
||||
const path = e.currentTarget.querySelector('path');
|
||||
if (path) path.setAttribute('fill', '#D0D0D0');
|
||||
}}
|
||||
>
|
||||
<svg width="18" height="18" viewBox="0 0 18 19" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M4.625 17.5C4.14375 17.5 3.73192 17.3261 3.3895 16.9782C3.04708 16.6304 2.87558 16.2117 2.875 15.7222V4.16667H2V2.38889H6.375V1.5H11.625V2.38889H16V4.16667H15.125V15.7222C15.125 16.2111 14.9538 16.6298 14.6114 16.9782C14.269 17.3267 13.8568 17.5006 13.375 17.5H4.625ZM6.375 13.9444H8.125V5.94444H6.375V13.9444ZM9.875 13.9444H11.625V5.94444H9.875V13.9444Z"
|
||||
fill="#D0D0D0"
|
||||
style={{ transition: 'fill 0.2s' }}
|
||||
/>
|
||||
</svg>
|
||||
<div className="relative text-sm leading-5 text-gray-600 group-hover:text-red-600 max-sm:hidden">Удалить</div>
|
||||
</div>
|
||||
</div>
|
||||
{onSelectMain && (
|
||||
|
@ -89,11 +89,11 @@ const ProfileBalanceCard: React.FC<ProfileBalanceCardProps> = ({
|
||||
{balance}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-row gap-5 items-end mt-5 w-full max-sm:flex-col">
|
||||
<div className="flex flex-row gap-5 items-end mt-5 w-full max-sm:flex-col max-sm:items-start">
|
||||
<div className="flex flex-col flex-1 shrink basis-0">
|
||||
<div className="flex flex-col min-w-[160px]">
|
||||
<div className="text-sm leading-snug text-gray-600">Лимит отсрочки</div>
|
||||
<div className="flex flex-col self-start mt-2">
|
||||
<div className="flex flex-col mt-2">
|
||||
<div className="text-lg font-medium leading-none text-gray-950">{limit}</div>
|
||||
<div className={`text-sm leading-snug ${isOverLimit ? 'text-red-600' : 'text-gray-600'}`}>
|
||||
{limitLeft.includes('Не установлен') ? limitLeft : `Осталось ${limitLeft}`}
|
||||
|
@ -179,7 +179,7 @@ const ProfileGarageMain = () => {
|
||||
|
||||
{!vehiclesLoading && filteredVehicles.map((vehicle) => (
|
||||
<div key={vehicle.id} className="mt-8">
|
||||
<div className="flex flex-col justify-center pr-5 py-3 w-full rounded-lg bg-slate-50 max-md:max-w-full">
|
||||
<div className="flex flex-col justify-center px-5 py-3 w-full rounded-lg bg-slate-50 max-md:max-w-full">
|
||||
<div className="flex flex-wrap gap-8 items-center w-full max-md:max-w-full">
|
||||
<div className="flex gap-8 items-center self-stretch my-auto min-w-[240px] max-md:flex-col max-md:min-w-0 max-md:gap-2">
|
||||
<div className="self-stretch my-auto text-xl font-bold leading-none text-gray-950">
|
||||
@ -203,15 +203,29 @@ const ProfileGarageMain = () => {
|
||||
<div className="flex gap-5 items-center self-stretch pr-2.5 my-auto text-sm leading-snug text-gray-600 whitespace-nowrap">
|
||||
<button
|
||||
type="button"
|
||||
className="flex gap-1.5 items-center self-stretch my-auto cursor-pointer text-sm leading-snug text-gray-600 hover:text-red-600 transition-colors"
|
||||
className="flex gap-1.5 items-center self-stretch my-auto text-sm leading-snug text-gray-600 cursor-pointer bg-transparent group"
|
||||
style={{ outline: 'none' }}
|
||||
aria-label="Удалить автомобиль"
|
||||
tabIndex={0}
|
||||
onClick={() => handleDeleteVehicle(vehicle.id)}
|
||||
onKeyDown={e => (e.key === 'Enter' || e.key === ' ') && handleDeleteVehicle(vehicle.id)}
|
||||
onMouseEnter={e => {
|
||||
const path = e.currentTarget.querySelector('path');
|
||||
if (path) path.setAttribute('fill', '#ec1c24');
|
||||
}}
|
||||
onMouseLeave={e => {
|
||||
const path = e.currentTarget.querySelector('path');
|
||||
if (path) path.setAttribute('fill', '#D0D0D0');
|
||||
}}
|
||||
>
|
||||
<img
|
||||
loading="lazy"
|
||||
src="/images/delete.svg"
|
||||
className="object-contain shrink-0 self-stretch my-auto aspect-[1.12] w-[18px]"
|
||||
/>
|
||||
<span className="self-stretch my-auto text-gray-600">
|
||||
<svg width="16" height="16" viewBox="0 0 18 19" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M4.625 17.5C4.14375 17.5 3.73192 17.3261 3.3895 16.9782C3.04708 16.6304 2.87558 16.2117 2.875 15.7222V4.16667H2V2.38889H6.375V1.5H11.625V2.38889H16V4.16667H15.125V15.7222C15.125 16.2111 14.9538 16.6298 14.6114 16.9782C14.269 17.3267 13.8568 17.5006 13.375 17.5H4.625ZM6.375 13.9444H8.125V5.94444H6.375V13.9444ZM9.875 13.9444H11.625V5.94444H9.875V13.9444Z"
|
||||
fill="#D0D0D0"
|
||||
style={{ transition: 'fill 0.2s' }}
|
||||
/>
|
||||
</svg>
|
||||
<span className="self-stretch my-auto text-gray-600 group-hover:text-red-600">
|
||||
Удалить
|
||||
</span>
|
||||
</button>
|
||||
@ -418,15 +432,29 @@ const ProfileGarageMain = () => {
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
className="flex gap-1.5 items-center self-stretch my-auto text-sm leading-snug text-gray-600 cursor-pointer bg-transparent hover:text-red-600 transition-colors"
|
||||
className="flex gap-1.5 items-center self-stretch my-auto text-sm leading-snug text-gray-600 cursor-pointer bg-transparent group"
|
||||
style={{ outline: 'none' }}
|
||||
aria-label="Удалить из истории поиска"
|
||||
tabIndex={0}
|
||||
onClick={() => handleDeleteFromHistory(historyItem.id)}
|
||||
onKeyDown={e => (e.key === 'Enter' || e.key === ' ') && handleDeleteFromHistory(historyItem.id)}
|
||||
onMouseEnter={e => {
|
||||
const path = e.currentTarget.querySelector('path');
|
||||
if (path) path.setAttribute('fill', '#ec1c24');
|
||||
}}
|
||||
onMouseLeave={e => {
|
||||
const path = e.currentTarget.querySelector('path');
|
||||
if (path) path.setAttribute('fill', '#D0D0D0');
|
||||
}}
|
||||
>
|
||||
<img
|
||||
loading="lazy"
|
||||
src="/images/delete.svg"
|
||||
className="object-contain shrink-0 self-stretch my-auto aspect-[1.12] w-[18px]"
|
||||
/>
|
||||
<span className="self-stretch my-auto text-gray-600">
|
||||
<svg width="16" height="16" viewBox="0 0 18 19" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M4.625 17.5C4.14375 17.5 3.73192 17.3261 3.3895 16.9782C3.04708 16.6304 2.87558 16.2117 2.875 15.7222V4.16667H2V2.38889H6.375V1.5H11.625V2.38889H16V4.16667H15.125V15.7222C15.125 16.2111 14.9538 16.6298 14.6114 16.9782C14.269 17.3267 13.8568 17.5006 13.375 17.5H4.625ZM6.375 13.9444H8.125V5.94444H6.375V13.9444ZM9.875 13.9444H11.625V5.94444H9.875V13.9444Z"
|
||||
fill="#D0D0D0"
|
||||
style={{ transition: 'fill 0.2s' }}
|
||||
/>
|
||||
</svg>
|
||||
<span className="self-stretch my-auto text-gray-600 group-hover:text-red-600">
|
||||
Удалить
|
||||
</span>
|
||||
</button>
|
||||
|
@ -80,24 +80,25 @@ const ProfileHistoryItem: React.FC<ProfileHistoryItemProps> = ({
|
||||
<div className="w-16 text-center max-md:w-full">
|
||||
<button
|
||||
onClick={handleDeleteClick}
|
||||
className="p-2 text-red-500 hover:text-red-700 hover:bg-red-50 rounded-lg transition-colors group"
|
||||
className="flex items-center p-2 group"
|
||||
title="Удалить из истории"
|
||||
aria-label="Удалить из истории"
|
||||
tabIndex={0}
|
||||
onMouseEnter={e => {
|
||||
const path = e.currentTarget.querySelector('path');
|
||||
if (path) path.setAttribute('fill', '#ec1c24');
|
||||
}}
|
||||
onMouseLeave={e => {
|
||||
const path = e.currentTarget.querySelector('path');
|
||||
if (path) path.setAttribute('fill', '#D0D0D0');
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
className="transition-colors"
|
||||
>
|
||||
<path d="M3 6h18" className="group-hover:stroke-[#ec1c24]" />
|
||||
<path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6" className="group-hover:stroke-[#ec1c24]" />
|
||||
<path d="M8 6V4c0-1 1-2 2-2h4c-1 0 2 1 2 2v2" className="group-hover:stroke-[#ec1c24]" />
|
||||
<svg width="16" height="16" viewBox="0 0 18 19" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M4.625 17.5C4.14375 17.5 3.73192 17.3261 3.3895 16.9782C3.04708 16.6304 2.87558 16.2117 2.875 15.7222V4.16667H2V2.38889H6.375V1.5H11.625V2.38889H16V4.16667H15.125V15.7222C15.125 16.2111 14.9538 16.6298 14.6114 16.9782C14.269 17.3267 13.8568 17.5006 13.375 17.5H4.625ZM6.375 13.9444H8.125V5.94444H6.375V13.9444ZM9.875 13.9444H11.625V5.94444H9.875V13.9444Z"
|
||||
fill="#D0D0D0"
|
||||
style={{ transition: 'fill 0.2s' }}
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
@ -272,7 +272,7 @@ const ProfileHistoryMain = () => {
|
||||
|
||||
return (
|
||||
<div className="flex flex-col min-h-[526px]">
|
||||
<div className="flex flex-wrap gap-5 items-center px-8 py-3 w-full leading-snug text-gray-400 whitespace-nowrap bg-white rounded-lg max-md:px-5 max-md:max-w-full max-md:flex-col">
|
||||
<div className="flex gap-5 items-center px-8 py-3 w-full leading-snug text-gray-400 whitespace-nowrap bg-white rounded-lg max-md:px-5 max-md:max-w-full">
|
||||
<div className="flex-1 shrink self-stretch my-auto text-gray-400 basis-0 text-ellipsis max-md:max-w-full max-md:w-full">
|
||||
<SearchInput
|
||||
value={search}
|
||||
@ -280,7 +280,7 @@ const ProfileHistoryMain = () => {
|
||||
placeholder="Поиск в истории..."
|
||||
/>
|
||||
</div>
|
||||
<div className="flex gap-2">
|
||||
<div className="flex gap-2 max-sm:hidden">
|
||||
{(selectedManufacturer !== "Все" || search.trim() || activeTab !== "Все") && (
|
||||
<button
|
||||
onClick={() => {
|
||||
|
@ -89,7 +89,7 @@ const ProfileHistoryTabs: React.FC<ProfileHistoryTabsProps> = ({
|
||||
</div>
|
||||
))}
|
||||
<div
|
||||
className="relative w-[240px] max-w-full"
|
||||
className="relative w-[240px] max-w-full max-sm:w-full"
|
||||
ref={dropdownRef}
|
||||
tabIndex={0}
|
||||
>
|
||||
|
@ -10,7 +10,7 @@ const ProfileSettingsActionsBlock: React.FC<ProfileSettingsActionsBlockProps> =
|
||||
Сохранить изменения
|
||||
</div>
|
||||
<div className="gap-2.5 self-stretch px-5 py-4 my-auto rounded-xl border border-red-600 min-h-[50px] min-w-[240px] cursor-pointer bg-white text-gray-950" onClick={onAddLegalEntity}>
|
||||
Добавить юридическое лицо
|
||||
Добавить юр лицо
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -47,7 +47,7 @@ const KnotIn: React.FC<KnotInProps> = ({ catalogCode, vehicleId, ssd, unitId, un
|
||||
GET_LAXIMO_UNIT_INFO,
|
||||
{
|
||||
variables: { catalogCode, vehicleId, unitId, ssd: ssd || '' },
|
||||
skip: !catalogCode || !vehicleId || !unitId,
|
||||
skip: !catalogCode || vehicleId === undefined || vehicleId === null || !unitId,
|
||||
errorPolicy: 'all',
|
||||
}
|
||||
);
|
||||
@ -56,7 +56,7 @@ const KnotIn: React.FC<KnotInProps> = ({ catalogCode, vehicleId, ssd, unitId, un
|
||||
GET_LAXIMO_UNIT_IMAGE_MAP,
|
||||
{
|
||||
variables: { catalogCode, vehicleId, unitId, ssd: ssd || '' },
|
||||
skip: !catalogCode || !vehicleId || !unitId,
|
||||
skip: !catalogCode || vehicleId === undefined || vehicleId === null || !unitId,
|
||||
errorPolicy: 'all',
|
||||
}
|
||||
);
|
||||
|
@ -12,7 +12,7 @@ interface VinCategoryProps {
|
||||
const VinCategory: React.FC<VinCategoryProps> = ({ catalogCode, vehicleId, ssd, onNodeSelect }) => {
|
||||
const { data: categoriesData, loading: categoriesLoading, error: categoriesError } = useQuery(GET_LAXIMO_CATEGORIES, {
|
||||
variables: { catalogCode, vehicleId, ssd },
|
||||
skip: !catalogCode || !vehicleId,
|
||||
skip: !catalogCode || vehicleId === undefined || vehicleId === null,
|
||||
errorPolicy: "all",
|
||||
});
|
||||
const categories = categoriesData?.laximoCategories || [];
|
||||
|
@ -25,7 +25,7 @@ const VinLeftbar: React.FC<VinLeftbarProps> = ({ vehicleInfo, onSearchResults, o
|
||||
|
||||
const { data: categoriesData, loading: categoriesLoading, error: categoriesError } = useQuery(GET_LAXIMO_CATEGORIES, {
|
||||
variables: { catalogCode, vehicleId, ssd },
|
||||
skip: !catalogCode || !vehicleId,
|
||||
skip: !catalogCode || vehicleId === undefined || vehicleId === null,
|
||||
errorPolicy: 'all'
|
||||
});
|
||||
const categories = categoriesData?.laximoCategories || [];
|
||||
@ -88,7 +88,7 @@ const VinLeftbar: React.FC<VinLeftbarProps> = ({ vehicleInfo, onSearchResults, o
|
||||
}, [searchResults, searchQuery, onSearchResults]);
|
||||
|
||||
// --- Новый блок: вычисляем доступность поиска ---
|
||||
const isSearchAvailable = !!catalogCode && !!vehicleId && !!ssd && ssd.trim() !== '';
|
||||
const isSearchAvailable = !!catalogCode && vehicleId !== undefined && vehicleId !== null && !!ssd && ssd.trim() !== '';
|
||||
const showWarning = !isSearchAvailable;
|
||||
const showError = !!error && isSearchAvailable && searchQuery.trim();
|
||||
const showNotFound = isSearchAvailable && searchQuery.trim() && !loading && data && searchResults && searchResults.details && searchResults.details.length === 0;
|
||||
@ -98,7 +98,7 @@ const VinLeftbar: React.FC<VinLeftbarProps> = ({ vehicleInfo, onSearchResults, o
|
||||
const [selectedQuickGroup, setSelectedQuickGroup] = useState<any | null>(null);
|
||||
const { data: quickGroupsData, loading: quickGroupsLoading, error: quickGroupsError } = useQuery(GET_LAXIMO_QUICK_GROUPS, {
|
||||
variables: { catalogCode, vehicleId, ssd },
|
||||
skip: !catalogCode || !vehicleId || activeTab !== 'manufacturer',
|
||||
skip: !catalogCode || vehicleId === undefined || vehicleId === null || activeTab !== 'manufacturer',
|
||||
errorPolicy: 'all'
|
||||
});
|
||||
const quickGroups = quickGroupsData?.laximoQuickGroups || [];
|
||||
@ -136,12 +136,30 @@ const VinLeftbar: React.FC<VinLeftbarProps> = ({ vehicleInfo, onSearchResults, o
|
||||
const skipQuickDetail =
|
||||
!selectedQuickGroup ||
|
||||
!catalogCode ||
|
||||
!vehicleId ||
|
||||
!selectedQuickGroup.quickgroupid ||
|
||||
!ssd;
|
||||
vehicleId === undefined ||
|
||||
vehicleId === null ||
|
||||
!selectedQuickGroup?.quickgroupid ||
|
||||
!ssd ||
|
||||
ssd.trim() === '';
|
||||
|
||||
console.log('QuickDetail QUERY VARS', {
|
||||
catalogCode,
|
||||
vehicleId,
|
||||
quickGroupId: selectedQuickGroup?.quickgroupid,
|
||||
ssd: ssd ? `${ssd.substring(0, 30)}...` : 'отсутствует'
|
||||
});
|
||||
|
||||
console.log('QuickDetail SKIP CONDITIONS', {
|
||||
hasSelectedQuickGroup: !!selectedQuickGroup,
|
||||
hasCatalogCode: !!catalogCode,
|
||||
hasVehicleId: vehicleId !== undefined && vehicleId !== null,
|
||||
hasQuickGroupId: !!selectedQuickGroup?.quickgroupid,
|
||||
hasSsd: !!ssd && ssd.trim() !== '',
|
||||
skipQuickDetail
|
||||
});
|
||||
|
||||
const { data: quickDetailData, loading: quickDetailLoading, error: quickDetailError } = useQuery(GET_LAXIMO_QUICK_DETAIL, {
|
||||
variables: selectedQuickGroup ? {
|
||||
variables: selectedQuickGroup?.quickgroupid && !skipQuickDetail ? {
|
||||
catalogCode,
|
||||
vehicleId,
|
||||
quickGroupId: selectedQuickGroup.quickgroupid,
|
||||
|
@ -58,7 +58,7 @@ const ProfileActsPage = () => {
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div className="page-wrapper">
|
||||
<>
|
||||
<Head>
|
||||
<title>ProfileActs</title>
|
||||
<meta content="ProfileActs" property="og:title" />
|
||||
@ -78,7 +78,7 @@ const ProfileActsPage = () => {
|
||||
</section>
|
||||
<MobileMenuBottomSection />
|
||||
<Footer />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -123,7 +123,7 @@ const VehicleDetailsPage = () => {
|
||||
...(finalSsd && { ssd: finalSsd }),
|
||||
localized: true
|
||||
},
|
||||
skip: !brand || !vehicleId,
|
||||
skip: !brand || vehicleId === undefined || vehicleId === null,
|
||||
errorPolicy: 'all'
|
||||
}
|
||||
);
|
||||
@ -194,8 +194,9 @@ const VehicleDetailsPage = () => {
|
||||
);
|
||||
}
|
||||
|
||||
// Если vehicleId невалидный (например, '0'), показываем предупреждение и не рендерим поиск
|
||||
if (!vehicleId || vehicleId === '0') {
|
||||
// Если vehicleId отсутствует или пустой, показываем предупреждение
|
||||
// Важно: vehicleId может быть '0' для некоторых автомобилей, найденных по VIN
|
||||
if (!vehicleId || vehicleId === '') {
|
||||
return (
|
||||
<main className="min-h-screen bg-yellow-50 flex items-center justify-center">
|
||||
<div className="text-center">
|
||||
@ -214,7 +215,8 @@ const VehicleDetailsPage = () => {
|
||||
|
||||
// Гарантируем, что vehicleId — строка
|
||||
const vehicleIdStr = Array.isArray(vehicleId) ? (vehicleId[0] || '') : (vehicleId || '');
|
||||
const fallbackVehicleId = (vehicleIdStr !== '0' ? vehicleIdStr : '');
|
||||
// Для Laximo API vehicleId может быть '0' для автомобилей, найденных по VIN
|
||||
const fallbackVehicleId = vehicleIdStr;
|
||||
|
||||
let vehicleInfo = vehicleData?.laximoVehicleInfo || {
|
||||
vehicleid: fallbackVehicleId,
|
||||
@ -225,8 +227,8 @@ const VehicleDetailsPage = () => {
|
||||
attributes: [] as never[]
|
||||
};
|
||||
|
||||
// Если вдруг с сервера пришёл vehicleid: '0', подменяем на корректный
|
||||
if (vehicleInfo.vehicleid === '0' && fallbackVehicleId) {
|
||||
// Убеждаемся, что vehicleid соответствует параметру из URL
|
||||
if (vehicleInfo.vehicleid !== fallbackVehicleId && fallbackVehicleId) {
|
||||
vehicleInfo = { ...vehicleInfo, vehicleid: fallbackVehicleId };
|
||||
}
|
||||
|
||||
|
@ -74,12 +74,12 @@ const PartDetailPage = () => {
|
||||
oemNumber: oemNumber,
|
||||
ssd: finalSsd
|
||||
},
|
||||
skip: !brand || !vehicleId || !oemNumber || !finalSsd,
|
||||
skip: !brand || vehicleId === undefined || vehicleId === null || !oemNumber || !finalSsd,
|
||||
errorPolicy: 'all'
|
||||
}
|
||||
);
|
||||
|
||||
if (!brand || !vehicleId || !oemNumber) {
|
||||
if (!brand || vehicleId === undefined || vehicleId === null || !oemNumber) {
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
|
@ -430,4 +430,32 @@ input#VinSearchInput {
|
||||
text-overflow: ellipsis;
|
||||
max-height: 2.8em;
|
||||
line-height: 1.4em;
|
||||
}
|
||||
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.w-layout-hflex.flex-block-6 {
|
||||
flex-direction: column !important;
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
.div-block-12,
|
||||
.div-block-12.small,
|
||||
.div-block-12-copy,
|
||||
.div-block-12-copy.small,
|
||||
.div-block-123,
|
||||
.div-block-123.small,
|
||||
.div-block-red,
|
||||
.div-block-red.small {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
.flex-block-6 {
|
||||
grid-template-columns: 1fr !important;
|
||||
grid-template-rows: none !important;
|
||||
grid-template-areas: none !important;
|
||||
grid-auto-flow: row !important; /* <--- ВАЖНО! */
|
||||
}
|
||||
}
|
@ -787,6 +787,8 @@
|
||||
.w-layout-blockcontainer {
|
||||
max-width: 728px;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@media screen and (max-width: 767px) {
|
||||
@ -794,6 +796,8 @@
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.w-commerce-commercelayoutcontainer {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
@ -4024,6 +4028,7 @@ body {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
|
||||
.button-for-mobile-menu-block:hover {
|
||||
background-color: var(--_button---hover-dark_blue);
|
||||
}
|
||||
@ -5426,10 +5431,10 @@ body {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.topmenuh {
|
||||
/*
|
||||
.bottom_head {
|
||||
margin-top: 0;
|
||||
}
|
||||
} */
|
||||
|
||||
.flex-block-4 {
|
||||
grid-column-gap: 40px;
|
||||
@ -5579,6 +5584,8 @@ body {
|
||||
background-color: var(--white);
|
||||
}
|
||||
|
||||
|
||||
|
||||
.button-for-mobile-menu-block {
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
@ -5680,9 +5687,9 @@ body {
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.topmenub {
|
||||
/* .bottom_head {
|
||||
margin-top: 0;
|
||||
}
|
||||
} */
|
||||
|
||||
.vinleftbar {
|
||||
width: 320px;
|
||||
@ -6082,7 +6089,7 @@ body {
|
||||
padding-bottom: 40px;
|
||||
}
|
||||
|
||||
.top_head, .topmenuh {
|
||||
.top_head, .bottom_head {
|
||||
padding-left: 30px;
|
||||
padding-right: 30px;
|
||||
}
|
||||
@ -6882,7 +6889,7 @@ body {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.topmenub {
|
||||
.bottom_head {
|
||||
padding-left: 30px;
|
||||
padding-right: 30px;
|
||||
}
|
||||
@ -7543,8 +7550,9 @@ body {
|
||||
}
|
||||
|
||||
.flex-block-18-copy-copy {
|
||||
grid-column-gap: 10px;
|
||||
grid-row-gap: 10px;
|
||||
grid-column-gap: 40px;
|
||||
grid-row-gap: 40px;
|
||||
flex-flow: column;
|
||||
}
|
||||
|
||||
.link-block-4-copy {
|
||||
@ -7602,8 +7610,9 @@ body {
|
||||
}
|
||||
|
||||
.flex-block-87 {
|
||||
grid-column-gap: 0px;
|
||||
grid-row-gap: 0px;
|
||||
grid-column-gap: 10px;
|
||||
grid-row-gap: 10px;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.mobile-menu-bottom {
|
||||
@ -7627,10 +7636,16 @@ body {
|
||||
}
|
||||
|
||||
.button-for-mobile-menu-block {
|
||||
grid-column-gap: 0px;
|
||||
grid-row-gap: 0px;
|
||||
width: 60px;
|
||||
padding-bottom: 5px;
|
||||
grid-column-gap: 2px;
|
||||
grid-row-gap: 2px;
|
||||
background-color: var(--_fonts---color--white);
|
||||
color: var(--_button---light-blue-grey);
|
||||
flex-flow: column;
|
||||
width: 70px;
|
||||
}
|
||||
|
||||
.button-for-mobile-menu-block:hover {
|
||||
background-color: var(--_button---light-blue);
|
||||
}
|
||||
|
||||
.section-3 {
|
||||
@ -7643,7 +7658,8 @@ body {
|
||||
}
|
||||
|
||||
.flex-block-93 {
|
||||
margin-left: 0;
|
||||
align-self: auto;
|
||||
min-height: 48px;
|
||||
}
|
||||
|
||||
.sort-list-card {
|
||||
@ -7882,6 +7898,10 @@ body {
|
||||
.container-copy.footer {
|
||||
padding-bottom: 90px;
|
||||
}
|
||||
|
||||
.mobile-menu-buttom-section {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 479px) {
|
||||
@ -7951,7 +7971,7 @@ body {
|
||||
grid-row-gap: 15px;
|
||||
}
|
||||
|
||||
.top_head, .topmenuh {
|
||||
.top_head, .bottom_head {
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
}
|
||||
@ -9132,7 +9152,7 @@ body {
|
||||
top: 58px;
|
||||
}
|
||||
|
||||
.topmenub {
|
||||
.bottom_head {
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
}
|
||||
@ -9400,6 +9420,12 @@ body {
|
||||
#w-node-_35f55517-cbe0-9ee3-13bb-a3ed00029bba-00029ba8, #w-node-_35f55517-cbe0-9ee3-13bb-a3ed00029bc7-00029ba8 {
|
||||
justify-self: stretch;
|
||||
}
|
||||
.button-for-mobile-menu-block {
|
||||
grid-column-gap: 0px;
|
||||
grid-row-gap: 0px;
|
||||
width: 60px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.flex-block-113 {
|
||||
|
Reference in New Issue
Block a user