
КРИТИЧЕСКИЕ ИСПРАВЛЕНИЯ: - Исправлено отображение входящих заявок (неправильное извлечение данных) - Устранен 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>
258 lines
8.4 KiB
TypeScript
258 lines
8.4 KiB
TypeScript
/**
|
||
* 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,
|
||
}
|
||
}
|