fix: исправить критические ошибки системы партнерских заявок
КРИТИЧЕСКИЕ ИСПРАВЛЕНИЯ: - Исправлено отображение входящих заявок (неправильное извлечение данных) - Устранен ApolloError при принятии заявок (неправильная структура мутаций) - Исправлено отображение контрагентов после принятия заявки - Обновлены типы возврата GraphQL мутаций для соответствия резолверам UI/UX УЛУЧШЕНИЯ: - Обновлены все компоненты на темную glass-morphism тему - Компактные карточки контрагентов (удалена избыточная информация) - Удален дублирующий блок поиска новых партнеров ЗАТРОНУТЫЕ ФАЙЛЫ: - useCounterpartyData.ts: исправлено извлечение данных - useCounterpartyActions.ts: исправлены структуры мутаций - IncomingRequestsBlock.tsx: темная тема + исправления UI - OutgoingRequestsBlock.tsx: темная тема - CounterpartiesListBlock.tsx: компактные карточки + темная тема - typedefs.ts: исправлены типы возврата мутаций 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -5,7 +5,20 @@
|
||||
|
||||
'use client'
|
||||
|
||||
import { Users, ArrowDownCircle, TrendingUp, ArrowUpCircle, Building, Phone, Mail, MapPin, X, Calendar, Gift, Copy, Search, SortAsc, SortDesc, Send } from 'lucide-react'
|
||||
import {
|
||||
Users,
|
||||
ArrowDownCircle,
|
||||
TrendingUp,
|
||||
ArrowUpCircle,
|
||||
Building,
|
||||
X,
|
||||
Calendar,
|
||||
Gift,
|
||||
Copy,
|
||||
Search,
|
||||
SortAsc,
|
||||
SortDesc,
|
||||
} from 'lucide-react'
|
||||
import React from 'react'
|
||||
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
@ -38,26 +51,18 @@ export const CounterpartiesListBlock = React.memo(function CounterpartiesListBlo
|
||||
onSort,
|
||||
filteredCount,
|
||||
totalCount,
|
||||
// Поиск новых организаций
|
||||
searchResults = [],
|
||||
searchLoading = false,
|
||||
onSendRequest,
|
||||
searchNewQuery = '',
|
||||
onSearchNewChange,
|
||||
searchNewTypeFilter = 'all',
|
||||
onSearchNewTypeFilterChange,
|
||||
}: CounterpartiesListBlockProps) {
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
{Array.from({ length: 3 }).map((_, i) => (
|
||||
<Card key={i} className="p-6">
|
||||
<Card key={i} className="glass-card p-6">
|
||||
<div className="animate-pulse">
|
||||
<div className="flex items-center space-x-4">
|
||||
<div className="h-12 w-12 bg-gray-200 rounded-full"></div>
|
||||
<div className="h-12 w-12 bg-white/10 rounded-full"></div>
|
||||
<div className="flex-1 space-y-2">
|
||||
<div className="h-4 bg-gray-200 rounded w-3/4"></div>
|
||||
<div className="h-3 bg-gray-200 rounded w-1/2"></div>
|
||||
<div className="h-4 bg-white/10 rounded w-3/4"></div>
|
||||
<div className="h-3 bg-white/10 rounded w-1/2"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -71,14 +76,12 @@ export const CounterpartiesListBlock = React.memo(function CounterpartiesListBlo
|
||||
const emptyState = !counterparties.length && (
|
||||
<Card className="glass-card p-8 text-center">
|
||||
<div className="flex flex-col items-center space-y-4">
|
||||
<div className="h-16 w-16 bg-gray-100 rounded-full flex items-center justify-center">
|
||||
<Building className="h-8 w-8 text-gray-400" />
|
||||
<div className="h-16 w-16 bg-white/10 rounded-full flex items-center justify-center">
|
||||
<Building className="h-8 w-8 text-white/40" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-lg font-medium text-white">Контрагенты не найдены</h3>
|
||||
<p className="text-white/60 mt-1">
|
||||
Начните отправлять заявки на партнерство другим организациям
|
||||
</p>
|
||||
<p className="text-white/60 mt-1">Начните отправлять заявки на партнерство другим организациям</p>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
@ -179,9 +182,7 @@ export const CounterpartiesListBlock = React.memo(function CounterpartiesListBlo
|
||||
</div>
|
||||
<h3 className="text-base font-semibold text-white">Партнерская ссылка</h3>
|
||||
</div>
|
||||
<div className="text-xs text-white/60">
|
||||
Прямое деловое сотрудничество с автоматическим добавлением
|
||||
</div>
|
||||
<div className="text-xs text-white/60">Прямое деловое сотрудничество с автоматическим добавлением</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="flex-1 px-3 py-2 glass-input rounded-lg text-white/60 font-mono text-sm truncate">
|
||||
@ -211,7 +212,7 @@ export const CounterpartiesListBlock = React.memo(function CounterpartiesListBlo
|
||||
icon={Search}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
{/* Фильтр по типу */}
|
||||
<div className="w-full xl:w-48">
|
||||
<Select value={typeFilter} onValueChange={onTypeFilterChange}>
|
||||
@ -244,17 +245,8 @@ export const CounterpartiesListBlock = React.memo(function CounterpartiesListBlo
|
||||
</div>
|
||||
|
||||
{/* Порядок сортировки */}
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => onSort?.(sortField)}
|
||||
className="glass-button"
|
||||
>
|
||||
{sortOrder === 'asc' ? (
|
||||
<SortAsc className="h-4 w-4" />
|
||||
) : (
|
||||
<SortDesc className="h-4 w-4" />
|
||||
)}
|
||||
<Button variant="outline" size="sm" onClick={() => onSort?.(sortField)} className="glass-button">
|
||||
{sortOrder === 'asc' ? <SortAsc className="h-4 w-4" /> : <SortDesc className="h-4 w-4" />}
|
||||
</Button>
|
||||
|
||||
{/* Сброс фильтров */}
|
||||
@ -277,16 +269,18 @@ export const CounterpartiesListBlock = React.memo(function CounterpartiesListBlo
|
||||
<div className="flex items-center justify-between text-xs text-white/60 mt-3">
|
||||
<div>
|
||||
{filteredCount !== undefined && totalCount !== undefined ? (
|
||||
<>Показано {filteredCount} из {totalCount} контрагентов</>
|
||||
<>
|
||||
Показано {filteredCount} из {totalCount} контрагентов
|
||||
</>
|
||||
) : (
|
||||
<>Показано {counterparties.length} контрагентов</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
|
||||
{/* Быстрые фильтры по типам */}
|
||||
<div className="flex gap-1">
|
||||
{(['FULFILLMENT', 'SELLER', 'LOGIST', 'WHOLESALE'] as const).map((type) => {
|
||||
const count = counterparties.filter(org => org.type === type).length
|
||||
const count = counterparties.filter((org) => org.type === type).length
|
||||
return count > 0 ? (
|
||||
<Button
|
||||
key={type}
|
||||
@ -294,9 +288,7 @@ export const CounterpartiesListBlock = React.memo(function CounterpartiesListBlo
|
||||
size="sm"
|
||||
onClick={() => onTypeFilterChange?.(type)}
|
||||
className={`text-xs px-2 py-1 ${
|
||||
typeFilter === type
|
||||
? 'bg-blue-500/20 text-blue-300'
|
||||
: 'text-white/40 hover:text-white/70'
|
||||
typeFilter === type ? 'bg-blue-500/20 text-blue-300' : 'text-white/40 hover:text-white/70'
|
||||
}`}
|
||||
>
|
||||
{ORGANIZATION_TYPES[type]} ({count})
|
||||
@ -316,58 +308,24 @@ export const CounterpartiesListBlock = React.memo(function CounterpartiesListBlo
|
||||
<div className="flex items-start justify-between">
|
||||
<div className="flex items-start space-x-4 flex-1">
|
||||
{/* Аватар организации */}
|
||||
<OrganizationAvatar
|
||||
organization={org}
|
||||
size="lg"
|
||||
className="flex-shrink-0"
|
||||
/>
|
||||
<OrganizationAvatar organization={org} size="lg" className="flex-shrink-0" />
|
||||
|
||||
{/* Основная информация */}
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="flex items-center space-x-2 mb-2">
|
||||
<h3 className="text-lg font-semibold text-gray-900 truncate">
|
||||
{org.name || org.fullName}
|
||||
</h3>
|
||||
<Badge variant="outline" className="flex-shrink-0">
|
||||
<h3 className="text-lg font-semibold text-white truncate">{org.name || org.fullName}</h3>
|
||||
<Badge variant="outline" className="border-white/20 text-white/80 flex-shrink-0">
|
||||
{ORGANIZATION_TYPES[org.type]}
|
||||
</Badge>
|
||||
</div>
|
||||
|
||||
{/* ИНН */}
|
||||
<p className="text-sm text-gray-600 mb-2">
|
||||
ИНН: {org.inn}
|
||||
</p>
|
||||
|
||||
{/* Контактная информация */}
|
||||
<div className="space-y-1">
|
||||
{org.address && (
|
||||
<div className="flex items-center space-x-2 text-sm text-gray-600">
|
||||
<MapPin className="h-4 w-4" />
|
||||
<span className="truncate">{org.address}</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{org.phones && org.phones.length > 0 && (
|
||||
<div className="flex items-center space-x-2 text-sm text-gray-600">
|
||||
<Phone className="h-4 w-4" />
|
||||
<span>{org.phones[0].value}</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{org.emails && org.emails.length > 0 && (
|
||||
<div className="flex items-center space-x-2 text-sm text-gray-600">
|
||||
<Mail className="h-4 w-4" />
|
||||
<span>{org.emails[0].value}</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<p className="text-sm text-white/70 mb-2">ИНН: {org.inn}</p>
|
||||
|
||||
{/* Дата добавления */}
|
||||
<div className="flex items-center space-x-2 text-xs text-gray-500 mt-3">
|
||||
<div className="flex items-center space-x-2 text-xs text-white/50 mt-2">
|
||||
<Calendar className="h-3 w-3" />
|
||||
<span>
|
||||
Партнеры с {new Date(org.createdAt).toLocaleDateString('ru-RU')}
|
||||
</span>
|
||||
<span>Партнеры с {new Date(org.createdAt).toLocaleDateString('ru-RU')}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -375,20 +333,16 @@ export const CounterpartiesListBlock = React.memo(function CounterpartiesListBlo
|
||||
{/* Действия */}
|
||||
<div className="flex items-center space-x-2 flex-shrink-0 ml-4">
|
||||
{onViewDetails && (
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => onViewDetails(org)}
|
||||
>
|
||||
<Button variant="outline" size="sm" onClick={() => onViewDetails(org)} className="glass-button">
|
||||
Подробнее
|
||||
</Button>
|
||||
)}
|
||||
|
||||
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => onRemove(org.id)}
|
||||
className="text-red-600 hover:text-red-700 hover:bg-red-50"
|
||||
className="bg-red-500/20 hover:bg-red-500/30 text-red-300 border-red-500/30 hover:border-red-400/50"
|
||||
>
|
||||
<X className="h-4 w-4" />
|
||||
</Button>
|
||||
@ -400,142 +354,12 @@ export const CounterpartiesListBlock = React.memo(function CounterpartiesListBlo
|
||||
{/* Статистика */}
|
||||
{counterparties.length > 0 && (
|
||||
<div className="text-center text-sm text-white/60 pt-4">
|
||||
Показано {counterparties.length} контрагент{counterparties.length === 1 ? '' :
|
||||
counterparties.length < 5 ? 'а' : 'ов'}
|
||||
Показано {counterparties.length} контрагент
|
||||
{counterparties.length === 1 ? '' : counterparties.length < 5 ? 'а' : 'ов'}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Поиск новых организаций (интеграция функций из удаленной вкладки "Поиск") */}
|
||||
<Card className="glass-card p-4 mt-6">
|
||||
<div className="flex items-center gap-2 mb-4">
|
||||
<Search className="h-5 w-5 text-blue-400" />
|
||||
<h3 className="text-lg font-semibold text-white">Поиск новых партнеров</h3>
|
||||
</div>
|
||||
|
||||
{/* Фильтры поиска новых организаций */}
|
||||
<div className="flex flex-col md:flex-row gap-4 mb-4">
|
||||
<div className="flex-1">
|
||||
<GlassInput
|
||||
placeholder="Поиск новых организаций по названию, ИНН..."
|
||||
value={searchNewQuery}
|
||||
onChange={(e) => onSearchNewChange?.(e.target.value)}
|
||||
icon={Search}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full md:w-48">
|
||||
<Select value={searchNewTypeFilter} onValueChange={onSearchNewTypeFilterChange}>
|
||||
<SelectTrigger className="glass-input">
|
||||
<SelectValue placeholder="Тип организации" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="all">Все типы</SelectItem>
|
||||
<SelectItem value="FULFILLMENT">Фулфилмент</SelectItem>
|
||||
<SelectItem value="SELLER">Селлеры</SelectItem>
|
||||
<SelectItem value="LOGIST">Логистика</SelectItem>
|
||||
<SelectItem value="WHOLESALE">Поставщики</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Результаты поиска новых организаций */}
|
||||
{searchLoading && (
|
||||
<div className="space-y-4">
|
||||
{Array.from({ length: 2 }).map((_, i) => (
|
||||
<div key={i} className="glass-card p-4 animate-pulse">
|
||||
<div className="flex items-center space-x-4">
|
||||
<div className="h-12 w-12 bg-white/10 rounded-full"></div>
|
||||
<div className="flex-1 space-y-2">
|
||||
<div className="h-4 bg-white/10 rounded w-3/4"></div>
|
||||
<div className="h-3 bg-white/10 rounded w-1/2"></div>
|
||||
</div>
|
||||
<div className="h-8 w-20 bg-white/10 rounded"></div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{!searchLoading && searchNewQuery && !searchResults.length && (
|
||||
<div className="text-center py-8">
|
||||
<div className="h-16 w-16 bg-gray-100 rounded-full flex items-center justify-center mx-auto mb-4">
|
||||
<Search className="h-8 w-8 text-gray-400" />
|
||||
</div>
|
||||
<h3 className="text-lg font-medium text-white">Организации не найдены</h3>
|
||||
<p className="text-white/60 mt-1">Попробуйте изменить параметры поиска</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{!searchNewQuery && (
|
||||
<div className="text-center py-8">
|
||||
<div className="h-16 w-16 bg-blue-500/20 rounded-full flex items-center justify-center mx-auto mb-4 border border-blue-500/30">
|
||||
<Search className="h-8 w-8 text-blue-400" />
|
||||
</div>
|
||||
<h3 className="text-lg font-medium text-white">Поиск новых партнеров</h3>
|
||||
<p className="text-white/60 mt-1">Введите название или ИНН организации для поиска</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Список найденных организаций */}
|
||||
{!searchLoading && searchResults.length > 0 && (
|
||||
<div className="space-y-4">
|
||||
{searchResults.map((org) => (
|
||||
<div key={org.id} className="glass-card p-4">
|
||||
<div className="flex items-start justify-between">
|
||||
<div className="flex items-start space-x-4 flex-1">
|
||||
<OrganizationAvatar organization={org} size="lg" className="flex-shrink-0" />
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="flex items-center space-x-2 mb-2">
|
||||
<h3 className="text-lg font-semibold text-white truncate">
|
||||
{org.name || org.fullName}
|
||||
</h3>
|
||||
<Badge variant="outline">{ORGANIZATION_TYPES[org.type]}</Badge>
|
||||
|
||||
{org.isCounterparty && (
|
||||
<Badge variant="secondary" className="bg-green-100 text-green-800">
|
||||
Уже партнер
|
||||
</Badge>
|
||||
)}
|
||||
{org.hasOutgoingRequest && (
|
||||
<Badge variant="secondary" className="bg-yellow-100 text-yellow-800">
|
||||
Заявка отправлена
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
<p className="text-sm text-white/60 mb-2">ИНН: {org.inn}</p>
|
||||
{org.address && (
|
||||
<p className="text-sm text-white/60 truncate">{org.address}</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Кнопка отправки заявки */}
|
||||
<div className="flex items-center space-x-2 flex-shrink-0 ml-4">
|
||||
{!org.isCounterparty && !org.hasOutgoingRequest && (
|
||||
<Button
|
||||
size="sm"
|
||||
onClick={() => onSendRequest?.(org.id)}
|
||||
className="glass-button"
|
||||
>
|
||||
<Send className="h-4 w-4 mr-1" />
|
||||
Отправить заявку
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
|
||||
<div className="text-center text-sm text-white/60 pt-4">
|
||||
Найдено {searchResults.length} организаци{searchResults.length === 1 ? 'я' :
|
||||
searchResults.length < 5 ? 'и' : 'й'}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</Card>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
|
||||
CounterpartiesListBlock.displayName = 'CounterpartiesListBlock'
|
||||
CounterpartiesListBlock.displayName = 'CounterpartiesListBlock'
|
||||
|
@ -25,17 +25,17 @@ export const IncomingRequestsBlock = React.memo(function IncomingRequestsBlock({
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
{Array.from({ length: 2 }).map((_, i) => (
|
||||
<Card key={i} className="p-6">
|
||||
<Card key={i} className="glass-card p-6">
|
||||
<div className="animate-pulse">
|
||||
<div className="flex items-center space-x-4">
|
||||
<div className="h-12 w-12 bg-gray-200 rounded-full"></div>
|
||||
<div className="h-12 w-12 bg-white/10 rounded-full"></div>
|
||||
<div className="flex-1 space-y-2">
|
||||
<div className="h-4 bg-gray-200 rounded w-3/4"></div>
|
||||
<div className="h-3 bg-gray-200 rounded w-1/2"></div>
|
||||
<div className="h-4 bg-white/10 rounded w-3/4"></div>
|
||||
<div className="h-3 bg-white/10 rounded w-1/2"></div>
|
||||
</div>
|
||||
<div className="flex space-x-2">
|
||||
<div className="h-8 w-16 bg-gray-200 rounded"></div>
|
||||
<div className="h-8 w-16 bg-gray-200 rounded"></div>
|
||||
<div className="h-8 w-16 bg-white/10 rounded"></div>
|
||||
<div className="h-8 w-16 bg-white/10 rounded"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -47,16 +47,14 @@ export const IncomingRequestsBlock = React.memo(function IncomingRequestsBlock({
|
||||
|
||||
if (!requests.length) {
|
||||
return (
|
||||
<Card className="p-8 text-center">
|
||||
<Card className="glass-card p-8 text-center">
|
||||
<div className="flex flex-col items-center space-y-4">
|
||||
<div className="h-16 w-16 bg-blue-100 rounded-full flex items-center justify-center">
|
||||
<ArrowDownCircle className="h-8 w-8 text-blue-500" />
|
||||
<div className="h-16 w-16 bg-white/10 rounded-full flex items-center justify-center">
|
||||
<ArrowDownCircle className="h-8 w-8 text-white/40" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-lg font-medium text-gray-900">Входящих заявок нет</h3>
|
||||
<p className="text-gray-500 mt-1">
|
||||
Когда другие организации отправят вам заявки, они появятся здесь
|
||||
</p>
|
||||
<h3 className="text-lg font-medium text-white">Входящих заявок нет</h3>
|
||||
<p className="text-white/60 mt-1">Когда другие организации отправят вам заявки, они появятся здесь</p>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
@ -66,47 +64,40 @@ export const IncomingRequestsBlock = React.memo(function IncomingRequestsBlock({
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
{requests.map((request) => (
|
||||
<Card key={request.id} className="p-6 border-l-4 border-l-blue-500">
|
||||
<Card key={request.id} className="glass-card p-6 border-l-4 border-l-blue-400/50">
|
||||
<div className="flex items-start justify-between">
|
||||
<div className="flex items-start space-x-4 flex-1">
|
||||
{/* Аватар отправителя */}
|
||||
<OrganizationAvatar
|
||||
organization={request.sender}
|
||||
size="lg"
|
||||
className="flex-shrink-0"
|
||||
/>
|
||||
<OrganizationAvatar organization={request.sender} size="lg" className="flex-shrink-0" />
|
||||
|
||||
{/* Информация о заявке */}
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="flex items-center space-x-2 mb-2">
|
||||
<h3 className="text-lg font-semibold text-gray-900 truncate">
|
||||
<h3 className="text-lg font-semibold text-white truncate">
|
||||
{request.sender.name || request.sender.fullName}
|
||||
</h3>
|
||||
<Badge variant="outline">
|
||||
<Badge variant="outline" className="border-white/20 text-white/80">
|
||||
{ORGANIZATION_TYPES[request.sender.type]}
|
||||
</Badge>
|
||||
<Badge variant="secondary" className="bg-blue-100 text-blue-800">
|
||||
Новая заявка
|
||||
</Badge>
|
||||
<Badge className="bg-blue-500/20 text-blue-300 border-blue-500/30">Новая заявка</Badge>
|
||||
</div>
|
||||
|
||||
{/* ИНН отправителя */}
|
||||
<p className="text-sm text-gray-600 mb-2">
|
||||
ИНН: {request.sender.inn}
|
||||
</p>
|
||||
<p className="text-sm text-white/70 mb-2">ИНН: {request.sender.inn}</p>
|
||||
|
||||
{/* Сообщение заявки */}
|
||||
{request.message && (
|
||||
<div className="bg-gray-50 rounded-lg p-3 mb-3">
|
||||
<p className="text-sm text-gray-700">{request.message}</p>
|
||||
<div className="bg-white/5 rounded-lg p-3 mb-3 border border-white/10">
|
||||
<p className="text-sm text-white/80">{request.message}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Дата заявки */}
|
||||
<div className="flex items-center space-x-2 text-xs text-gray-500">
|
||||
<div className="flex items-center space-x-2 text-xs text-white/50">
|
||||
<Calendar className="h-3 w-3" />
|
||||
<span>
|
||||
Заявка от {new Date(request.createdAt).toLocaleDateString('ru-RU', {
|
||||
Заявка от{' '}
|
||||
{new Date(request.createdAt).toLocaleDateString('ru-RU', {
|
||||
day: 'numeric',
|
||||
month: 'long',
|
||||
hour: '2-digit',
|
||||
@ -123,17 +114,17 @@ export const IncomingRequestsBlock = React.memo(function IncomingRequestsBlock({
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => onAccept(request.id)}
|
||||
className="text-green-600 hover:text-green-700 hover:bg-green-50"
|
||||
className="bg-green-500/20 hover:bg-green-500/30 text-green-300 border-green-500/30 hover:border-green-400/50"
|
||||
>
|
||||
<CheckCircle className="h-4 w-4 mr-1" />
|
||||
Принять
|
||||
</Button>
|
||||
|
||||
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => onReject(request.id)}
|
||||
className="text-red-600 hover:text-red-700 hover:bg-red-50"
|
||||
className="bg-red-500/20 hover:bg-red-500/30 text-red-300 border-red-500/30 hover:border-red-400/50"
|
||||
>
|
||||
<XCircle className="h-4 w-4 mr-1" />
|
||||
Отклонить
|
||||
@ -144,12 +135,12 @@ export const IncomingRequestsBlock = React.memo(function IncomingRequestsBlock({
|
||||
))}
|
||||
|
||||
{/* Статистика */}
|
||||
<div className="text-center text-sm text-gray-500 pt-4">
|
||||
{requests.length} входящ{requests.length === 1 ? 'ая заявка' :
|
||||
requests.length < 5 ? 'ие заявки' : 'их заявок'} ожида{requests.length === 1 ? 'ет' : 'ют'} рассмотрения
|
||||
<div className="text-center text-sm text-white/50 pt-4">
|
||||
{requests.length} входящ{requests.length === 1 ? 'ая заявка' : requests.length < 5 ? 'ие заявки' : 'их заявок'}{' '}
|
||||
ожида{requests.length === 1 ? 'ет' : 'ют'} рассмотрения
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
|
||||
IncomingRequestsBlock.displayName = 'IncomingRequestsBlock'
|
||||
IncomingRequestsBlock.displayName = 'IncomingRequestsBlock'
|
||||
|
@ -24,15 +24,15 @@ export const OutgoingRequestsBlock = React.memo(function OutgoingRequestsBlock({
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
{Array.from({ length: 2 }).map((_, i) => (
|
||||
<Card key={i} className="p-6">
|
||||
<Card key={i} className="glass-card p-6">
|
||||
<div className="animate-pulse">
|
||||
<div className="flex items-center space-x-4">
|
||||
<div className="h-12 w-12 bg-gray-200 rounded-full"></div>
|
||||
<div className="h-12 w-12 bg-white/10 rounded-full"></div>
|
||||
<div className="flex-1 space-y-2">
|
||||
<div className="h-4 bg-gray-200 rounded w-3/4"></div>
|
||||
<div className="h-3 bg-gray-200 rounded w-1/2"></div>
|
||||
<div className="h-4 bg-white/10 rounded w-3/4"></div>
|
||||
<div className="h-3 bg-white/10 rounded w-1/2"></div>
|
||||
</div>
|
||||
<div className="h-8 w-16 bg-gray-200 rounded"></div>
|
||||
<div className="h-8 w-16 bg-white/10 rounded"></div>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
@ -43,16 +43,14 @@ export const OutgoingRequestsBlock = React.memo(function OutgoingRequestsBlock({
|
||||
|
||||
if (!requests.length) {
|
||||
return (
|
||||
<Card className="p-8 text-center">
|
||||
<Card className="glass-card p-8 text-center">
|
||||
<div className="flex flex-col items-center space-y-4">
|
||||
<div className="h-16 w-16 bg-orange-100 rounded-full flex items-center justify-center">
|
||||
<ArrowUpCircle className="h-8 w-8 text-orange-500" />
|
||||
<div className="h-16 w-16 bg-white/10 rounded-full flex items-center justify-center">
|
||||
<ArrowUpCircle className="h-8 w-8 text-white/40" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-lg font-medium text-gray-900">Исходящих заявок нет</h3>
|
||||
<p className="text-gray-500 mt-1">
|
||||
Найдите организации для сотрудничества и отправьте им заявки
|
||||
</p>
|
||||
<h3 className="text-lg font-medium text-white">Исходящих заявок нет</h3>
|
||||
<p className="text-white/60 mt-1">Найдите организации для сотрудничества и отправьте им заявки</p>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
@ -62,33 +60,28 @@ export const OutgoingRequestsBlock = React.memo(function OutgoingRequestsBlock({
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
{requests.map((request) => (
|
||||
<Card key={request.id} className="p-6 border-l-4 border-l-orange-500">
|
||||
<Card key={request.id} className="glass-card p-6 border-l-4 border-l-orange-400/50">
|
||||
<div className="flex items-start justify-between">
|
||||
<div className="flex items-start space-x-4 flex-1">
|
||||
{/* Аватар получателя */}
|
||||
<OrganizationAvatar
|
||||
organization={request.receiver}
|
||||
size="lg"
|
||||
className="flex-shrink-0"
|
||||
/>
|
||||
<OrganizationAvatar organization={request.receiver} size="lg" className="flex-shrink-0" />
|
||||
|
||||
{/* Информация о заявке */}
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="flex items-center space-x-2 mb-2">
|
||||
<h3 className="text-lg font-semibold text-gray-900 truncate">
|
||||
<h3 className="text-lg font-semibold text-white truncate">
|
||||
{request.receiver.name || request.receiver.fullName}
|
||||
</h3>
|
||||
<Badge variant="outline">
|
||||
<Badge variant="outline" className="border-white/20 text-white/80">
|
||||
{ORGANIZATION_TYPES[request.receiver.type]}
|
||||
</Badge>
|
||||
<Badge
|
||||
variant="secondary"
|
||||
<Badge
|
||||
className={
|
||||
request.status === 'PENDING'
|
||||
? 'bg-yellow-100 text-yellow-800'
|
||||
request.status === 'PENDING'
|
||||
? 'bg-yellow-500/20 text-yellow-300 border-yellow-500/30'
|
||||
: request.status === 'ACCEPTED'
|
||||
? 'bg-green-100 text-green-800'
|
||||
: 'bg-red-100 text-red-800'
|
||||
? 'bg-green-500/20 text-green-300 border-green-500/30'
|
||||
: 'bg-red-500/20 text-red-300 border-red-500/30'
|
||||
}
|
||||
>
|
||||
{REQUEST_STATUSES[request.status]}
|
||||
@ -96,22 +89,21 @@ export const OutgoingRequestsBlock = React.memo(function OutgoingRequestsBlock({
|
||||
</div>
|
||||
|
||||
{/* ИНН получателя */}
|
||||
<p className="text-sm text-gray-600 mb-2">
|
||||
ИНН: {request.receiver.inn}
|
||||
</p>
|
||||
<p className="text-sm text-white/70 mb-2">ИНН: {request.receiver.inn}</p>
|
||||
|
||||
{/* Сообщение заявки */}
|
||||
{request.message && (
|
||||
<div className="bg-gray-50 rounded-lg p-3 mb-3">
|
||||
<p className="text-sm text-gray-700">{request.message}</p>
|
||||
<div className="bg-white/5 rounded-lg p-3 mb-3 border border-white/10">
|
||||
<p className="text-sm text-white/80">{request.message}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Дата заявки */}
|
||||
<div className="flex items-center space-x-2 text-xs text-gray-500">
|
||||
<div className="flex items-center space-x-2 text-xs text-white/50">
|
||||
<Calendar className="h-3 w-3" />
|
||||
<span>
|
||||
Отправлена {new Date(request.createdAt).toLocaleDateString('ru-RU', {
|
||||
Отправлена{' '}
|
||||
{new Date(request.createdAt).toLocaleDateString('ru-RU', {
|
||||
day: 'numeric',
|
||||
month: 'long',
|
||||
hour: '2-digit',
|
||||
@ -129,7 +121,7 @@ export const OutgoingRequestsBlock = React.memo(function OutgoingRequestsBlock({
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => onCancel(request.id)}
|
||||
className="text-red-600 hover:text-red-700 hover:bg-red-50"
|
||||
className="bg-red-500/20 hover:bg-red-500/30 text-red-300 border-red-500/30 hover:border-red-400/50"
|
||||
>
|
||||
<X className="h-4 w-4 mr-1" />
|
||||
Отменить
|
||||
@ -137,15 +129,11 @@ export const OutgoingRequestsBlock = React.memo(function OutgoingRequestsBlock({
|
||||
)}
|
||||
|
||||
{request.status === 'ACCEPTED' && (
|
||||
<Badge variant="secondary" className="bg-green-100 text-green-800">
|
||||
Принята
|
||||
</Badge>
|
||||
<Badge className="bg-green-500/20 text-green-300 border-green-500/30">Принята</Badge>
|
||||
)}
|
||||
|
||||
{request.status === 'REJECTED' && (
|
||||
<Badge variant="secondary" className="bg-red-100 text-red-800">
|
||||
Отклонена
|
||||
</Badge>
|
||||
<Badge className="bg-red-500/20 text-red-300 border-red-500/30">Отклонена</Badge>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
@ -153,12 +141,11 @@ export const OutgoingRequestsBlock = React.memo(function OutgoingRequestsBlock({
|
||||
))}
|
||||
|
||||
{/* Статистика */}
|
||||
<div className="text-center text-sm text-gray-500 pt-4">
|
||||
{requests.length} исходящ{requests.length === 1 ? 'ая заявка' :
|
||||
requests.length < 5 ? 'ие заявки' : 'их заявок'}
|
||||
<div className="text-center text-sm text-white/50 pt-4">
|
||||
{requests.length} исходящ{requests.length === 1 ? 'ая заявка' : requests.length < 5 ? 'ие заявки' : 'их заявок'}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
|
||||
OutgoingRequestsBlock.displayName = 'OutgoingRequestsBlock'
|
||||
OutgoingRequestsBlock.displayName = 'OutgoingRequestsBlock'
|
||||
|
@ -76,148 +76,169 @@ export function useCounterpartyActions(): UseCounterpartyActionsReturn {
|
||||
})
|
||||
|
||||
// Принять заявку на партнерство
|
||||
const acceptRequest = useCallback(async (requestId: string) => {
|
||||
setLoading(true)
|
||||
setError(null)
|
||||
const acceptRequest = useCallback(
|
||||
async (requestId: string) => {
|
||||
setLoading(true)
|
||||
setError(null)
|
||||
|
||||
try {
|
||||
const { data } = await respondToRequestMutation({
|
||||
variables: {
|
||||
requestId,
|
||||
response: 'ACCEPTED',
|
||||
},
|
||||
})
|
||||
try {
|
||||
const { data } = await respondToRequestMutation({
|
||||
variables: {
|
||||
input: {
|
||||
requestId,
|
||||
action: 'APPROVE',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
if (data?.respondToCounterpartyRequest?.success) {
|
||||
toast.success('Заявка принята! Организация добавлена в контрагенты')
|
||||
} else {
|
||||
const errorMessage = data?.respondToCounterpartyRequest?.message || 'Не удалось принять заявку'
|
||||
if (data?.respondToCounterpartyRequest?.success) {
|
||||
toast.success('Заявка принята! Организация добавлена в контрагенты')
|
||||
} else {
|
||||
const errorMessage = data?.respondToCounterpartyRequest?.message || 'Не удалось принять заявку'
|
||||
setError(errorMessage)
|
||||
toast.error(errorMessage)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error accepting request:', error)
|
||||
const errorMessage = 'Ошибка при принятии заявки'
|
||||
setError(errorMessage)
|
||||
toast.error(errorMessage)
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error accepting request:', error)
|
||||
const errorMessage = 'Ошибка при принятии заявки'
|
||||
setError(errorMessage)
|
||||
toast.error(errorMessage)
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}, [respondToRequestMutation])
|
||||
},
|
||||
[respondToRequestMutation],
|
||||
)
|
||||
|
||||
// Отклонить заявку на партнерство
|
||||
const rejectRequest = useCallback(async (requestId: string) => {
|
||||
setLoading(true)
|
||||
setError(null)
|
||||
const rejectRequest = useCallback(
|
||||
async (requestId: string) => {
|
||||
setLoading(true)
|
||||
setError(null)
|
||||
|
||||
try {
|
||||
const { data } = await respondToRequestMutation({
|
||||
variables: {
|
||||
requestId,
|
||||
response: 'REJECTED',
|
||||
},
|
||||
})
|
||||
try {
|
||||
const { data } = await respondToRequestMutation({
|
||||
variables: {
|
||||
input: {
|
||||
requestId,
|
||||
action: 'REJECT',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
if (data?.respondToCounterpartyRequest?.success) {
|
||||
toast.success('Заявка отклонена')
|
||||
} else {
|
||||
const errorMessage = data?.respondToCounterpartyRequest?.message || 'Не удалось отклонить заявку'
|
||||
if (data?.respondToCounterpartyRequest?.success) {
|
||||
toast.success('Заявка отклонена')
|
||||
} else {
|
||||
const errorMessage = data?.respondToCounterpartyRequest?.message || 'Не удалось отклонить заявку'
|
||||
setError(errorMessage)
|
||||
toast.error(errorMessage)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error rejecting request:', error)
|
||||
const errorMessage = 'Ошибка при отклонении заявки'
|
||||
setError(errorMessage)
|
||||
toast.error(errorMessage)
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error rejecting request:', error)
|
||||
const errorMessage = 'Ошибка при отклонении заявки'
|
||||
setError(errorMessage)
|
||||
toast.error(errorMessage)
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}, [respondToRequestMutation])
|
||||
},
|
||||
[respondToRequestMutation],
|
||||
)
|
||||
|
||||
// Отменить исходящую заявку
|
||||
const cancelRequest = useCallback(async (requestId: string) => {
|
||||
setLoading(true)
|
||||
setError(null)
|
||||
const cancelRequest = useCallback(
|
||||
async (requestId: string) => {
|
||||
setLoading(true)
|
||||
setError(null)
|
||||
|
||||
try {
|
||||
const { data } = await cancelRequestMutation({
|
||||
variables: { requestId },
|
||||
})
|
||||
try {
|
||||
const { data } = await cancelRequestMutation({
|
||||
variables: { requestId },
|
||||
})
|
||||
|
||||
if (data?.cancelCounterpartyRequest?.success) {
|
||||
toast.success('Заявка отменена')
|
||||
} else {
|
||||
const errorMessage = data?.cancelCounterpartyRequest?.message || 'Не удалось отменить заявку'
|
||||
if (data?.cancelCounterpartyRequest?.success) {
|
||||
toast.success('Заявка отменена')
|
||||
} else {
|
||||
const errorMessage = data?.cancelCounterpartyRequest?.message || 'Не удалось отменить заявку'
|
||||
setError(errorMessage)
|
||||
toast.error(errorMessage)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error canceling request:', error)
|
||||
const errorMessage = 'Ошибка при отмене заявки'
|
||||
setError(errorMessage)
|
||||
toast.error(errorMessage)
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error canceling request:', error)
|
||||
const errorMessage = 'Ошибка при отмене заявки'
|
||||
setError(errorMessage)
|
||||
toast.error(errorMessage)
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}, [cancelRequestMutation])
|
||||
},
|
||||
[cancelRequestMutation],
|
||||
)
|
||||
|
||||
// Отправить заявку на партнерство
|
||||
const sendRequest = useCallback(async (organizationId: string, message?: string) => {
|
||||
setLoading(true)
|
||||
setError(null)
|
||||
const sendRequest = useCallback(
|
||||
async (organizationId: string, message?: string) => {
|
||||
setLoading(true)
|
||||
setError(null)
|
||||
|
||||
try {
|
||||
const { data } = await sendRequestMutation({
|
||||
variables: {
|
||||
organizationId,
|
||||
message: message || 'Предлагаем партнерское сотрудничество',
|
||||
},
|
||||
})
|
||||
try {
|
||||
const { data } = await sendRequestMutation({
|
||||
variables: {
|
||||
input: {
|
||||
receiverId: organizationId,
|
||||
message: message || 'Предлагаем партнерское сотрудничество',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
if (data?.sendCounterpartyRequest?.success) {
|
||||
toast.success('Заявка отправлена! Ожидайте ответа от организации')
|
||||
} else {
|
||||
const errorMessage = data?.sendCounterpartyRequest?.message || 'Не удалось отправить заявку'
|
||||
if (data?.sendCounterpartyRequest?.success) {
|
||||
toast.success('Заявка отправлена! Ожидайте ответа от организации')
|
||||
} else {
|
||||
const errorMessage = data?.sendCounterpartyRequest?.message || 'Не удалось отправить заявку'
|
||||
setError(errorMessage)
|
||||
toast.error(errorMessage)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error sending request:', error)
|
||||
const errorMessage = 'Ошибка при отправке заявки'
|
||||
setError(errorMessage)
|
||||
toast.error(errorMessage)
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error sending request:', error)
|
||||
const errorMessage = 'Ошибка при отправке заявки'
|
||||
setError(errorMessage)
|
||||
toast.error(errorMessage)
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}, [sendRequestMutation])
|
||||
},
|
||||
[sendRequestMutation],
|
||||
)
|
||||
|
||||
// Удалить контрагента
|
||||
const removeCounterparty = useCallback(async (organizationId: string) => {
|
||||
setLoading(true)
|
||||
setError(null)
|
||||
const removeCounterparty = useCallback(
|
||||
async (organizationId: string) => {
|
||||
setLoading(true)
|
||||
setError(null)
|
||||
|
||||
try {
|
||||
const { data } = await removeCounterpartyMutation({
|
||||
variables: { organizationId },
|
||||
})
|
||||
try {
|
||||
const { data } = await removeCounterpartyMutation({
|
||||
variables: { organizationId },
|
||||
})
|
||||
|
||||
if (data?.removeCounterparty?.success) {
|
||||
toast.success('Контрагент удален из списка')
|
||||
} else {
|
||||
const errorMessage = data?.removeCounterparty?.message || 'Не удалось удалить контрагента'
|
||||
if (data?.removeCounterparty?.success) {
|
||||
toast.success('Контрагент удален из списка')
|
||||
} else {
|
||||
const errorMessage = data?.removeCounterparty?.message || 'Не удалось удалить контрагента'
|
||||
setError(errorMessage)
|
||||
toast.error(errorMessage)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error removing counterparty:', error)
|
||||
const errorMessage = 'Ошибка при удалении контрагента'
|
||||
setError(errorMessage)
|
||||
toast.error(errorMessage)
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error removing counterparty:', error)
|
||||
const errorMessage = 'Ошибка при удалении контрагента'
|
||||
setError(errorMessage)
|
||||
toast.error(errorMessage)
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}, [removeCounterpartyMutation])
|
||||
},
|
||||
[removeCounterpartyMutation],
|
||||
)
|
||||
|
||||
return {
|
||||
// Действия с заявками
|
||||
@ -233,4 +254,4 @@ export function useCounterpartyActions(): UseCounterpartyActionsReturn {
|
||||
loading,
|
||||
error,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,12 +14,7 @@ import {
|
||||
} from '@/graphql/queries'
|
||||
import { GET_MY_PARTNER_LINK } from '@/graphql/referral-queries'
|
||||
|
||||
import type {
|
||||
UseCounterpartyDataReturn,
|
||||
Organization,
|
||||
CounterpartyRequest,
|
||||
OrganizationType,
|
||||
} from '../types'
|
||||
import type { UseCounterpartyDataReturn, Organization, CounterpartyRequest, OrganizationType } from '../types'
|
||||
|
||||
export function useCounterpartyData(): UseCounterpartyDataReturn {
|
||||
const [searchResults, setSearchResults] = useState<Organization[]>([])
|
||||
@ -45,8 +40,21 @@ export function useCounterpartyData(): UseCounterpartyDataReturn {
|
||||
refetch: refetchIncoming,
|
||||
} = useQuery(GET_INCOMING_REQUESTS, {
|
||||
errorPolicy: 'all',
|
||||
onCompleted: (data) => {
|
||||
console.warn('🎯 INCOMING_REQUESTS ФРОНТЕНД:', {
|
||||
requestsCount: data?.incomingRequests?.length || 0,
|
||||
requests:
|
||||
data?.incomingRequests?.map((r: CounterpartyRequest) => ({
|
||||
id: r.id,
|
||||
senderId: r.sender?.id,
|
||||
senderName: r.sender?.name || r.sender?.fullName,
|
||||
status: r.status,
|
||||
})) || [],
|
||||
timestamp: new Date().toISOString(),
|
||||
})
|
||||
},
|
||||
onError: (error) => {
|
||||
console.error('Error loading incoming requests:', error)
|
||||
console.error('❌ Error loading incoming requests:', error)
|
||||
setError('Ошибка загрузки входящих заявок')
|
||||
},
|
||||
})
|
||||
@ -88,7 +96,7 @@ export function useCounterpartyData(): UseCounterpartyDataReturn {
|
||||
try {
|
||||
// Используем Apollo Client напрямую для поиска
|
||||
const { apolloClient } = await import('@/lib/apollo-client')
|
||||
|
||||
|
||||
const variables: { search: string; type?: string } = { search: query }
|
||||
if (type && type !== 'all') {
|
||||
variables.type = type
|
||||
@ -118,14 +126,9 @@ export function useCounterpartyData(): UseCounterpartyDataReturn {
|
||||
// Обновление всех данных
|
||||
const refetchAll = useCallback(async () => {
|
||||
setError(null)
|
||||
|
||||
|
||||
try {
|
||||
await Promise.all([
|
||||
refetchCounterparties(),
|
||||
refetchIncoming(),
|
||||
refetchOutgoing(),
|
||||
refetchPartnerLink(),
|
||||
])
|
||||
await Promise.all([refetchCounterparties(), refetchIncoming(), refetchOutgoing(), refetchPartnerLink()])
|
||||
} catch (error) {
|
||||
console.error('Error refetching data:', error)
|
||||
setError('Ошибка обновления данных')
|
||||
@ -133,9 +136,9 @@ export function useCounterpartyData(): UseCounterpartyDataReturn {
|
||||
}, [refetchCounterparties, refetchIncoming, refetchOutgoing, refetchPartnerLink])
|
||||
|
||||
// Извлечение данных из responses
|
||||
const counterparties: Organization[] = counterpartiesData?.getMyCounterparties || []
|
||||
const incomingRequests: CounterpartyRequest[] = incomingData?.getIncomingCounterpartyRequests || []
|
||||
const outgoingRequests: CounterpartyRequest[] = outgoingData?.getOutgoingCounterpartyRequests || []
|
||||
const counterparties: Organization[] = counterpartiesData?.myCounterparties || []
|
||||
const incomingRequests: CounterpartyRequest[] = incomingData?.incomingRequests || []
|
||||
const outgoingRequests: CounterpartyRequest[] = outgoingData?.outgoingRequests || []
|
||||
const partnerLink: string | null = partnerLinkData?.myPartnerLink || null
|
||||
|
||||
return {
|
||||
@ -160,4 +163,4 @@ export function useCounterpartyData(): UseCounterpartyDataReturn {
|
||||
refetchAll,
|
||||
searchOrganizations,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user