Files
sfera-new/src/components/market/market-counterparties/hooks/useCounterpartyActions.ts
Veronika Smirnova fe24b73634 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>
2025-09-19 23:23:03 +03:00

258 lines
8.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Hook для управления действиями с контрагентами
* Обрабатывает все GraphQL mutations и их результаты
*/
import { useMutation } from '@apollo/client'
import { useCallback, useState } from 'react'
import { toast } from 'sonner'
import {
RESPOND_TO_COUNTERPARTY_REQUEST,
CANCEL_COUNTERPARTY_REQUEST,
REMOVE_COUNTERPARTY,
SEND_COUNTERPARTY_REQUEST,
} from '@/graphql/mutations'
import {
GET_MY_COUNTERPARTIES,
GET_INCOMING_REQUESTS,
GET_OUTGOING_REQUESTS,
SEARCH_ORGANIZATIONS,
} from '@/graphql/queries'
import type { UseCounterpartyActionsReturn } from '../types'
export function useCounterpartyActions(): UseCounterpartyActionsReturn {
const [loading, setLoading] = useState(false)
const [error, setError] = useState<string | null>(null)
// Mutation для ответа на заявку (принять/отклонить)
const [respondToRequestMutation] = useMutation(RESPOND_TO_COUNTERPARTY_REQUEST, {
refetchQueries: [
{ query: GET_INCOMING_REQUESTS },
{ query: GET_MY_COUNTERPARTIES },
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'SELLER' } },
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'FULFILLMENT' } },
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'LOGIST' } },
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'WHOLESALE' } },
],
awaitRefetchQueries: true,
})
// Mutation для отмены исходящей заявки
const [cancelRequestMutation] = useMutation(CANCEL_COUNTERPARTY_REQUEST, {
refetchQueries: [
{ query: GET_OUTGOING_REQUESTS },
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'SELLER' } },
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'FULFILLMENT' } },
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'LOGIST' } },
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'WHOLESALE' } },
],
awaitRefetchQueries: true,
})
// Mutation для удаления контрагента
const [removeCounterpartyMutation] = useMutation(REMOVE_COUNTERPARTY, {
refetchQueries: [
{ query: GET_MY_COUNTERPARTIES },
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'SELLER' } },
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'FULFILLMENT' } },
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'LOGIST' } },
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'WHOLESALE' } },
],
awaitRefetchQueries: true,
})
// Mutation для отправки заявки на партнерство
const [sendRequestMutation] = useMutation(SEND_COUNTERPARTY_REQUEST, {
refetchQueries: [
{ query: GET_OUTGOING_REQUESTS },
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'SELLER' } },
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'FULFILLMENT' } },
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'LOGIST' } },
{ query: SEARCH_ORGANIZATIONS, variables: { type: 'WHOLESALE' } },
],
awaitRefetchQueries: true,
})
// Принять заявку на партнерство
const acceptRequest = useCallback(
async (requestId: string) => {
setLoading(true)
setError(null)
try {
const { data } = await respondToRequestMutation({
variables: {
input: {
requestId,
action: 'APPROVE',
},
},
})
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)
}
},
[respondToRequestMutation],
)
// Отклонить заявку на партнерство
const rejectRequest = useCallback(
async (requestId: string) => {
setLoading(true)
setError(null)
try {
const { data } = await respondToRequestMutation({
variables: {
input: {
requestId,
action: 'REJECT',
},
},
})
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)
}
},
[respondToRequestMutation],
)
// Отменить исходящую заявку
const cancelRequest = useCallback(
async (requestId: string) => {
setLoading(true)
setError(null)
try {
const { data } = await cancelRequestMutation({
variables: { requestId },
})
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)
}
},
[cancelRequestMutation],
)
// Отправить заявку на партнерство
const sendRequest = useCallback(
async (organizationId: string, message?: string) => {
setLoading(true)
setError(null)
try {
const { data } = await sendRequestMutation({
variables: {
input: {
receiverId: organizationId,
message: 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)
}
},
[sendRequestMutation],
)
// Удалить контрагента
const removeCounterparty = useCallback(
async (organizationId: string) => {
setLoading(true)
setError(null)
try {
const { data } = await removeCounterpartyMutation({
variables: { organizationId },
})
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)
}
},
[removeCounterpartyMutation],
)
return {
// Действия с заявками
acceptRequest,
rejectRequest,
cancelRequest,
sendRequest,
// Действия с контрагентами
removeCounterparty,
// Состояние
loading,
error,
}
}